diff --git a/engine/src/jbullet/com/jme3/bullet/control/RagdollControl.java b/engine/src/jbullet/com/jme3/bullet/control/RagdollControl.java index 4518e2506..86cb2d4b6 100644 --- a/engine/src/jbullet/com/jme3/bullet/control/RagdollControl.java +++ b/engine/src/jbullet/com/jme3/bullet/control/RagdollControl.java @@ -6,6 +6,10 @@ import com.jme3.animation.Skeleton; import com.jme3.animation.SkeletonControl; import com.jme3.asset.AssetManager; import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.collision.PhysicsCollisionEvent; +import com.jme3.bullet.collision.PhysicsCollisionGroupListener; +import com.jme3.bullet.collision.PhysicsCollisionListener; +import com.jme3.bullet.collision.PhysicsCollisionObject; import com.jme3.bullet.collision.shapes.BoxCollisionShape; import com.jme3.bullet.collision.shapes.HullCollisionShape; import com.jme3.bullet.joints.ConeJoint; @@ -36,7 +40,7 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -public class RagdollControl implements PhysicsControl { +public class RagdollControl implements PhysicsControl, PhysicsCollisionListener { protected static final Logger logger = Logger.getLogger(RagdollControl.class.getName()); protected List boneLinks = new LinkedList(); @@ -51,6 +55,7 @@ public class RagdollControl implements PhysicsControl { protected Vector3f initPosition; protected Quaternion initRotation; protected Vector3f initScale; + protected boolean control = false; //Normen: Think you have the system you want, with movement //Normen: but the rootBone movement and translation is also accessible like getRootBoneLocation() @@ -73,12 +78,13 @@ public class RagdollControl implements PhysicsControl { if (!enabled) { return; } - - TempVars vars = TempVars.get(); - assert vars.lock(); - Quaternion q2 = vars.quat1; - // skeleton.reset(); - for (PhysicsBoneLink link : boneLinks) { + TempVars vars = TempVars.get(); + assert vars.lock(); + if (control) { + + Quaternion q2 = vars.quat1; + // skeleton.reset(); + for (PhysicsBoneLink link : boneLinks) { // if(link.bone==skeleton.getRoots()[0]){ // Vector3f loc=vars.vect1; @@ -86,18 +92,31 @@ public class RagdollControl implements PhysicsControl { // ((Geometry)targetModel).setLocalTranslation(loc); // // } - Vector3f p = link.rigidBody.getMotionState().getWorldLocation(); - Quaternion q = link.rigidBody.getMotionState().getWorldRotationQuat(); + Vector3f p = link.rigidBody.getMotionState().getWorldLocation(); + Quaternion q = link.rigidBody.getMotionState().getWorldRotationQuat(); - q2.set(q).multLocal(link.initalWorldRotation).normalize(); + q2.set(q).multLocal(link.initalWorldRotation).normalize(); - link.bone.setUserTransformsWorld(p, q2); + link.bone.setUserTransformsWorld(p, q2); + } + }else{ + for (PhysicsBoneLink link : boneLinks) { + + Vector3f position = vars.vect1; + Quaternion rotation = vars.quat1; + Vector3f scale= vars.vect2; + + position.set(link.bone.getModelSpacePosition()); + rotation.set(link.bone.getModelSpaceRotation()).multLocal(link.bone.getWorldBindInverseRotation()); + scale.set(link.bone.getModelSpaceScale()); + link.rigidBody.setPhysicsLocation(position); + link.rigidBody.setPhysicsRotation(rotation); + } } assert vars.unlock(); - //baseRigidBody.getMotionState().applyTransform(targetModel); } @@ -108,7 +127,7 @@ public class RagdollControl implements PhysicsControl { public void setSpatial(Spatial model) { targetModel = model; - + //HACK ALERT change this //I remove the skeletonControl and readd it to the spatial to make sure it's after the ragdollControl in the stack //Find a proper way to order the controls. @@ -116,7 +135,7 @@ public class RagdollControl implements PhysicsControl { model.removeControl(sc); model.addControl(sc); //---- - + removeFromPhysicsSpace(); clearData(); // put into bind pose and compute bone transforms in model space @@ -131,7 +150,7 @@ public class RagdollControl implements PhysicsControl { } private void scanSpatial(Spatial model) { - AnimControl animControl = model.getControl(AnimControl.class); + AnimControl animControl = model.getControl(AnimControl.class); initPosition = model.getLocalTranslation(); initRotation = model.getLocalRotation(); @@ -144,11 +163,11 @@ public class RagdollControl implements PhysicsControl { childBone.setUserControl(true); if (childBone.getParent() == null) { Vector3f parentPos = childBone.getModelSpacePosition().add(initPosition); - // Quaternion parentRot= childBone.getModelSpaceRotation().mult(initRotation); + // Quaternion parentRot= childBone.getModelSpaceRotation().mult(initRotation); logger.log(Level.INFO, "Found root bone in skeleton {0}", skeleton); baseRigidBody = new PhysicsRigidBody(new BoxCollisionShape(Vector3f.UNIT_XYZ.mult(.1f)), 1); baseRigidBody.setPhysicsLocation(parentPos); - // baseRigidBody.setPhysicsRotation(parentRot); + // baseRigidBody.setPhysicsRotation(parentRot); boneLinks = boneRecursion(model, childBone, baseRigidBody, boneLinks, 1); return; } @@ -168,12 +187,13 @@ public class RagdollControl implements PhysicsControl { //get world space position of the bone Vector3f pos = bone.getModelSpacePosition().add(model.getLocalTranslation()); - Quaternion rot= bone.getModelSpaceRotation().mult(initRotation); + Quaternion rot = bone.getModelSpaceRotation().mult(initRotation); //creating the collision shape from the bone's associated vertices PhysicsRigidBody shapeNode = new PhysicsRigidBody(makeShape(bone, model), 10.0f / (float) reccount); shapeNode.setPhysicsLocation(pos); - // shapeNode.setPhysicsRotation(rot); + + // shapeNode.setPhysicsRotation(rot); PhysicsBoneLink link = new PhysicsBoneLink(); link.bone = bone; @@ -369,6 +389,7 @@ public class RagdollControl implements PhysicsControl { this.space = space; addToPhysicsSpace(); } + this.space.addCollisionListener(this); } public PhysicsSpace getPhysicsSpace() { @@ -383,6 +404,62 @@ public class RagdollControl implements PhysicsControl { throw new UnsupportedOperationException("Not supported yet."); } + public void collision(PhysicsCollisionEvent event) { + PhysicsCollisionObject objA = event.getObjectA(); + PhysicsCollisionObject objB = event.getObjectB(); +// System.out.println("----------------------------"); +// System.out.println("NodeA "+event.getNodeA()); +// System.out.println("NodeB "+event.getNodeB()); + if (event == null) { + return; + } + if (event.getNodeA() != null && "Floor".equals(event.getNodeA().getName())) { + return; + } + if (event.getNodeB() != null && "Floor".equals(event.getNodeB().getName())) { + return; + } +// if(event.getNodeB() == null && event.getNodeA() ==null){ +// return; +// } + if (event.getAppliedImpulse() < 3.0) { + return; + } + + boolean hit = false; + + + + if (objA instanceof PhysicsRigidBody) { + PhysicsRigidBody prb = (PhysicsRigidBody) objA; + for (PhysicsBoneLink physicsBoneLink : boneLinks) { + if (physicsBoneLink.rigidBody == prb) { + hit = true; + // System.out.println("objA " + physicsBoneLink.bone.getName() + " " + event.getAppliedImpulse() + " " + event.getAppliedImpulseLateral1() + " " + event.getAppliedImpulseLateral2()); + + } + } + } + if (objB instanceof PhysicsRigidBody) { + PhysicsRigidBody prb = (PhysicsRigidBody) objB; + for (PhysicsBoneLink physicsBoneLink : boneLinks) { + if (physicsBoneLink.rigidBody == prb) { + hit = false; + // System.out.println("objB " + physicsBoneLink.bone.getName() + " " + event.getAppliedImpulse() + " " + event.getAppliedImpulseLateral1() + " " + event.getAppliedImpulseLateral2()); + } + } + } + if (hit && event.getAppliedImpulse() > 10.0) { + control = true; + } + + // System.out.println("----------------------------"); + } + + public boolean collide(PhysicsCollisionObject nodeA, PhysicsCollisionObject nodeB) { + throw new UnsupportedOperationException("Not supported yet."); + } + protected static class PhysicsBoneLink { Bone bone; diff --git a/engine/src/test/jme3test/bullet/TestBoneRagdoll.java b/engine/src/test/jme3test/bullet/TestBoneRagdoll.java index 41b7970f7..71de2e951 100644 --- a/engine/src/test/jme3test/bullet/TestBoneRagdoll.java +++ b/engine/src/test/jme3test/bullet/TestBoneRagdoll.java @@ -79,10 +79,15 @@ public class TestBoneRagdoll extends SimpleApplication { public void simpleInitApp() { initCrossHairs(); initMaterial(); + + cam.setLocation(new Vector3f(0.26924422f, 6.646658f, 22.265987f)); + cam.setRotation(new Quaternion(-2.302544E-4f, 0.99302495f, -0.117888905f, -0.0019395084f)); + + bulletAppState = new BulletAppState(); - bulletAppState.setEnabled(false); + bulletAppState.setEnabled(true); stateManager.attach(bulletAppState); - bulletAppState.getPhysicsSpace().enableDebug(assetManager); + // bulletAppState.getPhysicsSpace().enableDebug(assetManager); PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace()); setupLight(); @@ -98,7 +103,7 @@ public class TestBoneRagdoll extends SimpleApplication { mat2.getAdditionalRenderState().setDepthTest(false); skeletonDebug.setMaterial(mat2); skeletonDebug.setLocalTranslation(model.getLocalTranslation()); - control.createChannel().setAnim("Dodge"); + control.createChannel().setAnim("Walk"); //Note: PhysicsRagdollControl is still TODO, constructor will change RagdollControl ragdoll = new RagdollControl(); @@ -115,10 +120,11 @@ public class TestBoneRagdoll extends SimpleApplication { rootNode.attachChild(model); rootNode.attachChild(skeletonDebug); - flyCam.setEnabled(false); - // flyCam.setMoveSpeed(10); - ChaseCamera chaseCamera=new ChaseCamera(cam, inputManager); - model.addControl(chaseCamera); + // flyCam.setEnabled(false); + flyCam.setMoveSpeed(50); +// ChaseCamera chaseCamera=new ChaseCamera(cam, inputManager); +// chaseCamera.setLookAtOffset(Vector3f.UNIT_Y.mult(4)); +// model.addControl(chaseCamera); inputManager.addListener(new ActionListener() { @@ -130,9 +136,9 @@ public class TestBoneRagdoll extends SimpleApplication { Geometry bulletg = new Geometry("bullet", bullet); bulletg.setMaterial(matBullet); bulletg.setLocalTranslation(cam.getLocation()); - RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1); - // RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1); - bulletNode.setLinearVelocity(cam.getDirection().mult(60)); + // RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1); + RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 20); + bulletNode.setLinearVelocity(cam.getDirection().mult(80)); bulletg.addControl(bulletNode); rootNode.attachChild(bulletg); getPhysicsSpace().add(bulletNode);