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)
This commit is contained in:
2025-05-25 21:27:25 -04:00
parent 83e3b9443b
commit 7c49e004b7
6 changed files with 336 additions and 267 deletions

View File

@@ -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 > {
/**
*
*/

View File

@@ -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
@@ -122,13 +122,18 @@ public class Mesh< T extends Region > {
edge = edge.split();
}
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,23 +320,21 @@ 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 ) {
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 ) {
addBack.add( other );
break;
}
@@ -323,12 +342,10 @@ public class Mesh< T extends Region > {
// be considered "the same"
if ( isSimilar( pos, otherPos ) ) {
HalfEdge.splice( vertex.getEdge(), other.getEdge() );
} else {
addBack.add( other );
it.remove();
}
}
queue.addAll( addBack );
}
{
// Remove any zero-edges
@@ -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,71 +521,45 @@ public class Mesh< T extends Region > {
}
}
}
scannedEdges.addAll( toInsert );
return toInsert;
}
/**
* Given a set of edges within the scan region, check for
* intersections with a half edge.
*
* @param scannedEdges
* @param edge
*/
private void resolveEdgeIntersections( final Collection< Vertex > vertices, final EdgeSet scannedEdges, final HalfEdge edge ) {
// 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();
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 );
}
final Optional< Intersection > optInt = getIntersection( positiveEdge, other );
if ( optInt.isPresent() ) {
final Intersection intersection = optInt.get();
if ( intersection instanceof IntersectionEdgeToEdge ) {
final IntersectionEdgeToEdge intEdge = ( IntersectionEdgeToEdge ) intersection;
if ( positiveEdge.getDest() == other.getDest() ) {
// TODO Remove this
throw new IllegalStateException( "Invalid intersection" );
}
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" );
}
// 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 );
// Split the first edge
HalfEdge aSplit = edge.split();
RegionRule< T > aRule = rules.get( edge );
rules.put( aSplit, aRule );
rules.put( aSplit.getSym(), aRule.inverse() );
// Ignore edges that are not collinear
if ( Math.abs( angle ) <= CROSS_TOLERANCE ) {
// Update the position
final Vertex origin = aSplit.getOrigin();
origin.setPosition( point );
HalfEdge shorter;
HalfEdge longer;
// 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 ) {
// Compare which edge is shorter
if ( r.lengthSquared() < s.lengthSquared() ) {
shorter = edge;
longer = other;
} else {
shorter = other;
longer = edge;
}
@@ -578,57 +576,59 @@ public class Mesh< T extends Region > {
// 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
* Given a set of edges within the scan region, check for
* intersections with a half edge.
*
* @param a
* @param b
* @return
* @param scannedEdges
* @param edge
*/
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 );
private void resolveEdgeIntersections( final Collection< Vertex > vertices, final EdgeSet scannedEdges, final HalfEdge edge ) {
final Vector2d p = edge.getOrigin().getPosition();
final double edgeOriginY = p.getY();
// Ignore edges that are not collinear
if ( Math.abs( angle ) <= CROSS_TOLERANCE ) {
// Recalculate these if the edge is split
double edgeDestY = edge.getDest().getPosition().getY();
Vector2d r = edge.toVector2d();
// 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 ) );
double edgeUpperY = Math.max( edgeOriginY, edgeDestY );
double edgeLowerY = Math.min( edgeOriginY, edgeDestY );
// Use the positive edge for finding the intersection
for ( HalfEdge other : scannedEdges ) {
if ( edge == other || edge == other.getSym() ) {
continue;
}
// 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;
}
}
}
} else if ( isSimilar( a.getOrigin(), b.getOrigin() ) ) {
// TODO Remove this
throw new IllegalArgumentException( "Vertex not merged!" );
} else if ( !isSimilar( a.getDest(), b.getDest() ) ) {
if ( edge.getOrigin() != other.getOrigin() && edge.getOrigin() != other.getDest() && !isSimilar( edge.getDest(), other.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 q = other.getOrigin().getPosition();
final Vector2d s = other.toVector2d();
final Vector2d pq = q.subtracted( p );
final double pqr = pq.cross( r );
final double rs = r.cross( s );
final double pqr = pq.cross( r );
// Check if parallel
if ( rs != 0 ) {
@@ -643,13 +643,40 @@ public class Mesh< T extends Region > {
// 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 );
final Vector2d intersection = r.multiplied( t ).add( p );
return Optional.of( new IntersectionEdgeToEdge( intersection ) );
// 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 );
}
}
}
}
return Optional.empty();
}
/**
@@ -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 ) ) {
@@ -854,6 +885,9 @@ public class Mesh< T extends Region > {
vertices = keep;
vertexMap.clear();
vertices.forEach( v -> vertexMap.put( v.getPosition(), v ) );
/*
* Invariants:
* - All vertices have an even number of edges
@@ -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 >();

View File

@@ -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;

View File

@@ -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,11 +263,18 @@ 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 ) );
data.vertices = mesh.getVertices();
data.edges = mesh.getEdges();
try {
mesh.generateRegions();
long end = System.currentTimeMillis();
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,19 +571,74 @@ 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;

View File

@@ -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 );
}

View File

@@ -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 );