From c407296ccbdae555b72730757ec07e8ec506f6e8 Mon Sep 17 00:00:00 2001 From: "rem..om" Date: Fri, 29 Apr 2011 17:31:04 +0000 Subject: [PATCH] Ragdoll - made some clean up - started a draft javadoc git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7360 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../jme3/bullet/control/RagdollControl.java | 303 ++++++++++++------ .../test/jme3test/bullet/TestBoneRagdoll.java | 59 ++-- 2 files changed, 237 insertions(+), 125 deletions(-) diff --git a/engine/src/jbullet/com/jme3/bullet/control/RagdollControl.java b/engine/src/jbullet/com/jme3/bullet/control/RagdollControl.java index 8fc00fa66..77e9d7f7c 100644 --- a/engine/src/jbullet/com/jme3/bullet/control/RagdollControl.java +++ b/engine/src/jbullet/com/jme3/bullet/control/RagdollControl.java @@ -75,8 +75,34 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -/** - * +/**This control is still a WIP, use it at your own risk
+ * To use this control you need a model with an AnimControl and a SkeletonControl.
+ * This should be the case if you imported an animated model from Ogre or blender.
+ *

+ * This control creates collision shapes for each bones of the skeleton when you call spatial.addControl(ragdollControl). + *

+ *

+ *

+ *There are 2 behavior for this control : + *

+ *

+ * * @author Normen Hansen and Rémy Bouquet (Nehon) */ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener { @@ -97,14 +123,13 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener protected float blendStart = 0.0f; protected List listeners; protected float eventDispatchImpulseThreshold = 10; - protected float eventDiscardImpulseThreshold = 3; protected RagdollPreset preset = new HumanoidRagdollPreset(); protected List boneList = new LinkedList(); protected Vector3f modelPosition = new Vector3f(); protected Quaternion modelRotation = new Quaternion(); protected float rootMass = 15; protected float totalMass = 0; - protected boolean added=false; + protected boolean added = false; public RagdollControl() { } @@ -128,116 +153,144 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener } TempVars vars = TempVars.get(); assert vars.lock(); - Quaternion q2 = vars.quat1; - Quaternion q3 = vars.quat2; + Quaternion tmpRot1 = vars.quat1; + Quaternion tmpRot2 = vars.quat2; + //if the ragdoll has the control of the skeleton, we update each bone with its position in physic world space. if (control) { - - for (PhysicsBoneLink link : boneLinks.values()) { - Vector3f p = link.rigidBody.getMotionState().getWorldLocation(); Vector3f position = vars.vect1; + //retrieving bone position in physic world space + Vector3f p = link.rigidBody.getMotionState().getWorldLocation(); + //transforming this position with inverse transforms of the model targetModel.getWorldTransform().transformInverseVector(p, position); + //retrieving bone rotation in physic world space Quaternion q = link.rigidBody.getMotionState().getWorldRotationQuat(); - q2.set(q).multLocal(link.initalWorldRotation).normalizeLocal(); - q3.set(targetModel.getWorldRotation()).inverseLocal().mult(q2, q2); - q2.normalizeLocal(); + //multiplying this rotation by the initialWorld rotation of the bone, + //then transforming it with the inverse world rotation of the model + tmpRot1.set(q).multLocal(link.initalWorldRotation); + tmpRot2.set(targetModel.getWorldRotation()).inverseLocal().mult(tmpRot1, tmpRot1); + tmpRot1.normalizeLocal(); + + //if the bone is the root bone, we apply the physic's transform to the model, so its position and rotation are correctly updated if (link.bone.getParent() == null) { + //offsetting the physic's position/rotation by the root bone inverse model space position/rotaion modelPosition.set(p).subtractLocal(link.bone.getInitialPos()); - modelRotation.set(q).multLocal(link.bone.getInitialRot().inverse()); + modelRotation.set(q).multLocal(tmpRot2.set(link.bone.getInitialRot()).inverseLocal()); + + //applying transforms to the model targetModel.setLocalTranslation(modelPosition); targetModel.setLocalRotation(modelRotation); - link.bone.setUserControl(true); - link.bone.setUserTransformsWorld(position, q2); + + //Applying computed transforms to the bone + link.bone.setUserTransformsWorld(position, tmpRot1); } else { + //if boneList is empty, this means that every bone in the ragdoll has a collision shape, + //so we just update the bone position if (boneList.isEmpty()) { - link.bone.setUserControl(true); - link.bone.setUserTransformsWorld(position, q2); + link.bone.setUserTransformsWorld(position, tmpRot1); } else { - setTransform(link.bone, position, q2); + //boneList is not empty, this means some bones of the skeleton might not be associated with a collision shape. + //So we update them recusively + setTransform(link.bone, position, tmpRot1, false); } } } } else { - - + //the ragdoll does not have the controll, so the keyframed animation updates the physic position of the physic bonces for (PhysicsBoneLink link : boneLinks.values()) { - //the ragdoll does not control the skeleton - link.bone.setUserControl(false); + if (!link.rigidBody.isKinematic()) { link.rigidBody.setKinematic(true); } - if (blendedControl) { - - + Vector3f position = vars.vect1; - Vector3f position = vars.vect1.set(link.startBlendingPos); + //if blended control this means, keyframed animation is updating the skeleton, + //but to allow smooth transition, we blend this transformation with the saved position of the ragdoll + if (blendedControl) { Vector3f position2 = vars.vect2; + //initializing tmp vars with the start position/rotation of the ragdoll + position.set(link.startBlendingPos); + tmpRot1.set(link.startBlendingRot); - q2.set(link.startBlendingRot); - - q3.set(q2).slerp(link.bone.getModelSpaceRotation(), blendStart / blendTime); + //interpolating between ragdoll position/rotation and keyframed position/rotation + tmpRot2.set(tmpRot1).slerp(link.bone.getModelSpaceRotation(), blendStart / blendTime); position2.set(position).interpolate(link.bone.getModelSpacePosition(), blendStart / blendTime); - q2.set(q3); + tmpRot1.set(tmpRot2); position.set(position2); + + //updating bones transforms if (boneList.isEmpty()) { + //we ensure we have the control to update the bone link.bone.setUserControl(true); - link.bone.setUserTransformsWorld(position, q2); + link.bone.setUserTransformsWorld(position, tmpRot1); + //we give control back to the key framed animation. + link.bone.setUserControl(false); } else { - setTransform(link.bone, position, q2); + setTransform(link.bone, position, tmpRot1, true); } } - - - - - Vector3f position = vars.vect1; - Quaternion rotation = vars.quat1; - //computing position from rotation and scale targetModel.getWorldTransform().transformVector(link.bone.getModelSpacePosition(), position); //computing rotation - rotation.set(link.bone.getModelSpaceRotation()).multLocal(link.bone.getWorldBindInverseRotation()); - targetModel.getWorldRotation().mult(rotation, rotation); - rotation.normalize(); + tmpRot1.set(link.bone.getModelSpaceRotation()).multLocal(link.bone.getWorldBindInverseRotation()); + targetModel.getWorldRotation().mult(tmpRot1, tmpRot1); + tmpRot1.normalizeLocal(); + //updating physic location/rotation of the physic bone link.rigidBody.setPhysicsLocation(position); - link.rigidBody.setPhysicsRotation(rotation); + link.rigidBody.setPhysicsRotation(tmpRot1); } + + //time control for blending if (blendedControl) { blendStart += tpf; - if (blendStart > blendTime) { blendedControl = false; } } } - - assert vars.unlock(); } - private void setTransform(Bone bone, Vector3f pos, Quaternion rot) { - bone.setUserControl(true); + /** + * Updates a bone position and rotation. + * if the child bones are not in the bone list this means, they are not associated with a physic shape. + * So they have to be updated + * @param bone the bone + * @param pos the position + * @param rot the rotation + */ + private void setTransform(Bone bone, Vector3f pos, Quaternion rot, boolean restoreBoneControl) { + //we ensure that we have the control + if (restoreBoneControl) { + bone.setUserControl(true); + } + //we set te user transforms of the bone bone.setUserTransformsWorld(pos, rot); for (Bone childBone : bone.getChildren()) { + //each child bone that is not in the list is updated if (!boneList.contains(childBone.getName())) { Transform t = childBone.getCombinedTransform(pos, rot); - setTransform(childBone, t.getTranslation(), t.getRotation()); + setTransform(childBone, t.getTranslation(), t.getRotation(), restoreBoneControl); } } - bone.setUserControl(false); + //we give back the control to the keyframed animation + if (restoreBoneControl) { + bone.setUserControl(false); + } + } public Control cloneForSpatial(Spatial spatial) { @@ -285,7 +338,7 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener model.setLocalRotation(initRotation); model.setLocalScale(initScale); - logger.log(Level.INFO, "Create physics ragdoll for skeleton {0}", skeleton); + logger.log(Level.INFO, "Created physics ragdoll for skeleton {0}", skeleton); } public void addBoneName(String name) { @@ -405,29 +458,36 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener } private void addToPhysicsSpace() { - + if (baseRigidBody != null) { space.add(baseRigidBody); - added=true; + added = true; } for (Iterator it = boneLinks.values().iterator(); it.hasNext();) { PhysicsBoneLink physicsBoneLink = it.next(); if (physicsBoneLink.rigidBody != null) { space.add(physicsBoneLink.rigidBody); - added=true; + added = true; } } for (Iterator it = boneLinks.values().iterator(); it.hasNext();) { PhysicsBoneLink physicsBoneLink = it.next(); if (physicsBoneLink.joint != null) { space.add(physicsBoneLink.joint); - added=true; + added = true; } } - + } - private HullCollisionShape makeShape(PhysicsBoneLink link, Spatial model) { + /** + * Create a hull collision shape from linked vertices to this bone. + * + * @param link + * @param model + * @return + */ + protected HullCollisionShape makeShape(PhysicsBoneLink link, Spatial model) { Bone bone = link.bone; List boneIndices = null; if (boneList.isEmpty()) { @@ -437,12 +497,11 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener boneIndices = getBoneIndices(bone, skeleton); } - ArrayList points = new ArrayList(); if (model instanceof Geometry) { Geometry g = (Geometry) model; for (Integer index : boneIndices) { - points.addAll(getPoints(g.getMesh(), index, bone.getModelSpacePosition(), link)); + points.addAll(getPoints(g.getMesh(), index, bone.getModelSpacePosition())); } } else if (model instanceof Node) { Node node = (Node) model; @@ -450,7 +509,7 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener if (s instanceof Geometry) { Geometry g = (Geometry) s; for (Integer index : boneIndices) { - points.addAll(getPoints(g.getMesh(), index, bone.getModelSpacePosition(), link)); + points.addAll(getPoints(g.getMesh(), index, bone.getModelSpacePosition())); } } @@ -464,7 +523,8 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener return new HullCollisionShape(p); } - private List getBoneIndices(Bone bone, Skeleton skeleton) { + //retruns the list of bone indices of the given bone and its child(if they are not in the boneList) + protected List getBoneIndices(Bone bone, Skeleton skeleton) { List list = new LinkedList(); list.add(skeleton.getBoneIndex(bone)); for (Bone chilBone : bone.getChildren()) { @@ -475,7 +535,15 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener return list; } - protected List getPoints(Mesh mesh, int boneIndex, Vector3f offset, PhysicsBoneLink link) { + /** + * returns a list of points for the given bone + * @param mesh + * @param boneIndex + * @param offset + * @param link + * @return + */ + private List getPoints(Mesh mesh, int boneIndex, Vector3f offset) { FloatBuffer vertices = mesh.getFloatBuffer(Type.Position); ByteBuffer boneIndices = (ByteBuffer) mesh.getBuffer(Type.BoneIndex).getData(); @@ -516,8 +584,8 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener return results; } - private void removeFromPhysicsSpace() { - + protected void removeFromPhysicsSpace() { + if (baseRigidBody != null) { space.remove(baseRigidBody); } @@ -533,9 +601,15 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener space.remove(physicsBoneLink.rigidBody); } } - added=false; + added = false; } + /** + * enable or disable the control + * note that if enabled is true and that the physic space has been set on the ragdoll, the ragdoll is added to the physic space + * if enabled is false the ragdoll is removed from physic space. + * @param enabled + */ public void setEnabled(boolean enabled) { if (this.enabled == enabled) { return; @@ -548,11 +622,15 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener } } + /** + * returns true if the control is enabled + * @return + */ public boolean isEnabled() { return enabled; } - public void attachDebugShape(AssetManager manager) { + protected void attachDebugShape(AssetManager manager) { for (Iterator it = boneLinks.values().iterator(); it.hasNext();) { PhysicsBoneLink physicsBoneLink = it.next(); physicsBoneLink.rigidBody.createDebugShape(manager); @@ -560,7 +638,7 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener debug = true; } - public void detachDebugShape() { + protected void detachDebugShape() { for (Iterator it = boneLinks.values().iterator(); it.hasNext();) { PhysicsBoneLink physicsBoneLink = it.next(); physicsBoneLink.rigidBody.detachDebugShape(); @@ -568,6 +646,12 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener debug = false; } + /** + * For internal use only + * specific render for the ragdoll(if debugging) + * @param rm + * @param vp + */ public void render(RenderManager rm, ViewPort vp) { if (enabled && space != null && space.getDebugManager() != null) { if (!debug) { @@ -586,6 +670,10 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener } } + /** + * set the physic space to this ragdoll + * @param space + */ public void setPhysicsSpace(PhysicsSpace space) { if (space == null) { removeFromPhysicsSpace(); @@ -600,27 +688,48 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener this.space.addCollisionListener(this); } + /** + * returns the physic space + * @return + */ public PhysicsSpace getPhysicsSpace() { return space; } + /** + * serialize this control + * @param ex + * @throws IOException + */ public void write(JmeExporter ex) throws IOException { throw new UnsupportedOperationException("Not supported yet."); } + /** + * de-serialize this control + * @param im + * @throws IOException + */ public void read(JmeImporter im) throws IOException { throw new UnsupportedOperationException("Not supported yet."); } + /** + * For internal use only + * callback for collisionevent + * @param event + */ public void collision(PhysicsCollisionEvent event) { PhysicsCollisionObject objA = event.getObjectA(); PhysicsCollisionObject objB = event.getObjectB(); + //excluding collisions that do not involve the ragdoll if (event.getNodeA() == null && event.getNodeB() == null) { return; } - if (event.getAppliedImpulse() < eventDiscardImpulseThreshold) { + //discarding low impulse collision + if (event.getAppliedImpulse() < eventDispatchImpulseThreshold) { return; } @@ -628,7 +737,7 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener Bone hitBone = null; PhysicsCollisionObject hitObject = null; - + //Computing which bone has been hit if (objA.getUserObject() instanceof PhysicsBoneLink) { PhysicsBoneLink link = (PhysicsBoneLink) objA.getUserObject(); if (link != null) { @@ -648,7 +757,8 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener } } - if (hit && event.getAppliedImpulse() > eventDispatchImpulseThreshold) { + //dispatching the event if the ragdoll has been hit + if (hit) { for (RagdollCollisionListener listener : listeners) { listener.collide(hitBone, hitObject, event); } @@ -656,26 +766,38 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener } - public void setControl(boolean control) { + /** + * Enable or disable the ragdoll behaviour. + * if ragdollEnabled is true, the character motion will only be powerd by physics + * else, the characted will be animated by the keyframe animation, + * but will be able to physically interact with its physic environnement + * @param ragdollEnabled + */ + public void setRagdollEnabled(boolean ragdollEnabled) { AnimControl animControl = targetModel.getControl(AnimControl.class); - animControl.setEnabled(!control); + animControl.setEnabled(!ragdollEnabled); - this.control = control; + this.control = ragdollEnabled; for (PhysicsBoneLink link : boneLinks.values()) { - // link.bone.setUserControl(control); - link.rigidBody.setKinematic(!control); + link.rigidBody.setKinematic(!ragdollEnabled); } - for (Bone bone : skeleton.getRoots()) { - setUserControl(bone, control); + setUserControl(bone, ragdollEnabled); } - } - public void blendControlToAnim(String anim, AnimChannel channel) { + /** + * Blend motion between the ragdoll actual physic state to the given animation, in the given blendTime + * Note that this disable the ragdoll behaviour of the control + * @param anim the animation name to blend to + * @param channel the channel to use for this animation + * @param blendTime the blending time between ragdoll to anim. + */ + public void blendRagdollToAnim(String anim, AnimChannel channel, float blendTime) { blendedControl = true; + this.blendTime = blendTime; control = false; AnimControl animControl = targetModel.getControl(AnimControl.class); animControl.setEnabled(true); @@ -696,9 +818,9 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener Quaternion q2 = vars.quat1; Quaternion q3 = vars.quat2; - q2.set(q).multLocal(link.initalWorldRotation).normalize(); + q2.set(q).multLocal(link.initalWorldRotation).normalizeLocal(); q3.set(targetModel.getWorldRotation()).inverseLocal().mult(q2, q2); - q2.normalize(); + q2.normalizeLocal(); link.startBlendingPos.set(position); link.startBlendingRot.set(q2); link.rigidBody.setKinematic(true); @@ -719,12 +841,19 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener } } - public boolean hasControl() { - + /** + * returns true if the ragdoll behaviour is enabled + * @return + */ + public boolean isRagdollEnabled() { return control; } + /** + * add a + * @param listener + */ public void addCollisionListener(RagdollCollisionListener listener) { if (listeners == null) { listeners = new ArrayList(); @@ -760,14 +889,6 @@ public class RagdollControl implements PhysicsControl, PhysicsCollisionListener this.weightThreshold = weightThreshold; } - public float getEventDiscardImpulseThreshold() { - return eventDiscardImpulseThreshold; - } - - public void setEventDiscardImpulseThreshold(float eventDiscardImpulseThreshold) { - this.eventDiscardImpulseThreshold = eventDiscardImpulseThreshold; - } - public float getEventDispatchImpulseThreshold() { return eventDispatchImpulseThreshold; } diff --git a/engine/src/test/jme3test/bullet/TestBoneRagdoll.java b/engine/src/test/jme3test/bullet/TestBoneRagdoll.java index 4efc0938f..0be1091a6 100644 --- a/engine/src/test/jme3test/bullet/TestBoneRagdoll.java +++ b/engine/src/test/jme3test/bullet/TestBoneRagdoll.java @@ -46,20 +46,16 @@ import com.jme3.bullet.collision.RagdollCollisionListener; import com.jme3.bullet.collision.shapes.SphereCollisionShape; import com.jme3.bullet.control.RagdollControl; import com.jme3.bullet.control.RigidBodyControl; -import com.jme3.bullet.joints.SixDofJoint; 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.MouseAxisTrigger; import com.jme3.input.controls.MouseButtonTrigger; -import com.jme3.light.AmbientLight; import com.jme3.light.DirectionalLight; import com.jme3.material.Material; import com.jme3.math.ColorRGBA; import com.jme3.math.FastMath; -import com.jme3.math.Matrix3f; import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; import com.jme3.scene.Geometry; @@ -73,7 +69,7 @@ import com.jme3.texture.Texture; * PHYSICS RAGDOLLS ARE NOT WORKING PROPERLY YET! * @author normenhansen */ -public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisionListener, AnimEventListener{ +public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisionListener, AnimEventListener { private BulletAppState bulletAppState; Material matBullet; @@ -131,8 +127,8 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi float eighth_pi = FastMath.PI * 0.125f; ragdoll.setJointLimit("Waist", eighth_pi, eighth_pi, eighth_pi, eighth_pi, eighth_pi, eighth_pi); ragdoll.setJointLimit("Chest", eighth_pi, eighth_pi, 0, 0, eighth_pi, eighth_pi); - - + + //Oto's head is almost rigid // ragdoll.setJointLimit("head", 0, 0, eighth_pi, -eighth_pi, 0, 0); @@ -152,21 +148,21 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi public void onAction(String name, boolean isPressed, float tpf) { if (name.equals("toggle") && isPressed) { - - Vector3f v=new Vector3f(); + + Vector3f v = new Vector3f(); v.set(model.getLocalTranslation()); - v.y=0; + v.y = 0; model.setLocalTranslation(v); - Quaternion q=new Quaternion(); - float[] angles=new float[3]; + Quaternion q = new Quaternion(); + float[] angles = new float[3]; model.getLocalRotation().toAngles(angles); - q.fromAngleAxis(angles[1], Vector3f.UNIT_Y); + q.fromAngleAxis(angles[1], Vector3f.UNIT_Y); //q.lookAt(model.getLocalRotation().toRotationMatrix().getColumn(2), Vector3f.UNIT_Y); - model.setLocalRotation(q); - if(angles[0]<0){ - ragdoll.blendControlToAnim("StandUpBack",animChannel); - }else{ - ragdoll.blendControlToAnim("StandUpFront",animChannel); + model.setLocalRotation(q); + if (angles[0] < 0) { + ragdoll.blendRagdollToAnim("StandUpBack", animChannel, 1); + } else { + ragdoll.blendRagdollToAnim("StandUpFront", animChannel, 1); } } @@ -190,7 +186,7 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi bulletg.setMaterial(matBullet); bulletg.setLocalTranslation(cam.getLocation()); bulletg.setLocalScale(bulletSize); - bulletCollisionShape = new SphereCollisionShape(bulletSize); + bulletCollisionShape = new SphereCollisionShape(bulletSize); RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, bulletSize * 10); bulletNode.setCcdMotionThreshold(0.001f); bulletNode.setLinearVelocity(cam.getDirection().mult(80)); @@ -206,7 +202,7 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi bulletCollisionShape = new SphereCollisionShape(bulletSize); BombControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1); bulletNode.setForceFactor(10); - bulletNode.setExplosionRadius(30); + bulletNode.setExplosionRadius(30); bulletNode.setCcdMotionThreshold(0.001f); bulletNode.setLinearVelocity(cam.getDirection().mult(180)); bulletg.addControl(bulletNode); @@ -214,7 +210,7 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi getPhysicsSpace().add(bulletNode); } } - }, "toggle", "shoot", "stop", "bullet+", "bullet-","boom"); + }, "toggle", "shoot", "stop", "bullet+", "bullet-", "boom"); inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); inputManager.addMapping("boom", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT)); @@ -226,7 +222,7 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi } private void setupLight() { - // AmbientLight al = new AmbientLight(); + // AmbientLight al = new AmbientLight(); // al.setColor(ColorRGBA.White.mult(1)); // rootNode.addLight(al); @@ -260,7 +256,7 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi guiNode.attachChild(ch); } - public void collide(Bone bone, PhysicsCollisionObject object,PhysicsCollisionEvent event) { + public void collide(Bone bone, PhysicsCollisionObject object, PhysicsCollisionEvent event) { if (object.getUserObject() != null && object.getUserObject() instanceof Geometry) { Geometry geom = (Geometry) object.getUserObject(); @@ -269,10 +265,8 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi } } - - if (!ragdoll.hasControl()) { - - ragdoll.setControl(true); + if (!ragdoll.isRagdollEnabled()) { + ragdoll.setRagdollEnabled(true); } } @@ -300,10 +294,8 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi ragdoll.addBoneName("Clavicle.R"); } - float elTime = 0; boolean forward = true; - AnimControl animControl; AnimChannel animChannel; Vector3f direction = new Vector3f(0, 0, 1); @@ -353,19 +345,18 @@ public class TestBoneRagdoll extends SimpleApplication implements RagdollCollisi // if(channel.getAnimationName().equals("StandUpFront")){ // channel.setAnim("Dance"); // } - - if(channel.getAnimationName().equals("StandUpBack") || channel.getAnimationName().equals("StandUpFront")){ + + if (channel.getAnimationName().equals("StandUpBack") || channel.getAnimationName().equals("StandUpFront")) { channel.setLoopMode(LoopMode.DontLoop); - channel.setAnim("IdleTop",5); + channel.setAnim("IdleTop", 5); channel.setLoopMode(LoopMode.Loop); } // if(channel.getAnimationName().equals("IdleTop")){ // channel.setAnim("StandUpFront"); // } - + } public void onAnimChange(AnimControl control, AnimChannel channel, String animName) { - } }