From 15a3072583e1bcdcccb38974c6d3d79eebf4a055 Mon Sep 17 00:00:00 2001 From: Stephen Gold Date: Fri, 2 Apr 2021 16:36:18 -0700 Subject: [PATCH] convert TestWalkingChar to the new animation system --- .../java/jme3test/bullet/TestWalkingChar.java | 99 ++++++++++++------- 1 file changed, 66 insertions(+), 33 deletions(-) diff --git a/jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java b/jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java index 8321131404..a6ac04ff99 100644 --- a/jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java +++ b/jme3-examples/src/main/java/jme3test/bullet/TestWalkingChar.java @@ -31,7 +31,13 @@ */ package jme3test.bullet; -import com.jme3.animation.*; +import com.jme3.anim.AnimComposer; +import com.jme3.anim.Armature; +import com.jme3.anim.ArmatureMask; +import com.jme3.anim.SkinningControl; +import com.jme3.anim.tween.Tween; +import com.jme3.anim.tween.Tweens; +import com.jme3.anim.tween.action.Action; import com.jme3.app.SimpleApplication; import com.jme3.bullet.BulletAppState; import com.jme3.bullet.PhysicsSpace; @@ -75,7 +81,8 @@ * A walking animated character followed by a 3rd person camera on a terrain with LOD. * @author normenhansen */ -public class TestWalkingChar extends SimpleApplication implements ActionListener, PhysicsCollisionListener, AnimEventListener { +public class TestWalkingChar extends SimpleApplication + implements ActionListener, PhysicsCollisionListener { private BulletAppState bulletAppState; //character @@ -90,9 +97,9 @@ public class TestWalkingChar extends SimpleApplication implements ActionListener private Material matRock; private Material matBullet; //animation - private AnimChannel animationChannel; - private AnimChannel shootingChannel; - private AnimControl animationControl; + private Action standAction; + private Action walkAction; + private AnimComposer composer; private float airTime = 0; //camera private boolean left = false, right = false, up = false, down = false; @@ -289,8 +296,7 @@ private void createTerrain() { private void createCharacter() { CapsuleCollisionShape capsule = new CapsuleCollisionShape(3f, 4f); character = new CharacterControl(capsule, 0.01f); - model = (Node) assetManager.loadModel("Models/Oto/OtoOldAnim.j3o"); - //model.setLocalScale(0.5f); + model = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); model.addControl(character); character.setPhysicsLocation(new Vector3f(-140, 40, -10)); rootNode.attachChild(model); @@ -303,13 +309,39 @@ private void setupChaseCamera() { } private void setupAnimationController() { - animationControl = model.getControl(AnimControl.class); - animationControl.addListener(this); - animationChannel = animationControl.createChannel(); - shootingChannel = animationControl.createChannel(); - shootingChannel.addBone(animationControl.getSkeleton().getBone("uparm.right")); - shootingChannel.addBone(animationControl.getSkeleton().getBone("arm.right")); - shootingChannel.addBone(animationControl.getSkeleton().getBone("hand.right")); + composer = model.getControl(AnimComposer.class); + standAction = composer.action("stand"); + walkAction = composer.action("Walk"); + /* + * Add a "shootOnce" animation action + * that performs the "Dodge" action one time only. + */ + Action dodgeAction = composer.action("Dodge"); + Tween doneTween = Tweens.callMethod(this, "onShootDone"); + composer.actionSequence("shootOnce", dodgeAction, doneTween); + /* + * Define a shooting animation layer + * that animates only the joints of the right arm. + */ + SkinningControl skinningControl + = model.getControl(SkinningControl.class); + Armature armature = skinningControl.getArmature(); + ArmatureMask shootingMask + = ArmatureMask.createMask(armature, "uparm.right"); + composer.makeLayer("shootingLayer", shootingMask); + /* + * Define a walking animation layer + * that animates all joints except those used for shooting. + */ + ArmatureMask walkingMask = new ArmatureMask(); + walkingMask.addBones(armature, "head", "spine", "spinehigh"); + walkingMask.addFromJoint(armature, "hip.left"); + walkingMask.addFromJoint(armature, "hip.right"); + walkingMask.addFromJoint(armature, "uparm.left"); + composer.makeLayer("walkingLayer", walkingMask); + + composer.setCurrentAction("stand", "shootingLayer"); + composer.setCurrentAction("stand", "walkingLayer"); } @Override @@ -336,18 +368,20 @@ public void simpleUpdate(float tpf) { } else { airTime = 0; } - if (walkDirection.length() == 0) { - if (!"stand".equals(animationChannel.getAnimationName())) { - animationChannel.setAnim("stand", 1f); + + Action action = composer.getCurrentAction("walkingLayer"); + if (walkDirection.length() == 0f) { + if (action != standAction) { + composer.setCurrentAction("stand", "walkingLayer"); } } else { character.setViewDirection(walkDirection); - if (airTime > .3f) { - if (!"stand".equals(animationChannel.getAnimationName())) { - animationChannel.setAnim("stand"); + if (airTime > 0.3f) { + if (action != standAction) { + composer.setCurrentAction("stand", "walkingLayer"); } - } else if (!"Walk".equals(animationChannel.getAnimationName())) { - animationChannel.setAnim("Walk", 0.7f); + } else if (action != walkAction) { + composer.setCurrentAction("Walk", "walkingLayer"); } } character.setWalkDirection(walkDirection); @@ -387,8 +421,8 @@ public void onAction(String binding, boolean value, float tpf) { } private void bulletControl() { - shootingChannel.setAnim("Dodge", 0.1f); - shootingChannel.setLoopMode(LoopMode.DontLoop); + composer.setCurrentAction("shootOnce", "shootingLayer"); + Geometry bulletg = new Geometry("bullet", bullet); bulletg.setMaterial(matBullet); bulletg.setShadowMode(ShadowMode.CastAndReceive); @@ -416,14 +450,13 @@ public void collision(PhysicsCollisionEvent event) { } } - @Override - public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) { - if (channel == shootingChannel) { - channel.setAnim("stand"); - } - } - - @Override - public void onAnimChange(AnimControl control, AnimChannel channel, String animName) { + /** + * Callback to indicate that the "shootOnce" animation action has completed. + */ + void onShootDone() { + /** + * Play the "stand" animation action on the shooting layer. + */ + composer.setCurrentAction("stand", "shootingLayer"); } }