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)
195 lines
7.3 KiB
Java
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;
|
|
}
|
|
}
|