Ogre loader now loads animations and armature with the new system

shader-nodes-enhancement
Nehon 7 years ago committed by Rémy Bouquet
parent 02a1fd544a
commit d6b05553b5
  1. 28
      jme3-bullet/src/common/java/com/jme3/bullet/control/KinematicRagdollControl.java
  2. 24
      jme3-core/src/main/java/com/jme3/anim/util/AnimMigrationUtils.java
  3. 17
      jme3-core/src/main/java/com/jme3/cinematic/events/AnimationEvent.java
  4. 20
      jme3-examples/src/main/java/jme3test/animation/TestCinematic.java
  5. 16
      jme3-examples/src/main/java/jme3test/bullet/TestBoneRagdoll.java
  6. 12
      jme3-examples/src/main/java/jme3test/bullet/TestRagdollCharacter.java
  7. 16
      jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java
  8. 13
      jme3-examples/src/main/java/jme3test/export/TestOgreConvert.java
  9. 7
      jme3-examples/src/main/java/jme3test/helloworld/HelloAnimation.java
  10. 132
      jme3-examples/src/main/java/jme3test/model/anim/TestAnimBlendBug.java
  11. 7
      jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java
  12. 27
      jme3-examples/src/main/java/jme3test/model/anim/TestHWSkinning.java
  13. 21
      jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java
  14. 11
      jme3-examples/src/main/java/jme3test/model/anim/TestOgreAnim.java
  15. 13
      jme3-examples/src/main/java/jme3test/model/anim/TestOgreComplexAnim.java
  16. 13
      jme3-examples/src/main/java/jme3test/model/anim/TestSkeletonControlRefresh.java
  17. 17
      jme3-examples/src/main/java/jme3test/stress/TestLodGeneration.java
  18. 13
      jme3-plugins/src/ogre/java/com/jme3/scene/plugins/ogre/AnimData.java
  19. 60
      jme3-plugins/src/ogre/java/com/jme3/scene/plugins/ogre/MeshLoader.java
  20. 149
      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

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

@ -80,16 +80,7 @@ public class AnimMigrationUtils {
} }
for (int i = 0; i < staticJoints.length; i++) { for (int i = 0; i < staticJoints.length; i++) {
Joint j = staticJoints[i]; padJointTracks(clip, 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);
}
} }
composer.addAnimClip(clip); 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 { private static class SkeletonControlVisitor implements SceneGraphVisitor {
Map<Skeleton, Armature> skeletonArmatureMap; Map<Skeleton, Armature> skeletonArmatureMap;

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

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

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

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

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

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

@ -32,10 +32,7 @@
package jme3test.helloworld; package jme3test.helloworld;
import com.jme3.animation.AnimChannel; import com.jme3.animation.*;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput; import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener; import com.jme3.input.controls.ActionListener;
@ -70,7 +67,7 @@ public class HelloAnimation extends SimpleApplication
rootNode.addLight(dl); rootNode.addLight(dl);
/** Load a model that contains animation */ /** 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); player.setLocalScale(0.5f);
rootNode.attachChild(player); rootNode.attachChild(player);

@ -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);
}
}

@ -2,7 +2,6 @@ package jme3test.model.anim;
import com.jme3.anim.AnimComposer; import com.jme3.anim.AnimComposer;
import com.jme3.anim.SkinningControl; import com.jme3.anim.SkinningControl;
import com.jme3.anim.util.AnimMigrationUtils;
import com.jme3.app.ChaseCameraAppState; import com.jme3.app.ChaseCameraAppState;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput; 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 DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal()));
rootNode.addLight(new AmbientLight(ColorRGBA.DarkGray)); rootNode.addLight(new AmbientLight(ColorRGBA.DarkGray));
Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o"); //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/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/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); rootNode.attachChild(model);

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

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

@ -38,14 +38,11 @@ import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener; import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger; import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight; import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA; import com.jme3.math.*;
import com.jme3.math.Quaternion; import com.jme3.scene.*;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box; import com.jme3.scene.shape.Box;
//TODO rework this Test when the new animation system is done.
public class TestOgreAnim extends SimpleApplication public class TestOgreAnim extends SimpleApplication
implements AnimEventListener, ActionListener { implements AnimEventListener, ActionListener {
@ -69,7 +66,7 @@ public class TestOgreAnim extends SimpleApplication
dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
rootNode.addLight(dl); rootNode.addLight(dl);
Spatial model = (Spatial) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); Spatial model = (Spatial) assetManager.loadModel("Models/Oto/OtoOldAnim.j3o");
model.center(); model.center();
control = model.getControl(AnimControl.class); control = model.getControl(AnimControl.class);

@ -32,20 +32,15 @@
package jme3test.model.anim; package jme3test.model.anim;
import com.jme3.animation.AnimChannel; import com.jme3.animation.*;
import com.jme3.animation.AnimControl;
import com.jme3.animation.Bone;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.light.DirectionalLight; import com.jme3.light.DirectionalLight;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.ColorRGBA; import com.jme3.math.*;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node; import com.jme3.scene.Node;
import com.jme3.scene.debug.SkeletonDebugger; import com.jme3.scene.debug.SkeletonDebugger;
//TODO rework this Test when the new animation system is done.
public class TestOgreComplexAnim extends SimpleApplication { public class TestOgreComplexAnim extends SimpleApplication {
private AnimControl control; private AnimControl control;
@ -69,7 +64,7 @@ public class TestOgreComplexAnim extends SimpleApplication {
dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
rootNode.addLight(dl); 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); control = model.getControl(AnimControl.class);

@ -37,7 +37,6 @@ package jme3test.model.anim;
*/ */
import com.jme3.animation.*; import com.jme3.animation.*;
import com.jme3.app.SimpleApplication; import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey; import com.jme3.asset.TextureKey;
@ -47,11 +46,7 @@ import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger; import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight; import com.jme3.light.DirectionalLight;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.ColorRGBA; import com.jme3.math.*;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor; import com.jme3.post.FilterPostProcessor;
import com.jme3.post.ssao.SSAOFilter; import com.jme3.post.ssao.SSAOFilter;
import com.jme3.renderer.queue.RenderQueue; import com.jme3.renderer.queue.RenderQueue;
@ -59,11 +54,11 @@ import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Quad; import com.jme3.scene.shape.Quad;
import com.jme3.shadow.DirectionalLightShadowFilter; import com.jme3.shadow.DirectionalLightShadowFilter;
import com.jme3.shadow.DirectionalLightShadowRenderer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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{ public class TestSkeletonControlRefresh extends SimpleApplication implements ActionListener{
private AnimChannel channel; private AnimChannel channel;
@ -97,7 +92,7 @@ public class TestSkeletonControlRefresh extends SimpleApplication implements Act
for (int i = 0; i < SIZE; i++) { for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) { 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 //setting a different material
model.setMaterial(m.clone()); model.setMaterial(m.clone());
model.setLocalScale(0.1f); model.setLocalScale(0.1f);

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

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

@ -31,9 +31,7 @@
*/ */
package com.jme3.scene.plugins.ogre; package com.jme3.scene.plugins.ogre;
import com.jme3.animation.AnimControl; import com.jme3.anim.*;
import com.jme3.animation.Animation;
import com.jme3.animation.SkeletonControl;
import com.jme3.asset.*; import com.jme3.asset.*;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.material.MaterialList; 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;
import com.jme3.renderer.queue.RenderQueue.Bucket; import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.*; import com.jme3.scene.*;
import com.jme3.scene.VertexBuffer.Format; import com.jme3.scene.VertexBuffer.*;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.scene.VertexBuffer.Usage;
import com.jme3.scene.plugins.ogre.matext.OgreMaterialKey; import com.jme3.scene.plugins.ogre.matext.OgreMaterialKey;
import com.jme3.util.BufferUtils; import com.jme3.util.*;
import com.jme3.util.IntMap;
import com.jme3.util.IntMap.Entry; import com.jme3.util.IntMap.Entry;
import com.jme3.util.PlaceholderAssets; import org.xml.sax.*;
import static com.jme3.util.xml.SAXUtil.*; import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.*; import java.nio.*;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory; import static com.jme3.util.xml.SAXUtil.*;
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;
/** /**
* Loads Ogre3D mesh.xml files. * Loads Ogre3D mesh.xml files.
@ -799,35 +790,28 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
for (int i = 0; i < geoms.size(); i++) { for (int i = 0; i < geoms.size(); i++) {
Geometry g = geoms.get(i); Geometry g = geoms.get(i);
Mesh m = geoms.get(i).getMesh(); Mesh m = geoms.get(i).getMesh();
m.generateBindPose();
//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);
} }
// Put the animations in the AnimControl // Put the animations in the AnimControl
HashMap<String, Animation> anims = new HashMap<String, Animation>(); HashMap<String, AnimClip> anims = new HashMap<>();
ArrayList<Animation> animList = animData.anims; ArrayList<AnimClip> animList = animData.anims;
for (int i = 0; i < animList.size(); i++) { for (int i = 0; i < animList.size(); i++) {
Animation anim = animList.get(i); AnimClip anim = animList.get(i);
anims.put(anim.getName(), anim); anims.put(anim.getName(), anim);
} }
AnimControl ctrl = new AnimControl(animData.skeleton); AnimComposer composer = new AnimComposer();
ctrl.setAnimations(anims); for (AnimClip clip : anims.values()) {
model.addControl(ctrl); composer.addAnimClip(clip);
}
model.addControl(composer);
// Put the skeleton in the skeleton control // 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 // This will acquire the targets from the node
model.addControl(skeletonControl); model.addControl(skinningControl);
} }
return model; return model;

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

Loading…
Cancel
Save