Răsfoiți Sursa

Ogre loader now loads animations and armature with the new system

Nehon 7 ani în urmă
părinte
comite
d6b05553b5
22 a modificat fișierele cu 212 adăugiri și 426 ștergeri
  1. 9 19
      jme3-bullet/src/common/java/com/jme3/bullet/control/KinematicRagdollControl.java
  2. 14 10
      jme3-core/src/main/java/com/jme3/anim/util/AnimMigrationUtils.java
  3. 5 12
      jme3-core/src/main/java/com/jme3/cinematic/events/AnimationEvent.java
  4. 6 14
      jme3-examples/src/main/java/jme3test/animation/TestCinematic.java
  5. 5 11
      jme3-examples/src/main/java/jme3test/bullet/TestBoneRagdoll.java
  6. 4 8
      jme3-examples/src/main/java/jme3test/bullet/TestRagdollCharacter.java
  7. 5 11
      jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java
  8. 6 9
      jme3-examples/src/main/java/jme3test/export/TestOgreConvert.java
  9. 2 5
      jme3-examples/src/main/java/jme3test/helloworld/HelloAnimation.java
  10. 0 132
      jme3-examples/src/main/java/jme3test/model/anim/TestAnimBlendBug.java
  11. 4 5
      jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java
  12. 13 14
      jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinning.java
  13. 9 14
      jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java
  14. 6 9
      jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java
  15. 9 14
      jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java
  16. 5 10
      jme3-examples/src/main/java/jme3test/model/anim/TestSkeletonControlRefresh.java
  17. 6 11
      jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java
  18. 7 6
      jme3-plugins/src/ogre/java/com/jme3/scene/plugins/ogre/AnimData.java
  19. 22 38
      jme3-plugins/src/ogre/java/com/jme3/scene/plugins/ogre/MeshLoader.java
  20. 75 74
      jme3-plugins/src/ogre/java/com/jme3/scene/plugins/ogre/SkeletonLoader.java
  21. BIN
      jme3-testdata/src/main/resources/Models/Oto/OtoOldAnim.j3o
  22. BIN
      jme3-testdata/src/main/resources/Models/Sinbad/SinbadOldAnim.j3o

+ 9 - 19
jme3-bullet/src/common/java/com/jme3/bullet/control/KinematicRagdollControl.java

@@ -31,36 +31,23 @@
  */
 package com.jme3.bullet.control;
 
-import com.jme3.animation.AnimControl;
-import com.jme3.animation.Bone;
-import com.jme3.animation.Skeleton;
-import com.jme3.animation.SkeletonControl;
+import com.jme3.animation.*;
 import com.jme3.bullet.PhysicsSpace;
-import com.jme3.bullet.collision.PhysicsCollisionEvent;
-import com.jme3.bullet.collision.PhysicsCollisionListener;
-import com.jme3.bullet.collision.PhysicsCollisionObject;
-import com.jme3.bullet.collision.RagdollCollisionListener;
+import com.jme3.bullet.collision.*;
 import com.jme3.bullet.collision.shapes.BoxCollisionShape;
 import com.jme3.bullet.collision.shapes.HullCollisionShape;
-import com.jme3.bullet.control.ragdoll.HumanoidRagdollPreset;
-import com.jme3.bullet.control.ragdoll.RagdollPreset;
-import com.jme3.bullet.control.ragdoll.RagdollUtils;
+import com.jme3.bullet.control.ragdoll.*;
 import com.jme3.bullet.joints.SixDofJoint;
 import com.jme3.bullet.objects.PhysicsRigidBody;
-import com.jme3.export.InputCapsule;
-import com.jme3.export.JmeExporter;
-import com.jme3.export.JmeImporter;
-import com.jme3.export.OutputCapsule;
-import com.jme3.export.Savable;
-import com.jme3.math.FastMath;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Vector3f;
+import com.jme3.export.*;
+import com.jme3.math.*;
 import com.jme3.renderer.RenderManager;
 import com.jme3.renderer.ViewPort;
 import com.jme3.scene.Node;
 import com.jme3.scene.Spatial;
 import com.jme3.util.TempVars;
 import com.jme3.util.clone.JmeCloneable;
+
 import java.io.IOException;
 import java.util.*;
 import java.util.logging.Level;
@@ -91,7 +78,10 @@ import java.util.logging.Logger;
  * </ul> </p>
  *
  * @author Normen Hansen and Rémy Bouquet (Nehon)
+ *
+ * TODO this needs to be redone with the new animation system
  */
+@Deprecated
 public class KinematicRagdollControl extends AbstractPhysicsControl implements PhysicsCollisionListener, JmeCloneable {
 
     protected static final Logger logger = Logger.getLogger(KinematicRagdollControl.class.getName());

+ 14 - 10
jme3-core/src/main/java/com/jme3/anim/util/AnimMigrationUtils.java

@@ -80,16 +80,7 @@ public class AnimMigrationUtils {
                     }
 
                     for (int i = 0; i < staticJoints.length; i++) {
-                        Joint j = staticJoints[i];
-                        if (j != null) {
-                            // joint has no track , we create one with the default pose
-                            float[] times = new float[]{0};
-                            Vector3f[] translations = new Vector3f[]{j.getLocalTranslation()};
-                            Quaternion[] rotations = new Quaternion[]{j.getLocalRotation()};
-                            Vector3f[] scales = new Vector3f[]{j.getLocalScale()};
-                            JointTrack track = new JointTrack(j, times, translations, rotations, scales);
-                            clip.addTrack(track);
-                        }
+                        padJointTracks(clip, staticJoints[i]);
                     }
 
                     composer.addAnimClip(clip);
@@ -104,6 +95,19 @@ public class AnimMigrationUtils {
         }
     }
 
+    public static void padJointTracks(AnimClip clip, Joint staticJoint) {
+        Joint j = staticJoint;
+        if (j != null) {
+            // joint has no track , we create one with the default pose
+            float[] times = new float[]{0};
+            Vector3f[] translations = new Vector3f[]{j.getLocalTranslation()};
+            Quaternion[] rotations = new Quaternion[]{j.getLocalRotation()};
+            Vector3f[] scales = new Vector3f[]{j.getLocalScale()};
+            JointTrack track = new JointTrack(j, times, translations, rotations, scales);
+            clip.addTrack(track);
+        }
+    }
+
     private static class SkeletonControlVisitor implements SceneGraphVisitor {
 
         Map<Skeleton, Armature> skeletonArmatureMap;

+ 5 - 12
jme3-core/src/main/java/com/jme3/cinematic/events/AnimationEvent.java

@@ -31,24 +31,16 @@
  */
 package com.jme3.cinematic.events;
 
-import com.jme3.animation.AnimChannel;
-import com.jme3.animation.AnimControl;
-import com.jme3.animation.LoopMode;
+import com.jme3.animation.*;
 import com.jme3.app.Application;
 import com.jme3.cinematic.Cinematic;
 import com.jme3.cinematic.PlayState;
-import com.jme3.export.InputCapsule;
-import com.jme3.export.JmeExporter;
-import com.jme3.export.JmeImporter;
-import com.jme3.export.OutputCapsule;
+import com.jme3.export.*;
 import com.jme3.scene.Node;
 import com.jme3.scene.Spatial;
-import com.jme3.util.clone.Cloner;
-import com.jme3.util.clone.JmeCloneable;
+
 import java.io.IOException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 import java.util.logging.Logger;
 
 /**
@@ -60,6 +52,7 @@ import java.util.logging.Logger;
  *
  * @author Nehon
  */
+@Deprecated
 public class AnimationEvent extends AbstractCinematicEvent {
 
     // Version #2: directly keeping track on the model instead of trying to retrieve 

+ 6 - 14
jme3-examples/src/main/java/jme3test/animation/TestCinematic.java

@@ -31,13 +31,9 @@
  */
 package jme3test.animation;
 
-import com.jme3.animation.AnimControl;
-import com.jme3.animation.AnimationFactory;
-import com.jme3.animation.LoopMode;
+import com.jme3.animation.*;
 import com.jme3.app.SimpleApplication;
-import com.jme3.cinematic.Cinematic;
-import com.jme3.cinematic.MotionPath;
-import com.jme3.cinematic.PlayState;
+import com.jme3.cinematic.*;
 import com.jme3.cinematic.events.*;
 import com.jme3.font.BitmapText;
 import com.jme3.input.ChaseCamera;
@@ -45,21 +41,18 @@ import com.jme3.input.controls.ActionListener;
 import com.jme3.input.controls.KeyTrigger;
 import com.jme3.light.DirectionalLight;
 import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.FastMath;
-import com.jme3.math.Vector3f;
+import com.jme3.math.*;
 import com.jme3.niftygui.NiftyJmeDisplay;
 import com.jme3.post.FilterPostProcessor;
 import com.jme3.post.filters.FadeFilter;
 import com.jme3.renderer.Caps;
 import com.jme3.renderer.queue.RenderQueue.ShadowMode;
-import com.jme3.scene.CameraNode;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.Spatial;
+import com.jme3.scene.*;
 import com.jme3.scene.shape.Box;
 import com.jme3.shadow.DirectionalLightShadowRenderer;
 import de.lessvoid.nifty.Nifty;
 
+//TODO rework this Test when the new animation system is done.
 public class TestCinematic extends SimpleApplication {
 
     private Spatial model;
@@ -77,7 +70,6 @@ public class TestCinematic extends SimpleApplication {
         app.start();
 
 
-
     }
 
     @Override
@@ -202,7 +194,7 @@ public class TestCinematic extends SimpleApplication {
 
     private void createScene() {
 
-        model = (Spatial) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
+        model = assetManager.loadModel("Models/Oto/OtoOldAnim.j3o");
         model.center();
         model.setShadowMode(ShadowMode.CastAndReceive);
         rootNode.attachChild(model);

+ 5 - 11
jme3-examples/src/main/java/jme3test/bullet/TestBoneRagdoll.java

@@ -36,24 +36,17 @@ import com.jme3.app.SimpleApplication;
 import com.jme3.asset.TextureKey;
 import com.jme3.bullet.BulletAppState;
 import com.jme3.bullet.PhysicsSpace;
-import com.jme3.bullet.collision.PhysicsCollisionEvent;
-import com.jme3.bullet.collision.PhysicsCollisionObject;
-import com.jme3.bullet.collision.RagdollCollisionListener;
+import com.jme3.bullet.collision.*;
 import com.jme3.bullet.collision.shapes.SphereCollisionShape;
 import com.jme3.bullet.control.KinematicRagdollControl;
 import com.jme3.bullet.control.RigidBodyControl;
 import com.jme3.font.BitmapText;
 import com.jme3.input.KeyInput;
 import com.jme3.input.MouseInput;
-import com.jme3.input.controls.ActionListener;
-import com.jme3.input.controls.KeyTrigger;
-import com.jme3.input.controls.MouseButtonTrigger;
+import com.jme3.input.controls.*;
 import com.jme3.light.DirectionalLight;
 import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.FastMath;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Vector3f;
+import com.jme3.math.*;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.Node;
 import com.jme3.scene.debug.SkeletonDebugger;
@@ -65,6 +58,7 @@ import com.jme3.texture.Texture;
  * PHYSICS RAGDOLLS ARE NOT WORKING PROPERLY YET!
  * @author normenhansen
  */
+//TODO rework this Test when the new animation system is done.
 public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisionListener, AnimEventListener {
 
     private BulletAppState bulletAppState;
@@ -101,7 +95,7 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi
         PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace());
         setupLight();
 
-        model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
+        model = (Node) assetManager.loadModel("Models/Sinbad/SinbadOldAnim.j3o");
 
         //  model.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_X));
 

+ 4 - 8
jme3-examples/src/main/java/jme3test/bullet/TestRagdollCharacter.java

@@ -31,10 +31,7 @@
  */
 package jme3test.bullet;
 
-import com.jme3.animation.AnimChannel;
-import com.jme3.animation.AnimControl;
-import com.jme3.animation.AnimEventListener;
-import com.jme3.animation.LoopMode;
+import com.jme3.animation.*;
 import com.jme3.app.SimpleApplication;
 import com.jme3.asset.TextureKey;
 import com.jme3.bullet.BulletAppState;
@@ -46,9 +43,7 @@ import com.jme3.input.controls.ActionListener;
 import com.jme3.input.controls.KeyTrigger;
 import com.jme3.light.DirectionalLight;
 import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.Vector2f;
-import com.jme3.math.Vector3f;
+import com.jme3.math.*;
 import com.jme3.renderer.queue.RenderQueue.ShadowMode;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.Node;
@@ -58,6 +53,7 @@ import com.jme3.texture.Texture;
 /**
  * @author normenhansen
  */
+//TODO rework this Test when the new animation system is done.
 public class TestRagdollCharacter extends SimpleApplication implements AnimEventListener, ActionListener {
 
     BulletAppState bulletAppState;
@@ -89,7 +85,7 @@ public class TestRagdollCharacter extends SimpleApplication implements AnimEvent
         cam.setLocation(new Vector3f(-8,0,-4));
         cam.lookAt(new Vector3f(4,0,-7), Vector3f.UNIT_Y);
 
-        model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
+        model = (Node) assetManager.loadModel("Models/Sinbad/SinbadOldAnim.j3o");
         model.lookAt(new Vector3f(0,0,-1), Vector3f.UNIT_Y);
         model.setLocalTranslation(4, 0, -7f);
 

+ 5 - 11
jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java

@@ -31,10 +31,7 @@
  */
 package jme3test.bullet;
 
-import com.jme3.animation.AnimChannel;
-import com.jme3.animation.AnimControl;
-import com.jme3.animation.AnimEventListener;
-import com.jme3.animation.LoopMode;
+import com.jme3.animation.*;
 import com.jme3.app.SimpleApplication;
 import com.jme3.bullet.BulletAppState;
 import com.jme3.bullet.PhysicsSpace;
@@ -54,16 +51,12 @@ import com.jme3.input.controls.ActionListener;
 import com.jme3.input.controls.KeyTrigger;
 import com.jme3.light.DirectionalLight;
 import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.Vector2f;
-import com.jme3.math.Vector3f;
+import com.jme3.math.*;
 import com.jme3.post.FilterPostProcessor;
 import com.jme3.post.filters.BloomFilter;
 import com.jme3.renderer.Camera;
 import com.jme3.renderer.queue.RenderQueue.ShadowMode;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.Node;
-import com.jme3.scene.Spatial;
+import com.jme3.scene.*;
 import com.jme3.scene.shape.Box;
 import com.jme3.scene.shape.Sphere;
 import com.jme3.scene.shape.Sphere.TextureMode;
@@ -74,6 +67,7 @@ import com.jme3.terrain.heightmap.ImageBasedHeightMap;
 import com.jme3.texture.Texture;
 import com.jme3.texture.Texture.WrapMode;
 import com.jme3.util.SkyFactory;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -297,7 +291,7 @@ public class TestWalkingChar extends SimpleApplication implements ActionListener
     private void createCharacter() {
         CapsuleCollisionShape capsule = new CapsuleCollisionShape(3f, 4f);
         character = new CharacterControl(capsule, 0.01f);
-        model = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
+        model = (Node) assetManager.loadModel("Models/Oto/OtoOldAnim.j3o");
         //model.setLocalScale(0.5f);
         model.addControl(character);
         character.setPhysicsLocation(new Vector3f(-140, 40, -10));

+ 6 - 9
jme3-examples/src/main/java/jme3test/export/TestOgreConvert.java

@@ -32,8 +32,7 @@
 
 package jme3test.export;
 
-import com.jme3.animation.AnimChannel;
-import com.jme3.animation.AnimControl;
+import com.jme3.anim.AnimComposer;
 import com.jme3.app.SimpleApplication;
 import com.jme3.export.binary.BinaryExporter;
 import com.jme3.export.binary.BinaryImporter;
@@ -42,9 +41,8 @@ import com.jme3.math.ColorRGBA;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Node;
 import com.jme3.scene.Spatial;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
+
+import java.io.*;
 
 public class TestOgreConvert extends SimpleApplication {
 
@@ -71,10 +69,9 @@ public class TestOgreConvert extends SimpleApplication {
             BinaryImporter imp = new BinaryImporter();
             imp.setAssetManager(assetManager);
             Node ogreModelReloaded = (Node) imp.load(bais, null, null);
-            
-            AnimControl control = ogreModelReloaded.getControl(AnimControl.class);
-            AnimChannel chan = control.createChannel();
-            chan.setAnim("Walk");
+
+            AnimComposer composer = ogreModelReloaded.getControl(AnimComposer.class);
+            composer.setCurrentAnimClip("Walk");
 
             rootNode.attachChild(ogreModelReloaded);
         } catch (IOException ex){

+ 2 - 5
jme3-examples/src/main/java/jme3test/helloworld/HelloAnimation.java

@@ -32,10 +32,7 @@
 
 package jme3test.helloworld;
 
-import com.jme3.animation.AnimChannel;
-import com.jme3.animation.AnimControl;
-import com.jme3.animation.AnimEventListener;
-import com.jme3.animation.LoopMode;
+import com.jme3.animation.*;
 import com.jme3.app.SimpleApplication;
 import com.jme3.input.KeyInput;
 import com.jme3.input.controls.ActionListener;
@@ -70,7 +67,7 @@ public class HelloAnimation extends SimpleApplication
     rootNode.addLight(dl);
 
     /** Load a model that contains animation */
-    player = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
+    player = (Node) assetManager.loadModel("Models/Oto/OtoOldAnim.j3o");
     player.setLocalScale(0.5f);
     rootNode.attachChild(player);
 

+ 0 - 132
jme3-examples/src/main/java/jme3test/model/anim/TestAnimBlendBug.java

@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2009-2012 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 jme3test.model.anim;
-
-import com.jme3.animation.AnimChannel;
-import com.jme3.animation.AnimControl;
-import com.jme3.app.SimpleApplication;
-import com.jme3.input.KeyInput;
-import com.jme3.input.controls.ActionListener;
-import com.jme3.input.controls.KeyTrigger;
-import com.jme3.light.DirectionalLight;
-import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Node;
-import com.jme3.scene.debug.SkeletonDebugger;
-
-public class TestAnimBlendBug extends SimpleApplication implements ActionListener {
-
-//    private AnimControl control;
-    private AnimChannel channel1, channel2;
-    private String[] animNames;
-
-    private float blendTime = 0.5f;
-    private float lockAfterBlending =  blendTime + 0.25f;
-    private float blendingAnimationLock;
-
-    public static void main(String[] args) {
-        TestAnimBlendBug app = new TestAnimBlendBug();
-        app.start();
-    }
-
-    public void onAction(String name, boolean value, float tpf) {
-        if (name.equals("One") && value){
-            channel1.setAnim(animNames[4], blendTime);
-            channel2.setAnim(animNames[4], 0);
-            channel1.setSpeed(0.25f);
-            channel2.setSpeed(0.25f);
-            blendingAnimationLock = lockAfterBlending;
-        }
-    }
-
-    public void onPreUpdate(float tpf) {
-    }
-
-    public void onPostUpdate(float tpf) {
-    }
-
-    @Override
-    public void simpleUpdate(float tpf) {
-        // Is there currently a blending underway?
-        if (blendingAnimationLock > 0f) {
-            blendingAnimationLock -= tpf;
-        }
-    }
-
-    @Override
-    public void simpleInitApp() {
-        inputManager.addMapping("One", new KeyTrigger(KeyInput.KEY_1));
-        inputManager.addListener(this, "One");
-
-        flyCam.setMoveSpeed(100f);
-        cam.setLocation( new Vector3f( 0f, 150f, -325f ) );
-        cam.lookAt( new Vector3f( 0f, 100f, 0f ), Vector3f.UNIT_Y );
-
-        DirectionalLight dl = new DirectionalLight();
-        dl.setDirection(new Vector3f(-0.1f, -0.7f, 1).normalizeLocal());
-        dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
-        rootNode.addLight(dl);
-
-        Node model1 = (Node) assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
-        Node model2 = (Node) assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
-//        Node model2 = model1.clone();
-
-        model1.setLocalTranslation(-60, 0, 0);
-        model2.setLocalTranslation(60, 0, 0);
-
-        AnimControl control1 = model1.getControl(AnimControl.class);
-        animNames = control1.getAnimationNames().toArray(new String[0]);
-        channel1 = control1.createChannel();
-        
-        AnimControl control2 = model2.getControl(AnimControl.class);
-        channel2 = control2.createChannel();
-
-        SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton1", control1.getSkeleton());
-        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-        mat.getAdditionalRenderState().setWireframe(true);
-        mat.setColor("Color", ColorRGBA.Red);
-        mat.setFloat("PointSize", 7f);
-        mat.getAdditionalRenderState().setDepthTest(false);
-        skeletonDebug.setMaterial(mat);
-        model1.attachChild(skeletonDebug);
-
-        skeletonDebug = new SkeletonDebugger("skeleton2", control2.getSkeleton());
-        skeletonDebug.setMaterial(mat);
-        model2.attachChild(skeletonDebug);
-
-        rootNode.attachChild(model1);
-        rootNode.attachChild(model2);
-    }
-
-}

+ 4 - 5
jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java

@@ -2,7 +2,6 @@ package jme3test.model.anim;
 
 import com.jme3.anim.AnimComposer;
 import com.jme3.anim.SkinningControl;
-import com.jme3.anim.util.AnimMigrationUtils;
 import com.jme3.app.ChaseCameraAppState;
 import com.jme3.app.SimpleApplication;
 import com.jme3.input.KeyInput;
@@ -41,12 +40,12 @@ public class TestAnimMigration extends SimpleApplication {
         rootNode.addLight(new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal()));
         rootNode.addLight(new AmbientLight(ColorRGBA.DarkGray));
 
-        Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o");
-        // Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml").scale(0.2f).move(0, 1, 0);
+        //Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o");
+        Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml").scale(0.2f).move(0, 1, 0);
         //Spatial model = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
-        //  Spatial model = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml").scale(0.02f);
+        //Spatial model = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml").scale(0.02f);
 
-        AnimMigrationUtils.migrate(model);
+        // AnimMigrationUtils.migrate(model);
 
         rootNode.attachChild(model);
 

+ 13 - 14
jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinning.java

@@ -31,28 +31,28 @@
  */
 package jme3test.model.anim;
 
-import com.jme3.animation.*;
+import com.jme3.anim.AnimComposer;
+import com.jme3.anim.SkinningControl;
 import com.jme3.app.SimpleApplication;
 import com.jme3.font.BitmapText;
 import com.jme3.input.KeyInput;
 import com.jme3.input.controls.ActionListener;
 import com.jme3.input.controls.KeyTrigger;
 import com.jme3.light.DirectionalLight;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Vector3f;
+import com.jme3.math.*;
 import com.jme3.scene.Spatial;
+
 import java.util.ArrayList;
 import java.util.List;
 
 public class TestHWSkinning extends SimpleApplication implements ActionListener{
 
-    private AnimChannel channel;
-    private AnimControl control;
+
+    private AnimComposer composer;
     private String[] animNames = {"Dodge", "Walk", "pull", "push"};
     private final static int SIZE = 10;
     private boolean hwSkinningEnable = true;
-    private List<SkeletonControl> skControls = new ArrayList<SkeletonControl>();
+    private List<SkinningControl> skControls = new ArrayList<SkinningControl>();
     private BitmapText hwsText;
 
     public static void main(String[] args) {
@@ -77,13 +77,12 @@ public class TestHWSkinning extends SimpleApplication implements ActionListener{
                 Spatial model = (Spatial) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
                 model.setLocalScale(0.1f);
                 model.setLocalTranslation(i - SIZE / 2, 0, j - SIZE / 2);
-                control = model.getControl(AnimControl.class);
+                composer = model.getControl(AnimComposer.class);
 
-                channel = control.createChannel();
-                channel.setAnim(animNames[(i + j) % 4]);
-                SkeletonControl skeletonControl = model.getControl(SkeletonControl.class);
-                skeletonControl.setHardwareSkinningPreferred(hwSkinningEnable);
-                skControls.add(skeletonControl);
+                composer.setCurrentAnimClip(animNames[(i + j) % 4]);
+                SkinningControl skinningControl = model.getControl(SkinningControl.class);
+                skinningControl.setHardwareSkinningPreferred(hwSkinningEnable);
+                skControls.add(skinningControl);
                 rootNode.attachChild(model);
             }
         }
@@ -96,7 +95,7 @@ public class TestHWSkinning extends SimpleApplication implements ActionListener{
     public void onAction(String name, boolean isPressed, float tpf) {
         if(isPressed && name.equals("toggleHWS")){
             hwSkinningEnable = !hwSkinningEnable;
-            for (SkeletonControl control : skControls) {
+            for (SkinningControl control : skControls) {
                 control.setHardwareSkinningPreferred(hwSkinningEnable);
                 hwsText.setText("HWS : "+ hwSkinningEnable);
             }

+ 9 - 14
jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java

@@ -31,8 +31,7 @@
  */
 package jme3test.model.anim;
 
-import com.jme3.animation.AnimChannel;
-import com.jme3.animation.AnimControl;
+import com.jme3.anim.AnimComposer;
 import com.jme3.app.SimpleApplication;
 import com.jme3.export.binary.BinaryExporter;
 import com.jme3.light.DirectionalLight;
@@ -57,27 +56,23 @@ public class TestModelExportingCloning extends SimpleApplication {
         dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
         rootNode.addLight(dl);
 
-        AnimControl control;
-        AnimChannel channel;
-        
+        AnimComposer composer;
+
         Spatial originalModel = assetManager.loadModel("Models/Oto/Oto.mesh.xml");
-        control = originalModel.getControl(AnimControl.class);
-        channel = control.createChannel();
-        channel.setAnim("Walk");
+        composer = originalModel.getControl(AnimComposer.class);
+        composer.setCurrentAnimClip("Walk");
         rootNode.attachChild(originalModel);
         
         Spatial clonedModel = originalModel.clone();
         clonedModel.move(10, 0, 0);
-        control = clonedModel.getControl(AnimControl.class);
-        channel = control.createChannel();
-        channel.setAnim("push");
+        composer = clonedModel.getControl(AnimComposer.class);
+        composer.setCurrentAnimClip("push");
         rootNode.attachChild(clonedModel);
         
         Spatial exportedModel = BinaryExporter.saveAndLoad(assetManager, originalModel);
         exportedModel.move(20, 0, 0);
-        control = exportedModel.getControl(AnimControl.class);
-        channel = control.createChannel();
-        channel.setAnim("pull");
+        composer = exportedModel.getControl(AnimComposer.class);
+        composer.setCurrentAnimClip("pull");
         rootNode.attachChild(exportedModel);
     }
 }

+ 6 - 9
jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java

@@ -38,15 +38,12 @@ import com.jme3.input.KeyInput;
 import com.jme3.input.controls.ActionListener;
 import com.jme3.input.controls.KeyTrigger;
 import com.jme3.light.DirectionalLight;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.Node;
-import com.jme3.scene.Spatial;
+import com.jme3.math.*;
+import com.jme3.scene.*;
 import com.jme3.scene.shape.Box;
 
-public class TestOgreAnim extends SimpleApplication 
+//TODO rework this Test when the new animation system is done.
+public class TestOgreAnim extends SimpleApplication
         implements AnimEventListener, ActionListener {
 
     private AnimChannel channel;
@@ -69,7 +66,7 @@ public class TestOgreAnim extends SimpleApplication
         dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
         rootNode.addLight(dl);
 
-        Spatial model = (Spatial) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
+        Spatial model = (Spatial) assetManager.loadModel("Models/Oto/OtoOldAnim.j3o");
         model.center();
 
         control = model.getControl(AnimControl.class);
@@ -102,7 +99,7 @@ public class TestOgreAnim extends SimpleApplication
 //                        geom.getMesh().createCollisionData();
 
     }
-    
+
 
     public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
         if (animName.equals("Dodge")){

+ 9 - 14
jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java

@@ -32,20 +32,15 @@
 
 package jme3test.model.anim;
 
-import com.jme3.animation.AnimChannel;
-import com.jme3.animation.AnimControl;
-import com.jme3.animation.Bone;
-import com.jme3.animation.LoopMode;
+import com.jme3.animation.*;
 import com.jme3.app.SimpleApplication;
 import com.jme3.light.DirectionalLight;
 import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.FastMath;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Vector3f;
+import com.jme3.math.*;
 import com.jme3.scene.Node;
 import com.jme3.scene.debug.SkeletonDebugger;
 
+//TODO rework this Test when the new animation system is done.
 public class TestOgreComplexAnim extends SimpleApplication {
 
     private AnimControl control;
@@ -69,7 +64,7 @@ public class TestOgreComplexAnim extends SimpleApplication {
         dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
         rootNode.addLight(dl);
 
-        Node model = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
+        Node model = (Node) assetManager.loadModel("Models/Oto/OtoOldAnim.j3o");
 
         control = model.getControl(AnimControl.class);
 
@@ -118,8 +113,8 @@ public class TestOgreComplexAnim extends SimpleApplication {
     public void simpleUpdate(float tpf){
         Bone b = control.getSkeleton().getBone("spinehigh");
         Bone b2 = control.getSkeleton().getBone("uparm.left");
-        
-        angle += tpf * rate;        
+
+        angle += tpf * rate;
         if (angle > FastMath.HALF_PI / 2f){
             angle = FastMath.HALF_PI / 2f;
             rate = -1;
@@ -133,11 +128,11 @@ public class TestOgreComplexAnim extends SimpleApplication {
 
         b.setUserControl(true);
         b.setUserTransforms(Vector3f.ZERO, q, Vector3f.UNIT_XYZ);
-        
+
         b2.setUserControl(true);
         b2.setUserTransforms(Vector3f.ZERO, Quaternion.IDENTITY, new Vector3f(1+angle,1+ angle, 1+angle));
-  
-  
+
+
     }
 
 }

+ 5 - 10
jme3-examples/src/main/java/jme3test/model/anim/TestSkeletonControlRefresh.java

@@ -37,7 +37,6 @@ package jme3test.model.anim;
  */
 
 
- 
 import com.jme3.animation.*;
 import com.jme3.app.SimpleApplication;
 import com.jme3.asset.TextureKey;
@@ -47,11 +46,7 @@ import com.jme3.input.controls.ActionListener;
 import com.jme3.input.controls.KeyTrigger;
 import com.jme3.light.DirectionalLight;
 import com.jme3.material.Material;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.FastMath;
-import com.jme3.math.Quaternion;
-import com.jme3.math.Vector2f;
-import com.jme3.math.Vector3f;
+import com.jme3.math.*;
 import com.jme3.post.FilterPostProcessor;
 import com.jme3.post.ssao.SSAOFilter;
 import com.jme3.renderer.queue.RenderQueue;
@@ -59,11 +54,11 @@ import com.jme3.scene.Geometry;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.shape.Quad;
 import com.jme3.shadow.DirectionalLightShadowFilter;
-import com.jme3.shadow.DirectionalLightShadowRenderer;
+
 import java.util.ArrayList;
 import java.util.List;
-import jme3test.post.SSAOUI;
- 
+
+//TODO rework this Test when the new animation system is done.
 public class TestSkeletonControlRefresh extends SimpleApplication implements ActionListener{
  
     private AnimChannel channel;
@@ -97,7 +92,7 @@ public class TestSkeletonControlRefresh extends SimpleApplication implements Act
  
         for (int i = 0; i < SIZE; i++) {
             for (int j = 0; j < SIZE; j++) {
-                Spatial model = (Spatial) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
+                Spatial model = (Spatial) assetManager.loadModel("Models/Oto/OtoOldAnim.j3o");
                 //setting a different material
                 model.setMaterial(m.clone());
                 model.setLocalScale(0.1f);

+ 6 - 11
jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java

@@ -31,9 +31,8 @@
  */
 package jme3test.stress;
 
+import com.jme3.anim.SkinningControl;
 import com.jme3.animation.AnimChannel;
-import com.jme3.animation.AnimControl;
-import com.jme3.animation.SkeletonControl;
 import com.jme3.app.SimpleApplication;
 import com.jme3.bounding.BoundingBox;
 import com.jme3.font.BitmapText;
@@ -43,18 +42,14 @@ import com.jme3.input.controls.ActionListener;
 import com.jme3.input.controls.KeyTrigger;
 import com.jme3.light.AmbientLight;
 import com.jme3.light.DirectionalLight;
-import com.jme3.math.ColorRGBA;
-import com.jme3.math.FastMath;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.Node;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.VertexBuffer;
+import com.jme3.math.*;
+import com.jme3.scene.*;
+import jme3tools.optimize.LodGenerator;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
-import jme3tools.optimize.LodGenerator;
 
 public class TestLodGeneration extends SimpleApplication {
 
@@ -101,7 +96,7 @@ public class TestLodGeneration extends SimpleApplication {
 
 //           ch = model.getControl(AnimControl.class).createChannel();
 //          ch.setAnim("Wave");
-        SkeletonControl c = model.getControl(SkeletonControl.class);
+        SkinningControl c = model.getControl(SkinningControl.class);
         if (c != null) {
             c.setEnabled(false);
         }

+ 7 - 6
jme3-plugins/src/ogre/java/com/jme3/scene/plugins/ogre/AnimData.java

@@ -31,17 +31,18 @@
  */
 package com.jme3.scene.plugins.ogre;
 
-import com.jme3.animation.Animation;
-import com.jme3.animation.Skeleton;
+import com.jme3.anim.AnimClip;
+import com.jme3.anim.Armature;
+
 import java.util.ArrayList;
 
 public class AnimData {
 
-    public final Skeleton skeleton;
-    public final ArrayList<Animation> anims;
+    public final Armature armature;
+    public final ArrayList<AnimClip> anims;
 
-    public AnimData(Skeleton skeleton, ArrayList<Animation> anims) {
-        this.skeleton = skeleton;
+    public AnimData(Armature armature, ArrayList<AnimClip> anims) {
+        this.armature = armature;
         this.anims = anims;
     }
 }

+ 22 - 38
jme3-plugins/src/ogre/java/com/jme3/scene/plugins/ogre/MeshLoader.java

@@ -31,9 +31,7 @@
  */
 package com.jme3.scene.plugins.ogre;
 
-import com.jme3.animation.AnimControl;
-import com.jme3.animation.Animation;
-import com.jme3.animation.SkeletonControl;
+import com.jme3.anim.*;
 import com.jme3.asset.*;
 import com.jme3.material.Material;
 import com.jme3.material.MaterialList;
@@ -41,30 +39,23 @@ import com.jme3.math.ColorRGBA;
 import com.jme3.renderer.queue.RenderQueue;
 import com.jme3.renderer.queue.RenderQueue.Bucket;
 import com.jme3.scene.*;
-import com.jme3.scene.VertexBuffer.Format;
-import com.jme3.scene.VertexBuffer.Type;
-import com.jme3.scene.VertexBuffer.Usage;
+import com.jme3.scene.VertexBuffer.*;
 import com.jme3.scene.plugins.ogre.matext.OgreMaterialKey;
-import com.jme3.util.BufferUtils;
-import com.jme3.util.IntMap;
+import com.jme3.util.*;
 import com.jme3.util.IntMap.Entry;
-import com.jme3.util.PlaceholderAssets;
-import static com.jme3.util.xml.SAXUtil.*;
+import org.xml.sax.*;
+import org.xml.sax.helpers.DefaultHandler;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.nio.*;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
+import java.util.*;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParserFactory;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
+
+import static com.jme3.util.xml.SAXUtil.*;
 
 /**
  * Loads Ogre3D mesh.xml files.
@@ -799,35 +790,28 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
             for (int i = 0; i < geoms.size(); i++) {
                 Geometry g = geoms.get(i);
                 Mesh m = geoms.get(i).getMesh();
-                
-                //FIXME the parameter is now useless.
-                //It was !HADWARE_SKINNING before, but since toggleing 
-                //HW skinning does not happen at load time it was always true.
-                //We should use something similar as for the HWBoneIndex and 
-                //HWBoneWeight : create the vertex buffers empty so that they 
-                //are put in the cache, and really populate them the first time 
-                //software skinning is used on the mesh.
-                m.generateBindPose(true);
-
+                m.generateBindPose();
             }
 
             // Put the animations in the AnimControl
-            HashMap<String, Animation> anims = new HashMap<String, Animation>();
-            ArrayList<Animation> animList = animData.anims;
+            HashMap<String, AnimClip> anims = new HashMap<>();
+            ArrayList<AnimClip> animList = animData.anims;
             for (int i = 0; i < animList.size(); i++) {
-                Animation anim = animList.get(i);
+                AnimClip anim = animList.get(i);
                 anims.put(anim.getName(), anim);
             }
 
-            AnimControl ctrl = new AnimControl(animData.skeleton);
-            ctrl.setAnimations(anims);
-            model.addControl(ctrl);
+            AnimComposer composer = new AnimComposer();
+            for (AnimClip clip : anims.values()) {
+                composer.addAnimClip(clip);
+            }
+            model.addControl(composer);
 
             // Put the skeleton in the skeleton control
-            SkeletonControl skeletonControl = new SkeletonControl(animData.skeleton);
+            SkinningControl skinningControl = new SkinningControl(animData.armature);
 
             // This will acquire the targets from the node
-            model.addControl(skeletonControl);
+            model.addControl(skinningControl);
         }
 
         return model;

+ 75 - 74
jme3-plugins/src/ogre/java/com/jme3/scene/plugins/ogre/SkeletonLoader.java

@@ -31,45 +31,35 @@
  */
 package com.jme3.scene.plugins.ogre;
 
-import com.jme3.animation.Animation;
-import com.jme3.animation.Bone;
-import com.jme3.animation.BoneTrack;
-import com.jme3.animation.Skeleton;
+import com.jme3.anim.*;
+import com.jme3.anim.util.AnimMigrationUtils;
 import com.jme3.asset.AssetInfo;
 import com.jme3.asset.AssetLoader;
-import com.jme3.asset.AssetManager;
 import com.jme3.math.Quaternion;
 import com.jme3.math.Vector3f;
 import com.jme3.util.xml.SAXUtil;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Stack;
-import java.util.logging.Logger;
+import org.xml.sax.*;
+import org.xml.sax.helpers.DefaultHandler;
+
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParserFactory;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
+import java.io.*;
+import java.util.*;
+import java.util.logging.Logger;
 
 public class SkeletonLoader extends DefaultHandler implements AssetLoader {
 
     private static final Logger logger = Logger.getLogger(SceneLoader.class.getName());
-    private AssetManager assetManager;
+    //private AssetManager assetManager;
     private Stack<String> elementStack = new Stack<String>();
-    private HashMap<Integer, Bone> indexToBone = new HashMap<Integer, Bone>();
-    private HashMap<String, Bone> nameToBone = new HashMap<String, Bone>();
-    private BoneTrack track;
-    private ArrayList<BoneTrack> tracks = new ArrayList<BoneTrack>();
-    private Animation animation;
-    private ArrayList<Animation> animations;
-    private Bone bone;
-    private Skeleton skeleton;
+    private HashMap<Integer, Joint> indexToJoint = new HashMap<>();
+    private HashMap<String, Joint> nameToJoint = new HashMap<>();
+    private JointTrack track;
+    private ArrayList<JointTrack> tracks = new ArrayList<>();
+    private AnimClip animClip;
+    private ArrayList<AnimClip> animClips;
+    private Joint joint;
+    private Armature armature;
     private ArrayList<Float> times = new ArrayList<Float>();
     private ArrayList<Vector3f> translations = new ArrayList<Vector3f>();
     private ArrayList<Quaternion> rotations = new ArrayList<Quaternion>();
@@ -80,6 +70,7 @@ public class SkeletonLoader extends DefaultHandler implements AssetLoader {
     private Vector3f scale;
     private float angle;
     private Vector3f axis;
+    private List<Joint> unusedJoints = new ArrayList<>();
 
     public void startElement(String uri, String localName, String qName, Attributes attribs) throws SAXException {
         if (qName.equals("position") || qName.equals("translate")) {
@@ -99,38 +90,40 @@ public class SkeletonLoader extends DefaultHandler implements AssetLoader {
             assert elementStack.peek().equals("track");
         } else if (qName.equals("track")) {
             assert elementStack.peek().equals("tracks");
-            String boneName = SAXUtil.parseString(attribs.getValue("bone"));
-            Bone bone = nameToBone.get(boneName);
-            int index = skeleton.getBoneIndex(bone);
-            track = new BoneTrack(index);
+            String jointName = SAXUtil.parseString(attribs.getValue("bone"));
+            joint = nameToJoint.get(jointName);
+            track = new JointTrack();
+            track.setTarget(joint);
         } else if (qName.equals("boneparent")) {
             assert elementStack.peek().equals("bonehierarchy");
-            String boneName = attribs.getValue("bone");
+            String jointName = attribs.getValue("bone");
             String parentName = attribs.getValue("parent");
-            Bone bone = nameToBone.get(boneName);
-            Bone parent = nameToBone.get(parentName);
-            parent.addChild(bone);
+            Joint joint = nameToJoint.get(jointName);
+            Joint parent = nameToJoint.get(parentName);
+            parent.addChild(joint);
         } else if (qName.equals("bone")) {
             assert elementStack.peek().equals("bones");
 
             // insert bone into indexed map
-            bone = new Bone(attribs.getValue("name"));
+            joint = new Joint(attribs.getValue("name"));
             int id = SAXUtil.parseInt(attribs.getValue("id"));
-            indexToBone.put(id, bone);
-            nameToBone.put(bone.getName(), bone);
+            indexToJoint.put(id, joint);
+            nameToJoint.put(joint.getName(), joint);
         } else if (qName.equals("tracks")) {
             assert elementStack.peek().equals("animation");
             tracks.clear();
+            unusedJoints.clear();
+            unusedJoints.addAll(nameToJoint.values());
         } else if (qName.equals("animation")) {
             assert elementStack.peek().equals("animations");
             String name = SAXUtil.parseString(attribs.getValue("name"));
-            float length = SAXUtil.parseFloat(attribs.getValue("length"));
-            animation = new Animation(name, length);
+            //float length = SAXUtil.parseFloat(attribs.getValue("length"));
+            animClip = new AnimClip(name);
         } else if (qName.equals("bonehierarchy")) {
             assert elementStack.peek().equals("skeleton");
         } else if (qName.equals("animations")) {
             assert elementStack.peek().equals("skeleton");
-            animations = new ArrayList<Animation>();
+            animClips = new ArrayList<>();
         } else if (qName.equals("bones")) {
             assert elementStack.peek().equals("skeleton");
         } else if (qName.equals("skeleton")) {
@@ -149,32 +142,42 @@ public class SkeletonLoader extends DefaultHandler implements AssetLoader {
             angle = 0;
             axis = null;
         } else if (qName.equals("bone")) {
-            bone.setBindTransforms(position, rotation, scale);
-            bone = null;
+            joint.getLocalTransform().setTranslation(position);
+            joint.getLocalTransform().setRotation(rotation);
+            if (scale != null) {
+                joint.getLocalTransform().setScale(scale);
+            }
+            joint = null;
             position = null;
             rotation = null;
             scale = null;
         } else if (qName.equals("bonehierarchy")) {
-            Bone[] bones = new Bone[indexToBone.size()];
-            // find bones without a parent and attach them to the skeleton
-            // also assign the bones to the bonelist
-            for (Map.Entry<Integer, Bone> entry : indexToBone.entrySet()) {
-                Bone bone = entry.getValue();
-                bones[entry.getKey()] = bone;
+            Joint[] joints = new Joint[indexToJoint.size()];
+            // find joints without a parent and attach them to the armature
+            // also assign the joints to the jointList
+            for (Map.Entry<Integer, Joint> entry : indexToJoint.entrySet()) {
+                Joint joint = entry.getValue();
+                joints[entry.getKey()] = joint;
             }
-            indexToBone.clear();
-            skeleton = new Skeleton(bones);
+            indexToJoint.clear();
+            armature = new Armature(joints);
+            armature.setBindPose();
         } else if (qName.equals("animation")) {
-            animations.add(animation);
-            animation = null;
+            //nameToJoint contains the joints with no track
+            for (Joint j : unusedJoints) {
+                AnimMigrationUtils.padJointTracks(animClip, j);
+            }
+            animClips.add(animClip);
+            animClip = null;
         } else if (qName.equals("track")) {
             if (track != null) { // if track has keyframes
                 tracks.add(track);
+                unusedJoints.remove(joint);
                 track = null;
             }
         } else if (qName.equals("tracks")) {
-            BoneTrack[] trackList = tracks.toArray(new BoneTrack[tracks.size()]);
-            animation.setTracks(trackList);
+            JointTrack[] trackList = tracks.toArray(new JointTrack[tracks.size()]);
+            animClip.setTracks(trackList);
             tracks.clear();
         } else if (qName.equals("keyframe")) {
             assert time >= 0;
@@ -182,14 +185,13 @@ public class SkeletonLoader extends DefaultHandler implements AssetLoader {
             assert rotation != null;
 
             times.add(time);
-            translations.add(position);
-            rotations.add(rotation);
+            translations.add(position.addLocal(joint.getLocalTranslation()));
+            rotations.add(joint.getLocalRotation().mult(rotation, rotation));
             if (scale != null) {
-                scales.add(scale);
+                scales.add(scale.multLocal(joint.getLocalScale()));
             }else{
                 scales.add(new Vector3f(1,1,1));
             }
-
             time = -1;
             position = null;
             rotation = null;
@@ -206,7 +208,6 @@ public class SkeletonLoader extends DefaultHandler implements AssetLoader {
                 Vector3f[] scalesArray = scales.toArray(new Vector3f[scales.size()]);
                 
                 track.setKeyframes(timesArray, transArray, rotArray, scalesArray);
-                //track.setKeyframes(timesArray, transArray, rotArray);
             } else {
                 track = null;
             }
@@ -216,7 +217,7 @@ public class SkeletonLoader extends DefaultHandler implements AssetLoader {
             rotations.clear();
             scales.clear();
         } else if (qName.equals("skeleton")) {
-            nameToBone.clear();
+            nameToJoint.clear();
         }
         assert elementStack.peek().equals(qName);
         elementStack.pop();
@@ -228,17 +229,17 @@ public class SkeletonLoader extends DefaultHandler implements AssetLoader {
      */
     private void fullReset() {
         elementStack.clear();
-        indexToBone.clear();
-        nameToBone.clear();
+        indexToJoint.clear();
+        nameToJoint.clear();
         track = null;
         tracks.clear();
-        animation = null;
-        if (animations != null) {
-            animations.clear();
+        animClip = null;
+        if (animClips != null) {
+            animClips.clear();
         }
 
-        bone = null;
-        skeleton = null;
+        joint = null;
+        armature = null;
         times.clear();
         rotations.clear();
         translations.clear();
@@ -266,12 +267,12 @@ public class SkeletonLoader extends DefaultHandler implements AssetLoader {
             xr.setErrorHandler(this);
             InputStreamReader r = new InputStreamReader(in);
             xr.parse(new InputSource(r));
-            if (animations == null) {
-                animations = new ArrayList<Animation>();
+            if (animClips == null) {
+                animClips = new ArrayList<AnimClip>();
             }
-            AnimData data = new AnimData(skeleton, animations);
-            skeleton = null;
-            animations = null;
+            AnimData data = new AnimData(armature, animClips);
+            armature = null;
+            animClips = null;
             return data;
         } catch (SAXException ex) {
             IOException ioEx = new IOException("Error while parsing Ogre3D dotScene");
@@ -288,7 +289,7 @@ public class SkeletonLoader extends DefaultHandler implements AssetLoader {
     }
 
     public Object load(AssetInfo info) throws IOException {
-        assetManager = info.getManager();
+        //AssetManager assetManager = info.getManager();
         InputStream in = null;
         try {
             in = info.openStream();

BIN
jme3-testdata/src/main/resources/Models/Oto/OtoOldAnim.j3o


BIN
jme3-testdata/src/main/resources/Models/Sinbad/SinbadOldAnim.j3o