- add wizard in SceneExplorer for creating NavMesh git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8987 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
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…
Reference in new issue