|
@@ -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 @@ import java.util.List;
|
|
|
* 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 @@ 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/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 @@ public class TestWalkingChar extends SimpleApplication implements ActionListener
|
|
|
}
|
|
|
|
|
|
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 class TestWalkingChar extends SimpleApplication implements ActionListener
|
|
|
} 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 class TestWalkingChar extends SimpleApplication implements ActionListener
|
|
|
}
|
|
|
|
|
|
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 class TestWalkingChar extends SimpleApplication implements ActionListener
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @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");
|
|
|
}
|
|
|
}
|