diff --git a/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/EdgeSet.java b/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/EdgeSet.java index 18ac793..2c142f1 100644 --- a/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/EdgeSet.java +++ b/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/EdgeSet.java @@ -1,13 +1,13 @@ package com.aaaaahhhhhhh.bananapuncher714.mesh; -import java.util.HashSet; +import java.util.LinkedHashSet; /** * A set for easily checking if a set contains/does not contain a half-edge or its sym. * * @author BananaPuncher714 */ -public class EdgeSet extends HashSet< HalfEdge > { +public class EdgeSet extends LinkedHashSet< HalfEdge > { /** * */ diff --git a/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/Mesh.java b/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/Mesh.java index 30420ca..2dcb53a 100644 --- a/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/Mesh.java +++ b/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/Mesh.java @@ -9,12 +9,9 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Optional; -import java.util.PriorityQueue; import java.util.Queue; import java.util.Set; import java.util.Stack; @@ -81,6 +78,9 @@ public class Mesh< T extends Region > { public static final double ANGLE_TOLERANCE = Math.toRadians( 1e-10 ); public static final double CROSS_TOLERANCE = Math.sin( ANGLE_TOLERANCE ); + // Point to vertex map, to avoid duplicating vertices when inserting polygons + protected Map< Point, Vertex > vertexMap = new HashMap< Point, Vertex >(); + // All points in the graph protected Collection< Vertex > vertices = new ArrayDeque< Vertex >(); // All rules associated with a given half edge @@ -121,14 +121,19 @@ public class Mesh< T extends Region > { } else { edge = edge.split(); } - - edge.getOrigin().setPosition( new Vector2d( point ) ); + + final Vertex vertex = vertexMap.get( point ); + if ( vertex != null ) { + HalfEdge.splice( edge.getPrev(), vertex.getEdge() ); + } else { + edge.getOrigin().setPosition( new Vector2d( point ) ); + + vertices.add( edge.getOrigin() ); + } rules.put( edge, rule ); rules.put( edge.getSym(), rule.inverse() ); - vertices.add( edge.getOrigin() ); - state = MeshState.DIRTY; } } @@ -179,6 +184,7 @@ public class Mesh< T extends Region > { vertices.clear(); rules.clear(); interiorEdges.clear(); + vertexMap.clear(); } public Mesh< T > copyOf() { @@ -244,7 +250,7 @@ public class Mesh< T extends Region > { } } - copy.vertices.parallelStream().forEach( v -> sort( v ) ); + copy.vertices.parallelStream().forEach( v -> { sort( v ); copy.vertexMap.put( v.getPosition(), v ); } ); copy.state = state; return copy; @@ -282,9 +288,24 @@ public class Mesh< T extends Region > { * will be simple, since there can be holes. */ public void simplify() { - // Create a queue and insert all vertices in O(nlogn) time. - final Queue< Vertex > queue = new PriorityQueue< Vertex >( Mesh::compare ); - queue.addAll( vertices ); + // Create a sorted set with duplicate vertices allowed + // Insert all vertices in O(nlogn) time. + // Use a treeset instead of a priority queue for constant time poll first + final TreeSet< Vertex > vertexSet = new TreeSet< Vertex >( ( a, b ) -> { + final int compare = compare( a, b ); + if ( compare == 0 ) { + return Integer.compare( a.hashCode(), b.hashCode() ); + } else { + return compare; + } + } ); + vertexSet.addAll( vertices ); + + // Need to update vertices if using the vertex map when inserting polygons + vertexSet.parallelStream().forEach( Vertex::update ); + + // Do a quick merging of edges so we don't have to deal with them later + mergeOverlappingEdges( vertexSet ); /* * As we iterate through each vertex, there are certain operations @@ -299,35 +320,31 @@ public class Mesh< T extends Region > { // This set contains the non-redundant vertices. final Set< Vertex > scannedVertices = new HashSet< Vertex >(); - Vertex vertex; - while ( ( vertex = queue.poll() ) != null ) { + while ( !vertexSet.isEmpty() ) { + final Vertex vertex = vertexSet.pollFirst(); final Vector2d pos = vertex.getPosition(); - { - final List< Vertex > addBack = new LinkedList< Vertex >(); - Vertex other; - // We must poll and add back later since priority queues are not - // sorted, so an iterator over its elements would not guarantee - // the correct ordering unless we poll it. - while ( ( other = queue.poll() ) != null ) { - final Vector2d otherPos = other.getPosition(); - - // Once the vertex scanned is past the tolerance in the X direction, - // we know there are no more vertices which can be merged with the - // current vertex. - if ( compareX( otherPos, pos ) > VERTEX_TOLERANCE ) { - addBack.add( other ); - break; - } - - // Check if the vertices are close enough that they can - // be considered "the same" - if ( isSimilar( pos, otherPos ) ) { - HalfEdge.splice( vertex.getEdge(), other.getEdge() ); - } else { - addBack.add( other ); - } + + // We must poll and add back later since priority queues are not + // sorted, so an iterator over its elements would not guarantee + // the correct ordering unless we poll it. + for ( final Iterator< Vertex > it = vertexSet.iterator(); it.hasNext(); ) { + final Vertex other = it.next(); + final Vector2d otherPos = other.getPosition(); + + // Once the vertex scanned is past the tolerance in the X direction, + // we know there are no more vertices which can be merged with the + // current vertex. + if ( compareX( otherPos, pos ) > VERTEX_TOLERANCE ) { + break; + } + + // Check if the vertices are close enough that they can + // be considered "the same" + if ( isSimilar( pos, otherPos ) ) { + HalfEdge.splice( vertex.getEdge(), other.getEdge() ); + + it.remove(); } - queue.addAll( addBack ); } { @@ -358,14 +375,8 @@ public class Mesh< T extends Region > { } } - // Add all edges from this vertex if they do not already exist in - // the set of scanned edges - for ( final HalfEdge edge : vertex ) { - scannedEdges.add( edge ); - } - // Add edges that belong to vertices up to VERTEX_TOLERANCE away in the X direction - for ( final Iterator< Vertex > it = queue.iterator(); it.hasNext(); ) { + for ( final Iterator< Vertex > it = vertexSet.iterator(); it.hasNext(); ) { final Vertex other = it.next(); final Vector2d otherPos = other.getPosition(); @@ -377,28 +388,36 @@ public class Mesh< T extends Region > { // horizontally onto the exact same x position as this vertex. // It saves us from having fuzzy errors in the future. otherPos.setX( pos.getX() ); - - for ( final HalfEdge edge : other ) { - scannedEdges.add( edge ); - } } // Update all edges this vertex is connected to for consistency vertex.update(); - // Merge any vertices with edges that they may be on + // Merge any vertices that are on edges resolveVertexIntersections( scannedEdges, vertex ); + + // Remove any collinear edges attached to this vertex + resolveCollinearEdges( scannedEdges, vertex ); + // Remove any intersections with edges from other vertices for ( final HalfEdge edge : vertex ) { // Resolve any intersections belonging to this edge which are still - // being scanned - if ( scannedEdges.contains( edge ) ) { - resolveEdgeIntersections( queue, scannedEdges, edge ); + // being scanned, but only if it's a new edge + if ( !scannedEdges.contains( edge ) && !scannedVertices.contains( edge.getDest() ) ) { + resolveEdgeIntersections( vertexSet, scannedEdges, edge ); } } + // Consider this vertex "scanned" + scannedVertices.add( vertex ); + // Remove all edges from previously scanned vertices that are no longer useful for ( final HalfEdge edge : vertex ) { + if ( vertex == edge.getDest() ) { + // TODO Remove this + throw new IllegalStateException( "Zero length edge!" ); + } + if ( scannedVertices.contains( edge.getDest() ) ) { /* * Remove the half edge and it's sym if the destination @@ -412,13 +431,16 @@ public class Mesh< T extends Region > { // TODO Remove this throw new IllegalStateException( "Tried to remove an invalid edge!" ); } + } else { + scannedEdges.add( edge ); } } - scannedVertices.add( vertex ); } mergeOverlappingEdges( scannedVertices ); + scannedVertices.parallelStream().forEach( Mesh::sort ); + // Update the list of vertices with our new updated list of vertices vertices = scannedVertices; @@ -446,7 +468,7 @@ public class Mesh< T extends Region > { * @param scannedEdges * @param vertex */ - private void resolveVertexIntersections( final EdgeSet scannedEdges, final Vertex vertex ) { + private Collection< HalfEdge > resolveVertexIntersections( final EdgeSet scannedEdges, final Vertex vertex ) { // Split any edges passing through vertex, which do not include // the vertex as the origin or destination final Vector2d v = vertex.getPosition(); @@ -455,6 +477,8 @@ public class Mesh< T extends Region > { final Vector2d a = edge.getOrigin().getPosition(); final Vector2d b = edge.getDest().getPosition(); + // TODO Can parallelize finding the edges, then do the merging sequentially afterwards + if ( v == a || v == b ) { // Skip if this edge continue; @@ -497,7 +521,67 @@ public class Mesh< T extends Region > { } } } - scannedEdges.addAll( toInsert ); + + return toInsert; + } + + private void resolveCollinearEdges( final EdgeSet scannedEdges, final Vertex vertex ) { + final Collection< HalfEdge > checked = new HashSet< HalfEdge >(); + for ( final HalfEdge edge : vertex ) { + if ( scannedEdges.contains( edge ) ) { + checked.add( edge ); + } + } + + // Assume a and b are both positive + // This assumes that if a and b are collinear, then they _must_ share + // the same origin, since we are traversing through the vertices + // starting with the smallest. + for ( final HalfEdge edge : vertex ) { + // Only check this edge if it is not already scanned + if ( checked.add( edge ) ) { + final Vector2d r = edge.toVector2d().normalize(); + for ( final HalfEdge other : vertex ) { + if ( !checked.contains( other ) ) { + // Do not split edges that are pretty much equal, since they will get merged later + if ( !isSimilar( edge.getDest(), other.getDest() ) ) { + final Vector2d s = other.toVector2d().normalize(); + final double angle = r.cross( s ); + + // Ignore edges that are not collinear + if ( Math.abs( angle ) <= CROSS_TOLERANCE ) { + + HalfEdge shorter; + HalfEdge longer; + + // Compare which edge is shorter + if ( r.lengthSquared() < s.lengthSquared() ) { + shorter = edge; + longer = other; + } else { + shorter = other; + longer = edge; + } + + // Update the winding rule for the split + final HalfEdge split = longer.split(); + RegionRule< T > rule = rules.get( longer ); + rules.put( split, rule ); + rules.put( split.getSym(), rule.inverse() ); + + // Update the vertex for the split + final Vertex vert = shorter.getDest(); + split.setOrigin( vert ); + longer.getSym().setOrigin( vert ); + + // Splice the two together + HalfEdge.splice( shorter.getSym(), split ); + } + } + } + } + } + } } /** @@ -508,150 +592,93 @@ public class Mesh< T extends Region > { * @param edge */ private void resolveEdgeIntersections( final Collection< Vertex > vertices, final EdgeSet scannedEdges, final HalfEdge edge ) { + final Vector2d p = edge.getOrigin().getPosition(); + final double edgeOriginY = p.getY(); + + // Recalculate these if the edge is split + double edgeDestY = edge.getDest().getPosition().getY(); + Vector2d r = edge.toVector2d(); + + double edgeUpperY = Math.max( edgeOriginY, edgeDestY ); + double edgeLowerY = Math.min( edgeOriginY, edgeDestY ); + // Use the positive edge for finding the intersection - final HalfEdge positiveEdge = isPositive( edge ) ? edge : edge.getSym(); for ( HalfEdge other : scannedEdges ) { - if ( !isPositive( other ) ) { - other = other.getSym(); + if ( edge == other || edge == other.getSym() ) { + continue; } - final Optional< Intersection > optInt = getIntersection( positiveEdge, other ); - if ( optInt.isPresent() ) { - final Intersection intersection = optInt.get(); - if ( intersection instanceof IntersectionEdgeToEdge ) { - final IntersectionEdgeToEdge intEdge = ( IntersectionEdgeToEdge ) intersection; + + // Do simple Y axis check between the two edges to see if they overlap + { + final double otherOriginY = other.getOrigin().getPosition().getY(); + final double otherDestY = other.getDest().getPosition().getY(); + + final double otherUpperY = Math.max( otherOriginY, otherDestY ); + final double otherLowerY = Math.min( otherOriginY, otherDestY ); + + if ( !( edgeLowerY < otherUpperY && otherLowerY < edgeUpperY ) ) { + continue; + } + } + + if ( edge.getOrigin() != other.getOrigin() && edge.getOrigin() != other.getDest() && !isSimilar( edge.getDest(), other.getDest() ) ) { + // Both edges may intersect somewhere in the middle + final Vector2d q = other.getOrigin().getPosition(); + final Vector2d s = other.toVector2d(); + + final Vector2d pq = q.subtracted( p ); + final double rs = r.cross( s ); + final double pqr = pq.cross( r ); + + // Check if parallel + if ( rs != 0 ) { + // Calculate t and u + final double t = pq.cross( s ) / rs; + final double u = pqr / rs; + + final double tTol = VERTEX_TOLERANCE / r.length(); + final double uTol = VERTEX_TOLERANCE / s.length(); - if ( positiveEdge.getDest() == other.getDest() ) { - // TODO Remove this - throw new IllegalStateException( "Invalid intersection" ); + // Do the line segments intersect + // They should NOT intersect at their endpoints + if ( t > tTol && t < ( 1 - tTol ) && u > uTol && u < ( 1 - uTol ) ) { + // Calculate the point of intersection + final Vector2d intersection = r.multiplied( t ).add( p ); + + // Split the first edge + HalfEdge aSplit = edge.split(); + RegionRule< T > aRule = rules.get( edge ); + rules.put( aSplit, aRule ); + rules.put( aSplit.getSym(), aRule.inverse() ); + + // Update the position + final Vertex aSplitOrigin = aSplit.getOrigin(); + aSplitOrigin.setPosition( intersection ); + + // Split the other edge + HalfEdge bSplit = other.split(); + RegionRule< T > bRule = rules.get( other ); + rules.put( bSplit, bRule ); + rules.put( bSplit.getSym(), bRule.inverse() ); + + // Splice the edges together into the same vertex + HalfEdge.splice( bSplit, aSplit ); + + aSplitOrigin.update(); + + vertices.add( aSplitOrigin ); + + // Recalculate the edge values + edgeDestY = intersection.getY(); + r = edge.toVector2d(); + edgeUpperY = Math.max( edgeOriginY, edgeDestY ); + edgeLowerY = Math.min( edgeOriginY, edgeDestY ); } - - final Vector2d point = intEdge.getPoint(); - if ( isSimilar( point, other.getDest().getPosition() ) || isSimilar( point, positiveEdge.getDest().getPosition() ) ) { - // TODO Remove this - throw new IllegalStateException( "Invalid intersection point" ); - } - - // Split the first edge - HalfEdge aSplit = edge.split(); - RegionRule< T > aRule = rules.get( edge ); - rules.put( aSplit, aRule ); - rules.put( aSplit.getSym(), aRule.inverse() ); - - // Update the position - final Vertex origin = aSplit.getOrigin(); - origin.setPosition( point ); - - // Split the other edge - HalfEdge bSplit = other.split(); - RegionRule< T > bRule = rules.get( other ); - rules.put( bSplit, bRule ); - rules.put( bSplit.getSym(), bRule.inverse() ); - - // Splice the edges together into the same vertex - HalfEdge.splice( bSplit, aSplit ); - - origin.update(); - - vertices.add( origin ); - } else if ( intersection instanceof IntersectionCollinear ) { - final IntersectionCollinear intCol = ( IntersectionCollinear ) intersection; - - final HalfEdge shorter = intCol.getShorterEdge(); - HalfEdge longer = intCol.getLongerEdge(); - - // Use the original edge for splitting to preserve the order of - // edges around the current vertex - if ( longer == positiveEdge ) { - longer = edge; - } - - // Update the winding rule for the split - final HalfEdge split = longer.split(); - RegionRule< T > rule = rules.get( longer ); - rules.put( split, rule ); - rules.put( split.getSym(), rule.inverse() ); - - // Update the vertex for the split - final Vertex vert = shorter.getDest(); - split.setOrigin( vert ); - longer.getSym().setOrigin( vert ); - - // Splice the two together - HalfEdge.splice( shorter.getSym(), split ); - } else { - // TODO Remove this - throw new IllegalStateException( "Unknown intersection type" ); } } } } - /** - * Calculate the intersection for two edges - * - * @param a - * @param b - * @return - */ - private static Optional< Intersection > getIntersection( HalfEdge a, HalfEdge b ) { - // Assume a and b are both positive - // This assumes that if a and b are collinear, then they _must_ share - // the same origin, since we are traversing through the vertices - // starting with the smallest. - if ( a.getOrigin() == b.getOrigin() ) { - // Do not split edges that are pretty much equal, since they will get merged later - if ( !isSimilar( a.getDest(), b.getDest() ) ) { - final Vector2d r = a.toVector2d().normalize(); - final Vector2d s = b.toVector2d().normalize(); - final double angle = r.cross( s ); - - // Ignore edges that are not collinear - if ( Math.abs( angle ) <= CROSS_TOLERANCE ) { - - // Compare which edge is shorter - if ( r.lengthSquared() < s.lengthSquared() ) { - return Optional.of( new IntersectionCollinear( a, b ) ); - } else { - return Optional.of( new IntersectionCollinear( b, a ) ); - } - } - } - } else if ( isSimilar( a.getOrigin(), b.getOrigin() ) ) { - // TODO Remove this - throw new IllegalArgumentException( "Vertex not merged!" ); - } else if ( !isSimilar( a.getDest(), b.getDest() ) ) { - // Both edges may intersect somewhere in the middle - final Vector2d p = a.getOrigin().getPosition(); - final Vector2d r = a.toVector2d(); - final Vector2d q = b.getOrigin().getPosition(); - final Vector2d s = b.toVector2d(); - - final Vector2d pq = q.subtracted( p ); - final double pqr = pq.cross( r ); - final double rs = r.cross( s ); - - // Check if parallel - if ( rs != 0 ) { - // Calculate t and u - final double t = pq.cross( s ) / rs; - final double u = pqr / rs; - - final double tTol = VERTEX_TOLERANCE / r.length(); - final double uTol = VERTEX_TOLERANCE / s.length(); - - // Do the line segments intersect - // They should NOT intersect at their endpoints - if ( t > tTol && t < ( 1 - tTol ) && u > uTol && u < ( 1 - uTol ) ) { - // Calculate the point of intersection - final Vector2d intersection = r.multiply( t ).add( p ); - - return Optional.of( new IntersectionEdgeToEdge( intersection ) ); - } - } - } - return Optional.empty(); - } - /** * The goal for this method is to sort vertices * and to ensure that edges with the same endpoint and @@ -659,8 +686,6 @@ public class Mesh< T extends Region > { */ private void mergeOverlappingEdges( final Collection< Vertex > vertices ) { for ( final Vertex vertex : vertices ) { - sort( vertex ); - // Keep track of which ranges of edges are attached to which final Map< Vertex, Queue< HalfEdge > > ranges = new HashMap< Vertex, Queue< HalfEdge > >(); @@ -729,8 +754,15 @@ public class Mesh< T extends Region > { throw new IllegalStateException( "Mesh is not simplified!" ); } - final Queue< Vertex > queue = new PriorityQueue< Vertex >( Mesh::compare ); - queue.addAll( vertices ); + final Collection< Vertex > vertexSet = new TreeSet< Vertex >( ( a, b ) -> { + final int compare = compare( a, b ); + if ( compare == 0 ) { + return Integer.compare( a.hashCode(), b.hashCode() ); + } else { + return compare; + } + } ); + vertexSet.addAll( vertices ); // Keep track of what regions belong to what edge final Map< HalfEdge, T > regions = new HashMap< HalfEdge, T >(); @@ -747,8 +779,7 @@ public class Mesh< T extends Region > { final Set< HalfEdge > toRemove = new HashSet< HalfEdge >(); // Assume the edges on each vertex is already sorted - Vertex vertex; - while ( ( vertex = queue.poll() ) != null ) { + for ( Vertex vertex : vertexSet ) { // Insert all edges into the edge set for ( final HalfEdge edge : vertex ) { if ( !isPositive( edge ) ) { @@ -853,6 +884,9 @@ public class Mesh< T extends Region > { interiorEdges.addAll( interiorAboveEdges ); vertices = keep; + + vertexMap.clear(); + vertices.forEach( v -> vertexMap.put( v.getPosition(), v ) ); /* * Invariants: @@ -2760,7 +2794,7 @@ public class Mesh< T extends Region > { // Keep track of which edge to insert new edges for the given vertex final Map< Vertex, HalfEdge > insertEdges = new HashMap< Vertex, HalfEdge >(); - final Queue< HalfEdge > edges = new PriorityQueue< HalfEdge >( ( a, b ) -> { + final TreeSet< HalfEdge > edges = new TreeSet< HalfEdge >( ( a, b ) -> { return compare( a.getOrigin(), b.getOrigin() ); } ); edges.addAll( polygon.getEdges() ); @@ -2768,12 +2802,12 @@ public class Mesh< T extends Region > { final Stack< HalfEdge > stack = new Stack< HalfEdge >(); // Add the first two vertices/edges - stack.add( edges.poll() ); - stack.add( edges.poll() ); + stack.add( edges.pollFirst() ); + stack.add( edges.pollFirst() ); HalfEdge prev = stack.peek(); while ( edges.size() > 1 ) { - final HalfEdge edge = edges.poll(); + final HalfEdge edge = edges.pollFirst(); final boolean isEdgePositive = isPositive( edge ); if ( isEdgePositive ^ isPositive( stack.peek() ) ) { @@ -2865,7 +2899,7 @@ public class Mesh< T extends Region > { // The last edge must be a negative edge, since // the last vertex must terminate the polygon and // therefore have no right-going edges. - final HalfEdge last = edges.poll(); + final HalfEdge last = edges.pollFirst(); stack.pop(); final boolean isPositive = isPositive( stack.peek() ); HalfEdge insertEdge = last; @@ -2999,48 +3033,6 @@ public class Mesh< T extends Region > { return v; } - /* - * Represents an intersection - */ - private static abstract class Intersection { - } - - /* - * When 2 edges both intersect somewhere in the middle - */ - private static class IntersectionEdgeToEdge extends Intersection { - private final Vector2d point; - - IntersectionEdgeToEdge( Vector2d point ) { - this.point = point; - } - - Vector2d getPoint() { - return point; - } - } - - /* - * When 2 edges are collinear, and do not share the same endpoint - */ - private static class IntersectionCollinear extends Intersection { - private final HalfEdge shorter; - private final HalfEdge longer; - - IntersectionCollinear( HalfEdge shorter, HalfEdge longer ) { - this.shorter = shorter; - this.longer = longer; - } - - public HalfEdge getShorterEdge() { - return shorter; - } - - public HalfEdge getLongerEdge() { - return longer; - } - } - private static class EdgePolygon { private Set< HalfEdge > edges = new HashSet< HalfEdge >(); private Set< Vertex > vertices = new HashSet< Vertex >(); diff --git a/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/Vector2d.java b/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/Vector2d.java index 314e999..e5d093c 100644 --- a/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/Vector2d.java +++ b/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/Vector2d.java @@ -66,6 +66,17 @@ public class Vector2d extends Point { return add( this, o ); } + public Vector2d absolute() { + x = Math.abs( x ); + y = Math.abs( y ); + + return this; + } + + public Vector2d absoluteOf() { + return new Vector2d( Math.abs( x ), Math.abs( y ) ); + } + public Vector2d subtract( double v ) { x -= v; y -= v; diff --git a/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MeshingTest2.java b/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MeshingTest2.java index ac35f8e..f372460 100644 --- a/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MeshingTest2.java +++ b/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MeshingTest2.java @@ -133,6 +133,9 @@ public class MeshingTest2 extends JPanel { // } final List< Plane > masterPlanes = new ArrayList< Plane >(); + System.out.println( "Adding test plane" ); + masterPlanes.add( getTestPlane() ); + System.out.println( "Chunk files: " + CHUNK_DIR.listFiles().length ); int limit = 1; for ( File file : CHUNK_DIR.listFiles() ) { @@ -144,12 +147,10 @@ public class MeshingTest2 extends JPanel { } } -// final List< Plane > planes = mesh( new File( CHUNK_DIR, "world,-1,-1" ) ); -// masterPlanes.add( planes.get( 20 ) ); +// final List< Plane > planes = mesh( new File( CHUNK_DIR, "world,-10,-10" ) ); +// masterPlanes.add( planes.get( 27 ) ); // masterPlanes.addAll( planes ); -// masterPlanes.add( getTestPlane() ); - SwingUtilities.invokeLater( new Runnable() { @Override public void run() { @@ -262,12 +263,19 @@ public class MeshingTest2 extends JPanel { System.out.println( "After simplify vertex count: " + mesh.getVertices().size() ); System.out.println( "After simplify edge count: " + ( mesh.getEdgeCount() / 2 ) ); - mesh.generateRegions(); - long end = System.currentTimeMillis(); - data.vertices = mesh.getVertices(); data.edges = mesh.getEdges(); + try { + mesh.generateRegions(); + + data.vertices = mesh.getVertices(); + data.edges = mesh.getEdges(); + } catch ( Exception e ) { + e.printStackTrace(); + } + long end = System.currentTimeMillis(); + System.out.println( "After generating regions vertex count: " + mesh.getVertices().size() ); System.out.println( "After generating regions edge count: " + ( mesh.getEdgeCount() / 2 ) ); @@ -547,6 +555,9 @@ public class MeshingTest2 extends JPanel { private static Plane getTestPlane() { final Plane plane = new Plane(); + plane.normal = new Vector( 0, 0, 1 ); + plane.point = new Vector( 1, 0, 0 ); + // plane.polygons.add( new Polygon( Arrays.asList( // new Point( 1, 0 ), // new Point( 2, 1 ), @@ -560,20 +571,75 @@ public class MeshingTest2 extends JPanel { // 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( 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, -1 ), + new Point( 1, -1 ), + new Point( 1, 1 ), + new Point( -1, 1 ) + ) ) ); + plane.polygons.add( new Polygon( Arrays.asList( + new Point( -1, -1 ), + new Point( 1, -1 ), + new Point( 1, 1 ), + new Point( -1, 1 ) + ) ) ); + + plane.polygons.add( new Polygon( Arrays.asList( + new Point( -1, -1 ), + new Point( 1, -1 ), + new Point( 1, 1 ), + new Point( -1, 1 ) + ) ) ); + plane.polygons.add( new Polygon( Arrays.asList( + new Point( -1, 1 ), + new Point( 1, 1 ), + new Point( 1, 3 ), + new Point( -1, 3 ) + ) ) ); + plane.polygons.add( new Polygon( Arrays.asList( + new Point( -2, -1 ), + new Point( -1, -1 ), + new Point( -1, 2 ), + new Point( -2, 2 ) + ) ) ); + plane.polygons.add( new Polygon( Arrays.asList( + new Point( -4, -2 ), + new Point( -1, -2 ), + new Point( -1, 1.5 ), + new Point( -4, 1.5 ) + ) ) ); + plane.polygons.add( new Polygon( Arrays.asList( + new Point( -3, 0 ), + new Point( 3, 0 ), + new Point( -1.5, -3 ), + new Point( 0, 1.5 ), + new Point( 1.5, -3 ) + ) ) ); + plane.polygons.add( new Polygon( Arrays.asList( + new Point( -1, 0 ), + new Point( 0, 1.5 ), + new Point( 1, 0 ) + ) ) ); 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 ) - ) ) ); + new Point( 0, -2 ), + new Point( -1, 0 ) + ) ) ); return plane; } diff --git a/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MeshingTest3.java b/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MeshingTest3.java index f444c55..22d0f96 100644 --- a/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MeshingTest3.java +++ b/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MeshingTest3.java @@ -48,13 +48,13 @@ public class MeshingTest3 { System.out.println( "\tTook " + time + "ms" ); } -// final List< Plane > planes = mesh( new File( CHUNK_DIR, "world,-1,-1" ) ); // 123 +// 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( 20 ) ); +// process( planes.get( 27 ) ); } else { System.err.println( "No such directory exists: " + CHUNK_DIR ); } diff --git a/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MiniePlugin.java b/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MiniePlugin.java index d1a7437..ce1b1a8 100644 --- a/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MiniePlugin.java +++ b/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MiniePlugin.java @@ -583,7 +583,7 @@ public class MiniePlugin extends JavaPlugin { final Location loc = block.getLocation(); // Start the box at 0, 0, 0 - final BoundingBox[] boundingBoxes = convertFrom( getShape( data, loc, BlockShapeType.VISUAL_SHAPE ), new Vector( x, y - worldMinHeight, z ) ); + final BoundingBox[] boundingBoxes = convertFrom( getShape( data, loc, BlockShapeType.COLLISION_SHAPE ), new Vector( x, y - worldMinHeight, z ) ); for ( BoundingBox box : boundingBoxes ) { boxes.add( box );