Search in sources :

Example 1 with Track

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

the class BoneTrack method setTime.

/**
     * 
     * Modify the bone which this track modifies in the skeleton to contain
     * the correct animation transforms for a given time.
     * The transforms can be interpolated in some method from the keyframes.
     *
     * @param time the current time of the animation
     * @param weight the weight of the animation
     * @param control
     * @param channel
     * @param vars
     */
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
    BitSet affectedBones = channel.getAffectedBones();
    if (affectedBones != null && !affectedBones.get(targetBoneIndex)) {
        return;
    }
    Bone target = control.getSkeleton().getBone(targetBoneIndex);
    Vector3f tempV = vars.vect1;
    Vector3f tempS = vars.vect2;
    Quaternion tempQ = vars.quat1;
    Vector3f tempV2 = vars.vect3;
    Vector3f tempS2 = vars.vect4;
    Quaternion tempQ2 = vars.quat2;
    int lastFrame = times.length - 1;
    if (time < 0 || lastFrame == 0) {
        rotations.get(0, tempQ);
        translations.get(0, tempV);
        if (scales != null) {
            scales.get(0, tempS);
        }
    } else if (time >= times[lastFrame]) {
        rotations.get(lastFrame, tempQ);
        translations.get(lastFrame, tempV);
        if (scales != null) {
            scales.get(lastFrame, tempS);
        }
    } else {
        int startFrame = 0;
        int endFrame = 1;
        // use lastFrame so we never overflow the array
        int i;
        for (i = 0; i < lastFrame && times[i] < time; i++) {
            startFrame = i;
            endFrame = i + 1;
        }
        float blend = (time - times[startFrame]) / (times[endFrame] - times[startFrame]);
        rotations.get(startFrame, tempQ);
        translations.get(startFrame, tempV);
        if (scales != null) {
            scales.get(startFrame, tempS);
        }
        rotations.get(endFrame, tempQ2);
        translations.get(endFrame, tempV2);
        if (scales != null) {
            scales.get(endFrame, tempS2);
        }
        tempQ.nlerp(tempQ2, blend);
        tempV.interpolateLocal(tempV2, blend);
        tempS.interpolateLocal(tempS2, blend);
    }
    //        if (weight != 1f) {
    target.blendAnimTransforms(tempV, tempQ, scales != null ? tempS : null, weight);
//        } else {
//            target.setAnimTransforms(tempV, tempQ, scales != null ? tempS : null);
//        }
}
Also used : Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f) BitSet(java.util.BitSet)

Example 2 with Track

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

the class EffectTrack method write.

/**
     * Internal use only serialization
     *
     * @param ex exporter
     * @throws IOException exception
     */
public void write(JmeExporter ex) throws IOException {
    OutputCapsule out = ex.getCapsule(this);
    //reseting the particle emission rate on the emitter before saving.
    emitter.setParticlesPerSec(particlesPerSeconds);
    out.write(emitter, "emitter", null);
    out.write(particlesPerSeconds, "particlesPerSeconds", 0);
    out.write(length, "length", 0);
    out.write(startOffset, "startOffset", 0);
    //Setting emission rate to 0 so that this track can go on being used.
    emitter.setParticlesPerSec(0);
}
Also used : OutputCapsule(com.jme3.export.OutputCapsule)

Example 3 with Track

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

the class AudioTrack method findAudio.

/**    
     * recursive function responsible for finding the newly cloned AudioNode
     *
     * @param spat
     * @return
     */
private AudioNode findAudio(Spatial spat) {
    if (spat instanceof AudioNode) {
        //spat is an AudioNode
        AudioNode em = (AudioNode) spat;
        //getting the UserData TrackInfo so check if it should be attached to this Track
        TrackInfo t = (TrackInfo) em.getUserData("TrackInfo");
        if (t != null && t.getTracks().contains(this)) {
            return em;
        }
        return null;
    } else if (spat instanceof Node) {
        for (Spatial child : ((Node) spat).getChildren()) {
            AudioNode em = findAudio(child);
            if (em != null) {
                return em;
            }
        }
    }
    return null;
}
Also used : Spatial(com.jme3.scene.Spatial) AudioNode(com.jme3.audio.AudioNode) Node(com.jme3.scene.Node) AudioNode(com.jme3.audio.AudioNode)

Example 4 with Track

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

the class FbxToJmeTrack method toJmeTrackInternal.

private Track toJmeTrackInternal(int boneIndex, Transform inverseBindPose) {
    float duration = animStack.getDuration();
    FbxAnimCurveNode translationCurve = animCurves.get("Lcl Translation");
    FbxAnimCurveNode rotationCurve = animCurves.get("Lcl Rotation");
    FbxAnimCurveNode scalingCurve = animCurves.get("Lcl Scaling");
    long[] fbxTimes = getKeyTimes();
    float[] times = new float[fbxTimes.length];
    // Translations / Rotations must be set on all tracks.
    // (Required for jME3)
    Vector3f[] translations = new Vector3f[fbxTimes.length];
    Quaternion[] rotations = new Quaternion[fbxTimes.length];
    Vector3f[] scales = null;
    if (scalingCurve != null) {
        scales = new Vector3f[fbxTimes.length];
    }
    for (int i = 0; i < fbxTimes.length; i++) {
        long fbxTime = fbxTimes[i];
        float time = (float) (fbxTime * FbxAnimUtil.SECONDS_PER_UNIT);
        if (time > duration) {
            // Expand animation duration to fit the curve.
            duration = time;
            System.out.println("actual duration: " + duration);
        }
        times[i] = time;
        if (translationCurve != null) {
            translations[i] = translationCurve.getVector3Value(fbxTime);
        } else {
            translations[i] = new Vector3f();
        }
        if (rotationCurve != null) {
            rotations[i] = rotationCurve.getQuaternionValue(fbxTime);
            if (i > 0) {
                if (rotations[i - 1].dot(rotations[i]) < 0) {
                    System.out.println("rotation will go the long way, oh noes");
                    rotations[i - 1].negate();
                }
            }
        } else {
            rotations[i] = new Quaternion();
        }
        if (scalingCurve != null) {
            scales[i] = scalingCurve.getVector3Value(fbxTime);
        }
        if (inverseBindPose != null) {
            applyInverse(translations[i], rotations[i], scales != null ? scales[i] : null, inverseBindPose);
        }
    }
    if (boneIndex == -1) {
        return new SpatialTrack(times, translations, rotations, scales);
    } else {
        if (scales != null) {
            return new BoneTrack(boneIndex, times, translations, rotations, scales);
        } else {
            return new BoneTrack(boneIndex, times, translations, rotations);
        }
    }
}
Also used : SpatialTrack(com.jme3.animation.SpatialTrack) BoneTrack(com.jme3.animation.BoneTrack) Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f)

Example 5 with Track

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

the class FbxLoader method constructAnimations.

private void constructAnimations() {
    // In FBX, animation are not attached to any root.
    // They are implicitly global.
    // So, we need to use hueristics to find which node(s) 
    // an animation is associated with, so we can create the AnimControl
    // in the appropriate location in the scene.
    Map<FbxToJmeTrack, FbxToJmeTrack> pairs = new HashMap<FbxToJmeTrack, FbxToJmeTrack>();
    for (FbxAnimStack stack : animStacks) {
        for (FbxAnimLayer layer : stack.getLayers()) {
            for (FbxAnimCurveNode curveNode : layer.getAnimationCurveNodes()) {
                for (Map.Entry<FbxNode, String> nodePropertyEntry : curveNode.getInfluencedNodeProperties().entrySet()) {
                    FbxToJmeTrack lookupPair = new FbxToJmeTrack();
                    lookupPair.animStack = stack;
                    lookupPair.animLayer = layer;
                    lookupPair.node = nodePropertyEntry.getKey();
                    // Find if this pair is already stored
                    FbxToJmeTrack storedPair = pairs.get(lookupPair);
                    if (storedPair == null) {
                        // If not, store it.
                        storedPair = lookupPair;
                        pairs.put(storedPair, storedPair);
                    }
                    String property = nodePropertyEntry.getValue();
                    storedPair.animCurves.put(property, curveNode);
                }
            }
        }
    }
    // At this point we can construct the animation for all pairs ...
    for (FbxToJmeTrack pair : pairs.values()) {
        String animName = pair.animStack.getName();
        float duration = pair.animStack.getDuration();
        System.out.println("ANIMATION: " + animName + ", duration = " + duration);
        System.out.println("NODE: " + pair.node.getName());
        duration = pair.getDuration();
        if (pair.node instanceof FbxLimbNode) {
            // Find the spatial that has the skeleton for this limb.
            FbxLimbNode limbNode = (FbxLimbNode) pair.node;
            Bone bone = limbNode.getJmeBone();
            Spatial jmeSpatial = limbNode.getSkeletonHolder().getJmeObject();
            Skeleton skeleton = limbNode.getSkeletonHolder().getJmeSkeleton();
            // Get the animation control (create if missing).
            AnimControl animControl = jmeSpatial.getControl(AnimControl.class);
            if (animControl.getSkeleton() != skeleton) {
                throw new UnsupportedOperationException();
            }
            // Get the animation (create if missing).
            Animation anim = animControl.getAnim(animName);
            if (anim == null) {
                anim = new Animation(animName, duration);
                animControl.addAnim(anim);
            }
            // Find the bone index from the spatial's skeleton.
            int boneIndex = skeleton.getBoneIndex(bone);
            // Generate the bone track.
            BoneTrack bt = pair.toJmeBoneTrack(boneIndex, bone.getBindInverseTransform());
            // Add the bone track to the animation.
            anim.addTrack(bt);
        } else {
            // Create the spatial animation
            Animation anim = new Animation(animName, duration);
            anim.setTracks(new Track[] { pair.toJmeSpatialTrack() });
            // Get the animation control (create if missing).
            Spatial jmeSpatial = pair.node.getJmeObject();
            AnimControl animControl = jmeSpatial.getControl(AnimControl.class);
            if (animControl == null) {
                animControl = new AnimControl(null);
                jmeSpatial.addControl(animControl);
            }
            // Add the spatial animation
            animControl.addAnim(anim);
        }
    }
}
Also used : BoneTrack(com.jme3.animation.BoneTrack) HashMap(java.util.HashMap) FbxAnimCurveNode(com.jme3.scene.plugins.fbx.anim.FbxAnimCurveNode) AnimControl(com.jme3.animation.AnimControl) FbxNode(com.jme3.scene.plugins.fbx.node.FbxNode) Spatial(com.jme3.scene.Spatial) Animation(com.jme3.animation.Animation) FbxToJmeTrack(com.jme3.scene.plugins.fbx.anim.FbxToJmeTrack) Skeleton(com.jme3.animation.Skeleton) Bone(com.jme3.animation.Bone) FbxLimbNode(com.jme3.scene.plugins.fbx.anim.FbxLimbNode) FbxAnimLayer(com.jme3.scene.plugins.fbx.anim.FbxAnimLayer) HashMap(java.util.HashMap) Map(java.util.Map) FbxAnimStack(com.jme3.scene.plugins.fbx.anim.FbxAnimStack)

Aggregations

BoneTrack (com.jme3.animation.BoneTrack)9 Vector3f (com.jme3.math.Vector3f)9 Quaternion (com.jme3.math.Quaternion)7 Animation (com.jme3.animation.Animation)5 SpatialTrack (com.jme3.animation.SpatialTrack)5 Spatial (com.jme3.scene.Spatial)5 HashMap (java.util.HashMap)5 Bone (com.jme3.animation.Bone)4 Track (com.jme3.animation.Track)4 Skeleton (com.jme3.animation.Skeleton)2 Node (com.jme3.scene.Node)2 Map (java.util.Map)2 AnimChannel (com.jme3.animation.AnimChannel)1 AnimControl (com.jme3.animation.AnimControl)1 AudioNode (com.jme3.audio.AudioNode)1 ParticleEmitter (com.jme3.effect.ParticleEmitter)1 InputCapsule (com.jme3.export.InputCapsule)1 OutputCapsule (com.jme3.export.OutputCapsule)1 Savable (com.jme3.export.Savable)1 TouchEvent (com.jme3.input.event.TouchEvent)1