git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8982 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
e4186c2497
commit
28a64bbfcf
@ -0,0 +1,8 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- You may freely edit this file. See harness/README in the NetBeans platform --> |
||||||
|
<!-- for some information on what you could do (e.g. targets to override). --> |
||||||
|
<!-- If you delete this file and reopen the project it will be recreated. --> |
||||||
|
<project name="com.jme3.dge.nmgen" default="netbeans" basedir="."> |
||||||
|
<description>Builds, tests, and runs the project com.jme3.gde.nmgen.</description> |
||||||
|
<import file="nbproject/build-impl.xml"/> |
||||||
|
</project> |
Binary file not shown.
@ -0,0 +1,7 @@ |
|||||||
|
Manifest-Version: 1.0 |
||||||
|
OpenIDE-Module: com.jme3.gde.nmgen |
||||||
|
OpenIDE-Module-Implementation-Version: 0 |
||||||
|
OpenIDE-Module-Layer: com/jme3/gde/nmgen/layer.xml |
||||||
|
OpenIDE-Module-Localizing-Bundle: com/jme3/gde/nmgen/Bundle.properties |
||||||
|
OpenIDE-Module-Requires: org.openide.windows.WindowManager |
||||||
|
|
@ -0,0 +1,45 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
*** GENERATED FROM project.xml - DO NOT EDIT *** |
||||||
|
*** EDIT ../build.xml INSTEAD *** |
||||||
|
--> |
||||||
|
<project name="com.jme3.gde.nmgen-impl" basedir=".."> |
||||||
|
<fail message="Please build using Ant 1.7.1 or higher."> |
||||||
|
<condition> |
||||||
|
<not> |
||||||
|
<antversion atleast="1.7.1"/> |
||||||
|
</not> |
||||||
|
</condition> |
||||||
|
</fail> |
||||||
|
<property file="nbproject/private/suite-private.properties"/> |
||||||
|
<property file="nbproject/suite.properties"/> |
||||||
|
<fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail> |
||||||
|
<property file="${suite.dir}/nbproject/private/platform-private.properties"/> |
||||||
|
<property file="${suite.dir}/nbproject/platform.properties"/> |
||||||
|
<macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2"> |
||||||
|
<attribute name="name"/> |
||||||
|
<attribute name="value"/> |
||||||
|
<sequential> |
||||||
|
<property name="@{name}" value="${@{value}}"/> |
||||||
|
</sequential> |
||||||
|
</macrodef> |
||||||
|
<macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2"> |
||||||
|
<attribute name="property"/> |
||||||
|
<attribute name="value"/> |
||||||
|
<sequential> |
||||||
|
<property name="@{property}" value="@{value}"/> |
||||||
|
</sequential> |
||||||
|
</macrodef> |
||||||
|
<property file="${user.properties.file}"/> |
||||||
|
<nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/> |
||||||
|
<nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/> |
||||||
|
<nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/> |
||||||
|
<fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness)."> |
||||||
|
<condition> |
||||||
|
<not> |
||||||
|
<contains string="${cluster.path.evaluated}" substring="platform"/> |
||||||
|
</not> |
||||||
|
</condition> |
||||||
|
</fail> |
||||||
|
<import file="${harness.dir}/build.xml"/> |
||||||
|
</project> |
@ -0,0 +1,8 @@ |
|||||||
|
build.xml.data.CRC32=0efc30b9 |
||||||
|
build.xml.script.CRC32=d1f1ecca |
||||||
|
build.xml.stylesheet.CRC32=a56c6a5b@1.46.2 |
||||||
|
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. |
||||||
|
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. |
||||||
|
nbproject/build-impl.xml.data.CRC32=0efc30b9 |
||||||
|
nbproject/build-impl.xml.script.CRC32=fe180a9d |
||||||
|
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.46.2 |
@ -0,0 +1,6 @@ |
|||||||
|
javac.source=1.6 |
||||||
|
javac.compilerargs=-Xlint -Xlint:-serial |
||||||
|
license.file=../license-jme.txt |
||||||
|
nbm.homepage=http://www.jmonkeyengine.com |
||||||
|
nbm.module.author=Brent Owens |
||||||
|
spec.version.base=3.0.0 |
@ -0,0 +1,134 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://www.netbeans.org/ns/project/1"> |
||||||
|
<type>org.netbeans.modules.apisupport.project</type> |
||||||
|
<configuration> |
||||||
|
<data xmlns="http://www.netbeans.org/ns/nb-module-project/3"> |
||||||
|
<code-name-base>com.jme3.gde.nmgen</code-name-base> |
||||||
|
<suite-component/> |
||||||
|
<module-dependencies> |
||||||
|
<dependency> |
||||||
|
<code-name-base>com.jme3.gde.core</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<release-version>1</release-version> |
||||||
|
<specification-version>3.0.0</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>com.jme3.gde.core.baselibs</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<release-version>1</release-version> |
||||||
|
<specification-version>3.0.0</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>org.jdesktop.beansbinding</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<release-version>1</release-version> |
||||||
|
<specification-version>1.11.0.121</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>org.netbeans.api.progress</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<release-version>1</release-version> |
||||||
|
<specification-version>1.24</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>org.netbeans.modules.settings</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<release-version>1</release-version> |
||||||
|
<specification-version>1.31</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>org.openide.awt</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<specification-version>7.31</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>org.openide.dialogs</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<specification-version>7.20</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>org.openide.explorer</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<specification-version>6.35</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>org.openide.filesystems</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<specification-version>7.47</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>org.openide.loaders</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<specification-version>7.21</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>org.openide.nodes</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<specification-version>7.21</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>org.openide.util</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<specification-version>8.15</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>org.openide.util.lookup</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<specification-version>8.8</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<code-name-base>org.openide.windows</code-name-base> |
||||||
|
<build-prerequisite/> |
||||||
|
<compile-dependency/> |
||||||
|
<run-dependency> |
||||||
|
<specification-version>6.40</specification-version> |
||||||
|
</run-dependency> |
||||||
|
</dependency> |
||||||
|
</module-dependencies> |
||||||
|
<public-packages/> |
||||||
|
<class-path-extension> |
||||||
|
<runtime-relative-path>ext/cai-nmgen-0.2.0.jar</runtime-relative-path> |
||||||
|
<binary-origin>release/modules/ext/cai-nmgen-0.2.0.jar</binary-origin> |
||||||
|
</class-path-extension> |
||||||
|
</data> |
||||||
|
</configuration> |
||||||
|
</project> |
@ -0,0 +1 @@ |
|||||||
|
suite.dir=${basedir}/.. |
@ -0,0 +1,7 @@ |
|||||||
|
OpenIDE-Module-Long-Description=\ |
||||||
|
Nav Mesh Generator - generates a triangle mesh to be used for navigation |
||||||
|
OpenIDE-Module-Name=NavMeshGen |
||||||
|
OpenIDE-Module-Display-Category=Nav Mesh Generator |
||||||
|
CTL_NavMeshTopComponent=Nav Mesh Editor |
||||||
|
HINT_NavMeshTopComponent=Nav Mesh generator window |
||||||
|
OpenIDE-Module-Short-Description=NavMeshGen |
@ -0,0 +1,67 @@ |
|||||||
|
/* |
||||||
|
* To change this template, choose Tools | Templates |
||||||
|
* and open the template in the editor. |
||||||
|
*/ |
||||||
|
package com.jme3.gde.nmgen; |
||||||
|
|
||||||
|
import com.jme3.asset.DesktopAssetManager; |
||||||
|
import com.jme3.gde.core.assets.BinaryModelDataObject; |
||||||
|
import com.jme3.gde.core.assets.ProjectAssetManager; |
||||||
|
import com.jme3.scene.Spatial; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import org.netbeans.api.progress.ProgressHandle; |
||||||
|
import org.netbeans.api.progress.ProgressHandleFactory; |
||||||
|
import org.openide.DialogDisplayer; |
||||||
|
import org.openide.NotifyDescriptor; |
||||||
|
import org.openide.NotifyDescriptor.Confirmation; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author sploreg |
||||||
|
*/ |
||||||
|
public class NavMeshAction implements ActionListener { |
||||||
|
|
||||||
|
private final BinaryModelDataObject context; |
||||||
|
|
||||||
|
public NavMeshAction(BinaryModelDataObject context) { |
||||||
|
this.context = context; |
||||||
|
} |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent ev) { |
||||||
|
final ProjectAssetManager manager = context.getLookup().lookup(ProjectAssetManager.class); |
||||||
|
if (manager == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
Runnable call = new Runnable() { |
||||||
|
|
||||||
|
public void run() { |
||||||
|
ProgressHandle progressHandle = ProgressHandleFactory.createHandle("Opening in Nav Mesh Editor"); |
||||||
|
progressHandle.start(); |
||||||
|
|
||||||
|
|
||||||
|
final Spatial asset = context.loadAsset(); |
||||||
|
|
||||||
|
if(asset!=null){ |
||||||
|
java.awt.EventQueue.invokeLater(new Runnable() { |
||||||
|
|
||||||
|
public void run() { |
||||||
|
((DesktopAssetManager)manager.getManager()).clearCache(); |
||||||
|
NavMeshTopComponent composer = NavMeshTopComponent.findInstance(); |
||||||
|
composer.openScene(asset, context, manager); |
||||||
|
} |
||||||
|
}); |
||||||
|
}else { |
||||||
|
Confirmation msg = new NotifyDescriptor.Confirmation( |
||||||
|
"Error opening " + context.getPrimaryFile().getNameExt(), |
||||||
|
NotifyDescriptor.OK_CANCEL_OPTION, |
||||||
|
NotifyDescriptor.ERROR_MESSAGE); |
||||||
|
DialogDisplayer.getDefault().notify(msg); |
||||||
|
} |
||||||
|
progressHandle.finish(); |
||||||
|
} |
||||||
|
}; |
||||||
|
new Thread(call).start(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
/* |
||||||
|
* To change this template, choose Tools | Templates |
||||||
|
* and open the template in the editor. |
||||||
|
*/ |
||||||
|
package com.jme3.gde.nmgen; |
||||||
|
|
||||||
|
import com.jme3.app.Application; |
||||||
|
import com.jme3.gde.core.scene.SceneApplication; |
||||||
|
import com.jme3.gde.core.scene.controller.AbstractCameraController; |
||||||
|
import com.jme3.renderer.Camera; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author sploreg |
||||||
|
*/ |
||||||
|
public class NavMeshCameraController extends AbstractCameraController { |
||||||
|
|
||||||
|
private NavMeshToolController toolController; |
||||||
|
private NavMeshController editorController; |
||||||
|
private Application app; |
||||||
|
|
||||||
|
public NavMeshCameraController(Camera cam) { |
||||||
|
super(cam, SceneApplication.getApplication().getInputManager()); |
||||||
|
app = SceneApplication.getApplication(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setEditorController(NavMeshController editorController) { |
||||||
|
this.editorController = editorController; |
||||||
|
} |
||||||
|
|
||||||
|
public void setToolController(NavMeshToolController toolController) { |
||||||
|
this.toolController = toolController; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean useCameraControls() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void checkClick(int button, boolean pressed) { |
||||||
|
//TODO
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,199 @@ |
|||||||
|
/* |
||||||
|
* To change this template, choose Tools | Templates |
||||||
|
* and open the template in the editor. |
||||||
|
*/ |
||||||
|
package com.jme3.gde.nmgen; |
||||||
|
|
||||||
|
import com.jme3.bounding.BoundingBox; |
||||||
|
import com.jme3.gde.core.assets.AssetDataObject; |
||||||
|
import com.jme3.gde.core.scene.SceneApplication; |
||||||
|
import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; |
||||||
|
import com.jme3.material.Material; |
||||||
|
import com.jme3.math.ColorRGBA; |
||||||
|
import com.jme3.scene.Geometry; |
||||||
|
import com.jme3.scene.Mesh; |
||||||
|
import com.jme3.scene.Node; |
||||||
|
import com.jme3.scene.Spatial; |
||||||
|
import com.jme3.scene.Spatial.CullHint; |
||||||
|
import com.jme3.terrain.Terrain; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.concurrent.Callable; |
||||||
|
import jme3tools.optimize.GeometryBatchFactory; |
||||||
|
import org.critterai.nmgen.IntermediateData; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author sploreg |
||||||
|
*/ |
||||||
|
public class NavMeshController { |
||||||
|
private JmeSpatial jmeRootNode; |
||||||
|
private Node rootNode; |
||||||
|
private AssetDataObject currentFileObject; |
||||||
|
private NavMeshTopComponent topComponent; |
||||||
|
//private NavMesh navMesh; // current nav mesh in this scene
|
||||||
|
private Material navMaterial; |
||||||
|
|
||||||
|
public NavMeshController(JmeSpatial jmeRootNode, AssetDataObject currentFileObject, NavMeshTopComponent topComponent) { |
||||||
|
this.jmeRootNode = jmeRootNode; |
||||||
|
this.currentFileObject = currentFileObject; |
||||||
|
this.topComponent = topComponent; |
||||||
|
rootNode = this.jmeRootNode.getLookup().lookup(Node.class); |
||||||
|
} |
||||||
|
|
||||||
|
protected void cleanup() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public void setNeedsSave(boolean state) { |
||||||
|
currentFileObject.setModified(state); |
||||||
|
} |
||||||
|
|
||||||
|
protected Mesh generateNavMesh(float cellSize, |
||||||
|
float cellHeight, |
||||||
|
float minTraversableHeight, |
||||||
|
float maxTraversableStep, |
||||||
|
float maxTraversableSlope, |
||||||
|
boolean clipLedges, |
||||||
|
float traversableAreaBorderSize, |
||||||
|
float smoothingThreshold, |
||||||
|
boolean useConservativeExpansion, |
||||||
|
float minUnconnectedRegionSize, |
||||||
|
float mergeRegionSize, |
||||||
|
float maxEdgeLength, |
||||||
|
float edgeMaxDeviation, |
||||||
|
float maxVertsPerPoly, |
||||||
|
float contourSampleDistance, |
||||||
|
float contourMaxDeviation) |
||||||
|
{ |
||||||
|
NavMeshGenerator generator = new NavMeshGenerator(); |
||||||
|
generator.setCellSize(cellSize); |
||||||
|
generator.setCellHeight(cellHeight); |
||||||
|
generator.setMinTraversableHeight(minTraversableHeight); |
||||||
|
generator.setMaxTraversableStep(maxTraversableStep); |
||||||
|
generator.setMaxTraversableSlope(maxTraversableSlope); |
||||||
|
generator.setClipLedges(clipLedges); |
||||||
|
generator.setTraversableAreaBorderSize(traversableAreaBorderSize); |
||||||
|
generator.setSmoothingThreshold((int)smoothingThreshold); |
||||||
|
generator.setUseConservativeExpansion(useConservativeExpansion); |
||||||
|
generator.setMergeRegionSize((int)mergeRegionSize); |
||||||
|
generator.setMaxEdgeLength(maxEdgeLength); |
||||||
|
generator.setEdgeMaxDeviation(edgeMaxDeviation); |
||||||
|
generator.setMaxVertsPerPoly((int)maxVertsPerPoly); |
||||||
|
generator.setContourSampleDistance(contourSampleDistance); |
||||||
|
generator.setContourMaxDeviation(contourMaxDeviation); |
||||||
|
|
||||||
|
IntermediateData id = new IntermediateData(); |
||||||
|
|
||||||
|
generator.setIntermediateData(null); |
||||||
|
|
||||||
|
Mesh mesh = new Mesh(); |
||||||
|
//NavMesh navMesh = new NavMesh();
|
||||||
|
|
||||||
|
GeometryBatchFactory.mergeGeometries(findGeometries(rootNode, new LinkedList<Geometry>(), generator), mesh); |
||||||
|
Mesh optiMesh = generator.optimize(mesh); |
||||||
|
|
||||||
|
final Geometry navMesh = new Geometry("NavMesh"); |
||||||
|
navMesh.setMesh(optiMesh); |
||||||
|
navMesh.setCullHint(CullHint.Always); |
||||||
|
navMesh.setModelBound(new BoundingBox()); |
||||||
|
|
||||||
|
Spatial previous = rootNode.getChild("NavMesh"); |
||||||
|
if (previous != null) |
||||||
|
previous.removeFromParent(); |
||||||
|
|
||||||
|
SceneApplication.getApplication().enqueue(new Callable<Void>() { |
||||||
|
public Void call() throws Exception { |
||||||
|
rootNode.attachChild(navMesh); |
||||||
|
return null; |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
jmeRootNode.refresh(true); |
||||||
|
|
||||||
|
//navMesh.setUserData("NavMeshGenerator", generator);
|
||||||
|
|
||||||
|
//navMesh.loadFromMesh(optiMesh);
|
||||||
|
//saveNavMesh(navMesh, generator);
|
||||||
|
|
||||||
|
setNeedsSave(true); |
||||||
|
|
||||||
|
return optiMesh; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* NavMesh saves as user data on the scene's root node |
||||||
|
*/ |
||||||
|
/*private void saveNavMesh(NavMesh navMesh, NavMeshGenerator generator) { |
||||||
|
rootNode.setUserData("NavMesh", navMesh); |
||||||
|
rootNode.setUserData("NavMeshGenerator", generator); |
||||||
|
this.navMesh = navMesh; |
||||||
|
} |
||||||
|
|
||||||
|
protected NavMesh getNavMesh() { |
||||||
|
if (navMesh == null) { |
||||||
|
navMesh = findNavMesh(); |
||||||
|
} |
||||||
|
return navMesh; |
||||||
|
} |
||||||
|
|
||||||
|
protected NavMesh findNavMesh() { |
||||||
|
return rootNode.getUserData("NavMesh"); |
||||||
|
}*/ |
||||||
|
|
||||||
|
protected NavMeshGenerator getNavMeshGenerator() { |
||||||
|
return rootNode.getUserData("NavMeshGenerator"); |
||||||
|
} |
||||||
|
|
||||||
|
private List<Geometry> findGeometries(Node node, List<Geometry> geoms, NavMeshGenerator generator) { |
||||||
|
for (Iterator<Spatial> it = node.getChildren().iterator(); it.hasNext();) { |
||||||
|
Spatial spatial = it.next(); |
||||||
|
if (spatial instanceof Geometry) { |
||||||
|
geoms.add((Geometry) spatial); |
||||||
|
} else if (spatial instanceof Node) { |
||||||
|
if (spatial instanceof Terrain) { |
||||||
|
Mesh merged = generator.terrain2mesh((Terrain)spatial); |
||||||
|
Geometry g = new Geometry("mergedTerrain"); |
||||||
|
g.setMesh(merged); |
||||||
|
geoms.add(g); |
||||||
|
} else |
||||||
|
findGeometries((Node) spatial, geoms, generator); |
||||||
|
} |
||||||
|
} |
||||||
|
return geoms; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create polygons from each of the Nav Mesh Cells. |
||||||
|
* @return a single mesh representing the nav mesh |
||||||
|
*/ |
||||||
|
/*protected Mesh createDebugMesh() { |
||||||
|
NavMesh navMesh = getNavMesh(); |
||||||
|
if (navMesh != null) { |
||||||
|
List<Geometry> meshes = new ArrayList<Geometry>(); |
||||||
|
for (int i=0; i<navMesh.getNumCells(); i++) { |
||||||
|
Mesh m = navMesh.getCell(i).getDebugMesh(); |
||||||
|
Geometry g = new Geometry(); |
||||||
|
g.setMaterial(getNavMaterial()); |
||||||
|
g.setMesh(m); |
||||||
|
meshes.add(g); |
||||||
|
} |
||||||
|
Mesh mesh = new Mesh(); |
||||||
|
GeometryBatchFactory.mergeGeometries(meshes, mesh); |
||||||
|
return mesh; |
||||||
|
} |
||||||
|
return null; |
||||||
|
}*/ |
||||||
|
|
||||||
|
private Material getNavMaterial() { |
||||||
|
if (navMaterial != null) |
||||||
|
return navMaterial; |
||||||
|
navMaterial = new Material(SceneApplication.getApplication().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); |
||||||
|
navMaterial.setColor("Color", ColorRGBA.Green); |
||||||
|
navMaterial.getAdditionalRenderState().setWireframe(true); |
||||||
|
return navMaterial; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,344 @@ |
|||||||
|
package com.jme3.gde.nmgen; |
||||||
|
|
||||||
|
import com.jme3.export.InputCapsule; |
||||||
|
import com.jme3.export.JmeExporter; |
||||||
|
import com.jme3.export.JmeImporter; |
||||||
|
import com.jme3.export.OutputCapsule; |
||||||
|
import com.jme3.export.Savable; |
||||||
|
import com.jme3.math.FastMath; |
||||||
|
import com.jme3.math.Vector3f; |
||||||
|
import com.jme3.scene.Mesh; |
||||||
|
import com.jme3.scene.Node; |
||||||
|
import com.jme3.scene.VertexBuffer.Type; |
||||||
|
import com.jme3.scene.mesh.IndexBuffer; |
||||||
|
import com.jme3.terrain.Terrain; |
||||||
|
import java.io.IOException; |
||||||
|
import java.nio.FloatBuffer; |
||||||
|
import org.critterai.nmgen.IntermediateData; |
||||||
|
import org.critterai.nmgen.NavmeshGenerator; |
||||||
|
import org.critterai.nmgen.TriangleMesh; |
||||||
|
|
||||||
|
public class NavMeshGenerator implements Savable { |
||||||
|
|
||||||
|
private org.critterai.nmgen.NavmeshGenerator nmgen; |
||||||
|
private float cellSize = 1f; |
||||||
|
private float cellHeight = 1.5f; |
||||||
|
private float minTraversableHeight = 7.5f; |
||||||
|
private float maxTraversableStep = 1f; |
||||||
|
private float maxTraversableSlope = 48.0f; |
||||||
|
private boolean clipLedges = false; |
||||||
|
private float traversableAreaBorderSize = 1.2f; |
||||||
|
private int smoothingThreshold = 2; |
||||||
|
private boolean useConservativeExpansion = true; |
||||||
|
private int minUnconnectedRegionSize = 3; |
||||||
|
private int mergeRegionSize = 10; |
||||||
|
private float maxEdgeLength = 0; |
||||||
|
private float edgeMaxDeviation = 2.4f; |
||||||
|
private int maxVertsPerPoly = 6; |
||||||
|
private float contourSampleDistance = 25; |
||||||
|
private float contourMaxDeviation = 25; |
||||||
|
|
||||||
|
private IntermediateData intermediateData; |
||||||
|
|
||||||
|
public NavMeshGenerator() { |
||||||
|
} |
||||||
|
|
||||||
|
public void printParams() { |
||||||
|
System.out.println("Cell Size: " + cellSize); |
||||||
|
System.out.println("Cell Height: " + cellHeight); |
||||||
|
System.out.println("Min Trav. Height: " + minTraversableHeight); |
||||||
|
System.out.println("Max Trav. Step: " + maxTraversableStep); |
||||||
|
System.out.println("Max Trav. Slope: " + maxTraversableSlope); |
||||||
|
System.out.println("Clip Ledges: " + clipLedges); |
||||||
|
System.out.println("Trav. Area Border Size: " + traversableAreaBorderSize); |
||||||
|
System.out.println("Smooth Thresh.: " + smoothingThreshold); |
||||||
|
System.out.println("Use Cons. Expansion: " + useConservativeExpansion); |
||||||
|
System.out.println("Min Unconn. Region Size: " + minUnconnectedRegionSize); |
||||||
|
System.out.println("Merge Region Size: " + mergeRegionSize); |
||||||
|
System.out.println("Max Edge Length: " + maxEdgeLength); |
||||||
|
System.out.println("Edge Max Dev.: " + edgeMaxDeviation); |
||||||
|
System.out.println("Max Verts/Poly: " + maxVertsPerPoly); |
||||||
|
System.out.println("Contour Sample Dist: " + contourSampleDistance); |
||||||
|
System.out.println("Contour Max Dev.: " + contourMaxDeviation); |
||||||
|
} |
||||||
|
|
||||||
|
public void setIntermediateData(IntermediateData data) { |
||||||
|
this.intermediateData = data; |
||||||
|
} |
||||||
|
|
||||||
|
public Mesh optimize(Mesh mesh) { |
||||||
|
nmgen = new NavmeshGenerator(cellSize, cellHeight, minTraversableHeight, |
||||||
|
maxTraversableStep, maxTraversableSlope, |
||||||
|
clipLedges, traversableAreaBorderSize, |
||||||
|
smoothingThreshold, useConservativeExpansion, |
||||||
|
minUnconnectedRegionSize, mergeRegionSize, |
||||||
|
maxEdgeLength, edgeMaxDeviation, maxVertsPerPoly, |
||||||
|
contourSampleDistance, contourMaxDeviation); |
||||||
|
|
||||||
|
FloatBuffer pb = mesh.getFloatBuffer(Type.Position); |
||||||
|
IndexBuffer ib = mesh.getIndexBuffer(); |
||||||
|
|
||||||
|
// copy positions to float array
|
||||||
|
float[] positions = new float[pb.capacity()]; |
||||||
|
pb.clear(); |
||||||
|
pb.get(positions); |
||||||
|
|
||||||
|
// generate int array of indices
|
||||||
|
int[] indices = new int[ib.size()]; |
||||||
|
for (int i = 0; i < indices.length; i++) { |
||||||
|
indices[i] = ib.get(i); |
||||||
|
} |
||||||
|
|
||||||
|
TriangleMesh triMesh = nmgen.build(positions, indices, intermediateData); |
||||||
|
if (triMesh == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
int[] indices2 = triMesh.indices; |
||||||
|
float[] positions2 = triMesh.vertices; |
||||||
|
|
||||||
|
Mesh mesh2 = new Mesh(); |
||||||
|
mesh2.setBuffer(Type.Position, 3, positions2); |
||||||
|
mesh2.setBuffer(Type.Index, 3, indices2); |
||||||
|
mesh2.updateBound(); |
||||||
|
mesh2.updateCounts(); |
||||||
|
|
||||||
|
return mesh2; |
||||||
|
} |
||||||
|
|
||||||
|
public Mesh terrain2mesh(Terrain terr) { |
||||||
|
float[] heights = terr.getHeightMap(); |
||||||
|
int length = heights.length; |
||||||
|
int side = (int) FastMath.sqrt(heights.length); |
||||||
|
float[] vertices = new float[length * 3]; |
||||||
|
int[] indices = new int[(side-1)*(side-1)*6]; |
||||||
|
|
||||||
|
Vector3f scale = ((Node)terr).getWorldScale().clone(); |
||||||
|
Vector3f trans = ((Node)terr).getWorldTranslation().clone(); |
||||||
|
trans.x -= terr.getTerrainSize()/2f; |
||||||
|
trans.z -= terr.getTerrainSize()/2f; |
||||||
|
float offsetX = trans.x * scale.x; |
||||||
|
float offsetZ = trans.z * scale.z; |
||||||
|
|
||||||
|
// do vertices
|
||||||
|
int i=0; |
||||||
|
for (int z=0; z<side; z++) { |
||||||
|
for (int x=0; x<side; x++) { |
||||||
|
vertices[i++] = x+offsetX; |
||||||
|
vertices[i++] = heights[z*side+x]*scale.y; |
||||||
|
vertices[i++] = z+offsetZ; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// do indexes
|
||||||
|
i=0; |
||||||
|
for (int z=0; z<side-1; z++) { |
||||||
|
for (int x=0; x<side-1; x++) { |
||||||
|
// triangle 1
|
||||||
|
indices[i++] = z*side+x; |
||||||
|
indices[i++] = (z+1)*side+x; |
||||||
|
indices[i++] = (z+1)*side+x+1; |
||||||
|
// triangle 2
|
||||||
|
indices[i++] = z*side+x; |
||||||
|
indices[i++] = (z+1)*side+x+1; |
||||||
|
indices[i++] = z*side+x+1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Mesh mesh2 = new Mesh(); |
||||||
|
mesh2.setBuffer(Type.Position, 3, vertices); |
||||||
|
mesh2.setBuffer(Type.Index, 3, indices); |
||||||
|
mesh2.updateBound(); |
||||||
|
mesh2.updateCounts(); |
||||||
|
|
||||||
|
return mesh2; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return The height resolution used when sampling the source mesh. Value must be > 0. |
||||||
|
*/ |
||||||
|
public float getCellHeight() { |
||||||
|
return cellHeight; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param cellHeight - The height resolution used when sampling the source mesh. Value must be > 0. |
||||||
|
*/ |
||||||
|
public void setCellHeight(float cellHeight) { |
||||||
|
this.cellHeight = cellHeight; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return The width and depth resolution used when sampling the the source mesh. |
||||||
|
*/ |
||||||
|
public float getCellSize() { |
||||||
|
return cellSize; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param cellSize - The width and depth resolution used when sampling the the source mesh. |
||||||
|
*/ |
||||||
|
public void setCellSize(float cellSize) { |
||||||
|
this.cellSize = cellSize; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isClipLedges() { |
||||||
|
return clipLedges; |
||||||
|
} |
||||||
|
|
||||||
|
public void setClipLedges(boolean clipLedges) { |
||||||
|
this.clipLedges = clipLedges; |
||||||
|
} |
||||||
|
|
||||||
|
public float getContourMaxDeviation() { |
||||||
|
return contourMaxDeviation; |
||||||
|
} |
||||||
|
|
||||||
|
public void setContourMaxDeviation(float contourMaxDeviation) { |
||||||
|
this.contourMaxDeviation = contourMaxDeviation; |
||||||
|
} |
||||||
|
|
||||||
|
public float getContourSampleDistance() { |
||||||
|
return contourSampleDistance; |
||||||
|
} |
||||||
|
|
||||||
|
public void setContourSampleDistance(float contourSampleDistance) { |
||||||
|
this.contourSampleDistance = contourSampleDistance; |
||||||
|
} |
||||||
|
|
||||||
|
public float getEdgeMaxDeviation() { |
||||||
|
return edgeMaxDeviation; |
||||||
|
} |
||||||
|
|
||||||
|
public void setEdgeMaxDeviation(float edgeMaxDeviation) { |
||||||
|
this.edgeMaxDeviation = edgeMaxDeviation; |
||||||
|
} |
||||||
|
|
||||||
|
public float getMaxEdgeLength() { |
||||||
|
return maxEdgeLength; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMaxEdgeLength(float maxEdgeLength) { |
||||||
|
this.maxEdgeLength = maxEdgeLength; |
||||||
|
} |
||||||
|
|
||||||
|
public float getMaxTraversableSlope() { |
||||||
|
return maxTraversableSlope; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMaxTraversableSlope(float maxTraversableSlope) { |
||||||
|
this.maxTraversableSlope = maxTraversableSlope; |
||||||
|
} |
||||||
|
|
||||||
|
public float getMaxTraversableStep() { |
||||||
|
return maxTraversableStep; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMaxTraversableStep(float maxTraversableStep) { |
||||||
|
this.maxTraversableStep = maxTraversableStep; |
||||||
|
} |
||||||
|
|
||||||
|
public int getMaxVertsPerPoly() { |
||||||
|
return maxVertsPerPoly; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMaxVertsPerPoly(int maxVertsPerPoly) { |
||||||
|
this.maxVertsPerPoly = maxVertsPerPoly; |
||||||
|
} |
||||||
|
|
||||||
|
public int getMergeRegionSize() { |
||||||
|
return mergeRegionSize; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMergeRegionSize(int mergeRegionSize) { |
||||||
|
this.mergeRegionSize = mergeRegionSize; |
||||||
|
} |
||||||
|
|
||||||
|
public float getMinTraversableHeight() { |
||||||
|
return minTraversableHeight; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMinTraversableHeight(float minTraversableHeight) { |
||||||
|
this.minTraversableHeight = minTraversableHeight; |
||||||
|
} |
||||||
|
|
||||||
|
public int getMinUnconnectedRegionSize() { |
||||||
|
return minUnconnectedRegionSize; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMinUnconnectedRegionSize(int minUnconnectedRegionSize) { |
||||||
|
this.minUnconnectedRegionSize = minUnconnectedRegionSize; |
||||||
|
} |
||||||
|
|
||||||
|
public NavmeshGenerator getNmgen() { |
||||||
|
return nmgen; |
||||||
|
} |
||||||
|
|
||||||
|
public void setNmgen(NavmeshGenerator nmgen) { |
||||||
|
this.nmgen = nmgen; |
||||||
|
} |
||||||
|
|
||||||
|
public int getSmoothingThreshold() { |
||||||
|
return smoothingThreshold; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSmoothingThreshold(int smoothingThreshold) { |
||||||
|
this.smoothingThreshold = smoothingThreshold; |
||||||
|
} |
||||||
|
|
||||||
|
public float getTraversableAreaBorderSize() { |
||||||
|
return traversableAreaBorderSize; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTraversableAreaBorderSize(float traversableAreaBorderSize) { |
||||||
|
this.traversableAreaBorderSize = traversableAreaBorderSize; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isUseConservativeExpansion() { |
||||||
|
return useConservativeExpansion; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUseConservativeExpansion(boolean useConservativeExpansion) { |
||||||
|
this.useConservativeExpansion = useConservativeExpansion; |
||||||
|
} |
||||||
|
|
||||||
|
public void write(JmeExporter ex) throws IOException { |
||||||
|
OutputCapsule oc = ex.getCapsule(this); |
||||||
|
oc.write(cellSize, "cellSize", 1f); |
||||||
|
oc.write(cellHeight, "cellHeight", 1.5f); |
||||||
|
oc.write(minTraversableHeight, "minTraversableHeight", 7.5f); |
||||||
|
oc.write(maxTraversableStep, "maxTraversableStep", 1f); |
||||||
|
oc.write(maxTraversableSlope, "maxTraversableSlope", 48f); |
||||||
|
oc.write(clipLedges, "clipLedges", false); |
||||||
|
oc.write(traversableAreaBorderSize, "traversableAreaBorderSize", 1.2f); |
||||||
|
oc.write(smoothingThreshold, "smoothingThreshold", 2); |
||||||
|
oc.write(useConservativeExpansion, "useConservativeExpansion", true); |
||||||
|
oc.write(minUnconnectedRegionSize, "minUnconnectedRegionSize", 3); |
||||||
|
oc.write(mergeRegionSize, "mergeRegionSize", 10); |
||||||
|
oc.write(maxEdgeLength, "maxEdgeLength", 0); |
||||||
|
oc.write(edgeMaxDeviation, "edgeMaxDeviation", 2.4f); |
||||||
|
oc.write(maxVertsPerPoly, "maxVertsPerPoly", 6); |
||||||
|
oc.write(contourSampleDistance, "contourSampleDistance", 25); |
||||||
|
oc.write(contourMaxDeviation, "contourMaxDeviation", 25); |
||||||
|
} |
||||||
|
|
||||||
|
public void read(JmeImporter im) throws IOException { |
||||||
|
InputCapsule ic = im.getCapsule(this); |
||||||
|
cellSize = ic.readFloat("cellSize", 1f); |
||||||
|
cellHeight = ic.readFloat("cellHeight", 1.5f); |
||||||
|
minTraversableHeight = ic.readFloat("minTraversableHeight", 7.5f); |
||||||
|
maxTraversableStep = ic.readFloat("maxTraversableStep", 1f); |
||||||
|
maxTraversableSlope = ic.readFloat("maxTraversableSlope", 48f); |
||||||
|
clipLedges = ic.readBoolean("clipLedges", false); |
||||||
|
traversableAreaBorderSize = ic.readFloat("traversableAreaBorderSize", 1.2f); |
||||||
|
smoothingThreshold = (int)ic.readFloat("smoothingThreshold", 2); |
||||||
|
useConservativeExpansion = ic.readBoolean("useConservativeExpansion", true); |
||||||
|
minUnconnectedRegionSize = (int)ic.readFloat("minUnconnectedRegionSize", 3); |
||||||
|
mergeRegionSize = (int)ic.readFloat("mergeRegionSize", 10); |
||||||
|
maxEdgeLength = ic.readFloat("maxEdgeLength", 0); |
||||||
|
edgeMaxDeviation = ic.readFloat("edgeMaxDeviation", 2.4f); |
||||||
|
maxVertsPerPoly = (int)ic.readFloat("maxVertsPerPoly", 6); |
||||||
|
contourSampleDistance = ic.readFloat("contourSampleDistance", 25); |
||||||
|
contourMaxDeviation = ic.readFloat("contourMaxDeviation", 25); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
/* |
||||||
|
* To change this template, choose Tools | Templates |
||||||
|
* and open the template in the editor. |
||||||
|
*/ |
||||||
|
package com.jme3.gde.nmgen; |
||||||
|
|
||||||
|
import com.jme3.asset.AssetManager; |
||||||
|
import com.jme3.gde.core.scene.controller.SceneToolController; |
||||||
|
import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; |
||||||
|
import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; |
||||||
|
import com.jme3.material.Material; |
||||||
|
import com.jme3.math.ColorRGBA; |
||||||
|
import com.jme3.scene.Geometry; |
||||||
|
import com.jme3.scene.Mesh; |
||||||
|
import com.jme3.scene.Node; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author sploreg |
||||||
|
*/ |
||||||
|
public class NavMeshToolController extends SceneToolController { |
||||||
|
|
||||||
|
private NavMeshController editorController; |
||||||
|
private NavMeshCameraController cameraController; |
||||||
|
private JmeSpatial jmeRootNode; |
||||||
|
private Geometry navGeom; |
||||||
|
private Material navMaterial; |
||||||
|
|
||||||
|
public NavMeshToolController(Node toolsNode, AssetManager manager, JmeNode rootNode) { |
||||||
|
super(toolsNode, manager); |
||||||
|
this.jmeRootNode = rootNode; |
||||||
|
} |
||||||
|
|
||||||
|
public void setEditorController(NavMeshController editorController) { |
||||||
|
this.editorController = editorController; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCameraController(NavMeshCameraController cameraController) { |
||||||
|
this.cameraController = cameraController; |
||||||
|
} |
||||||
|
|
||||||
|
private Material getNavMaterial() { |
||||||
|
if (navMaterial != null) |
||||||
|
return navMaterial; |
||||||
|
navMaterial = new Material(manager, "Common/MatDefs/Misc/Unshaded.j3md"); |
||||||
|
navMaterial.setColor("Color", ColorRGBA.Green); |
||||||
|
navMaterial.getAdditionalRenderState().setWireframe(true); |
||||||
|
return navMaterial; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Render the new nav mesh |
||||||
|
*/ |
||||||
|
protected void attachNavMesh(Mesh navMesh) { |
||||||
|
if (navMesh == null) |
||||||
|
return; |
||||||
|
if (navGeom == null) |
||||||
|
navGeom = new Geometry("NavMesh"); |
||||||
|
navGeom.setMesh(navMesh); |
||||||
|
navGeom.setMaterial(getNavMaterial()); |
||||||
|
toolsNode.attachChild(navGeom); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,379 @@ |
|||||||
|
<?xml version="1.1" encoding="UTF-8" ?> |
||||||
|
|
||||||
|
<Form version="1.4" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> |
||||||
|
<AuxValues> |
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> |
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> |
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> |
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/> |
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/> |
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> |
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> |
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> |
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> |
||||||
|
</AuxValues> |
||||||
|
|
||||||
|
<Layout> |
||||||
|
<DimensionLayout dim="0"> |
||||||
|
<Group type="103" groupAlignment="0" attributes="0"> |
||||||
|
<Component id="jToolBar1" alignment="1" pref="664" max="32767" attributes="0"/> |
||||||
|
<Component id="jScrollPane1" alignment="1" pref="664" max="32767" attributes="0"/> |
||||||
|
</Group> |
||||||
|
</DimensionLayout> |
||||||
|
<DimensionLayout dim="1"> |
||||||
|
<Group type="103" groupAlignment="0" attributes="0"> |
||||||
|
<Group type="102" alignment="0" attributes="0"> |
||||||
|
<Component id="jToolBar1" min="-2" pref="25" max="-2" attributes="0"/> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Component id="jScrollPane1" min="-2" pref="194" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
</Group> |
||||||
|
</DimensionLayout> |
||||||
|
</Layout> |
||||||
|
<SubComponents> |
||||||
|
<Container class="javax.swing.JScrollPane" name="jScrollPane1"> |
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> |
||||||
|
<SubComponents> |
||||||
|
<Container class="javax.swing.JPanel" name="jPanel1"> |
||||||
|
|
||||||
|
<Layout> |
||||||
|
<DimensionLayout dim="0"> |
||||||
|
<Group type="103" groupAlignment="0" attributes="0"> |
||||||
|
<Group type="102" attributes="0"> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="1" attributes="0"> |
||||||
|
<Component id="jLabel16" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel15" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel14" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel13" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel12" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel11" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel10" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel9" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel8" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel7" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel6" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel5" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel4" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel3" alignment="1" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel2" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel1" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace type="unrelated" max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="0" max="-2" attributes="0"> |
||||||
|
<Component id="minUnconnectedRegionSizeField" max="32767" attributes="1"/> |
||||||
|
<Component id="contourMaxDeviationField" max="32767" attributes="1"/> |
||||||
|
<Component id="contourSampleDistanceField" max="32767" attributes="1"/> |
||||||
|
<Component id="maxVertsPerPolyField" max="32767" attributes="1"/> |
||||||
|
<Component id="edgeMaxDeviationField" max="32767" attributes="1"/> |
||||||
|
<Component id="maxEdgeLengthField" max="32767" attributes="1"/> |
||||||
|
<Component id="smoothingThresholdField" max="32767" attributes="1"/> |
||||||
|
<Component id="maxTraversableSlopeField" max="32767" attributes="1"/> |
||||||
|
<Component id="maxTraversableStepField" max="32767" attributes="1"/> |
||||||
|
<Component id="minTraversableHeightField" max="32767" attributes="1"/> |
||||||
|
<Component id="cellSizeField" alignment="0" pref="58" max="32767" attributes="1"/> |
||||||
|
<Component id="cellHeightField" alignment="0" max="32767" attributes="0"/> |
||||||
|
<Component id="clipLedgesBox" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="traversableAreaBorderSizeField" alignment="0" max="32767" attributes="1"/> |
||||||
|
<Component id="useConservativeExpansionBox" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="mergeRegionSizeField" alignment="0" max="32767" attributes="1"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace pref="594" max="32767" attributes="0"/> |
||||||
|
</Group> |
||||||
|
</Group> |
||||||
|
</DimensionLayout> |
||||||
|
<DimensionLayout dim="1"> |
||||||
|
<Group type="103" groupAlignment="0" attributes="0"> |
||||||
|
<Group type="102" alignment="0" attributes="0"> |
||||||
|
<EmptySpace min="-2" pref="31" max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="cellSizeField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="cellHeightField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="minTraversableHeightField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="maxTraversableStepField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="maxTraversableSlopeField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="0" attributes="0"> |
||||||
|
<Component id="jLabel6" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="clipLedgesBox" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="traversableAreaBorderSizeField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="smoothingThresholdField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="0" attributes="0"> |
||||||
|
<Component id="jLabel9" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="useConservativeExpansionBox" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel10" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="mergeRegionSizeField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel11" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="maxEdgeLengthField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel12" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="edgeMaxDeviationField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel13" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="maxVertsPerPolyField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel14" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="contourSampleDistanceField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel15" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="contourMaxDeviationField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Group type="103" groupAlignment="3" attributes="0"> |
||||||
|
<Component id="jLabel16" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
<Component id="minUnconnectedRegionSizeField" alignment="3" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<EmptySpace pref="57" max="32767" attributes="0"/> |
||||||
|
</Group> |
||||||
|
</Group> |
||||||
|
</DimensionLayout> |
||||||
|
</Layout> |
||||||
|
<SubComponents> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel1"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Cell Size"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="The width and depth resolution used when sampling the source mesh"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="cellSizeField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="1"/> |
||||||
|
</Properties> |
||||||
|
<Events> |
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cellSizeFieldActionPerformed"/> |
||||||
|
</Events> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel2"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Cell Height"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="The height resolution used when sampling the source mesh"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="cellHeightField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="1.5"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel3"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Min Traversable Height"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="Represents the minimum floor to ceiling height that will still allow the floor area to be considered walkable"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="minTraversableHeightField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="7.5"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel4"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Max Traversable Step"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="Represents the maximum ledge height that is considered to still be walkable"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="maxTraversableStepField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="1"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel5"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Max Traversable Slope"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="The maximum slope that is considered walkable. (Degrees)"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="maxTraversableSlopeField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="48"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel6"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Clip Ledges"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="Indicates whether ledges should be marked as unwalkable"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JCheckBox" name="clipLedgesBox"> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel7"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Traversable Area Border Size"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="Represents the closest any part of the navmesh can get to an obstruction in the source mesh"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="traversableAreaBorderSizeField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="1.2"/> |
||||||
|
</Properties> |
||||||
|
<Events> |
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="traversableAreaBorderSizeFieldActionPerformed"/> |
||||||
|
</Events> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel8"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Smoothing Threshold"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="The amount of smoothing to be performed when generating the distance field"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="smoothingThresholdField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="2"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel9"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Use Conservative Expansion"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="Applies extra algorithms to regions to help prevent poorly formed regions from forming. Enabling this feature significantly increased processing cost."/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JCheckBox" name="useConservativeExpansionBox"> |
||||||
|
<Properties> |
||||||
|
<Property name="selected" type="boolean" value="true"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel10"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Merge Region Size"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="Any regions smaller than this size will, if possible, be merged with larger regions. (Voxels)"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="mergeRegionSizeField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="10"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel11"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Max Edge Length"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="The maximum length of polygon edges that represent the border of the navmesh"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="maxEdgeLengthField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="0"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel12"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Edge Max Deviation"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="The maximum distance the edge of the navmesh may deviate from the source geometry. Setting this lower will result in the navmesh edges following the geometry contour more accurately at the expense of an increased triangle count."/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="edgeMaxDeviationField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="2.4"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel13"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Max Verts Per Poly"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="The maximum number of vertices per polygon for polygons generated during the voxel to polygon conversion stage. Higher values reduce performance, but can also result in better formed triangles in the navmesh. A value of around 6 is generally adequate with diminishing returns for values higher than 6."/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="maxVertsPerPolyField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="6"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel14"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Contour Sample Distance"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="Sets the sampling distance to use when matching the navmesh to the surface of the original geometry. Impacts how well the final mesh conforms to the original geometry's surface contour. Higher values result in a navmesh which conforms more closely to the original geometry's surface at the cost of a higher final triangle count and higher processing cost"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="contourSampleDistanceField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="25"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel15"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Contour Max Deviation"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="The maximum distance the surface of the navmesh may deviate from the surface of the original geometry."/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="contourMaxDeviationField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="25"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JLabel" name="jLabel16"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Min Unconnected Region Size"/> |
||||||
|
<Property name="toolTipText" type="java.lang.String" value="The minimum region size for unconnected (island) regions. (Voxels) "/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
<Component class="javax.swing.JTextField" name="minUnconnectedRegionSizeField"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="3"/> |
||||||
|
</Properties> |
||||||
|
</Component> |
||||||
|
</SubComponents> |
||||||
|
</Container> |
||||||
|
</SubComponents> |
||||||
|
</Container> |
||||||
|
<Container class="javax.swing.JToolBar" name="jToolBar1"> |
||||||
|
<Properties> |
||||||
|
<Property name="rollover" type="boolean" value="true"/> |
||||||
|
</Properties> |
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/> |
||||||
|
<SubComponents> |
||||||
|
<Component class="javax.swing.JButton" name="jButton1"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" value="Generate"/> |
||||||
|
<Property name="focusable" type="boolean" value="false"/> |
||||||
|
<Property name="horizontalTextPosition" type="int" value="0"/> |
||||||
|
<Property name="verticalTextPosition" type="int" value="3"/> |
||||||
|
</Properties> |
||||||
|
<Events> |
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/> |
||||||
|
</Events> |
||||||
|
</Component> |
||||||
|
</SubComponents> |
||||||
|
</Container> |
||||||
|
</SubComponents> |
||||||
|
</Form> |
@ -0,0 +1,674 @@ |
|||||||
|
/* |
||||||
|
* To change this template, choose Tools | Templates |
||||||
|
* and open the template in the editor. |
||||||
|
*/ |
||||||
|
|
||||||
|
package com.jme3.gde.nmgen; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.jme3.gde.core.assets.AssetDataObject; |
||||||
|
import com.jme3.gde.core.assets.ProjectAssetManager; |
||||||
|
import com.jme3.gde.core.scene.PreviewRequest; |
||||||
|
import com.jme3.gde.core.scene.SceneApplication; |
||||||
|
import com.jme3.gde.core.scene.SceneListener; |
||||||
|
import com.jme3.gde.core.scene.SceneRequest; |
||||||
|
import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; |
||||||
|
import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; |
||||||
|
import com.jme3.gde.core.sceneexplorer.nodes.NodeUtility; |
||||||
|
import com.jme3.scene.Mesh; |
||||||
|
import com.jme3.scene.Node; |
||||||
|
import com.jme3.scene.Spatial; |
||||||
|
import java.util.Collection; |
||||||
|
import java.util.logging.Logger; |
||||||
|
import org.openide.util.LookupEvent; |
||||||
|
import org.openide.util.NbBundle; |
||||||
|
import org.openide.windows.TopComponent; |
||||||
|
import org.netbeans.api.settings.ConvertAsProperties; |
||||||
|
import org.openide.util.ImageUtilities; |
||||||
|
import org.openide.util.Lookup.Result; |
||||||
|
import org.openide.util.LookupListener; |
||||||
|
import org.openide.util.Utilities; |
||||||
|
import org.openide.windows.WindowManager; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Top component which displays the Nav Mesh editor. |
||||||
|
* |
||||||
|
* http://critterai.org/javadoc/nmgen/org/critterai/nmgen/NavmeshGenerator.html
|
||||||
|
*/ |
||||||
|
@ConvertAsProperties( |
||||||
|
dtd="-//com.sploreg.tritium.editor.navmesh//NavMesh//EN", |
||||||
|
autostore=false |
||||||
|
) |
||||||
|
public final class NavMeshTopComponent extends TopComponent implements SceneListener, LookupListener { |
||||||
|
|
||||||
|
private static NavMeshTopComponent instance; |
||||||
|
static final String ICON_PATH = "com/sploreg/tritium/editor/navmesh/logo.png"; |
||||||
|
private static final String PREFERRED_ID = "NavMeshTopComponent"; |
||||||
|
private SceneRequest currentRequest; |
||||||
|
private final Result<JmeSpatial> result; |
||||||
|
private NavMeshController editorController; |
||||||
|
private NavMeshToolController toolController; |
||||||
|
private NavMeshCameraController cameraController; |
||||||
|
private JmeSpatial selectedSpat; |
||||||
|
|
||||||
|
public NavMeshTopComponent() { |
||||||
|
initComponents(); |
||||||
|
setName(NbBundle.getMessage(NavMeshTopComponent.class, "CTL_NavMeshTopComponent")); |
||||||
|
setToolTipText(NbBundle.getMessage(NavMeshTopComponent.class, "HINT_NavMeshTopComponent")); |
||||||
|
setIcon(ImageUtilities.loadImage(ICON_PATH, true)); |
||||||
|
result = Utilities.actionsGlobalContext().lookupResult(JmeSpatial.class); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets default instance. Do not use directly: reserved for *.settings files only, |
||||||
|
* i.e. deserialization routines; otherwise you could get a non-deserialized instance. |
||||||
|
* To obtain the singleton instance, use {@link #findInstance}. |
||||||
|
*/ |
||||||
|
public static synchronized NavMeshTopComponent getDefault() { |
||||||
|
if (instance == null) { |
||||||
|
instance = new NavMeshTopComponent(); |
||||||
|
} |
||||||
|
return instance; |
||||||
|
} |
||||||
|
|
||||||
|
/** This method is called from within the constructor to |
||||||
|
* initialize the form. |
||||||
|
* WARNING: Do NOT modify this code. The content of this method is |
||||||
|
* always regenerated by the Form Editor. |
||||||
|
*/ |
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() { |
||||||
|
|
||||||
|
jScrollPane1 = new javax.swing.JScrollPane(); |
||||||
|
jPanel1 = new javax.swing.JPanel(); |
||||||
|
jLabel1 = new javax.swing.JLabel(); |
||||||
|
cellSizeField = new javax.swing.JTextField(); |
||||||
|
jLabel2 = new javax.swing.JLabel(); |
||||||
|
cellHeightField = new javax.swing.JTextField(); |
||||||
|
jLabel3 = new javax.swing.JLabel(); |
||||||
|
minTraversableHeightField = new javax.swing.JTextField(); |
||||||
|
jLabel4 = new javax.swing.JLabel(); |
||||||
|
maxTraversableStepField = new javax.swing.JTextField(); |
||||||
|
jLabel5 = new javax.swing.JLabel(); |
||||||
|
maxTraversableSlopeField = new javax.swing.JTextField(); |
||||||
|
jLabel6 = new javax.swing.JLabel(); |
||||||
|
clipLedgesBox = new javax.swing.JCheckBox(); |
||||||
|
jLabel7 = new javax.swing.JLabel(); |
||||||
|
traversableAreaBorderSizeField = new javax.swing.JTextField(); |
||||||
|
jLabel8 = new javax.swing.JLabel(); |
||||||
|
smoothingThresholdField = new javax.swing.JTextField(); |
||||||
|
jLabel9 = new javax.swing.JLabel(); |
||||||
|
useConservativeExpansionBox = new javax.swing.JCheckBox(); |
||||||
|
jLabel10 = new javax.swing.JLabel(); |
||||||
|
mergeRegionSizeField = new javax.swing.JTextField(); |
||||||
|
jLabel11 = new javax.swing.JLabel(); |
||||||
|
maxEdgeLengthField = new javax.swing.JTextField(); |
||||||
|
jLabel12 = new javax.swing.JLabel(); |
||||||
|
edgeMaxDeviationField = new javax.swing.JTextField(); |
||||||
|
jLabel13 = new javax.swing.JLabel(); |
||||||
|
maxVertsPerPolyField = new javax.swing.JTextField(); |
||||||
|
jLabel14 = new javax.swing.JLabel(); |
||||||
|
contourSampleDistanceField = new javax.swing.JTextField(); |
||||||
|
jLabel15 = new javax.swing.JLabel(); |
||||||
|
contourMaxDeviationField = new javax.swing.JTextField(); |
||||||
|
jLabel16 = new javax.swing.JLabel(); |
||||||
|
minUnconnectedRegionSizeField = new javax.swing.JTextField(); |
||||||
|
jToolBar1 = new javax.swing.JToolBar(); |
||||||
|
jButton1 = new javax.swing.JButton(); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, "Cell Size"); |
||||||
|
jLabel1.setToolTipText("The width and depth resolution used when sampling the source mesh"); |
||||||
|
|
||||||
|
cellSizeField.setText("1"); |
||||||
|
cellSizeField.addActionListener(new java.awt.event.ActionListener() { |
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) { |
||||||
|
cellSizeFieldActionPerformed(evt); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel2, "Cell Height"); |
||||||
|
jLabel2.setToolTipText("The height resolution used when sampling the source mesh"); |
||||||
|
|
||||||
|
cellHeightField.setText("1.5"); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel3, "Min Traversable Height"); |
||||||
|
jLabel3.setToolTipText("Represents the minimum floor to ceiling height that will still allow the floor area to be considered walkable"); |
||||||
|
|
||||||
|
minTraversableHeightField.setText("7.5"); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel4, "Max Traversable Step"); |
||||||
|
jLabel4.setToolTipText("Represents the maximum ledge height that is considered to still be walkable"); |
||||||
|
|
||||||
|
maxTraversableStepField.setText("1"); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel5, "Max Traversable Slope"); |
||||||
|
jLabel5.setToolTipText("The maximum slope that is considered walkable. (Degrees)"); |
||||||
|
|
||||||
|
maxTraversableSlopeField.setText("48"); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel6, "Clip Ledges"); |
||||||
|
jLabel6.setToolTipText("Indicates whether ledges should be marked as unwalkable"); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel7, "Traversable Area Border Size"); |
||||||
|
jLabel7.setToolTipText("Represents the closest any part of the navmesh can get to an obstruction in the source mesh"); |
||||||
|
|
||||||
|
traversableAreaBorderSizeField.setText("1.2"); |
||||||
|
traversableAreaBorderSizeField.addActionListener(new java.awt.event.ActionListener() { |
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) { |
||||||
|
traversableAreaBorderSizeFieldActionPerformed(evt); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel8, "Smoothing Threshold"); |
||||||
|
jLabel8.setToolTipText("The amount of smoothing to be performed when generating the distance field"); |
||||||
|
|
||||||
|
smoothingThresholdField.setText("2"); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel9, "Use Conservative Expansion"); |
||||||
|
jLabel9.setToolTipText("Applies extra algorithms to regions to help prevent poorly formed regions from forming. Enabling this feature significantly increased processing cost."); |
||||||
|
|
||||||
|
useConservativeExpansionBox.setSelected(true); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel10, "Merge Region Size"); |
||||||
|
jLabel10.setToolTipText("Any regions smaller than this size will, if possible, be merged with larger regions. (Voxels)"); |
||||||
|
|
||||||
|
mergeRegionSizeField.setText("10"); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel11, "Max Edge Length"); |
||||||
|
jLabel11.setToolTipText("The maximum length of polygon edges that represent the border of the navmesh"); |
||||||
|
|
||||||
|
maxEdgeLengthField.setText("0"); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel12, "Edge Max Deviation"); |
||||||
|
jLabel12.setToolTipText("The maximum distance the edge of the navmesh may deviate from the source geometry. Setting this lower will result in the navmesh edges following the geometry contour more accurately at the expense of an increased triangle count."); |
||||||
|
|
||||||
|
edgeMaxDeviationField.setText("2.4"); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel13, "Max Verts Per Poly"); |
||||||
|
jLabel13.setToolTipText("The maximum number of vertices per polygon for polygons generated during the voxel to polygon conversion stage. Higher values reduce performance, but can also result in better formed triangles in the navmesh. A value of around 6 is generally adequate with diminishing returns for values higher than 6."); |
||||||
|
|
||||||
|
maxVertsPerPolyField.setText("6"); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel14, "Contour Sample Distance"); |
||||||
|
jLabel14.setToolTipText("Sets the sampling distance to use when matching the navmesh to the surface of the original geometry. Impacts how well the final mesh conforms to the original geometry's surface contour. Higher values result in a navmesh which conforms more closely to the original geometry's surface at the cost of a higher final triangle count and higher processing cost"); |
||||||
|
|
||||||
|
contourSampleDistanceField.setText("25"); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel15, "Contour Max Deviation"); |
||||||
|
jLabel15.setToolTipText("The maximum distance the surface of the navmesh may deviate from the surface of the original geometry."); |
||||||
|
|
||||||
|
contourMaxDeviationField.setText("25"); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel16, "Min Unconnected Region Size"); |
||||||
|
jLabel16.setToolTipText("The minimum region size for unconnected (island) regions. (Voxels) "); |
||||||
|
|
||||||
|
minUnconnectedRegionSizeField.setText("3"); |
||||||
|
|
||||||
|
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); |
||||||
|
jPanel1.setLayout(jPanel1Layout); |
||||||
|
jPanel1Layout.setHorizontalGroup( |
||||||
|
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
||||||
|
.addGroup(jPanel1Layout.createSequentialGroup() |
||||||
|
.addContainerGap() |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) |
||||||
|
.addComponent(jLabel16) |
||||||
|
.addComponent(jLabel15) |
||||||
|
.addComponent(jLabel14) |
||||||
|
.addComponent(jLabel13) |
||||||
|
.addComponent(jLabel12) |
||||||
|
.addComponent(jLabel11) |
||||||
|
.addComponent(jLabel10) |
||||||
|
.addComponent(jLabel9) |
||||||
|
.addComponent(jLabel8) |
||||||
|
.addComponent(jLabel7) |
||||||
|
.addComponent(jLabel6) |
||||||
|
.addComponent(jLabel5) |
||||||
|
.addComponent(jLabel4) |
||||||
|
.addComponent(jLabel3) |
||||||
|
.addComponent(jLabel2) |
||||||
|
.addComponent(jLabel1)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) |
||||||
|
.addComponent(minUnconnectedRegionSizeField) |
||||||
|
.addComponent(contourMaxDeviationField) |
||||||
|
.addComponent(contourSampleDistanceField) |
||||||
|
.addComponent(maxVertsPerPolyField) |
||||||
|
.addComponent(edgeMaxDeviationField) |
||||||
|
.addComponent(maxEdgeLengthField) |
||||||
|
.addComponent(smoothingThresholdField) |
||||||
|
.addComponent(maxTraversableSlopeField) |
||||||
|
.addComponent(maxTraversableStepField) |
||||||
|
.addComponent(minTraversableHeightField) |
||||||
|
.addComponent(cellSizeField, javax.swing.GroupLayout.DEFAULT_SIZE, 58, Short.MAX_VALUE) |
||||||
|
.addComponent(cellHeightField) |
||||||
|
.addComponent(clipLedgesBox) |
||||||
|
.addComponent(traversableAreaBorderSizeField) |
||||||
|
.addComponent(useConservativeExpansionBox) |
||||||
|
.addComponent(mergeRegionSizeField)) |
||||||
|
.addContainerGap(594, Short.MAX_VALUE)) |
||||||
|
); |
||||||
|
jPanel1Layout.setVerticalGroup( |
||||||
|
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
||||||
|
.addGroup(jPanel1Layout.createSequentialGroup() |
||||||
|
.addGap(31, 31, 31) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(cellSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) |
||||||
|
.addComponent(jLabel1)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel2) |
||||||
|
.addComponent(cellHeightField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel3) |
||||||
|
.addComponent(minTraversableHeightField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel4) |
||||||
|
.addComponent(maxTraversableStepField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel5) |
||||||
|
.addComponent(maxTraversableSlopeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
||||||
|
.addComponent(jLabel6) |
||||||
|
.addComponent(clipLedgesBox)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel7) |
||||||
|
.addComponent(traversableAreaBorderSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel8) |
||||||
|
.addComponent(smoothingThresholdField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
||||||
|
.addComponent(jLabel9) |
||||||
|
.addComponent(useConservativeExpansionBox)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel10) |
||||||
|
.addComponent(mergeRegionSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel11) |
||||||
|
.addComponent(maxEdgeLengthField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel12) |
||||||
|
.addComponent(edgeMaxDeviationField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel13) |
||||||
|
.addComponent(maxVertsPerPolyField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel14) |
||||||
|
.addComponent(contourSampleDistanceField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel15) |
||||||
|
.addComponent(contourMaxDeviationField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
||||||
|
.addComponent(jLabel16) |
||||||
|
.addComponent(minUnconnectedRegionSizeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
.addContainerGap(57, Short.MAX_VALUE)) |
||||||
|
); |
||||||
|
|
||||||
|
jScrollPane1.setViewportView(jPanel1); |
||||||
|
|
||||||
|
jToolBar1.setRollover(true); |
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jButton1, "Generate"); |
||||||
|
jButton1.setFocusable(false); |
||||||
|
jButton1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); |
||||||
|
jButton1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); |
||||||
|
jButton1.addActionListener(new java.awt.event.ActionListener() { |
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) { |
||||||
|
jButton1ActionPerformed(evt); |
||||||
|
} |
||||||
|
}); |
||||||
|
jToolBar1.add(jButton1); |
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); |
||||||
|
this.setLayout(layout); |
||||||
|
layout.setHorizontalGroup( |
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
||||||
|
.addComponent(jToolBar1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 664, Short.MAX_VALUE) |
||||||
|
.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 664, Short.MAX_VALUE) |
||||||
|
); |
||||||
|
layout.setVerticalGroup( |
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
||||||
|
.addGroup(layout.createSequentialGroup() |
||||||
|
.addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 194, javax.swing.GroupLayout.PREFERRED_SIZE)) |
||||||
|
); |
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
|
||||||
|
generateNavMesh(); |
||||||
|
}//GEN-LAST:event_jButton1ActionPerformed
|
||||||
|
|
||||||
|
private void cellSizeFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cellSizeFieldActionPerformed
|
||||||
|
// TODO add your handling code here:
|
||||||
|
}//GEN-LAST:event_cellSizeFieldActionPerformed
|
||||||
|
|
||||||
|
private void traversableAreaBorderSizeFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_traversableAreaBorderSizeFieldActionPerformed
|
||||||
|
// TODO add your handling code here:
|
||||||
|
}//GEN-LAST:event_traversableAreaBorderSizeFieldActionPerformed
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JTextField cellHeightField; |
||||||
|
private javax.swing.JTextField cellSizeField; |
||||||
|
private javax.swing.JCheckBox clipLedgesBox; |
||||||
|
private javax.swing.JTextField contourMaxDeviationField; |
||||||
|
private javax.swing.JTextField contourSampleDistanceField; |
||||||
|
private javax.swing.JTextField edgeMaxDeviationField; |
||||||
|
private javax.swing.JButton jButton1; |
||||||
|
private javax.swing.JLabel jLabel1; |
||||||
|
private javax.swing.JLabel jLabel10; |
||||||
|
private javax.swing.JLabel jLabel11; |
||||||
|
private javax.swing.JLabel jLabel12; |
||||||
|
private javax.swing.JLabel jLabel13; |
||||||
|
private javax.swing.JLabel jLabel14; |
||||||
|
private javax.swing.JLabel jLabel15; |
||||||
|
private javax.swing.JLabel jLabel16; |
||||||
|
private javax.swing.JLabel jLabel2; |
||||||
|
private javax.swing.JLabel jLabel3; |
||||||
|
private javax.swing.JLabel jLabel4; |
||||||
|
private javax.swing.JLabel jLabel5; |
||||||
|
private javax.swing.JLabel jLabel6; |
||||||
|
private javax.swing.JLabel jLabel7; |
||||||
|
private javax.swing.JLabel jLabel8; |
||||||
|
private javax.swing.JLabel jLabel9; |
||||||
|
private javax.swing.JPanel jPanel1; |
||||||
|
private javax.swing.JScrollPane jScrollPane1; |
||||||
|
private javax.swing.JToolBar jToolBar1; |
||||||
|
private javax.swing.JTextField maxEdgeLengthField; |
||||||
|
private javax.swing.JTextField maxTraversableSlopeField; |
||||||
|
private javax.swing.JTextField maxTraversableStepField; |
||||||
|
private javax.swing.JTextField maxVertsPerPolyField; |
||||||
|
private javax.swing.JTextField mergeRegionSizeField; |
||||||
|
private javax.swing.JTextField minTraversableHeightField; |
||||||
|
private javax.swing.JTextField minUnconnectedRegionSizeField; |
||||||
|
private javax.swing.JTextField smoothingThresholdField; |
||||||
|
private javax.swing.JTextField traversableAreaBorderSizeField; |
||||||
|
private javax.swing.JCheckBox useConservativeExpansionBox; |
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void componentOpened() { |
||||||
|
super.componentOpened(); |
||||||
|
if (currentRequest == null) { |
||||||
|
close(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void componentClosed() { |
||||||
|
super.componentClosed(); |
||||||
|
if (currentRequest != null) { |
||||||
|
SceneApplication.getApplication().closeScene(currentRequest); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void writeProperties(java.util.Properties p) { |
||||||
|
// better to version settings since initial version as advocated at
|
||||||
|
// http://wiki.apidesign.org/wiki/PropertyFiles
|
||||||
|
p.setProperty("version", "1.0"); |
||||||
|
// TODO store your settings
|
||||||
|
} |
||||||
|
void readProperties(java.util.Properties p) { |
||||||
|
String version = p.getProperty("version"); |
||||||
|
// TODO read your settings according to their version
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Obtain the TerrainEditorTopComponent instance. Never call {@link #getDefault} directly! |
||||||
|
*/ |
||||||
|
public static synchronized NavMeshTopComponent findInstance() { |
||||||
|
TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID); |
||||||
|
if (win == null) { |
||||||
|
Logger.getLogger(NavMeshTopComponent.class.getName()).warning( |
||||||
|
"Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system."); |
||||||
|
return getDefault(); |
||||||
|
} |
||||||
|
if (win instanceof NavMeshTopComponent) { |
||||||
|
return (NavMeshTopComponent) win; |
||||||
|
} |
||||||
|
Logger.getLogger(NavMeshTopComponent.class.getName()).warning( |
||||||
|
"There seem to be multiple components with the '" + PREFERRED_ID |
||||||
|
+ "' ID. That is a potential source of errors and unexpected behavior."); |
||||||
|
return getDefault(); |
||||||
|
} |
||||||
|
|
||||||
|
// run on swing thread
|
||||||
|
public void openScene(Spatial spat, AssetDataObject file, ProjectAssetManager manager) { |
||||||
|
cleanupControllers(); |
||||||
|
SceneApplication.getApplication().addSceneListener(this); |
||||||
|
result.addLookupListener(this); |
||||||
|
//TODO: handle request change
|
||||||
|
Node node; |
||||||
|
if (spat instanceof Node) { |
||||||
|
node = (Node) spat; |
||||||
|
} else { |
||||||
|
node = new Node(); |
||||||
|
node.attachChild(spat); |
||||||
|
} |
||||||
|
JmeNode jmeNode = NodeUtility.createNode(node, file, false); |
||||||
|
SceneRequest request = new SceneRequest(this, jmeNode, manager); |
||||||
|
request.setDataObject(file); |
||||||
|
|
||||||
|
addSaveNode(jmeNode); |
||||||
|
|
||||||
|
Logger.getLogger(NavMeshTopComponent.class.getName()).finer("NavMesh openScene " + file.getName()); |
||||||
|
|
||||||
|
if (editorController != null) { |
||||||
|
editorController.cleanup(); |
||||||
|
} |
||||||
|
editorController = new NavMeshController(jmeNode, file, this); |
||||||
|
this.currentRequest = request; |
||||||
|
request.setWindowTitle("NavMesh - " + manager.getRelativeAssetPath(file.getPrimaryFile().getPath())); |
||||||
|
request.setToolNode(new Node("NavMeshEditorToolNode")); |
||||||
|
SceneApplication.getApplication().openScene(request); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void previewCreated(PreviewRequest request) { |
||||||
|
} |
||||||
|
|
||||||
|
// run on GL thread
|
||||||
|
/*@Override |
||||||
|
public void sceneRequested(SceneRequest request) { |
||||||
|
if (request.equals(currentRequest)) { |
||||||
|
Logger.getLogger(NavMeshTopComponent.class.getName()).finer("Terrain sceneRequested " + request.getWindowTitle()); |
||||||
|
|
||||||
|
setSceneInfo(currentRequest.getJmeNode(), true); |
||||||
|
|
||||||
|
if (cameraController != null) { |
||||||
|
cameraController.disable(); |
||||||
|
} |
||||||
|
if (toolController != null) { |
||||||
|
toolController.cleanup(); |
||||||
|
} |
||||||
|
|
||||||
|
//for (int i=0; i<textureTable.getModel().getRowCount(); i++)
|
||||||
|
// ((TextureTableModel)textureTable.getModel()).removeRow(i);
|
||||||
|
|
||||||
|
toolController = new NavMeshToolController(currentRequest.getToolNode(), currentRequest.getManager().getManager(), request.getJmeNode()); |
||||||
|
|
||||||
|
cameraController = new NavMeshCameraController(SceneApplication.getApplication().getCamera()); |
||||||
|
cameraController.setMaster(this); |
||||||
|
cameraController.enable(); |
||||||
|
cameraController.setToolController(toolController); |
||||||
|
cameraController.setEditorController(editorController); |
||||||
|
|
||||||
|
toolController.setEditorController(editorController); |
||||||
|
toolController.setCameraController(cameraController); |
||||||
|
|
||||||
|
initUIFields(); |
||||||
|
Mesh debugMesh = editorController.createDebugMesh(); |
||||||
|
toolController.attachNavMesh(debugMesh); |
||||||
|
} |
||||||
|
}*/ |
||||||
|
|
||||||
|
@Override |
||||||
|
public void sceneClosed(SceneRequest request) { |
||||||
|
if (request.equals(currentRequest)) { |
||||||
|
SceneApplication.getApplication().removeSceneListener(this); |
||||||
|
setSceneInfo(null, false); |
||||||
|
currentRequest = null; |
||||||
|
cleanupControllers(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void resultChanged(LookupEvent ev) { |
||||||
|
if (currentRequest == null || !currentRequest.isDisplayed()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
Collection<JmeSpatial> items = (Collection<JmeSpatial>) result.allInstances(); |
||||||
|
for (JmeSpatial spatial : items) { |
||||||
|
selectSpatial(spatial); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void setSceneInfo(final JmeNode jmeNode, final boolean active) { |
||||||
|
final NavMeshTopComponent inst = this; |
||||||
|
java.awt.EventQueue.invokeLater(new Runnable() { |
||||||
|
|
||||||
|
public void run() { |
||||||
|
if (jmeNode != null) { |
||||||
|
} else { |
||||||
|
} |
||||||
|
|
||||||
|
if (!active) { |
||||||
|
result.removeLookupListener(inst); |
||||||
|
close(); |
||||||
|
} else { |
||||||
|
open(); |
||||||
|
requestActive(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
protected void addSaveNode(org.openide.nodes.Node node) { |
||||||
|
setActivatedNodes(new org.openide.nodes.Node[]{node}); |
||||||
|
} |
||||||
|
|
||||||
|
private void cleanupControllers() { |
||||||
|
if (cameraController != null) { |
||||||
|
cameraController.disable(); |
||||||
|
cameraController = null; |
||||||
|
} |
||||||
|
if (toolController != null) { |
||||||
|
toolController.cleanup(); |
||||||
|
toolController = null; |
||||||
|
} |
||||||
|
if (editorController != null) { |
||||||
|
editorController.cleanup(); |
||||||
|
editorController = null; |
||||||
|
} |
||||||
|
setActivatedNodes(new org.openide.nodes.Node[]{}); |
||||||
|
} |
||||||
|
|
||||||
|
private void selectSpatial(JmeSpatial spatial) { |
||||||
|
selectedSpat = spatial; |
||||||
|
} |
||||||
|
|
||||||
|
private void generateNavMesh() { |
||||||
|
float cellHeight = Float.parseFloat(cellHeightField.getText()); |
||||||
|
float cellSize = Float.parseFloat(cellSizeField.getText()); |
||||||
|
boolean clipLedges = clipLedgesBox.isSelected(); |
||||||
|
float contourMaxDeviation = Float.parseFloat(contourMaxDeviationField.getText()); |
||||||
|
float contourSampleDistance = Float.parseFloat(contourSampleDistanceField.getText()); |
||||||
|
float edgeMaxDeviation = Float.parseFloat(edgeMaxDeviationField.getText()); |
||||||
|
float maxEdgeLength = Float.parseFloat(maxEdgeLengthField.getText()); |
||||||
|
float maxTraversableSlope = Float.parseFloat(maxTraversableSlopeField.getText()); |
||||||
|
float maxTraversableStep = Float.parseFloat(maxTraversableStepField.getText()); |
||||||
|
float maxVertsPerPoly = Float.parseFloat(maxVertsPerPolyField.getText()); |
||||||
|
float mergeRegionSize = Float.parseFloat(mergeRegionSizeField.getText()); |
||||||
|
float minTraversableHeight = Float.parseFloat(minTraversableHeightField.getText()); |
||||||
|
float smoothingThreshold = Float.parseFloat(smoothingThresholdField.getText()); |
||||||
|
float traversableAreaBorderSize = Float.parseFloat(traversableAreaBorderSizeField.getText()); |
||||||
|
boolean useConservativeExpansion = useConservativeExpansionBox.isSelected(); |
||||||
|
float minUnconnectedRegionSize = Float.parseFloat(minUnconnectedRegionSizeField.getText()); |
||||||
|
|
||||||
|
Mesh debugMesh = editorController.generateNavMesh(cellSize, cellHeight, minTraversableHeight, |
||||||
|
maxTraversableStep, maxTraversableSlope, |
||||||
|
clipLedges, traversableAreaBorderSize, |
||||||
|
smoothingThreshold, useConservativeExpansion, |
||||||
|
minUnconnectedRegionSize, mergeRegionSize, |
||||||
|
maxEdgeLength, edgeMaxDeviation, maxVertsPerPoly, |
||||||
|
contourSampleDistance, contourMaxDeviation); |
||||||
|
|
||||||
|
toolController.attachNavMesh(debugMesh); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void initUIFields() { |
||||||
|
NavMeshGenerator generator = editorController.getNavMeshGenerator(); |
||||||
|
if (generator != null) { |
||||||
|
cellSizeField.setText(""+generator.getCellSize()); |
||||||
|
cellHeightField.setText(""+generator.getCellHeight()); |
||||||
|
minTraversableHeightField.setText(""+generator.getMinTraversableHeight()); |
||||||
|
maxTraversableStepField.setText(""+generator.getMaxTraversableStep()); |
||||||
|
maxTraversableSlopeField.setText(""+generator.getMaxTraversableSlope()); |
||||||
|
clipLedgesBox.setSelected(generator.isClipLedges()); |
||||||
|
traversableAreaBorderSizeField.setText(""+generator.getTraversableAreaBorderSize()); |
||||||
|
smoothingThresholdField.setText(""+generator.getSmoothingThreshold()); |
||||||
|
useConservativeExpansionBox.setSelected(generator.isUseConservativeExpansion()); |
||||||
|
minUnconnectedRegionSizeField.setText(""+generator.getMinUnconnectedRegionSize()); |
||||||
|
mergeRegionSizeField.setText(""+generator.getMergeRegionSize()); |
||||||
|
maxEdgeLengthField.setText(""+generator.getMaxEdgeLength()); |
||||||
|
edgeMaxDeviationField.setText(""+generator.getEdgeMaxDeviation()); |
||||||
|
maxVertsPerPolyField.setText(""+generator.getMaxVertsPerPoly()); |
||||||
|
contourSampleDistanceField.setText(""+generator.getContourSampleDistance()); |
||||||
|
contourMaxDeviationField.setText(""+generator.getContourMaxDeviation()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void sceneOpened(SceneRequest request) { |
||||||
|
if (request.equals(currentRequest)) { |
||||||
|
Logger.getLogger(NavMeshTopComponent.class.getName()).finer("Terrain sceneRequested " + request.getWindowTitle()); |
||||||
|
|
||||||
|
setSceneInfo(currentRequest.getJmeNode(), true); |
||||||
|
|
||||||
|
if (cameraController != null) { |
||||||
|
cameraController.disable(); |
||||||
|
} |
||||||
|
if (toolController != null) { |
||||||
|
toolController.cleanup(); |
||||||
|
} |
||||||
|
|
||||||
|
//for (int i=0; i<textureTable.getModel().getRowCount(); i++)
|
||||||
|
// ((TextureTableModel)textureTable.getModel()).removeRow(i);
|
||||||
|
|
||||||
|
toolController = new NavMeshToolController(currentRequest.getToolNode(), currentRequest.getManager().getManager(), request.getJmeNode()); |
||||||
|
|
||||||
|
cameraController = new NavMeshCameraController(SceneApplication.getApplication().getCamera()); |
||||||
|
cameraController.setMaster(this); |
||||||
|
cameraController.enable(); |
||||||
|
cameraController.setToolController(toolController); |
||||||
|
cameraController.setEditorController(editorController); |
||||||
|
|
||||||
|
toolController.setEditorController(editorController); |
||||||
|
toolController.setCameraController(cameraController); |
||||||
|
|
||||||
|
initUIFields(); |
||||||
|
//Mesh debugMesh = editorController.createDebugMesh();
|
||||||
|
//toolController.attachNavMesh(debugMesh);
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
To change this template, choose Tools | Templates |
||||||
|
and open the template in the editor. |
||||||
|
--> |
||||||
|
<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd"> |
||||||
|
<settings version="1.0"> |
||||||
|
<module name="com.sploreg.tritium.editor.navmesh" spec="0.1"/> |
||||||
|
<instanceof class="org.openide.windows.TopComponent"/> |
||||||
|
<instanceof class="com.sploreg.tritium.editor.navmesh.NavMeshTopComponent"/> |
||||||
|
<instance class="com.sploreg.tritium.editor.navmesh.NavMeshTopComponent" method="getDefault"/> |
||||||
|
</settings> |
@ -0,0 +1,11 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!-- |
||||||
|
To change this template, choose Tools | Templates |
||||||
|
and open the template in the editor. |
||||||
|
--> |
||||||
|
<!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN" "http://www.netbeans.org/dtds/tc-ref2_0.dtd"> |
||||||
|
<tc-ref version="2.0" > |
||||||
|
<module name="com.sploreg.tritium.editor.navmesh.navmesh" spec="0.1"/> |
||||||
|
<tc-id id="NavMeshTopComponent"/> |
||||||
|
<state opened="false"/> |
||||||
|
</tc-ref> |
@ -0,0 +1,45 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd"> |
||||||
|
<filesystem> |
||||||
|
<folder name="Actions"> |
||||||
|
<folder name="NavMesh"> |
||||||
|
<file name="com-jme3-gde-nmgen-NavMeshAction.instance"> |
||||||
|
<attr name="delegate" methodvalue="org.openide.awt.Actions.inject"/> |
||||||
|
<attr name="displayName" bundlevalue="com.jme3.gde.nmgen.Bundle#CTL_EditTerrainAction"/> |
||||||
|
<attr name="iconBase" stringvalue="com/jme3/gde/nmgen/logo.png"/> |
||||||
|
<attr name="injectable" stringvalue="com.jme3.gde.nmgen.NavMeshAction"/> |
||||||
|
<attr name="instanceCreate" methodvalue="org.openide.awt.Actions.context"/> |
||||||
|
<attr name="noIconInMenu" boolvalue="false"/> |
||||||
|
<attr name="selectionType" stringvalue="EXACTLY_ONE"/> |
||||||
|
<attr name="type" stringvalue="com.jme3.gde.core.assets.BinaryModelDataObject"/> |
||||||
|
</file> |
||||||
|
</folder> |
||||||
|
<folder name="Window"> |
||||||
|
<file name="com-jme3-gde-nmgen-NavMeshAction.instance"> |
||||||
|
<attr name="component" methodvalue="com.jme3.gde.nmgen.NavMeshTopComponent.findInstance"/> |
||||||
|
<attr name="displayName" bundlevalue="com.jme3.gde.nmgen.Bundle#CTL_TerrainEditorAction"/> |
||||||
|
<attr name="iconBase" stringvalue="com/jme3/gde/nmgen/logo.png"/> |
||||||
|
<attr name="instanceCreate" methodvalue="org.openide.windows.TopComponent.openAction"/> |
||||||
|
</file> |
||||||
|
</folder> |
||||||
|
</folder> |
||||||
|
<folder name="Toolbars"> |
||||||
|
<folder name="jMonkeyPlatform-Tools"> |
||||||
|
<file name="com-jme3-gde-nmgen-NavMeshAction.shadow"> |
||||||
|
<attr name="originalFile" stringvalue="Actions/NavMesh/com-jme3-gde-nmgen-NavMeshAction.instance"/> |
||||||
|
<attr name="position" intvalue="210"/> |
||||||
|
</file> |
||||||
|
</folder> |
||||||
|
</folder> |
||||||
|
<folder name="Windows2"> |
||||||
|
<folder name="Components"> |
||||||
|
<file name="NavMeshTopComponent.settings" url="NavMeshTopComponentSettings.xml"/> |
||||||
|
</folder> |
||||||
|
<folder name="Modes"> |
||||||
|
<folder name="output"> |
||||||
|
<file name="NavMeshTopComponent.wstcref" url="NavMeshTopComponentWstcref.xml"/> |
||||||
|
</folder> |
||||||
|
</folder> |
||||||
|
</folder> |
||||||
|
|
||||||
|
</filesystem> |
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
Loading…
Reference in new issue