Selaa lähdekoodia

SDK:
- add wizard in SceneExplorer for creating NavMesh

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8987 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

nor..67 13 vuotta sitten
vanhempi
commit
89694c115e

+ 54 - 0
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;
+    }
+}

+ 34 - 0
jme3-navmesh-gen/src/com/jme3/gde/nmgen/wizard/NewNavMeshVisualPanel1.form

@@ -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>

+ 64 - 0
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.
+     */
+    // <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
+}

+ 136 - 0
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;
+
[email protected](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;
+    }
+}

+ 88 - 0
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<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);
+    }
+}