Search in sources :

Example 11 with Skeleton

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

the class ConstraintHelper method applyTransform.

/**
     * Applies transform to a feature (bone or spatial). Computations transform
     * the given transformation from the given space to the feature's local
     * space.
     * 
     * @param oma
     *            the OMA of the feature we apply transformation to
     * @param subtargetName
     *            the name of the feature's subtarget (bone in case of armature)
     * @param space
     *            the space in which the given transform is to be applied
     * @param transform
     *            the transform we apply
     */
public void applyTransform(Long oma, String subtargetName, Space space, Transform transform) {
    Spatial feature = (Spatial) blenderContext.getLoadedFeature(oma, LoadedDataType.FEATURE);
    boolean isArmature = blenderContext.getMarkerValue(ObjectHelper.ARMATURE_NODE_MARKER, feature) != null;
    if (isArmature) {
        Skeleton skeleton = blenderContext.getSkeleton(oma);
        BoneContext targetBoneContext = blenderContext.getBoneByName(oma, subtargetName);
        Bone bone = targetBoneContext.getBone();
        if (bone.getParent() == null && (space == Space.CONSTRAINT_SPACE_LOCAL || space == Space.CONSTRAINT_SPACE_PARLOCAL)) {
            space = Space.CONSTRAINT_SPACE_POSE;
        }
        TempVars tempVars = TempVars.get();
        switch(space) {
            case CONSTRAINT_SPACE_LOCAL:
                assert bone.getParent() != null : "CONSTRAINT_SPACE_LOCAL should be evaluated as CONSTRAINT_SPACE_POSE if the bone has no parent!";
                bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
                break;
            case CONSTRAINT_SPACE_WORLD:
                {
                    Matrix4f boneMatrixInWorldSpace = this.toMatrix(transform, tempVars.tempMat4);
                    Matrix4f modelWorldMatrix = this.toMatrix(this.getTransform(targetBoneContext.getSkeletonOwnerOma(), null, Space.CONSTRAINT_SPACE_WORLD), tempVars.tempMat42);
                    Matrix4f boneMatrixInModelSpace = modelWorldMatrix.invertLocal().multLocal(boneMatrixInWorldSpace);
                    Bone parent = bone.getParent();
                    if (parent != null) {
                        Matrix4f parentMatrixInModelSpace = this.toMatrix(parent.getModelSpacePosition(), parent.getModelSpaceRotation(), parent.getModelSpaceScale(), tempVars.tempMat4);
                        boneMatrixInModelSpace = parentMatrixInModelSpace.invertLocal().multLocal(boneMatrixInModelSpace);
                    }
                    bone.setBindTransforms(boneMatrixInModelSpace.toTranslationVector(), boneMatrixInModelSpace.toRotationQuat(), boneMatrixInModelSpace.toScaleVector());
                    break;
                }
            case CONSTRAINT_SPACE_POSE:
                {
                    Matrix4f armatureWorldMatrix = this.toMatrix(feature.getWorldTransform(), tempVars.tempMat4);
                    Matrix4f boneMatrixInWorldSpace = armatureWorldMatrix.multLocal(this.toMatrix(transform, tempVars.tempMat42));
                    Matrix4f invertedModelMatrix = this.toMatrix(this.getTransform(targetBoneContext.getSkeletonOwnerOma(), null, Space.CONSTRAINT_SPACE_WORLD), tempVars.tempMat42).invertLocal();
                    Matrix4f boneMatrixInModelSpace = invertedModelMatrix.multLocal(boneMatrixInWorldSpace);
                    Bone parent = bone.getParent();
                    if (parent != null) {
                        Matrix4f parentMatrixInModelSpace = this.toMatrix(parent.getModelSpacePosition(), parent.getModelSpaceRotation(), parent.getModelSpaceScale(), tempVars.tempMat4);
                        boneMatrixInModelSpace = parentMatrixInModelSpace.invertLocal().multLocal(boneMatrixInModelSpace);
                    }
                    bone.setBindTransforms(boneMatrixInModelSpace.toTranslationVector(), boneMatrixInModelSpace.toRotationQuat(), boneMatrixInModelSpace.toScaleVector());
                    break;
                }
            case CONSTRAINT_SPACE_PARLOCAL:
                Matrix4f armatureWorldMatrix = this.toMatrix(feature.getWorldTransform(), tempVars.tempMat4);
                Matrix4f boneMatrixInWorldSpace = armatureWorldMatrix.multLocal(this.toMatrix(transform, tempVars.tempMat42));
                Matrix4f invertedModelMatrix = this.toMatrix(this.getTransform(targetBoneContext.getSkeletonOwnerOma(), null, Space.CONSTRAINT_SPACE_WORLD), tempVars.tempMat42).invertLocal();
                Matrix4f boneMatrixInModelSpace = invertedModelMatrix.multLocal(boneMatrixInWorldSpace);
                Bone parent = bone.getParent();
                if (parent != null) {
                    //first add the initial parent matrix to the bone's model matrix
                    BoneContext parentContext = blenderContext.getBoneContext(parent);
                    Matrix4f initialParentMatrixInModelSpace = parentContext.getBoneMatrixInModelSpace();
                    Matrix4f currentParentMatrixInModelSpace = this.toMatrix(parent.getModelSpacePosition(), parent.getModelSpaceRotation(), parent.getModelSpaceScale(), tempVars.tempMat4);
                    //the bone will now move with its parent in model space
                    //now we need to subtract the difference between current parent's model matrix and its initial model matrix
                    boneMatrixInModelSpace = initialParentMatrixInModelSpace.mult(boneMatrixInModelSpace);
                    Matrix4f diffMatrix = initialParentMatrixInModelSpace.mult(currentParentMatrixInModelSpace.invert());
                    boneMatrixInModelSpace.multLocal(diffMatrix);
                //now the bone will have its position in model space with initial parent's model matrix added
                }
                bone.setBindTransforms(boneMatrixInModelSpace.toTranslationVector(), boneMatrixInModelSpace.toRotationQuat(), boneMatrixInModelSpace.toScaleVector());
                break;
            default:
                tempVars.release();
                throw new IllegalStateException("Invalid space type for target object: " + space.toString());
        }
        tempVars.release();
        skeleton.updateWorldVectors();
    } else {
        switch(space) {
            case CONSTRAINT_SPACE_LOCAL:
                feature.getLocalTransform().set(transform);
                break;
            case CONSTRAINT_SPACE_WORLD:
                if (feature.getParent() == null) {
                    feature.setLocalTransform(transform);
                } else {
                    Transform parentWorldTransform = feature.getParent().getWorldTransform();
                    TempVars tempVars = TempVars.get();
                    Matrix4f parentInverseMatrix = this.toMatrix(parentWorldTransform, tempVars.tempMat4).invertLocal();
                    Matrix4f m = this.toMatrix(transform, tempVars.tempMat42);
                    m = m.multLocal(parentInverseMatrix);
                    tempVars.release();
                    transform.setTranslation(m.toTranslationVector());
                    transform.setRotation(m.toRotationQuat());
                    transform.setScale(m.toScaleVector());
                    feature.setLocalTransform(transform);
                }
                break;
            default:
                throw new IllegalStateException("Invalid space type for spatial object: " + space.toString());
        }
    }
}
Also used : Matrix4f(com.jme3.math.Matrix4f) Spatial(com.jme3.scene.Spatial) BoneContext(com.jme3.scene.plugins.blender.animations.BoneContext) Skeleton(com.jme3.animation.Skeleton) Bone(com.jme3.animation.Bone) TempVars(com.jme3.util.TempVars) Transform(com.jme3.math.Transform)

Example 12 with Skeleton

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

the class ConstraintDefinitionTransLike method getTarget.

/**
     * @return the target feature; it is either Node or Bone (vertex group subtarger is not yet supported)
     */
private Object getTarget() {
    Object target = blenderContext.getLoadedFeature(targetOMA, LoadedDataType.FEATURE);
    if (subtargetName != null && blenderContext.getMarkerValue(ObjectHelper.ARMATURE_NODE_MARKER, target) != null) {
        Skeleton skeleton = blenderContext.getSkeleton(targetOMA);
        target = skeleton.getBone(subtargetName);
    }
    return target;
}
Also used : Skeleton(com.jme3.animation.Skeleton)

Example 13 with Skeleton

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

the class TestBoneRagdoll method simpleInitApp.

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(true);
    stateManager.attach(bulletAppState);
    bullet = new Sphere(32, 32, 1.0f, true, false);
    bullet.setTextureMode(TextureMode.Projected);
    bulletCollisionShape = new SphereCollisionShape(1.0f);
    //        bulletAppState.getPhysicsSpace().enableDebug(assetManager);
    PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace());
    setupLight();
    model = (Node) assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
    //  model.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_X));
    //debug view
    AnimControl control = model.getControl(AnimControl.class);
    SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton", control.getSkeleton());
    Material mat2 = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
    mat2.getAdditionalRenderState().setWireframe(true);
    mat2.setColor("Color", ColorRGBA.Green);
    mat2.getAdditionalRenderState().setDepthTest(false);
    skeletonDebug.setMaterial(mat2);
    skeletonDebug.setLocalTranslation(model.getLocalTranslation());
    //Note: PhysicsRagdollControl is still TODO, constructor will change
    ragdoll = new KinematicRagdollControl(0.5f);
    setupSinbad(ragdoll);
    ragdoll.addCollisionListener(this);
    model.addControl(ragdoll);
    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);
    getPhysicsSpace().add(ragdoll);
    speed = 1.3f;
    rootNode.attachChild(model);
    // rootNode.attachChild(skeletonDebug);
    flyCam.setMoveSpeed(50);
    animChannel = control.createChannel();
    animChannel.setAnim("Dance");
    control.addListener(this);
    inputManager.addListener(new ActionListener() {

        public void onAction(String name, boolean isPressed, float tpf) {
            if (name.equals("toggle") && isPressed) {
                Vector3f v = new Vector3f();
                v.set(model.getLocalTranslation());
                v.y = 0;
                model.setLocalTranslation(v);
                Quaternion q = new Quaternion();
                float[] angles = new float[3];
                model.getLocalRotation().toAngles(angles);
                q.fromAngleAxis(angles[1], Vector3f.UNIT_Y);
                model.setLocalRotation(q);
                if (angles[0] < 0) {
                    animChannel.setAnim("StandUpBack");
                    ragdoll.blendToKinematicMode(0.5f);
                } else {
                    animChannel.setAnim("StandUpFront");
                    ragdoll.blendToKinematicMode(0.5f);
                }
            }
            if (name.equals("bullet+") && isPressed) {
                bulletSize += 0.1f;
            }
            if (name.equals("bullet-") && isPressed) {
                bulletSize -= 0.1f;
            }
            if (name.equals("stop") && isPressed) {
                ragdoll.setEnabled(!ragdoll.isEnabled());
                ragdoll.setRagdollMode();
            }
            if (name.equals("shoot") && !isPressed) {
                Geometry bulletg = new Geometry("bullet", bullet);
                bulletg.setMaterial(matBullet);
                bulletg.setLocalTranslation(cam.getLocation());
                bulletg.setLocalScale(bulletSize);
                bulletCollisionShape = new SphereCollisionShape(bulletSize);
                RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, bulletSize * 10);
                bulletNode.setCcdMotionThreshold(0.001f);
                bulletNode.setLinearVelocity(cam.getDirection().mult(80));
                bulletg.addControl(bulletNode);
                rootNode.attachChild(bulletg);
                getPhysicsSpace().add(bulletNode);
            }
            if (name.equals("boom") && !isPressed) {
                Geometry bulletg = new Geometry("bullet", bullet);
                bulletg.setMaterial(matBullet);
                bulletg.setLocalTranslation(cam.getLocation());
                bulletg.setLocalScale(bulletSize);
                bulletCollisionShape = new SphereCollisionShape(bulletSize);
                BombControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1);
                bulletNode.setForceFactor(8);
                bulletNode.setExplosionRadius(20);
                bulletNode.setCcdMotionThreshold(0.001f);
                bulletNode.setLinearVelocity(cam.getDirection().mult(180));
                bulletg.addControl(bulletNode);
                rootNode.attachChild(bulletg);
                getPhysicsSpace().add(bulletNode);
            }
        }
    }, "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));
    inputManager.addMapping("stop", new KeyTrigger(KeyInput.KEY_H));
    inputManager.addMapping("bullet-", new KeyTrigger(KeyInput.KEY_COMMA));
    inputManager.addMapping("bullet+", new KeyTrigger(KeyInput.KEY_PERIOD));
}
Also used : SphereCollisionShape(com.jme3.bullet.collision.shapes.SphereCollisionShape) Quaternion(com.jme3.math.Quaternion) KeyTrigger(com.jme3.input.controls.KeyTrigger) Material(com.jme3.material.Material) KinematicRagdollControl(com.jme3.bullet.control.KinematicRagdollControl) RigidBodyControl(com.jme3.bullet.control.RigidBodyControl) Sphere(com.jme3.scene.shape.Sphere) Geometry(com.jme3.scene.Geometry) SkeletonDebugger(com.jme3.scene.debug.SkeletonDebugger) ActionListener(com.jme3.input.controls.ActionListener) Vector3f(com.jme3.math.Vector3f) BulletAppState(com.jme3.bullet.BulletAppState) MouseButtonTrigger(com.jme3.input.controls.MouseButtonTrigger)

Example 14 with Skeleton

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

the class KinematicRagdollControl method boneRecursion.

protected void boneRecursion(Spatial model, Bone bone, PhysicsRigidBody parent, int reccount, Map<Integer, List<Float>> pointsMap) {
    PhysicsRigidBody parentShape = parent;
    if (boneList.isEmpty() || boneList.contains(bone.getName())) {
        PhysicsBoneLink link = new PhysicsBoneLink();
        link.bone = bone;
        //creating the collision shape 
        HullCollisionShape shape = null;
        if (pointsMap != null) {
            //build a shape for the bone, using the vertices that are most influenced by this bone
            shape = RagdollUtils.makeShapeFromPointMap(pointsMap, RagdollUtils.getBoneIndices(link.bone, skeleton, boneList), initScale, link.bone.getModelSpacePosition());
        } else {
            //build a shape for the bone, using the vertices associated with this bone with a weight above the threshold
            shape = RagdollUtils.makeShapeFromVerticeWeights(model, RagdollUtils.getBoneIndices(link.bone, skeleton, boneList), initScale, link.bone.getModelSpacePosition(), weightThreshold);
        }
        PhysicsRigidBody shapeNode = new PhysicsRigidBody(shape, rootMass / (float) reccount);
        shapeNode.setKinematic(mode == Mode.Kinematic);
        totalMass += rootMass / (float) reccount;
        link.rigidBody = shapeNode;
        link.initalWorldRotation = bone.getModelSpaceRotation().clone();
        if (parent != null) {
            //get joint position for parent
            Vector3f posToParent = new Vector3f();
            if (bone.getParent() != null) {
                bone.getModelSpacePosition().subtract(bone.getParent().getModelSpacePosition(), posToParent).multLocal(initScale);
            }
            SixDofJoint joint = new SixDofJoint(parent, shapeNode, posToParent, new Vector3f(0, 0, 0f), true);
            preset.setupJointForBone(bone.getName(), joint);
            link.joint = joint;
            joint.setCollisionBetweenLinkedBodys(false);
        }
        boneLinks.put(bone.getName(), link);
        shapeNode.setUserObject(link);
        parentShape = shapeNode;
    }
    for (Iterator<Bone> it = bone.getChildren().iterator(); it.hasNext(); ) {
        Bone childBone = it.next();
        boneRecursion(model, childBone, parentShape, reccount + 1, pointsMap);
    }
}
Also used : SixDofJoint(com.jme3.bullet.joints.SixDofJoint) Vector3f(com.jme3.math.Vector3f) Bone(com.jme3.animation.Bone) PhysicsRigidBody(com.jme3.bullet.objects.PhysicsRigidBody) HullCollisionShape(com.jme3.bullet.collision.shapes.HullCollisionShape)

Example 15 with Skeleton

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

the class KinematicRagdollControl method kinematicUpdate.

protected void kinematicUpdate(float tpf) {
    //the ragdoll does not have the controll, so the keyframed animation updates the physic position of the physic bonces
    TempVars vars = TempVars.get();
    Quaternion tmpRot1 = vars.quat1;
    Quaternion tmpRot2 = vars.quat2;
    Vector3f position = vars.vect1;
    for (PhysicsBoneLink link : boneLinks.values()) {
        //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);
            //interpolating between ragdoll position/rotation and keyframed position/rotation
            tmpRot2.set(tmpRot1).nlerp(link.bone.getModelSpaceRotation(), blendStart / blendTime);
            position2.set(position).interpolateLocal(link.bone.getModelSpacePosition(), blendStart / blendTime);
            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.setUserTransformsInModelSpace(position, tmpRot1);
                //we give control back to the key framed animation.
                link.bone.setUserControl(false);
            } else {
                RagdollUtils.setTransform(link.bone, position, tmpRot1, true, boneList);
            }
        }
        //setting skeleton transforms to the ragdoll
        matchPhysicObjectToBone(link, position, tmpRot1);
        modelPosition.set(targetModel.getLocalTranslation());
    }
    //time control for blending
    if (blendedControl) {
        blendStart += tpf;
        if (blendStart > blendTime) {
            blendedControl = false;
        }
    }
    vars.release();
}
Also used : Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f) TempVars(com.jme3.util.TempVars)

Aggregations

Quaternion (com.jme3.math.Quaternion)13 Vector3f (com.jme3.math.Vector3f)13 Bone (com.jme3.animation.Bone)11 Animation (com.jme3.animation.Animation)7 Skeleton (com.jme3.animation.Skeleton)7 AnimControl (com.jme3.animation.AnimControl)6 BoneTrack (com.jme3.animation.BoneTrack)6 TempVars (com.jme3.util.TempVars)6 HashMap (java.util.HashMap)6 SkeletonControl (com.jme3.animation.SkeletonControl)5 Material (com.jme3.material.Material)3 Transform (com.jme3.math.Transform)3 Node (com.jme3.scene.Node)3 Spatial (com.jme3.scene.Spatial)3 AnimChannel (com.jme3.animation.AnimChannel)2 Track (com.jme3.animation.Track)2 SixDofJoint (com.jme3.bullet.joints.SixDofJoint)2 DirectionalLight (com.jme3.light.DirectionalLight)2 Matrix4f (com.jme3.math.Matrix4f)2 Geometry (com.jme3.scene.Geometry)2