SDK:
- add wizard in SceneExplorer for creating NavMesh git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8987 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
a1e36ebd98
commit
58c2287352
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.jme3.gde.nmgen.wizard;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetKey;
|
||||||
|
import com.jme3.gde.core.util.PropertyUtils;
|
||||||
|
import com.jme3.gde.nmgen.NavMeshGenerator;
|
||||||
|
import java.beans.PropertyDescriptor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import org.openide.nodes.AbstractNode;
|
||||||
|
import org.openide.nodes.Children;
|
||||||
|
import org.openide.nodes.Node.Property;
|
||||||
|
import org.openide.nodes.PropertySupport;
|
||||||
|
import org.openide.nodes.Sheet;
|
||||||
|
import org.openide.util.Exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author normenhansen
|
||||||
|
*/
|
||||||
|
public class NavMeshGeneratorNode extends AbstractNode {
|
||||||
|
|
||||||
|
private NavMeshGenerator key;
|
||||||
|
|
||||||
|
public NavMeshGeneratorNode(NavMeshGenerator key) {
|
||||||
|
super(Children.LEAF);
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Sheet createSheet() {
|
||||||
|
Sheet sheet = super.createSheet();
|
||||||
|
Sheet.Set set = sheet.createPropertiesSet();
|
||||||
|
set.setName("NavMeshGenerator");
|
||||||
|
set.setDisplayName("Settings");
|
||||||
|
for (Field field : key.getClass().getDeclaredFields()) {
|
||||||
|
PropertyDescriptor prop = PropertyUtils.getPropertyDescriptor(key.getClass(), field);
|
||||||
|
if (prop != null) {
|
||||||
|
try {
|
||||||
|
Property sup = new PropertySupport.Reflection(key, prop.getPropertyType(), prop.getReadMethod(), prop.getWriteMethod());
|
||||||
|
sup.setName(prop.getName());
|
||||||
|
sup.setDisplayName(prop.getDisplayName());
|
||||||
|
set.put(sup);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Exceptions.printStackTrace(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sheet.put(set);
|
||||||
|
return sheet;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.3" 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="jPanel1" alignment="0" pref="400" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="jPanel1" alignment="0" pref="300" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.jme3.gde.nmgen.wizard;
|
||||||
|
|
||||||
|
import com.jme3.gde.nmgen.NavMeshGenerator;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import org.openide.WizardDescriptor;
|
||||||
|
import org.openide.explorer.propertysheet.PropertySheet;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
|
|
||||||
|
public final class NewNavMeshVisualPanel1 extends JPanel {
|
||||||
|
|
||||||
|
private PropertySheet ps;
|
||||||
|
|
||||||
|
/** Creates new form NewNavMeshVisualPanel1 */
|
||||||
|
public NewNavMeshVisualPanel1() {
|
||||||
|
initComponents();
|
||||||
|
ps = new PropertySheet();
|
||||||
|
ps.setNodes(new Node[]{});
|
||||||
|
jPanel1.add(ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Step #1";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadSettings(WizardDescriptor wiz){
|
||||||
|
NavMeshGenerator gen = (NavMeshGenerator)wiz.getProperty("generator");
|
||||||
|
ps.setNodes(new Node[]{new NavMeshGeneratorNode(gen)});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveSettings(WizardDescriptor wiz){
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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() {
|
||||||
|
|
||||||
|
jPanel1 = new javax.swing.JPanel();
|
||||||
|
|
||||||
|
jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.LINE_AXIS));
|
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
|
this.setLayout(layout);
|
||||||
|
layout.setHorizontalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JPanel jPanel1;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.jme3.gde.nmgen.wizard;
|
||||||
|
|
||||||
|
import com.jme3.bounding.BoundingBox;
|
||||||
|
import com.jme3.gde.core.sceneexplorer.nodes.actions.AbstractNewSpatialWizardAction;
|
||||||
|
import com.jme3.gde.core.sceneexplorer.nodes.actions.NewSpatialAction;
|
||||||
|
import com.jme3.gde.nmgen.NavMeshGenerator;
|
||||||
|
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.awt.Component;
|
||||||
|
import java.awt.Dialog;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import jme3tools.optimize.GeometryBatchFactory;
|
||||||
|
import org.critterai.nmgen.IntermediateData;
|
||||||
|
import org.openide.DialogDisplayer;
|
||||||
|
import org.openide.WizardDescriptor;
|
||||||
|
|
||||||
|
@org.openide.util.lookup.ServiceProvider(service = NewSpatialAction.class)
|
||||||
|
public final class NewNavMeshWizardAction extends AbstractNewSpatialWizardAction {
|
||||||
|
|
||||||
|
private WizardDescriptor.Panel[] panels;
|
||||||
|
|
||||||
|
public NewNavMeshWizardAction() {
|
||||||
|
name = "NavMesh..";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Object showWizard(org.openide.nodes.Node node) {
|
||||||
|
WizardDescriptor wizardDescriptor = new WizardDescriptor(getPanels());
|
||||||
|
// {0} will be replaced by WizardDesriptor.Panel.getComponent().getName()
|
||||||
|
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
|
||||||
|
wizardDescriptor.setTitle("Your wizard dialog title here");
|
||||||
|
NavMeshGenerator gen = new NavMeshGenerator();
|
||||||
|
wizardDescriptor.putProperty("generator", gen);
|
||||||
|
|
||||||
|
Dialog dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
|
||||||
|
dialog.setVisible(true);
|
||||||
|
dialog.toFront();
|
||||||
|
boolean cancelled = wizardDescriptor.getValue() != WizardDescriptor.FINISH_OPTION;
|
||||||
|
if (!cancelled) {
|
||||||
|
return wizardDescriptor;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Spatial doCreateSpatial(com.jme3.scene.Node rootNode, Object configuration) {
|
||||||
|
if (configuration == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//TODO: maybe offload to other thread..
|
||||||
|
WizardDescriptor wizardDescriptor = (WizardDescriptor) configuration;
|
||||||
|
|
||||||
|
NavMeshGenerator generator = (NavMeshGenerator) wizardDescriptor.getProperty("generator");
|
||||||
|
IntermediateData id = new IntermediateData();
|
||||||
|
|
||||||
|
generator.setIntermediateData(null);
|
||||||
|
|
||||||
|
Mesh mesh = new Mesh();
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
return navMesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize panels representing individual wizard's steps and sets
|
||||||
|
* various properties for them influencing wizard appearance.
|
||||||
|
*/
|
||||||
|
private WizardDescriptor.Panel[] getPanels() {
|
||||||
|
if (panels == null) {
|
||||||
|
panels = new WizardDescriptor.Panel[]{
|
||||||
|
new NewNavMeshWizardPanel1()
|
||||||
|
};
|
||||||
|
String[] steps = new String[panels.length];
|
||||||
|
for (int i = 0; i < panels.length; i++) {
|
||||||
|
Component c = panels[i].getComponent();
|
||||||
|
// Default step name to component name of panel. Mainly useful
|
||||||
|
// for getting the name of the target chooser to appear in the
|
||||||
|
// list of steps.
|
||||||
|
steps[i] = c.getName();
|
||||||
|
if (c instanceof JComponent) { // assume Swing components
|
||||||
|
JComponent jc = (JComponent) c;
|
||||||
|
// Sets step number of a component
|
||||||
|
// TODO if using org.openide.dialogs >= 7.8, can use WizardDescriptor.PROP_*:
|
||||||
|
jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i));
|
||||||
|
// Sets steps names for a panel
|
||||||
|
jc.putClientProperty("WizardPanel_contentData", steps);
|
||||||
|
// Turn on subtitle creation on each step
|
||||||
|
jc.putClientProperty("WizardPanel_autoWizardStyle", Boolean.TRUE);
|
||||||
|
// Show steps on the left side with the image on the background
|
||||||
|
jc.putClientProperty("WizardPanel_contentDisplayed", Boolean.TRUE);
|
||||||
|
// Turn on numbering of all steps
|
||||||
|
jc.putClientProperty("WizardPanel_contentNumbered", Boolean.TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return panels;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.jme3.gde.nmgen.wizard;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import javax.swing.event.ChangeListener;
|
||||||
|
import org.openide.WizardDescriptor;
|
||||||
|
import org.openide.util.HelpCtx;
|
||||||
|
|
||||||
|
public class NewNavMeshWizardPanel1 implements WizardDescriptor.Panel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The visual component that displays this panel. If you need to access the
|
||||||
|
* component from this class, just use getComponent().
|
||||||
|
*/
|
||||||
|
private NewNavMeshVisualPanel1 component;
|
||||||
|
|
||||||
|
// Get the visual component for the panel. In this template, the component
|
||||||
|
// is kept separate. This can be more efficient: if the wizard is created
|
||||||
|
// but never displayed, or not all panels are displayed, it is better to
|
||||||
|
// create only those which really need to be visible.
|
||||||
|
public Component getComponent() {
|
||||||
|
if (component == null) {
|
||||||
|
component = new NewNavMeshVisualPanel1();
|
||||||
|
}
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HelpCtx getHelp() {
|
||||||
|
// Show no Help button for this panel:
|
||||||
|
return HelpCtx.DEFAULT_HELP;
|
||||||
|
// If you have context help:
|
||||||
|
// return new HelpCtx(SampleWizardPanel1.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
// If it is always OK to press Next or Finish, then:
|
||||||
|
return true;
|
||||||
|
// If it depends on some condition (form filled out...), then:
|
||||||
|
// return someCondition();
|
||||||
|
// and when this condition changes (last form field filled in...) then:
|
||||||
|
// fireChangeEvent();
|
||||||
|
// and uncomment the complicated stuff below.
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void addChangeListener(ChangeListener l) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void removeChangeListener(ChangeListener l) {
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1); // or can use ChangeSupport in NB 6.0
|
||||||
|
public final void addChangeListener(ChangeListener l) {
|
||||||
|
synchronized (listeners) {
|
||||||
|
listeners.add(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public final void removeChangeListener(ChangeListener l) {
|
||||||
|
synchronized (listeners) {
|
||||||
|
listeners.remove(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected final void fireChangeEvent() {
|
||||||
|
Iterator<ChangeListener> it;
|
||||||
|
synchronized (listeners) {
|
||||||
|
it = new HashSet<ChangeListener>(listeners).iterator();
|
||||||
|
}
|
||||||
|
ChangeEvent ev = new ChangeEvent(this);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next().stateChanged(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// You can use a settings object to keep track of state. Normally the
|
||||||
|
// settings object will be the WizardDescriptor, so you can use
|
||||||
|
// WizardDescriptor.getProperty & putProperty to store information entered
|
||||||
|
// by the user.
|
||||||
|
public void readSettings(Object settings) {
|
||||||
|
component.loadSettings((WizardDescriptor)settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void storeSettings(Object settings) {
|
||||||
|
component.saveSettings((WizardDescriptor)settings);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user