Search in sources :

Example 51 with Bone

use of com.jme3.animation.Bone in project jmonkeyengine by jMonkeyEngine.

the class KinematicRagdollControl method collision.

/**
     * 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 involve 2 parts of the ragdoll
    if (event.getNodeA() == null && event.getNodeB() == null) {
        return;
    }
    //discarding low impulse collision
    if (event.getAppliedImpulse() < eventDispatchImpulseThreshold) {
        return;
    }
    boolean hit = false;
    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) {
            hit = true;
            hitBone = link.bone;
            hitObject = objB;
        }
    }
    if (objB.getUserObject() instanceof PhysicsBoneLink) {
        PhysicsBoneLink link = (PhysicsBoneLink) objB.getUserObject();
        if (link != null) {
            hit = true;
            hitBone = link.bone;
            hitObject = objA;
        }
    }
    //dispatching the event if the ragdoll has been hit
    if (hit && listeners != null) {
        for (RagdollCollisionListener listener : listeners) {
            listener.collide(hitBone, hitObject, event);
        }
    }
}
Also used : RagdollCollisionListener(com.jme3.bullet.collision.RagdollCollisionListener) Bone(com.jme3.animation.Bone) PhysicsCollisionObject(com.jme3.bullet.collision.PhysicsCollisionObject)

Example 52 with Bone

use of com.jme3.animation.Bone in project jmonkeyengine by jMonkeyEngine.

the class KinematicRagdollControl method ragDollUpdate.

protected void ragDollUpdate(float tpf) {
    TempVars vars = TempVars.get();
    Quaternion tmpRot1 = vars.quat1;
    Quaternion tmpRot2 = vars.quat2;
    for (PhysicsBoneLink link : boneLinks.values()) {
        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();
        //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.getBindPosition());
            targetModel.getParent().getWorldTransform().transformInverseVector(modelPosition, modelPosition);
            modelRotation.set(q).multLocal(tmpRot2.set(link.bone.getBindRotation()).inverseLocal());
            //applying transforms to the model
            targetModel.setLocalTranslation(modelPosition);
            targetModel.setLocalRotation(modelRotation);
            //Applying computed transforms to the bone
            link.bone.setUserTransformsInModelSpace(position, tmpRot1);
        } else {
            //so we just update the bone position
            if (boneList.isEmpty()) {
                link.bone.setUserTransformsInModelSpace(position, tmpRot1);
            } else {
                //boneList is not empty, this means some bones of the skeleton might not be associated with a collision shape.
                //So we update them recusively
                RagdollUtils.setTransform(link.bone, position, tmpRot1, false, boneList);
            }
        }
    }
    vars.release();
}
Also used : Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f) TempVars(com.jme3.util.TempVars)

Example 53 with Bone

use of com.jme3.animation.Bone in project jmonkeyengine by jMonkeyEngine.

the class KinematicRagdollControl method createSpatialData.

@Override
protected void createSpatialData(Spatial model) {
    targetModel = model;
    Node parent = model.getParent();
    Vector3f initPosition = model.getLocalTranslation().clone();
    Quaternion initRotation = model.getLocalRotation().clone();
    initScale = model.getLocalScale().clone();
    model.removeFromParent();
    model.setLocalTranslation(Vector3f.ZERO);
    model.setLocalRotation(Quaternion.IDENTITY);
    model.setLocalScale(1);
    //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.
    SkeletonControl sc = model.getControl(SkeletonControl.class);
    if (sc == null) {
        throw new IllegalArgumentException("The root node of the model should have a SkeletonControl. Make sure the control is there and that it's not on a sub node.");
    }
    model.removeControl(sc);
    model.addControl(sc);
    // put into bind pose and compute bone transforms in model space
    // maybe dont reset to ragdoll out of animations?
    scanSpatial(model);
    if (parent != null) {
        parent.attachChild(model);
    }
    model.setLocalTranslation(initPosition);
    model.setLocalRotation(initRotation);
    model.setLocalScale(initScale);
    if (added) {
        addPhysics(space);
    }
    logger.log(Level.FINE, "Created physics ragdoll for skeleton {0}", skeleton);
}
Also used : Quaternion(com.jme3.math.Quaternion) Node(com.jme3.scene.Node) Vector3f(com.jme3.math.Vector3f) SkeletonControl(com.jme3.animation.SkeletonControl)

Example 54 with Bone

use of com.jme3.animation.Bone in project jmonkeyengine by jMonkeyEngine.

the class KinematicRagdollControl method updateBone.

public void updateBone(PhysicsBoneLink link, float tpf, TempVars vars, Quaternion tmpRot1, Quaternion[] tmpRot2, Bone tipBone, Vector3f target, int depth, int maxDepth) {
    if (link == null || link.bone.getParent() == null) {
        return;
    }
    Quaternion preQuat = link.bone.getLocalRotation();
    Vector3f vectorAxis;
    float[] measureDist = new float[] { Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY };
    for (int dirIndex = 0; dirIndex < 3; dirIndex++) {
        if (dirIndex == 0) {
            vectorAxis = Vector3f.UNIT_Z;
        } else if (dirIndex == 1) {
            vectorAxis = Vector3f.UNIT_X;
        } else {
            vectorAxis = Vector3f.UNIT_Y;
        }
        for (int posOrNeg = 0; posOrNeg < 2; posOrNeg++) {
            float rot = ikRotSpeed * tpf / (link.rigidBody.getMass() * 2);
            rot = FastMath.clamp(rot, link.joint.getRotationalLimitMotor(dirIndex).getLoLimit(), link.joint.getRotationalLimitMotor(dirIndex).getHiLimit());
            tmpRot1.fromAngleAxis(rot, vectorAxis);
            //                tmpRot1.fromAngleAxis(rotSpeed * tpf / (link.rigidBody.getMass() * 2), vectorAxis);
            tmpRot2[posOrNeg] = link.bone.getLocalRotation().mult(tmpRot1);
            tmpRot2[posOrNeg].normalizeLocal();
            ikRotSpeed = -ikRotSpeed;
            link.bone.setLocalRotation(tmpRot2[posOrNeg]);
            link.bone.update();
            measureDist[posOrNeg] = tipBone.getModelSpacePosition().distance(target);
            link.bone.setLocalRotation(preQuat);
        }
        if (measureDist[0] < measureDist[1]) {
            link.bone.setLocalRotation(tmpRot2[0]);
        } else if (measureDist[0] > measureDist[1]) {
            link.bone.setLocalRotation(tmpRot2[1]);
        }
    }
    link.bone.getLocalRotation().normalizeLocal();
    link.bone.update();
    //        link.usedbyIK = true;
    if (link.bone.getParent() != null && depth < maxDepth) {
        updateBone(boneLinks.get(link.bone.getParent().getName()), tpf * limbDampening, vars, tmpRot1, tmpRot2, tipBone, target, depth + 1, maxDepth);
    }
}
Also used : Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f) SixDofJoint(com.jme3.bullet.joints.SixDofJoint)

Example 55 with Bone

use of com.jme3.animation.Bone in project jmonkeyengine by jMonkeyEngine.

the class KinematicRagdollControl method scanSpatial.

protected void scanSpatial(Spatial model) {
    AnimControl animControl = model.getControl(AnimControl.class);
    Map<Integer, List<Float>> pointsMap = null;
    if (weightThreshold == -1.0f) {
        pointsMap = RagdollUtils.buildPointMap(model);
    }
    skeleton = animControl.getSkeleton();
    skeleton.resetAndUpdate();
    for (int i = 0; i < skeleton.getRoots().length; i++) {
        Bone childBone = skeleton.getRoots()[i];
        if (childBone.getParent() == null) {
            logger.log(Level.FINE, "Found root bone in skeleton {0}", skeleton);
            boneRecursion(model, childBone, baseRigidBody, 1, pointsMap);
        }
    }
}
Also used : Bone(com.jme3.animation.Bone) AnimControl(com.jme3.animation.AnimControl) SixDofJoint(com.jme3.bullet.joints.SixDofJoint)

Aggregations

Bone (com.jme3.animation.Bone)35 Vector3f (com.jme3.math.Vector3f)25 Quaternion (com.jme3.math.Quaternion)17 TempVars (com.jme3.util.TempVars)13 SixDofJoint (com.jme3.bullet.joints.SixDofJoint)10 FloatBuffer (java.nio.FloatBuffer)10 VertexBuffer (com.jme3.scene.VertexBuffer)8 HashMap (java.util.HashMap)8 Skeleton (com.jme3.animation.Skeleton)7 Matrix4f (com.jme3.math.Matrix4f)7 Transform (com.jme3.math.Transform)7 BoneContext (com.jme3.scene.plugins.blender.animations.BoneContext)7 ByteBuffer (java.nio.ByteBuffer)7 BoneTrack (com.jme3.animation.BoneTrack)6 Structure (com.jme3.scene.plugins.blender.file.Structure)6 ArrayList (java.util.ArrayList)6 AnimControl (com.jme3.animation.AnimControl)5 Spatial (com.jme3.scene.Spatial)5 Map (java.util.Map)5 Animation (com.jme3.animation.Animation)4