ソースを参照

New Animation System: Support for Joints, Skinning Control and Attachment Nodes

MeFisto94 5 年 前
コミット
7c4cd3ba13

+ 139 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/animation/JmeJoint.java

@@ -0,0 +1,139 @@
+/*
+ *  Copyright (c) 2009-2020 jMonkeyEngine
+ *  All rights reserved.
+ * 
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ * 
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ *  * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.gde.core.sceneexplorer.nodes.animation;
+
+import com.jme3.anim.Joint;
+import com.jme3.gde.core.icons.IconList;
+import com.jme3.gde.core.scene.SceneApplication;
+import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
+import com.jme3.gde.core.sceneexplorer.nodes.ClipboardSpatial;
+import com.jme3.gde.core.sceneexplorer.nodes.SceneExplorerNode;
+import java.awt.Image;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.concurrent.ExecutionException;
+import javax.swing.Action;
+import org.openide.awt.Actions;
+import org.openide.loaders.DataObject;
+import org.openide.nodes.Sheet;
+import org.openide.util.Exceptions;
+
+/**
+ * Visual representation of the Joint Class in the Scene Explorer
+ * @author MeFisto94
+ */
[email protected](service = SceneExplorerNode.class)
+@SuppressWarnings({"unchecked", "rawtypes"})
+public class JmeJoint extends AbstractSceneExplorerNode {
+    private static Image smallImage = IconList.bone.getImage();
+    private Joint joint;
+    private JmeSkinningControl jmeSkinningControl;
+    protected final DataFlavor BONE_FLAVOR = new DataFlavor(ClipboardSpatial.class, "Joint");
+
+    public JmeJoint() {
+    }
+
+    public JmeJoint(JmeSkinningControl jmeSkinningControl, Joint joint, JmeJointChildren children) {
+        super(children);
+        this.jmeSkinningControl = jmeSkinningControl;
+        getLookupContents().add(joint);
+        getLookupContents().add(this);
+        super.setName(joint.getName());
+        this.joint = joint;
+    }
+
+    @Override
+    public Image getIcon(int type) {
+        return smallImage;
+    }
+
+    @Override
+    public Image getOpenedIcon(int type) {
+        return smallImage;
+    }
+
+    @Override
+    protected Sheet createSheet() {
+        Sheet sheet = super.createSheet();
+        Sheet.Set set = Sheet.createPropertiesSet();
+        set.setDisplayName("Joint");
+        set.setName(Joint.class.getName());
+        
+        if (joint != null) {
+            sheet.put(set);
+        } // Otherwise: Empty Set
+        
+        return sheet;
+    }
+
+    @Override
+    public Action[] getActions(boolean context) {
+        return new Action[]{
+            Actions.alwaysEnabled(new AttachementNodeActionListener(), "Get attachement Node", "", false)
+        };
+    }
+
+    private class AttachementNodeActionListener implements ActionListener {
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            fireSave(true);
+            try {
+                SceneApplication.getApplication().enqueue(() -> 
+                    jmeSkinningControl.getSkinningControl().getAttachmentsNode(joint.getName())
+                ).get();
+                
+                ((AbstractSceneExplorerNode)jmeSkinningControl.getParentNode()).refresh(false);
+            } catch (InterruptedException | ExecutionException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+        }
+    }
+
+    @Override
+    public Class getExplorerObjectClass() {
+        return Joint.class;
+    }
+
+    @Override
+    public Class getExplorerNodeClass() {
+        return JmeJoint.class;
+    }
+
+    @Override
+    public org.openide.nodes.Node[] createNodes(Object key, DataObject key2, boolean cookie) {
+        JmeJointChildren children = new JmeJointChildren(jmeSkinningControl, (Joint)key);
+        children.setReadOnly(cookie);
+        children.setDataObject(key2);
+        return new org.openide.nodes.Node[]{new JmeJoint(jmeSkinningControl, (Joint)key, children).setReadOnly(cookie)};
+    }
+}

+ 121 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/animation/JmeJointChildren.java

@@ -0,0 +1,121 @@
+/*
+ *  Copyright (c) 2009-2020 jMonkeyEngine
+ *  All rights reserved.
+ * 
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ * 
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ *  * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.gde.core.sceneexplorer.nodes.animation;
+
+import com.jme3.anim.Joint;
+import com.jme3.gde.core.scene.SceneApplication;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import org.openide.loaders.DataObject;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.Exceptions;
+
+/**
+ * Representation of multiple Joints in the Scene Explorer
+ * @author MeFisto94
+ */
+public class JmeJointChildren extends Children.Keys<Object> {
+    protected Joint rootJoint;
+    protected JmeSkinningControl jmeSkinningControl;
+    protected boolean readOnly = true;
+    protected HashMap<Object, Node> map = new HashMap<>();
+    private DataObject dataObject;
+
+    public JmeJointChildren() {
+    }
+
+    public JmeJointChildren(JmeSkinningControl jmeSkinningControl, Joint rootJoint) {
+        this.rootJoint = rootJoint;
+        this.jmeSkinningControl = jmeSkinningControl;
+    }
+
+    public void refreshChildren(boolean immediate) {
+        setKeys(createKeys());
+        refresh();
+    }
+
+    public void setReadOnly(boolean cookie) {
+        this.readOnly = cookie;
+    }
+
+    @Override
+    protected void addNotify() {
+        super.addNotify();
+        setKeys(createKeys());
+    }
+
+    protected List<Object> createKeys() {
+        try {
+            return SceneApplication.getApplication().enqueue(() -> {
+                List<Object> keys = new LinkedList<>();
+                if (rootJoint != null) {
+                    keys.addAll(rootJoint.getChildren());
+                } else {
+                    keys.addAll(Arrays.asList(jmeSkinningControl.getSkinningControl().getArmature().getRoots()));
+                }
+                
+                return keys;
+            }).get();
+        } catch (InterruptedException | ExecutionException ex) {
+            Exceptions.printStackTrace(ex);
+            return null;
+        }
+    }
+
+    @Override
+    protected Node[] createNodes(Object key) {
+        if (key instanceof Joint) {
+            JmeJointChildren children = new JmeJointChildren(jmeSkinningControl, (Joint)key);
+            children.setReadOnly(readOnly);
+            children.setDataObject(dataObject);
+            return new Node[]{new JmeJoint(jmeSkinningControl, (Joint)key, children).setReadOnly(readOnly)};
+        } else {
+            return new Node[]{Node.EMPTY};
+        }
+    }
+
+    public void setSkinningControl(JmeSkinningControl jmeSkinningControl) {
+        this.jmeSkinningControl = jmeSkinningControl;
+    }
+
+    public DataObject getDataObject() {
+        return dataObject;
+    }
+
+    public void setDataObject(DataObject dataObject) {
+        this.dataObject = dataObject;
+    }
+}

+ 19 - 21
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/animation/JmeArmature.java → jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/animation/JmeSkinningControl.java

@@ -31,7 +31,7 @@
  */
 package com.jme3.gde.core.sceneexplorer.nodes.animation;
 
-import com.jme3.anim.Armature;
+import com.jme3.anim.SkinningControl;
 import com.jme3.gde.core.icons.IconList;
 import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
 import com.jme3.gde.core.sceneexplorer.nodes.SceneExplorerNode;
@@ -46,20 +46,20 @@ import org.openide.nodes.Sheet;
  */
 @org.openide.util.lookup.ServiceProvider(service = SceneExplorerNode.class)
 @SuppressWarnings({"unchecked", "rawtypes"})
-public class JmeArmature extends AbstractSceneExplorerNode {
-    private Armature armature;
+public class JmeSkinningControl extends AbstractSceneExplorerNode {
+    private SkinningControl skinningControl;
     private static Image smallImage = IconList.skeletonControl.getImage();
 
-    public JmeArmature() {
+    public JmeSkinningControl() {
     }
 
-    public JmeArmature(Armature armature, JmeBoneChildren children) {
+    public JmeSkinningControl(SkinningControl skinningControl, JmeJointChildren children) {
         super(children);
-        this.armature = armature;
+        this.skinningControl = skinningControl;
         lookupContents.add(this);
-        lookupContents.add(armature);
+        lookupContents.add(skinningControl);
         setName("Armature");
-        //children.setSkeltonControl(this);
+        children.setSkinningControl(this);
     }
 
     @Override
@@ -76,34 +76,32 @@ public class JmeArmature extends AbstractSceneExplorerNode {
     protected Sheet createSheet() {
         Sheet sheet = Sheet.createDefault();
         Sheet.Set set = Sheet.createPropertiesSet();
-        set.setDisplayName("Armature");
-        set.setName(Armature.class.getName());
-        if (armature == null) {
-            return sheet;
-        }
+        set.setDisplayName("SkinningControl");
+        set.setName(SkinningControl.class.getName());
+        if (skinningControl != null) {
+            sheet.put(set);
+        } // else: empty sheet
         
-        sheet.put(set);
         return sheet;
     }
 
     @Override
     public Class getExplorerObjectClass() {
-        return Armature.class;
+        return SkinningControl.class;
     }
 
     @Override
     public Class getExplorerNodeClass() {
-        return JmeArmature.class;
+        return JmeSkinningControl.class;
     }
 
-    public Armature getArmature() {
-        return armature;
+    public SkinningControl getSkinningControl() {
+        return skinningControl;
     }
 
     @Override
     public Node[] createNodes(Object key, DataObject key2, boolean cookie) {
-        JmeBoneChildren children = new JmeBoneChildren(null, null);
-        JmeArmature jsc = new JmeArmature((Armature) key, children);
-        return new Node[]{jsc};
+        JmeJointChildren children = new JmeJointChildren(null, null);
+        return new Node[]{new JmeSkinningControl((SkinningControl)key, children)};
     }
 }