Introduce fuzzy iterating when finding chains; Found another bug when detecting chain collisions
This commit is contained in:
@@ -231,6 +231,25 @@ public class Mesh< T extends Region > {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return A collection of triangles
|
||||||
|
*/
|
||||||
|
public Collection< Polygon > meshify() {
|
||||||
|
switch ( state ) {
|
||||||
|
case DIRTY:
|
||||||
|
simplify();
|
||||||
|
case SIMPLIFIED:
|
||||||
|
generateRegions();
|
||||||
|
case TRIANGULATION_READY:
|
||||||
|
return mesh();
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException( "Invalid mesh state!" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do a check over all vertices to see if there are any within
|
* Do a check over all vertices to see if there are any within
|
||||||
* VERTEX_TOLERANCE of each other. If so, then merge them.
|
* VERTEX_TOLERANCE of each other. If so, then merge them.
|
||||||
@@ -973,13 +992,13 @@ public class Mesh< T extends Region > {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Have a single set of edges
|
// Have a single set of edges
|
||||||
final TreeSet< Vertex > vertices = new TreeSet< Vertex >( Mesh::compare );
|
final TreeSet< Vertex > fuzzyVertices = new TreeSet< Vertex >( Mesh::fuzzyCompare );
|
||||||
vertices.addAll( newVertices.values() );
|
fuzzyVertices.addAll( newVertices.values() );
|
||||||
|
|
||||||
// Sort each vertex so that the edge they are pointing to is the least edge
|
// Sort each vertex so that the edge they are pointing to is the least edge
|
||||||
vertices.parallelStream().forEach( v -> sort( v ) );
|
fuzzyVertices.parallelStream().forEach( v -> sort( v ) );
|
||||||
|
|
||||||
final Collection< Link > allChains = findChains( vertices, edges );
|
final Collection< Link > allChains = findChains( fuzzyVertices, edges );
|
||||||
final Collection< Link > chains = maximizeChains( allChains );
|
final Collection< Link > chains = maximizeChains( allChains );
|
||||||
if ( !handlers.isEmpty() ) {
|
if ( !handlers.isEmpty() ) {
|
||||||
final Collection< Chain > newChains = new HashSet< Chain >();
|
final Collection< Chain > newChains = new HashSet< Chain >();
|
||||||
@@ -1034,10 +1053,15 @@ public class Mesh< T extends Region > {
|
|||||||
|
|
||||||
mergeChains( chains, edges );
|
mergeChains( chains, edges );
|
||||||
|
|
||||||
return partitionMonotone( vertices, edges ).parallelStream()
|
// return Collections.emptySet();
|
||||||
.map( Mesh::triangulate )
|
final TreeSet< Vertex > vertices = new TreeSet< Vertex >( Mesh::compare );
|
||||||
.flatMap( p -> p.parallelStream() )
|
vertices.addAll( fuzzyVertices );
|
||||||
.collect( Collectors.toSet() );
|
|
||||||
|
return Collections.emptySet();
|
||||||
|
// return partitionMonotone( vertices, edges ).parallelStream()
|
||||||
|
// .map( Mesh::triangulate )
|
||||||
|
// .flatMap( p -> p.parallelStream() )
|
||||||
|
// .collect( Collectors.toSet() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1431,6 +1455,10 @@ public class Mesh< T extends Region > {
|
|||||||
// The new chain is a continuation of this chain
|
// The new chain is a continuation of this chain
|
||||||
other.next = chain;
|
other.next = chain;
|
||||||
chain.previous = other;
|
chain.previous = other;
|
||||||
|
} else if ( chainMidpoint == other.getOrigin() && chainDestination == other.getMidpoint() ) {
|
||||||
|
System.out.println( "BUG" );
|
||||||
|
other.previous = chain;
|
||||||
|
chain.next = other;
|
||||||
} else if ( compare( other.getDest(), chainOrigin ) > 0 ) {
|
} else if ( compare( other.getDest(), chainOrigin ) > 0 ) {
|
||||||
// Do the chains even overlap?
|
// Do the chains even overlap?
|
||||||
if ( chainOrigin == other.getMidpoint() ) {
|
if ( chainOrigin == other.getMidpoint() ) {
|
||||||
@@ -1457,6 +1485,31 @@ public class Mesh< T extends Region > {
|
|||||||
intersects = otherDirection.cross( secondLink.toVector2d() ) < 0 ^ cross < 0;
|
intersects = otherDirection.cross( secondLink.toVector2d() ) < 0 ^ cross < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( intersects ) {
|
||||||
|
synchronized ( intersections ) {
|
||||||
|
intersections.add( other );
|
||||||
|
}
|
||||||
|
other.intersections.add( chain );
|
||||||
|
}
|
||||||
|
} else if ( chainDestination == other.getMidpoint() ) {
|
||||||
|
System.out.println( "BUG 2" );
|
||||||
|
final Vector2d otherDirection = other.getDest().getPosition().subtracted( other.getOrigin().getPosition() );
|
||||||
|
final double cross = r.cross( otherDirection );
|
||||||
|
|
||||||
|
boolean intersects = true;
|
||||||
|
final HalfEdge firstLink = other.links.get( 0 );
|
||||||
|
final HalfEdge secondLink = other.links.get( 1 );
|
||||||
|
if ( firstLink.getDest() == other.getMidpoint() ) {
|
||||||
|
// Is the first link a direct connection?
|
||||||
|
intersects = interior.contains( firstLink ) ^ cross < 0;
|
||||||
|
} else if ( secondLink.getDest() == other.getDest() ) {
|
||||||
|
// Is the second link a direct connection?
|
||||||
|
intersects = interior.contains( secondLink ) ^ cross < 0;
|
||||||
|
} else {
|
||||||
|
// The chain is comprised of only vertices...
|
||||||
|
intersects = otherDirection.cross( secondLink.toVector2d() ) < 0 ^ cross < 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ( intersects ) {
|
if ( intersects ) {
|
||||||
synchronized ( intersections ) {
|
synchronized ( intersections ) {
|
||||||
intersections.add( other );
|
intersections.add( other );
|
||||||
@@ -1478,6 +1531,27 @@ public class Mesh< T extends Region > {
|
|||||||
intersects = r.cross( secondEdgeVec ) < 0 ^ cross < 0;
|
intersects = r.cross( secondEdgeVec ) < 0 ^ cross < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( intersects ) {
|
||||||
|
synchronized ( intersections ) {
|
||||||
|
intersections.add( other );
|
||||||
|
}
|
||||||
|
other.intersections.add( chain );
|
||||||
|
}
|
||||||
|
} else if ( other.getOrigin() == chainMidpoint ) {
|
||||||
|
// Third and last case
|
||||||
|
// destination. We need to check for that case too.
|
||||||
|
final Vector2d otherDirection = other.getDest().getPosition().subtracted( other.getOrigin().getPosition() ).normalize();
|
||||||
|
final double cross = r.cross( otherDirection );
|
||||||
|
|
||||||
|
boolean intersects = true;
|
||||||
|
if ( firstEdge.getDest() == chainMidpoint ) {
|
||||||
|
intersects = interior.contains( firstEdge ) ^ cross < 0;
|
||||||
|
} else if ( secondEdge.getDest() == chainDestination ) {
|
||||||
|
intersects = interior.contains( secondEdge ) ^ cross < 0;
|
||||||
|
} else {
|
||||||
|
intersects = r.cross( secondEdgeVec ) < 0 ^ cross < 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ( intersects ) {
|
if ( intersects ) {
|
||||||
synchronized ( intersections ) {
|
synchronized ( intersections ) {
|
||||||
intersections.add( other );
|
intersections.add( other );
|
||||||
@@ -1808,8 +1882,6 @@ public class Mesh< T extends Region > {
|
|||||||
throw new IllegalStateException( "Lower partition not found!" );
|
throw new IllegalStateException( "Lower partition not found!" );
|
||||||
}
|
}
|
||||||
|
|
||||||
top.chains.addAll( bottom.chains );
|
|
||||||
|
|
||||||
lowerEdgeMap.remove( bottom.upper );
|
lowerEdgeMap.remove( bottom.upper );
|
||||||
|
|
||||||
// Merge the top and bottom partition
|
// Merge the top and bottom partition
|
||||||
@@ -1821,7 +1893,13 @@ public class Mesh< T extends Region > {
|
|||||||
// Update all visibility regions for the top and bottom partitions, separately
|
// Update all visibility regions for the top and bottom partitions, separately
|
||||||
top.incrementLower( topLeft );
|
top.incrementLower( topLeft );
|
||||||
bottom.incrementUpper( bottomLeft );
|
bottom.incrementUpper( bottomLeft );
|
||||||
|
|
||||||
|
// Problem... need to make bottom chains and top chains the same because merging regions must use the same chain map...
|
||||||
|
// TODO Do it... make a reverse region map for each chain... it only makes some sense...
|
||||||
|
// And then technically just combine all chain maps at the end because that also only makes sense
|
||||||
|
// Fixes the issues...
|
||||||
|
top.chains.addAll( bottom.chains );
|
||||||
|
|
||||||
// Merge the two partitions
|
// Merge the two partitions
|
||||||
top.add( bottom );
|
top.add( bottom );
|
||||||
|
|
||||||
@@ -2342,6 +2420,7 @@ public class Mesh< T extends Region > {
|
|||||||
if ( upper == null ) {
|
if ( upper == null ) {
|
||||||
throw new IllegalStateException( "Lower does not have an upper edge!" );
|
throw new IllegalStateException( "Lower does not have an upper edge!" );
|
||||||
} if ( !interior.contains( upper.getSym() ) ) {
|
} if ( !interior.contains( upper.getSym() ) ) {
|
||||||
|
System.out.println( upper );
|
||||||
throw new IllegalStateException( "Polygon is not simple!" );
|
throw new IllegalStateException( "Polygon is not simple!" );
|
||||||
} else if ( upper.getOrigin() == event || lower.getOrigin() == event ) {
|
} else if ( upper.getOrigin() == event || lower.getOrigin() == event ) {
|
||||||
throw new IllegalStateException( "Vertex is invalid!" );
|
throw new IllegalStateException( "Vertex is invalid!" );
|
||||||
@@ -2641,8 +2720,11 @@ public class Mesh< T extends Region > {
|
|||||||
|
|
||||||
// Lazy solution, just sort the vertices
|
// Lazy solution, just sort the vertices
|
||||||
// Eventually we will remove this
|
// Eventually we will remove this
|
||||||
|
// TODO Remove this NOW
|
||||||
toSort.parallelStream().forEach( v -> sort( v ) );
|
toSort.parallelStream().forEach( v -> sort( v ) );
|
||||||
|
|
||||||
|
Map< Vertex, Point > pointMap = polygon.vertices.parallelStream().collect( Collectors.toMap( Function.identity(), v -> { return new Point( v.getPosition() ); } ) );
|
||||||
|
|
||||||
final Collection< Polygon > polygons = new ArrayDeque< Polygon >();
|
final Collection< Polygon > polygons = new ArrayDeque< Polygon >();
|
||||||
final Set< HalfEdge > scanned = new HashSet< HalfEdge >();
|
final Set< HalfEdge > scanned = new HashSet< HalfEdge >();
|
||||||
for ( final HalfEdge edge : polygon.getEdges() ) {
|
for ( final HalfEdge edge : polygon.getEdges() ) {
|
||||||
@@ -2651,7 +2733,7 @@ public class Mesh< T extends Region > {
|
|||||||
|
|
||||||
final List< Point > points = new ArrayList< Point >();
|
final List< Point > points = new ArrayList< Point >();
|
||||||
do {
|
do {
|
||||||
points.add( new Point( temp.getOrigin().getPosition() ) );
|
points.add( pointMap.get( temp.getOrigin() ) );
|
||||||
} while ( scanned.add( temp = temp.getNext() ) );
|
} while ( scanned.add( temp = temp.getNext() ) );
|
||||||
|
|
||||||
if ( points.size() != 3 ) {
|
if ( points.size() != 3 ) {
|
||||||
@@ -2701,10 +2783,32 @@ public class Mesh< T extends Region > {
|
|||||||
* @param edge
|
* @param edge
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean isPositive( HalfEdge edge ) {
|
private static boolean isPositive( HalfEdge edge ) {
|
||||||
return compare( edge.getOrigin(), edge.getDest() ) <= 0;
|
return compare( edge.getOrigin(), edge.getDest() ) <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since sometimes vertices will be off by a few floating point errors,
|
||||||
|
* it will cause problems because we have checks for tolerance, but if
|
||||||
|
* the sorting for vertices does not, it causes issues.
|
||||||
|
*/
|
||||||
|
private static int fuzzyCompare( final Vertex a, final Vertex b ) {
|
||||||
|
if ( a == b ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
final Vector2d aPos = a.getPosition();
|
||||||
|
final Vector2d bPos = b.getPosition();
|
||||||
|
|
||||||
|
final double xDiff = aPos.getX() - bPos.getX();
|
||||||
|
if ( Math.abs( xDiff ) < VERTEX_TOLERANCE ) {
|
||||||
|
return Double.compare( aPos.getY(), bPos.getY() );
|
||||||
|
} else {
|
||||||
|
return Double.compare( aPos.getX(), bPos.getX() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static int compare( final Vertex a, final Vertex b ) {
|
private static int compare( final Vertex a, final Vertex b ) {
|
||||||
if ( a == b ) {
|
if ( a == b ) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.aaaaahhhhhhh.bananapuncher714.minietest;
|
|||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.FlowLayout;
|
import java.awt.FlowLayout;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
@@ -24,24 +25,24 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import com.aaaaahhhhhhh.bananapuncher714.mesh.Chain;
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.Chain;
|
||||||
import com.aaaaahhhhhhh.bananapuncher714.mesh.HalfEdge;
|
|
||||||
import com.aaaaahhhhhhh.bananapuncher714.mesh.Mesh;
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.Mesh;
|
||||||
import com.aaaaahhhhhhh.bananapuncher714.mesh.Mesh.MeshEventHandler;
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.Mesh.MeshEventHandler;
|
||||||
import com.aaaaahhhhhhh.bananapuncher714.mesh.Point;
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.Point;
|
||||||
import com.aaaaahhhhhhh.bananapuncher714.mesh.Polygon;
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.Polygon;
|
||||||
import com.aaaaahhhhhhh.bananapuncher714.mesh.Segment;
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.Segment;
|
||||||
import com.aaaaahhhhhhh.bananapuncher714.mesh.Vector2d;
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.Vector2d;
|
||||||
import com.aaaaahhhhhhh.bananapuncher714.mesh.Vertex;
|
|
||||||
import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionRuleWinding;
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionRuleWinding;
|
||||||
import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionSimple;
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionSimple;
|
||||||
import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionSimple.GluWindingRule;
|
import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionSimple.GluWindingRule;
|
||||||
@@ -73,26 +74,31 @@ public class MeshingTest2 extends JPanel {
|
|||||||
|
|
||||||
private double scale = 8;
|
private double scale = 8;
|
||||||
|
|
||||||
private PlaneData data;
|
|
||||||
|
|
||||||
private int stringBoardX = -100;
|
private int stringBoardX = -100;
|
||||||
private int stringBoardY = 20;
|
private int stringBoardY = 20;
|
||||||
|
|
||||||
|
final private List< Plane > planes;
|
||||||
|
final private PlaneData[] data;
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
private JLabel statusBar;
|
||||||
|
private JComboBox< String > selectionBox;
|
||||||
|
|
||||||
public static void main( String[] args ) {
|
public static void main( String[] args ) {
|
||||||
if ( CHUNK_DIR.exists() && CHUNK_DIR.isDirectory() ) {
|
if ( CHUNK_DIR.exists() && CHUNK_DIR.isDirectory() ) {
|
||||||
System.out.println( "Found " + CHUNK_DIR.list().length + " files" );
|
System.out.println( "Found " + CHUNK_DIR.list().length + " files" );
|
||||||
for ( File file : CHUNK_DIR.listFiles() ) {
|
// for ( File file : CHUNK_DIR.listFiles() ) {
|
||||||
List< Plane > planes = mesh( file );
|
// List< Plane > planes = mesh( file );
|
||||||
|
|
||||||
Plane draw = null;
|
// Plane draw = null;
|
||||||
|
|
||||||
System.out.println( "Planes: " + planes.size() );
|
// System.out.println( "Planes: " + planes.size() );
|
||||||
for ( Plane plane : planes ) {
|
// int planeIndex = 0;
|
||||||
if ( plane.polygons.size() > 100 ) {
|
// for ( planeIndex = 0; planeIndex < planes.size(); ++planeIndex ) {
|
||||||
draw = plane;
|
// if ( planes.get( planeIndex ).polygons.size() > 100 ) {
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Collections.sort( planes, ( a, b ) -> Integer.compare( b.polygons.size(), a.polygons.size() ) );
|
// Collections.sort( planes, ( a, b ) -> Integer.compare( b.polygons.size(), a.polygons.size() ) );
|
||||||
// draw = planes.get( 4 );
|
// draw = planes.get( 4 );
|
||||||
@@ -100,7 +106,7 @@ public class MeshingTest2 extends JPanel {
|
|||||||
// Select a random plane to draw
|
// Select a random plane to draw
|
||||||
// draw = planes.get( new Random().nextInt( planes.size() ) );
|
// draw = planes.get( new Random().nextInt( planes.size() ) );
|
||||||
|
|
||||||
System.out.println( "Draw is " + draw );
|
// System.out.println( "Draw is " + draw );
|
||||||
// Attempt to mesh all planes
|
// Attempt to mesh all planes
|
||||||
// try {
|
// try {
|
||||||
// test( planes );
|
// test( planes );
|
||||||
@@ -109,20 +115,43 @@ public class MeshingTest2 extends JPanel {
|
|||||||
// System.out.println( "Draw is now " + draw );
|
// System.out.println( "Draw is now " + draw );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
final PlaneData data = process( draw );
|
// final PlaneData data = process( draw );
|
||||||
final Collection< Polygon > polys = triangulate( draw );
|
// final Collection< Polygon > polys = triangulate( draw );
|
||||||
// final Collection< Polygon > polys = test();
|
// final Collection< Polygon > polys = test();
|
||||||
|
// System.out.println( "Polygon count: " + data.polygons.size() );
|
||||||
|
|
||||||
System.out.println( "Polygon count: " + polys.size() );
|
// final int startingIndex = planeIndex;
|
||||||
|
// SwingUtilities.invokeLater( new Runnable() {
|
||||||
SwingUtilities.invokeLater( new Runnable() {
|
// @Override
|
||||||
@Override
|
// public void run() {
|
||||||
public void run() {
|
// new MeshingTest2( planes ).setIndex( startingIndex ).start();;
|
||||||
new MeshingTest2( data );
|
// }
|
||||||
}
|
// } );
|
||||||
} );
|
// break;
|
||||||
break;
|
// }
|
||||||
}
|
|
||||||
|
List< Plane > masterPlanes = new ArrayList< Plane >();
|
||||||
|
// System.out.println( "Chunk files: " + CHUNK_DIR.listFiles().length );
|
||||||
|
// int limit = 1;
|
||||||
|
// for ( File file : CHUNK_DIR.listFiles() ) {
|
||||||
|
// masterPlanes.addAll( mesh( file ) );
|
||||||
|
// if ( --limit <= 0 ) {
|
||||||
|
// break;
|
||||||
|
// } else {
|
||||||
|
// System.out.println( "Remaining: " + limit );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
final List< Plane > planes = mesh( new File( CHUNK_DIR, "world,-2,1" ) );
|
||||||
|
masterPlanes.add( planes.get( 218 ) );
|
||||||
|
|
||||||
|
// masterPlanes.add( getTestPlane() );
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater( new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
new MeshingTest2( masterPlanes ).start();
|
||||||
|
}
|
||||||
|
} );
|
||||||
} else {
|
} else {
|
||||||
System.err.println( "No such directory exists: " + CHUNK_DIR );
|
System.err.println( "No such directory exists: " + CHUNK_DIR );
|
||||||
}
|
}
|
||||||
@@ -247,11 +276,44 @@ public class MeshingTest2 extends JPanel {
|
|||||||
@Override
|
@Override
|
||||||
public void onPreChainMergeEvent( Collection< Chain > chains ) {
|
public void onPreChainMergeEvent( Collection< Chain > chains ) {
|
||||||
data.selectedChains = chains;
|
data.selectedChains = chains;
|
||||||
|
|
||||||
|
final List< Chain > sorted = new ArrayList< Chain >( chains );
|
||||||
|
Collections.sort( sorted, ( a, b ) -> {
|
||||||
|
final double diff = a.getStart().getX() - b.getStart().getX();
|
||||||
|
if ( Math.abs( diff ) < 1e-7 ) {
|
||||||
|
return Double.compare( a.getStart().getY(), b.getStart().getY() );
|
||||||
|
}
|
||||||
|
return Double.compare( diff, 0 );
|
||||||
|
} );
|
||||||
|
for ( Chain chain : sorted ) {
|
||||||
|
System.out.println( "c: " + chain.getPoints() );
|
||||||
|
}
|
||||||
|
|
||||||
|
final Set< Point > points = new HashSet< Point >();
|
||||||
|
for ( Chain chain : chains ) {
|
||||||
|
for ( int i = 1; i < chain.getPoints().size() - 1; ++i ) {
|
||||||
|
if ( !points.add( chain.getPoints().get( i ) ) ) {
|
||||||
|
System.out.println( "Intersection at " + chain.getPoints().get( i ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
data.polygons = mesh.mesh();
|
data.polygons = mesh.mesh();
|
||||||
|
|
||||||
|
// final List< Point > points = new ArrayList< Point >( data.vertices );
|
||||||
|
// Collections.sort( points, ( a, b ) -> {
|
||||||
|
// final int x = Double.compare( a.getX(), b.getX() );
|
||||||
|
// if ( x == 0 ) {
|
||||||
|
// return Double.compare( a.getY(), b.getY() );
|
||||||
|
// }
|
||||||
|
// return x;
|
||||||
|
// } );
|
||||||
|
// for ( Point v : points ) {
|
||||||
|
// System.out.println( v.getX() + ", " + v.getY() );
|
||||||
|
// }
|
||||||
|
|
||||||
System.out.println( "Took " + ( end - start ) + "ms" );
|
System.out.println( "Took " + ( end - start ) + "ms" );
|
||||||
return data;
|
return data;
|
||||||
} else {
|
} else {
|
||||||
@@ -306,8 +368,24 @@ public class MeshingTest2 extends JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Collection< Polygon > test() {
|
private static PlaneData test() {
|
||||||
Mesh< RegionSimple > mesh = new Mesh< RegionSimple >( () -> { return new RegionSimple( GluWindingRule.ODD ); } );
|
final PlaneData data = new PlaneData();
|
||||||
|
final Mesh< RegionSimple > mesh = new Mesh< RegionSimple >( () -> { return new RegionSimple( GluWindingRule.ODD ); } );
|
||||||
|
mesh.addHandler( new MeshEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void onChainGenerationEvent( Collection< Chain > chains ) {
|
||||||
|
data.chains = chains;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPreChainMergeEvent( Collection< Chain > chains ) {
|
||||||
|
data.selectedChains = chains;
|
||||||
|
|
||||||
|
for ( Chain chain : chains ) {
|
||||||
|
System.out.println( "c: " + chain.getPoints() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
// mesh.addPolygon( new Polygon( Arrays.asList(
|
// mesh.addPolygon( new Polygon( Arrays.asList(
|
||||||
// new Point( -1, 0 ),
|
// new Point( -1, 0 ),
|
||||||
@@ -428,39 +506,64 @@ public class MeshingTest2 extends JPanel {
|
|||||||
// new Point( 2.8151429293905887, -2.747294403063162 )
|
// new Point( 2.8151429293905887, -2.747294403063162 )
|
||||||
// ) ), RegionRuleWinding.CLOCKWISE );
|
// ) ), RegionRuleWinding.CLOCKWISE );
|
||||||
|
|
||||||
mesh.addPolygon( new Polygon( Arrays.asList(
|
// mesh.addPolygon( new Polygon( Arrays.asList(
|
||||||
new Point( 0, 0 ),
|
// new Point( 0, 0 ),
|
||||||
|
// new Point( 1, 0 ),
|
||||||
|
// new Point( 1, 1 ),
|
||||||
|
// new Point( 0, 1 )
|
||||||
|
// ) ), RegionRuleWinding.CLOCKWISE );
|
||||||
|
// mesh.addPolygon( new Polygon( Arrays.asList(
|
||||||
|
// new Point( 0, 2 ),
|
||||||
|
// new Point( 1, 2 ),
|
||||||
|
// new Point( 1, 3 ),
|
||||||
|
// new Point( 0, 3 )
|
||||||
|
// ) ), RegionRuleWinding.CLOCKWISE );
|
||||||
|
// mesh.addPolygon( new Polygon( Arrays.asList(
|
||||||
|
// new Point( -1, -1 ),
|
||||||
|
// new Point( 2, -1 ),
|
||||||
|
// new Point( 2, 4 ),
|
||||||
|
// new Point( -1, 4 )
|
||||||
|
// ) ), RegionRuleWinding.CLOCKWISE );
|
||||||
|
|
||||||
|
data.polygons = mesh.mesh();
|
||||||
|
data.vertices = mesh.getVertices();
|
||||||
|
data.edges = mesh.getEdges();
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Plane getTestPlane() {
|
||||||
|
final Plane plane = new Plane();
|
||||||
|
|
||||||
|
// plane.polygons.add( new Polygon( Arrays.asList(
|
||||||
|
// new Point( 1, 0 ),
|
||||||
|
// new Point( 2, 1 ),
|
||||||
|
// new Point( 3, 0 ),
|
||||||
|
// new Point( 4, 1 ),
|
||||||
|
// new Point( 3, 2 ),
|
||||||
|
// new Point( 4, 3 ),
|
||||||
|
// new Point( 3, 4 ),
|
||||||
|
// new Point( 2, 3 ),
|
||||||
|
// new Point( 1, 4 ),
|
||||||
|
// new Point( 0, 3 ),
|
||||||
|
// new Point( 1, 2 ),
|
||||||
|
// new Point( 0, 1 )
|
||||||
|
plane.polygons.add( new Polygon( Arrays.asList(
|
||||||
new Point( 1, 0 ),
|
new Point( 1, 0 ),
|
||||||
new Point( 1, 1 ),
|
new Point( 2, 1 ),
|
||||||
new Point( 0, 1 )
|
new Point( 3, 0 ),
|
||||||
) ), RegionRuleWinding.CLOCKWISE );
|
new Point( 4, 1 ),
|
||||||
mesh.addPolygon( new Polygon( Arrays.asList(
|
new Point( 3, 2 ),
|
||||||
new Point( 0, 2 ),
|
new Point( 4, 3 ),
|
||||||
|
new Point( 3, 4 ),
|
||||||
|
new Point( 2, 3 ),
|
||||||
|
new Point( 1, 4 ),
|
||||||
|
new Point( 0, 3 ),
|
||||||
new Point( 1, 2 ),
|
new Point( 1, 2 ),
|
||||||
new Point( 1, 3 ),
|
new Point( 0, 1 )
|
||||||
new Point( 0, 3 )
|
) ) );
|
||||||
) ), RegionRuleWinding.CLOCKWISE );
|
|
||||||
mesh.addPolygon( new Polygon( Arrays.asList(
|
|
||||||
new Point( -1, -1 ),
|
|
||||||
new Point( 2, -1 ),
|
|
||||||
new Point( 2, 4 ),
|
|
||||||
new Point( -1, 4 )
|
|
||||||
) ), RegionRuleWinding.CLOCKWISE );
|
|
||||||
|
|
||||||
mesh.simplify();
|
return plane;
|
||||||
|
|
||||||
mesh.generateRegions();
|
|
||||||
|
|
||||||
try {
|
|
||||||
final Collection< Polygon > polys = mesh.mesh();
|
|
||||||
return polys;
|
|
||||||
} catch ( Exception e ) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
final Collection< Polygon > polys = mesh.mesh();
|
|
||||||
|
|
||||||
return polys;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List< Facet > generateFacetsFor( AABB box ) {
|
private static List< Facet > generateFacetsFor( AABB box ) {
|
||||||
@@ -562,8 +665,59 @@ public class MeshingTest2 extends JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MeshingTest2( PlaneData data ) {
|
public MeshingTest2( List< Plane > data ) {
|
||||||
this.data = data;
|
this.planes = data;
|
||||||
|
this.data = new PlaneData[ data.size() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
private MeshingTest2 setIndex( final int index ) {
|
||||||
|
// TODO Synchronize this
|
||||||
|
final int planeCount = planes.size();
|
||||||
|
final int newIndex = ( ( ( index % planeCount ) + planeCount ) % planeCount );
|
||||||
|
if ( this.index != newIndex ) {
|
||||||
|
this.index = newIndex;
|
||||||
|
|
||||||
|
new Thread( () -> { getData( this::repaint ); } ).start();
|
||||||
|
|
||||||
|
if ( selectionBox != null ) {
|
||||||
|
selectionBox.setSelectedIndex( newIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlaneData getData( final Runnable callback ) {
|
||||||
|
if ( data[ index ] != null ) {
|
||||||
|
callback.run();
|
||||||
|
return data[ index ];
|
||||||
|
} else {
|
||||||
|
setStatus( "Loading..." );
|
||||||
|
final PlaneData data = process( planes.set( index, null ) );
|
||||||
|
setStatus( "Done!" );
|
||||||
|
this.data[ index ] = data;
|
||||||
|
callback.run();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setStatus( final String status ) {
|
||||||
|
if ( statusBar != null ) {
|
||||||
|
statusBar.setText( status );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MeshingTest2 preMesh() {
|
||||||
|
for ( int i = 0; i < planes.size(); ++i ) {
|
||||||
|
this.data[ i ] = process( planes.set( i, null ) );
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void start() {
|
||||||
|
if ( index == -1 ) {
|
||||||
|
setIndex( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
f = new JFrame( "Drawing Board" );
|
f = new JFrame( "Drawing Board" );
|
||||||
f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
|
f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
|
||||||
@@ -631,13 +785,45 @@ public class MeshingTest2 extends JPanel {
|
|||||||
};
|
};
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// final JPanel taskbar = new JPanel();
|
final JPanel taskbar = new JPanel();
|
||||||
// taskbar.setLayout( new FlowLayout() );
|
taskbar.setLayout( new FlowLayout() );
|
||||||
//
|
|
||||||
// taskbar.add( new JButton( "Previous" ) );
|
{
|
||||||
// taskbar.add( new JButton( "Next" ) );
|
final JComboBox< String > data = new JComboBox< String >();
|
||||||
//
|
for ( int i = 0; i < planes.size(); ++i ) {
|
||||||
// f.add( taskbar, BorderLayout.NORTH );
|
data.addItem( "Plane " + i );
|
||||||
|
}
|
||||||
|
data.addActionListener( e -> {
|
||||||
|
setIndex( data.getSelectedIndex() );
|
||||||
|
} );
|
||||||
|
taskbar.add( data );
|
||||||
|
|
||||||
|
selectionBox = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final JLabel label = new JLabel();
|
||||||
|
label.setPreferredSize( new Dimension( 100, 16 ) );
|
||||||
|
label.setHorizontalAlignment( SwingConstants.LEFT );
|
||||||
|
taskbar.add( label );
|
||||||
|
|
||||||
|
statusBar = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final JButton prev = new JButton( "Previous" );
|
||||||
|
prev.addActionListener( e -> { setIndex( index - 1 ); } );
|
||||||
|
taskbar.add( prev );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
final JButton prev = new JButton( "Next" );
|
||||||
|
prev.addActionListener( e -> { setIndex( index + 1 ); } );
|
||||||
|
taskbar.add( prev );
|
||||||
|
}
|
||||||
|
|
||||||
|
f.add( taskbar, BorderLayout.NORTH );
|
||||||
|
|
||||||
f.add( this );
|
f.add( this );
|
||||||
|
|
||||||
@@ -665,18 +851,24 @@ public class MeshingTest2 extends JPanel {
|
|||||||
public void paintComponent( Graphics g ) {
|
public void paintComponent( Graphics g ) {
|
||||||
super.paintComponent( g );
|
super.paintComponent( g );
|
||||||
|
|
||||||
|
final PlaneData data = this.data[ index ];
|
||||||
|
|
||||||
g.setColor( new Color( 200, 200, 200 ) );
|
g.setColor( new Color( 200, 200, 200 ) );
|
||||||
g.drawLine( ( int ) ( scale * centerX ) + offsetX, 0, ( int ) ( scale * centerX ) + offsetX, getHeight() );
|
g.drawLine( ( int ) ( scale * centerX ) + offsetX, 0, ( int ) ( scale * centerX ) + offsetX, getHeight() );
|
||||||
g.drawLine( 0, ( int ) ( scale * centerY ) + offsetY, getWidth(), ( int ) ( scale * centerY ) + offsetY );
|
g.drawLine( 0, ( int ) ( scale * centerY ) + offsetY, getWidth(), ( int ) ( scale * centerY ) + offsetY );
|
||||||
g.setColor( Color.BLACK );
|
g.setColor( Color.BLACK );
|
||||||
|
|
||||||
int highestX = 40;
|
|
||||||
if ( data != null ) {
|
if ( data != null ) {
|
||||||
|
int highestX = 40;
|
||||||
if ( !data.edges.isEmpty() ) {
|
if ( !data.edges.isEmpty() ) {
|
||||||
Collection< Point > points = data.vertices;
|
Collection< Point > points = data.vertices;
|
||||||
|
|
||||||
highestX = ( int ) ( points.parallelStream()
|
if ( !data.polygons.isEmpty() ) {
|
||||||
.max( ( a, b ) -> { return Double.compare( a.getX(), b.getX() ); } ).get().getX() + 40.5 );
|
highestX = ( int ) ( points.parallelStream()
|
||||||
|
.max( ( a, b ) -> { return Double.compare( a.getX(), b.getX() ); } ).get().getX() + 40.5 );
|
||||||
|
} else {
|
||||||
|
highestX = 0;
|
||||||
|
}
|
||||||
|
|
||||||
g.setColor( Color.BLACK );
|
g.setColor( Color.BLACK );
|
||||||
for ( final Segment segment : data.edges ) {
|
for ( final Segment segment : data.edges ) {
|
||||||
@@ -694,12 +886,9 @@ public class MeshingTest2 extends JPanel {
|
|||||||
final double diff = scale * 0.15;
|
final double diff = scale * 0.15;
|
||||||
g.drawRect( ( int ) ( ( centerX + point.getX() + highestX ) * scale ) - ( int ) diff + offsetX, ( int ) ( ( centerY - point.getY() ) * scale ) - ( int ) diff + offsetY, ( int ) ( diff * 2 ), ( int ) ( diff * 2 ) );
|
g.drawRect( ( int ) ( ( centerX + point.getX() + highestX ) * scale ) - ( int ) diff + offsetX, ( int ) ( ( centerY - point.getY() ) * scale ) - ( int ) diff + offsetY, ( int ) ( diff * 2 ), ( int ) ( diff * 2 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
drawOnBoard( g, "Edge count: " + data.edges.size(), 0, 0 );
|
|
||||||
drawOnBoard( g, "Vertex count: " + points.size(), 0, -5 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( data.polygons != null ) {
|
{
|
||||||
int count = 2;
|
int count = 2;
|
||||||
Random random = new Random( hashCode() );
|
Random random = new Random( hashCode() );
|
||||||
|
|
||||||
@@ -730,12 +919,9 @@ public class MeshingTest2 extends JPanel {
|
|||||||
g.fillPolygon( filledX, filledY, points.size() );
|
g.fillPolygon( filledX, filledY, points.size() );
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
g.setColor( Color.MAGENTA );
|
|
||||||
drawOnBoard( g, "Polygon count: " + data.polygons.size(), 0, -10 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( data.chains != null ) {
|
{
|
||||||
g.setColor( Color.RED );
|
g.setColor( Color.RED );
|
||||||
for ( final Chain chain : data.chains ) {
|
for ( final Chain chain : data.chains ) {
|
||||||
final Point p1 = chain.getStart();
|
final Point p1 = chain.getStart();
|
||||||
@@ -749,10 +935,9 @@ public class MeshingTest2 extends JPanel {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawOnBoard( g, "Chain count: " + data.chains.size(), 0, -15 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( data.selectedChains != null ) {
|
{
|
||||||
g.setColor( Color.BLUE );
|
g.setColor( Color.BLUE );
|
||||||
for ( final Chain chain : data.selectedChains ) {
|
for ( final Chain chain : data.selectedChains ) {
|
||||||
final Point p1 = chain.getStart();
|
final Point p1 = chain.getStart();
|
||||||
@@ -765,8 +950,20 @@ public class MeshingTest2 extends JPanel {
|
|||||||
( int ) ( ( centerY - p2.getY() ) * scale ) + offsetY
|
( int ) ( ( centerY - p2.getY() ) * scale ) + offsetY
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
drawOnBoard( g, "Minimum chain count: " + data.selectedChains.size(), 0, -20 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g.setColor( Color.BLACK );
|
||||||
|
drawOnBoard( g, "Plane index: " + index, 0, 10 );
|
||||||
|
g.setColor( Color.CYAN );
|
||||||
|
drawOnBoard( g, "Edge count: " + data.edges.size(), 0, 0 );
|
||||||
|
g.setColor( Color.GREEN );
|
||||||
|
drawOnBoard( g, "Vertex count: " + data.vertices.size(), 0, -5 );
|
||||||
|
g.setColor( Color.MAGENTA );
|
||||||
|
drawOnBoard( g, "Triangle count: " + data.polygons.size(), 0, -10 );
|
||||||
|
g.setColor( Color.RED );
|
||||||
|
drawOnBoard( g, "Total Chain count: " + data.chains.size(), 0, -15 );
|
||||||
|
g.setColor( Color.BLUE );
|
||||||
|
drawOnBoard( g, "Possible chain count: " + data.selectedChains.size(), 0, -20 );
|
||||||
}
|
}
|
||||||
|
|
||||||
java.awt.Point p = MouseInfo.getPointerInfo().getLocation();
|
java.awt.Point p = MouseInfo.getPointerInfo().getLocation();
|
||||||
@@ -779,10 +976,10 @@ public class MeshingTest2 extends JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class PlaneData {
|
private static class PlaneData {
|
||||||
Collection< Point > vertices;
|
Collection< Point > vertices = new HashSet< Point >();
|
||||||
Collection< Segment > edges;
|
Collection< Segment > edges = new HashSet< Segment >();
|
||||||
Collection< Chain > chains;
|
Collection< Chain > chains = new HashSet< Chain >();
|
||||||
Collection< Chain > selectedChains;
|
Collection< Chain > selectedChains = new HashSet< Chain >();
|
||||||
Collection< Polygon > polygons;
|
Collection< Polygon > polygons = new HashSet< Polygon >();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
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.Point;
|
||||||
|
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( "Meshing " + file + "\t" + ( i + 1 ) + "/" + CHUNK_DIR.listFiles().length );
|
||||||
|
// final List< Plane > planes = mesh( file );
|
||||||
|
// planes.parallelStream().forEach( p -> {
|
||||||
|
// try {
|
||||||
|
// process( p );
|
||||||
|
// } catch ( IllegalStateException e ) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
//
|
||||||
|
// semiProcess( p );
|
||||||
|
//
|
||||||
|
// System.exit( 1 );
|
||||||
|
// }
|
||||||
|
// } );
|
||||||
|
// }
|
||||||
|
|
||||||
|
final List< Plane > planes = mesh( new File( CHUNK_DIR, "world,-2,1" ) );
|
||||||
|
// for ( int i = 0; i < planes.size(); ++i ) {
|
||||||
|
// System.out.println( "Meshing plane " + i );
|
||||||
|
// process( planes.get( i ) );
|
||||||
|
// }
|
||||||
|
|
||||||
|
process( planes.get( 218 ) );
|
||||||
|
} 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 void semiProcess( final Plane plane ) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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( "Parsing 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( "Found " + 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user