diff --git a/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NavMeshGeneratorNode.java b/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NavMeshGeneratorNode.java new file mode 100644 index 000000000..fbf26df38 --- /dev/null +++ b/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NavMeshGeneratorNode.java @@ -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; + } +} diff --git a/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshVisualPanel1.form b/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshVisualPanel1.form new file mode 100644 index 000000000..a48d18901 --- /dev/null +++ b/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshVisualPanel1.form @@ -0,0 +1,34 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshVisualPanel1.java b/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshVisualPanel1.java new file mode 100644 index 000000000..297d314ff --- /dev/null +++ b/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshVisualPanel1.java @@ -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. + */ + // //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) + ); + }// //GEN-END:initComponents + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel jPanel1; + // End of variables declaration//GEN-END:variables +} diff --git a/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshWizardAction.java b/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshWizardAction.java new file mode 100644 index 000000000..7e565a03f --- /dev/null +++ b/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshWizardAction.java @@ -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(), 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 findGeometries(Node node, List geoms, NavMeshGenerator generator) { + for (Iterator 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; + } +} diff --git a/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshWizardPanel1.java b/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshWizardPanel1.java new file mode 100644 index 000000000..2d7d58879 --- /dev/null +++ b/sdk/jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshWizardPanel1.java @@ -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 listeners = new HashSet(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 it; + synchronized (listeners) { + it = new HashSet(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); + } +}