Search in sources :

Example 16 with Track

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

the class EffectTrack method findEmitter.

/**
     * recursive function responsible for finding the newly cloned Emitter
     *
     * @param spat
     * @return
     */
private ParticleEmitter findEmitter(Spatial spat) {
    if (spat instanceof ParticleEmitter) {
        //spat is a PArticleEmitter
        ParticleEmitter em = (ParticleEmitter) 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()) {
            ParticleEmitter em = findEmitter(child);
            if (em != null) {
                return em;
            }
        }
    }
    return null;
}
Also used : ParticleEmitter(com.jme3.effect.ParticleEmitter) Spatial(com.jme3.scene.Spatial) Node(com.jme3.scene.Node)

Example 17 with Track

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

the class EffectTrack method read.

/**
     * Internal use only serialization
     *
     * @param im importer
     * @throws IOException Exception
     */
public void read(JmeImporter im) throws IOException {
    InputCapsule in = im.getCapsule(this);
    this.particlesPerSeconds = in.readFloat("particlesPerSeconds", 0);
    //reading the emitter even if the track will then reference its cloned counter part if it's loaded with the assetManager.
    //This also avoid null pointer exception if the model is not loaded via the AssetManager.
    emitter = (ParticleEmitter) in.readSavable("emitter", null);
    emitter.setParticlesPerSec(0);
    //if the emitter was saved with a KillParticleControl we remove it.
    //        Control c = emitter.getControl(KillParticleControl.class);
    //        if(c!=null){
    //            emitter.removeControl(c);
    //        }
    //emitter.removeControl(KillParticleControl.class);
    length = in.readFloat("length", length);
    startOffset = in.readFloat("startOffset", 0);
}
Also used : InputCapsule(com.jme3.export.InputCapsule)

Example 18 with Track

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

the class SceneLoader method buildAnimations.

private void buildAnimations() {
    if (skeleton == null)
        return;
    if (animList == null || animList.list.size() == 0) {
        animList = new AnimationList();
        for (long layerId : alayerMap.keySet()) {
            FbxObject layer = alayerMap.get(layerId);
            animList.add(layer.name, layer.name, 0, -1);
        }
    }
    // Extract aminations
    HashMap<String, Animation> anims = new HashMap<String, Animation>();
    for (AnimInverval animInfo : animList.list) {
        float realLength = 0;
        float length = (animInfo.lastFrame - animInfo.firstFrame) / this.animFrameRate;
        float animStart = animInfo.firstFrame / this.animFrameRate;
        float animStop = animInfo.lastFrame / this.animFrameRate;
        Animation anim = new Animation(animInfo.name, length);
        // Search source layer for animation nodes
        long sourceLayerId = 0L;
        for (long layerId : alayerMap.keySet()) {
            FbxObject layer = alayerMap.get(layerId);
            if (layer.name.equals(animInfo.layerName)) {
                sourceLayerId = layerId;
                break;
            }
        }
        // Build bone tracks
        for (FbxNode limb : limbMap.values()) {
            // Animation channels may have different keyframes (non-baked animation).
            //   So we have to restore intermediate values for all channels cause of JME requires
            //   a bone track as a single channel with collective transformation for each keyframe
            // Sorted unique timestamps
            Set<Long> stamps = new TreeSet<Long>();
            FbxAnimNode animTranslation = limb.animTranslation(sourceLayerId);
            FbxAnimNode animRotation = limb.animRotation(sourceLayerId);
            FbxAnimNode animScale = limb.animScale(sourceLayerId);
            boolean haveTranslation = haveAnyChannel(animTranslation);
            boolean haveRotation = haveAnyChannel(animRotation);
            boolean haveScale = haveAnyChannel(animScale);
            // Collect keyframes stamps
            if (haveTranslation)
                animTranslation.exportTimes(stamps);
            if (haveRotation)
                animRotation.exportTimes(stamps);
            if (haveScale)
                animScale.exportTimes(stamps);
            if (stamps.isEmpty())
                continue;
            long[] keyTimes = new long[stamps.size()];
            int cnt = 0;
            for (long t : stamps) keyTimes[cnt++] = t;
            // Calculate keys interval by animation time interval
            int firstKeyIndex = 0;
            int lastKeyIndex = keyTimes.length - 1;
            for (int i = 0; i < keyTimes.length; ++i) {
                // Translate into seconds
                float time = (float) (((double) keyTimes[i]) * secondsPerUnit);
                if (time <= animStart)
                    firstKeyIndex = i;
                if (time >= animStop && animStop >= 0) {
                    lastKeyIndex = i;
                    break;
                }
            }
            int keysCount = lastKeyIndex - firstKeyIndex + 1;
            if (keysCount <= 0)
                continue;
            float[] times = new float[keysCount];
            Vector3f[] translations = new Vector3f[keysCount];
            Quaternion[] rotations = new Quaternion[keysCount];
            Vector3f[] scales = null;
            // Calculate keyframes times
            for (int i = 0; i < keysCount; ++i) {
                int keyIndex = firstKeyIndex + i;
                // Translate into seconds
                float time = (float) (((double) keyTimes[keyIndex]) * secondsPerUnit);
                times[i] = time - animStart;
                realLength = Math.max(realLength, times[i]);
            }
            // Load keyframes from animation curves
            if (haveTranslation) {
                for (int i = 0; i < keysCount; ++i) {
                    int keyIndex = firstKeyIndex + i;
                    FbxAnimNode n = animTranslation;
                    // Why do it here but not in other places? FBX magic?
                    Vector3f tvec = n.getValue(keyTimes[keyIndex], n.value).subtractLocal(n.value);
                    translations[i] = tvec.divideLocal(unitSize);
                }
            } else {
                for (int i = 0; i < keysCount; ++i) translations[i] = Vector3f.ZERO;
            }
            RotationOrder ro = RotationOrder.EULER_XYZ;
            if (haveRotation) {
                for (int i = 0; i < keysCount; ++i) {
                    int keyIndex = firstKeyIndex + i;
                    FbxAnimNode n = animRotation;
                    Vector3f tvec = n.getValue(keyTimes[keyIndex], n.value);
                    rotations[i] = ro.rotate(tvec);
                }
            } else {
                for (int i = 0; i < keysCount; ++i) rotations[i] = Quaternion.IDENTITY;
            }
            if (haveScale) {
                scales = new Vector3f[keysCount];
                for (int i = 0; i < keysCount; ++i) {
                    int keyIndex = firstKeyIndex + i;
                    FbxAnimNode n = animScale;
                    Vector3f tvec = n.getValue(keyTimes[keyIndex], n.value);
                    scales[i] = tvec;
                }
            }
            BoneTrack track = null;
            if (haveScale)
                track = new BoneTrack(limb.boneIndex, times, translations, rotations, scales);
            else
                track = new BoneTrack(limb.boneIndex, times, translations, rotations);
            anim.addTrack(track);
        }
        if (realLength != length && animInfo.lastFrame == -1) {
            Track[] tracks = anim.getTracks();
            if (tracks == null || tracks.length == 0)
                continue;
            anim = new Animation(animInfo.name, realLength);
            for (Track track : tracks) anim.addTrack(track);
        }
        anims.put(anim.getName(), anim);
    }
    animControl.setAnimations(anims);
}
Also used : FbxObject(com.jme3.scene.plugins.fbx.objects.FbxObject) HashMap(java.util.HashMap) Quaternion(com.jme3.math.Quaternion) FbxAnimNode(com.jme3.scene.plugins.fbx.objects.FbxAnimNode) FbxNode(com.jme3.scene.plugins.fbx.objects.FbxNode) TreeSet(java.util.TreeSet) BoneTrack(com.jme3.animation.BoneTrack) AnimInverval(com.jme3.scene.plugins.fbx.AnimationList.AnimInverval) Vector3f(com.jme3.math.Vector3f) Animation(com.jme3.animation.Animation) BoneTrack(com.jme3.animation.BoneTrack) Track(com.jme3.animation.Track)

Example 19 with Track

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

the class SkeletonLoader method endElement.

public void endElement(String uri, String name, String qName) {
    if (qName.equals("translate") || qName.equals("position") || qName.equals("scale")) {
    } else if (qName.equals("axis")) {
    } else if (qName.equals("rotate") || qName.equals("rotation")) {
        rotation = new Quaternion();
        axis.normalizeLocal();
        rotation.fromAngleNormalAxis(angle, axis);
        angle = 0;
        axis = null;
    } else if (qName.equals("bone")) {
        bone.setBindTransforms(position, rotation, scale);
        bone = null;
        position = null;
        rotation = null;
        scale = null;
    } else if (qName.equals("bonehierarchy")) {
        Bone[] bones = new Bone[indexToBone.size()];
        // also assign the bones to the bonelist
        for (Map.Entry<Integer, Bone> entry : indexToBone.entrySet()) {
            Bone bone = entry.getValue();
            bones[entry.getKey()] = bone;
        }
        indexToBone.clear();
        skeleton = new Skeleton(bones);
    } else if (qName.equals("animation")) {
        animations.add(animation);
        animation = null;
    } else if (qName.equals("track")) {
        if (track != null) {
            // if track has keyframes
            tracks.add(track);
            track = null;
        }
    } else if (qName.equals("tracks")) {
        BoneTrack[] trackList = tracks.toArray(new BoneTrack[tracks.size()]);
        animation.setTracks(trackList);
        tracks.clear();
    } else if (qName.equals("keyframe")) {
        assert time >= 0;
        assert position != null;
        assert rotation != null;
        times.add(time);
        translations.add(position);
        rotations.add(rotation);
        if (scale != null) {
            scales.add(scale);
        } else {
            scales.add(new Vector3f(1, 1, 1));
        }
        time = -1;
        position = null;
        rotation = null;
        scale = null;
    } else if (qName.equals("keyframes")) {
        if (times.size() > 0) {
            float[] timesArray = new float[times.size()];
            for (int i = 0; i < timesArray.length; i++) {
                timesArray[i] = times.get(i);
            }
            Vector3f[] transArray = translations.toArray(new Vector3f[translations.size()]);
            Quaternion[] rotArray = rotations.toArray(new Quaternion[rotations.size()]);
            Vector3f[] scalesArray = scales.toArray(new Vector3f[scales.size()]);
            track.setKeyframes(timesArray, transArray, rotArray, scalesArray);
        //track.setKeyframes(timesArray, transArray, rotArray);
        } else {
            track = null;
        }
        times.clear();
        translations.clear();
        rotations.clear();
        scales.clear();
    } else if (qName.equals("skeleton")) {
        nameToBone.clear();
    }
    assert elementStack.peek().equals(qName);
    elementStack.pop();
}
Also used : BoneTrack(com.jme3.animation.BoneTrack) Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f) Skeleton(com.jme3.animation.Skeleton) Bone(com.jme3.animation.Bone) HashMap(java.util.HashMap) Map(java.util.Map)

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