|
|
@ -17,6 +17,8 @@ import java.nio.FloatBuffer; |
|
|
|
import org.critterai.nmgen.IntermediateData; |
|
|
|
import org.critterai.nmgen.IntermediateData; |
|
|
|
import org.critterai.nmgen.NavmeshGenerator; |
|
|
|
import org.critterai.nmgen.NavmeshGenerator; |
|
|
|
import org.critterai.nmgen.TriangleMesh; |
|
|
|
import org.critterai.nmgen.TriangleMesh; |
|
|
|
|
|
|
|
import org.openide.DialogDisplayer; |
|
|
|
|
|
|
|
import org.openide.NotifyDescriptor; |
|
|
|
|
|
|
|
|
|
|
|
public class NavMeshGenerator implements Savable { |
|
|
|
public class NavMeshGenerator implements Savable { |
|
|
|
|
|
|
|
|
|
|
@ -37,8 +39,8 @@ public class NavMeshGenerator implements Savable { |
|
|
|
private int maxVertsPerPoly = 6; |
|
|
|
private int maxVertsPerPoly = 6; |
|
|
|
private float contourSampleDistance = 25; |
|
|
|
private float contourSampleDistance = 25; |
|
|
|
private float contourMaxDeviation = 25; |
|
|
|
private float contourMaxDeviation = 25; |
|
|
|
|
|
|
|
|
|
|
|
private IntermediateData intermediateData; |
|
|
|
private IntermediateData intermediateData; |
|
|
|
|
|
|
|
private int timeout = 10000; |
|
|
|
|
|
|
|
|
|
|
|
public NavMeshGenerator() { |
|
|
|
public NavMeshGenerator() { |
|
|
|
} |
|
|
|
} |
|
|
@ -89,7 +91,8 @@ public class NavMeshGenerator implements Savable { |
|
|
|
indices[i] = ib.get(i); |
|
|
|
indices[i] = ib.get(i); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
TriangleMesh triMesh = nmgen.build(positions, indices, intermediateData); |
|
|
|
|
|
|
|
|
|
|
|
TriangleMesh triMesh = buildNavMesh(positions, indices, intermediateData); |
|
|
|
if (triMesh == null) { |
|
|
|
if (triMesh == null) { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
@ -106,6 +109,34 @@ public class NavMeshGenerator implements Savable { |
|
|
|
return mesh2; |
|
|
|
return mesh2; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private TriangleMesh buildNavMesh(float[] positions, int[] indices, IntermediateData intermediateData) { |
|
|
|
|
|
|
|
MeshBuildRunnable runnable = new MeshBuildRunnable(positions, indices, intermediateData); |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
execute(runnable, timeout); |
|
|
|
|
|
|
|
} catch (TimeoutException ex) { |
|
|
|
|
|
|
|
DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("NavMesh Generation timed out.")); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return runnable.getTriMesh(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void execute(Thread task, long timeout) throws TimeoutException { |
|
|
|
|
|
|
|
task.start(); |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
task.join(timeout); |
|
|
|
|
|
|
|
} catch (InterruptedException e) { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (task.isAlive()) { |
|
|
|
|
|
|
|
task.interrupt(); |
|
|
|
|
|
|
|
throw new TimeoutException(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static void execute(Runnable task, long timeout) throws TimeoutException { |
|
|
|
|
|
|
|
Thread t = new Thread(task, "Timeout guard"); |
|
|
|
|
|
|
|
t.setDaemon(true); |
|
|
|
|
|
|
|
execute(t, timeout); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Mesh terrain2mesh(Terrain terr) { |
|
|
|
public Mesh terrain2mesh(Terrain terr) { |
|
|
|
float[] heights = terr.getHeightMap(); |
|
|
|
float[] heights = terr.getHeightMap(); |
|
|
|
int length = heights.length; |
|
|
|
int length = heights.length; |
|
|
@ -302,6 +333,14 @@ public class NavMeshGenerator implements Savable { |
|
|
|
this.useConservativeExpansion = useConservativeExpansion; |
|
|
|
this.useConservativeExpansion = useConservativeExpansion; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public int getTimeout() { |
|
|
|
|
|
|
|
return timeout; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setTimeout(int timeout) { |
|
|
|
|
|
|
|
this.timeout = timeout; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void write(JmeExporter ex) throws IOException { |
|
|
|
public void write(JmeExporter ex) throws IOException { |
|
|
|
OutputCapsule oc = ex.getCapsule(this); |
|
|
|
OutputCapsule oc = ex.getCapsule(this); |
|
|
|
oc.write(cellSize, "cellSize", 1f); |
|
|
|
oc.write(cellSize, "cellSize", 1f); |
|
|
@ -341,4 +380,34 @@ public class NavMeshGenerator implements Savable { |
|
|
|
contourSampleDistance = ic.readFloat("contourSampleDistance", 25); |
|
|
|
contourSampleDistance = ic.readFloat("contourSampleDistance", 25); |
|
|
|
contourMaxDeviation = ic.readFloat("contourMaxDeviation", 25); |
|
|
|
contourMaxDeviation = ic.readFloat("contourMaxDeviation", 25); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private class MeshBuildRunnable implements Runnable { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private float[] positions; |
|
|
|
|
|
|
|
private int[] indices; |
|
|
|
|
|
|
|
private IntermediateData intermediateData; |
|
|
|
|
|
|
|
private TriangleMesh triMesh; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public MeshBuildRunnable(float[] positions, int[] indices, IntermediateData intermediateData) { |
|
|
|
|
|
|
|
this.positions = positions; |
|
|
|
|
|
|
|
this.indices = indices; |
|
|
|
|
|
|
|
this.intermediateData = intermediateData; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void run() { |
|
|
|
|
|
|
|
triMesh = nmgen.build(positions, indices, intermediateData); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public TriangleMesh getTriMesh() { |
|
|
|
|
|
|
|
return triMesh; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class TimeoutException extends Exception { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Create an instance */ |
|
|
|
|
|
|
|
public TimeoutException() { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|