Search in sources :

Example 16 with Skeleton

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

the class KinematicRagdollControl method write.

/**
     * serialize this control
     *
     * @param ex
     * @throws IOException
     */
@Override
public void write(JmeExporter ex) throws IOException {
    super.write(ex);
    OutputCapsule oc = ex.getCapsule(this);
    oc.write(boneList.toArray(new String[boneList.size()]), "boneList", new String[0]);
    oc.write(boneLinks.values().toArray(new PhysicsBoneLink[boneLinks.size()]), "boneLinks", new PhysicsBoneLink[0]);
    oc.write(modelPosition, "modelPosition", new Vector3f());
    oc.write(modelRotation, "modelRotation", new Quaternion());
    oc.write(targetModel, "targetModel", null);
    oc.write(skeleton, "skeleton", null);
    //        oc.write(preset, "preset", null);//TODO
    oc.write(initScale, "initScale", null);
    oc.write(mode, "mode", null);
    oc.write(blendedControl, "blendedControl", false);
    oc.write(weightThreshold, "weightThreshold", -1.0f);
    oc.write(blendStart, "blendStart", 0.0f);
    oc.write(blendTime, "blendTime", 1.0f);
    oc.write(eventDispatchImpulseThreshold, "eventDispatchImpulseThreshold", 10);
    oc.write(rootMass, "rootMass", 15);
    oc.write(totalMass, "totalMass", 0);
    oc.write(ikRotSpeed, "rotSpeed", 7f);
    oc.write(limbDampening, "limbDampening", 0.6f);
}
Also used : OutputCapsule(com.jme3.export.OutputCapsule) Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f)

Example 17 with Skeleton

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

the class KinematicRagdollControl method read.

/**
     * de-serialize this control
     *
     * @param im
     * @throws IOException
     */
@Override
public void read(JmeImporter im) throws IOException {
    super.read(im);
    InputCapsule ic = im.getCapsule(this);
    String[] loadedBoneList = ic.readStringArray("boneList", new String[0]);
    boneList.addAll(Arrays.asList(loadedBoneList));
    PhysicsBoneLink[] loadedBoneLinks = (PhysicsBoneLink[]) ic.readSavableArray("boneList", new PhysicsBoneLink[0]);
    for (PhysicsBoneLink physicsBoneLink : loadedBoneLinks) {
        boneLinks.put(physicsBoneLink.bone.getName(), physicsBoneLink);
    }
    modelPosition.set((Vector3f) ic.readSavable("modelPosition", new Vector3f()));
    modelRotation.set((Quaternion) ic.readSavable("modelRotation", new Quaternion()));
    targetModel = (Spatial) ic.readSavable("targetModel", null);
    skeleton = (Skeleton) ic.readSavable("skeleton", null);
    //        preset //TODO
    initScale = (Vector3f) ic.readSavable("initScale", null);
    mode = ic.readEnum("mode", Mode.class, Mode.Kinematic);
    blendedControl = ic.readBoolean("blendedControl", false);
    weightThreshold = ic.readFloat("weightThreshold", -1.0f);
    blendStart = ic.readFloat("blendStart", 0.0f);
    blendTime = ic.readFloat("blendTime", 1.0f);
    eventDispatchImpulseThreshold = ic.readFloat("eventDispatchImpulseThreshold", 10);
    rootMass = ic.readFloat("rootMass", 15);
    totalMass = ic.readFloat("totalMass", 0);
}
Also used : Quaternion(com.jme3.math.Quaternion) InputCapsule(com.jme3.export.InputCapsule) Vector3f(com.jme3.math.Vector3f)

Example 18 with Skeleton

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

the class Constraint method apply.

/**
     * Applies the constraint to owner (and in some cases can alter other bones of the skeleton).
     * @param frame
     *            the frame of the animation
     */
public void apply(int frame) {
    if (LOGGER.isLoggable(Level.FINEST)) {
        LOGGER.log(Level.FINEST, "Applying constraint: {0} for frame {1}", new Object[] { name, frame });
    }
    Transform targetTransform = targetOMA != null ? constraintHelper.getTransform(targetOMA, subtargetName, targetSpace) : null;
    constraintDefinition.bake(ownerSpace, targetSpace, targetTransform, (float) ipo.calculateValue(frame));
}
Also used : Transform(com.jme3.math.Transform)

Example 19 with Skeleton

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

the class SimulationNode method simulateSkeleton.

/**
     * Simulates the bone node.
     */
private void simulateSkeleton() {
    LOGGER.fine("Simulating skeleton.");
    Set<Long> alteredOmas = new HashSet<Long>();
    if (animations != null) {
        TempVars vars = TempVars.get();
        AnimChannel animChannel = animControl.createChannel();
        for (Animation animation : animations) {
            float[] animationTimeBoundaries = this.computeAnimationTimeBoundaries(animation);
            int maxFrame = (int) animationTimeBoundaries[0];
            float maxTime = animationTimeBoundaries[1];
            Map<Integer, VirtualTrack> tracks = new HashMap<Integer, VirtualTrack>();
            for (int frame = 0; frame < maxFrame; ++frame) {
                // this MUST be done here, otherwise setting next frame of animation will
                // lead to possible errors
                this.reset();
                // first set proper time for all bones in all the tracks ...
                for (Track track : animation.getTracks()) {
                    float time = ((BoneTrack) track).getTimes()[frame];
                    track.setTime(time, 1, animControl, animChannel, vars);
                    skeleton.updateWorldVectors();
                }
                // ... and then apply constraints from the root bone to the last child ...
                Set<Long> applied = new HashSet<Long>();
                for (Bone rootBone : skeleton.getRoots()) {
                    // ignore the 0-indexed bone
                    if (skeleton.getBoneIndex(rootBone) > 0) {
                        this.applyConstraints(rootBone, alteredOmas, applied, frame, new Stack<Bone>());
                    }
                }
                // ... add virtual tracks if neccessary, for bones that were altered but had no tracks before ...
                for (Long boneOMA : alteredOmas) {
                    BoneContext boneContext = blenderContext.getBoneContext(boneOMA);
                    int boneIndex = skeleton.getBoneIndex(boneContext.getBone());
                    if (!tracks.containsKey(boneIndex)) {
                        tracks.put(boneIndex, new VirtualTrack(boneContext.getBone().getName(), maxFrame, maxTime));
                    }
                }
                alteredOmas.clear();
                // ... and fill in another frame in the result track
                for (Entry<Integer, VirtualTrack> trackEntry : tracks.entrySet()) {
                    Bone bone = skeleton.getBone(trackEntry.getKey());
                    Transform startTransform = boneStartTransforms.get(bone);
                    // track contains differences between the frame position and bind positions of bones/spatials
                    Vector3f bonePositionDifference = bone.getLocalPosition().subtract(startTransform.getTranslation());
                    Quaternion boneRotationDifference = startTransform.getRotation().inverse().mult(bone.getLocalRotation()).normalizeLocal();
                    Vector3f boneScaleDifference = bone.getLocalScale().divide(startTransform.getScale());
                    trackEntry.getValue().setTransform(frame, new Transform(bonePositionDifference, boneRotationDifference, boneScaleDifference));
                }
            }
            for (Entry<Integer, VirtualTrack> trackEntry : tracks.entrySet()) {
                Track newTrack = trackEntry.getValue().getAsBoneTrack(trackEntry.getKey());
                if (newTrack != null) {
                    boolean trackReplaced = false;
                    for (Track track : animation.getTracks()) {
                        if (((BoneTrack) track).getTargetBoneIndex() == trackEntry.getKey().intValue()) {
                            animation.removeTrack(track);
                            animation.addTrack(newTrack);
                            trackReplaced = true;
                            break;
                        }
                    }
                    if (!trackReplaced) {
                        animation.addTrack(newTrack);
                    }
                }
            }
        }
        vars.release();
        animControl.clearChannels();
        this.reset();
    }
}
Also used : HashMap(java.util.HashMap) Quaternion(com.jme3.math.Quaternion) AnimChannel(com.jme3.animation.AnimChannel) TempVars(com.jme3.util.TempVars) BoneContext(com.jme3.scene.plugins.blender.animations.BoneContext) Vector3f(com.jme3.math.Vector3f) Animation(com.jme3.animation.Animation) Bone(com.jme3.animation.Bone) Transform(com.jme3.math.Transform) SpatialTrack(com.jme3.animation.SpatialTrack) BoneTrack(com.jme3.animation.BoneTrack) Track(com.jme3.animation.Track) HashSet(java.util.HashSet)

Example 20 with Skeleton

use of com.jme3.animation.Skeleton 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)

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