Files
mc-mesh/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MeshingTest3.java
BananaPuncher714 7c49e004b7 Speedup the mesh simplification
Change EdgeSet to use LinkedHashSet for better iteration, potentially.
Map polygon points to existing vertices to reduce unnecessary vertex duplication
Attempt to merge overlapping edges initially before doing anything else when simplifying
Use tree sets instead of priority queues for constant time poll
Split intersection calculation method into two separate methods
Rework which edges are actively within the scan zone to reduce the amount of edges to check when looking for intersections. This should help make the entire algorithm closer to O(nlogn)
Removed intersection classes
Added method to resolve only collinear edges around a vertex
Added method to resolve edge intersections directly from the edge, rather than the positive side
Added simple Y check to see if two edges can even intersect
Added method to calculate absolute vector
Added test plane by default to MeshingTest2(the plane viewer)
2025-05-25 21:34:35 -04:00

195 lines
7.3 KiB
Java

package com.aaaaahhhhhhh.bananapuncher714.minietest;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.util.Vector;
import com.aaaaahhhhhhh.bananapuncher714.mesh.Mesh;
import com.aaaaahhhhhhh.bananapuncher714.mesh.Polygon;
import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionRuleWinding;
import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionSimple;
import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionSimple.GluWindingRule;
import com.aaaaahhhhhhh.bananapuncher714.minietest.MeshingTest2.AABB;
import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.ChunkLocation;
import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.mesh.Facet;
import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.mesh.MeshBuilder;
import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.mesh.Plane;
public class MeshingTest3 {
private static final File BASE = new File( System.getProperty( "user.dir" ) );
private static final File CHUNK_DIR = new File( BASE, "chunks" );
public static void main( String[] args ) {
if ( CHUNK_DIR.exists() && CHUNK_DIR.isDirectory() ) {
System.out.println( "Found " + CHUNK_DIR.list().length + " files" );
for ( int i = 0; i < CHUNK_DIR.listFiles().length; ++i ) {
final File file = CHUNK_DIR.listFiles()[ i ];
System.out.println( ( i + 1 ) + "/" + CHUNK_DIR.listFiles().length + ":\tMeshing " + file );
long start = System.currentTimeMillis();
final List< Plane > planes = mesh( file );
planes.parallelStream().forEach( p -> {
try {
process( p );
} catch ( IllegalStateException e ) {
e.printStackTrace();
System.exit( 1 );
}
} );
long time = System.currentTimeMillis() - start;
System.out.println( "\tTook " + time + "ms" );
}
// final List< Plane > planes = mesh( new File( CHUNK_DIR, "world,-10,-10" ) ); // 25
// for ( int i = 0; i < planes.size(); ++i ) {
// System.out.println( "Meshing plane " + i );
// process( planes.get( i ) );
// }
// process( planes.get( 27 ) );
} else {
System.err.println( "No such directory exists: " + CHUNK_DIR );
}
}
private static void process( final Plane plane ) {
if ( plane != null ) {
Mesh< RegionSimple > mesh = new Mesh< RegionSimple >( () -> { return new RegionSimple( GluWindingRule.ODD ); } );
for ( Polygon poly : plane.polygons ) {
mesh.addPolygon( poly, RegionRuleWinding.CLOCKWISE );
}
mesh.meshify();
} else {
System.out.println( "No data!" );
}
}
private static List< Plane > mesh( File file ) {
String name = file.getName();
String[] split = name.split( "," );
ChunkLocation location = new ChunkLocation( split[ 0 ], Integer.parseInt( split[ 1 ] ), Integer.parseInt( split[ 2 ] ) );
System.out.println( "\tParsing chunk " + location );
// First parse the file to get a list of all bounding boxes that we can use
List< AABB > boxes = new ArrayList< AABB >();
try ( BufferedReader reader = new BufferedReader( new FileReader( file ) ) ) {
String line;
while ( ( line = reader.readLine() ) != null ) {
if ( !line.isEmpty() ) {
String[] values = line.split( "," );
double minX = Double.parseDouble( values[ 0 ] );
double minY = Double.parseDouble( values[ 1 ] );
double minZ = Double.parseDouble( values[ 2 ] );
double maxX = Double.parseDouble( values[ 3 ] );
double maxY = Double.parseDouble( values[ 4 ] );
double maxZ = Double.parseDouble( values[ 5 ] );
boxes.add( new AABB( minX, minY, minZ, maxX, maxY, maxZ ) );
}
}
} catch ( FileNotFoundException e ) {
e.printStackTrace();
return null;
} catch ( IOException e ) {
e.printStackTrace();
return null;
}
System.out.println( "\tFound " + boxes.size() + " boxes" );
// Now that we have a bunch of bounding boxes, do whatever
MeshBuilder builder = new MeshBuilder();
for ( AABB box : boxes ) {
for ( Facet facet : generateFacetsFor( box ) ) {
builder.addFacet( facet );
}
}
return builder.planes;
}
private static List< Facet > generateFacetsFor( AABB box ) {
List< Facet > facets = new ArrayList< Facet >();
Vector p1 = new Vector( box.xmin, box.ymin, box.zmin );
Vector p2 = new Vector( box.xmin, box.ymin, box.zmax );
Vector p3 = new Vector( box.xmin, box.ymax, box.zmin );
Vector p4 = new Vector( box.xmin, box.ymax, box.zmax );
Vector p5 = new Vector( box.xmax, box.ymin, box.zmin );
Vector p6 = new Vector( box.xmax, box.ymin, box.zmax );
Vector p7 = new Vector( box.xmax, box.ymax, box.zmin );
Vector p8 = new Vector( box.xmax, box.ymax, box.zmax );
{
Facet facet = new Facet();
facet.points.add( p1 );
facet.points.add( p2 );
facet.points.add( p4 );
facet.points.add( p3 );
facet.normal = new Vector( -1, 0, 0 );
facets.add( facet );
}
{
Facet facet = new Facet();
facet.points.add( p5 );
facet.points.add( p6 );
facet.points.add( p8 );
facet.points.add( p7 );
facet.normal = new Vector( 1, 0, 0 );
facets.add( facet );
}
{
Facet facet = new Facet();
facet.points.add( p1 );
facet.points.add( p2 );
facet.points.add( p6 );
facet.points.add( p5 );
facet.normal = new Vector( 0, -1, 0 );
facets.add( facet );
}
{
Facet facet = new Facet();
facet.points.add( p3 );
facet.points.add( p4 );
facet.points.add( p8 );
facet.points.add( p7 );
facet.normal = new Vector( 0, 1, 0 );
facets.add( facet );
}
{
Facet facet = new Facet();
facet.points.add( p1 );
facet.points.add( p3 );
facet.points.add( p7 );
facet.points.add( p5 );
facet.normal = new Vector( 0, 0, -1 );
facets.add( facet );
}
{
Facet facet = new Facet();
facet.points.add( p2 );
facet.points.add( p4 );
facet.points.add( p8 );
facet.points.add( p6 );
facet.normal = new Vector( 0, 0, 1 );
facets.add( facet );
}
return facets;
}
}