Search in sources :

Example 6 with FbxObject

use of com.jme3.scene.plugins.fbx.obj.FbxObject 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 7 with FbxObject

use of com.jme3.scene.plugins.fbx.obj.FbxObject in project jmonkeyengine by jMonkeyEngine.

the class SceneLoader method loadDeformer.

private FbxObject loadDeformer(FbxElement element) {
    String type = (String) element.properties.get(2);
    switch(type) {
        case "Skin":
            FbxSkin skinData = new FbxSkin(this, element);
            skinMap.put(skinData.id, skinData);
            return skinData;
        case "Cluster":
            FbxCluster clusterData = new FbxCluster(this, element);
            return clusterData;
    }
    return null;
}
Also used : FbxCluster(com.jme3.scene.plugins.fbx.objects.FbxCluster) FbxSkin(com.jme3.scene.plugins.fbx.objects.FbxSkin)

Example 8 with FbxObject

use of com.jme3.scene.plugins.fbx.obj.FbxObject in project jmonkeyengine by jMonkeyEngine.

the class SceneLoader method loadConnections.

private void loadConnections(FbxElement element) {
    for (FbxElement e : element.children) {
        if (e.id.equals("C")) {
            String type = (String) e.properties.get(0);
            long objId, refId;
            FbxObject obj, ref;
            switch(type) {
                case "OO":
                    objId = (Long) e.properties.get(1);
                    refId = (Long) e.properties.get(2);
                    obj = allObjects.get(objId);
                    ref = allObjects.get(refId);
                    if (ref != null) {
                        ref.link(obj);
                    } else if (refId == 0) {
                        obj.linkToZero();
                    }
                    break;
                case "OP":
                    objId = (Long) e.properties.get(1);
                    refId = (Long) e.properties.get(2);
                    String propName = (String) e.properties.get(3);
                    obj = allObjects.get(objId);
                    ref = allObjects.get(refId);
                    if (ref != null)
                        ref.link(obj, propName);
                    break;
            }
        }
    }
}
Also used : FbxElement(com.jme3.scene.plugins.fbx.file.FbxElement) FbxObject(com.jme3.scene.plugins.fbx.objects.FbxObject)

Example 9 with FbxObject

use of com.jme3.scene.plugins.fbx.obj.FbxObject in project jmonkeyengine by jMonkeyEngine.

the class FbxNode method connectObjectProperty.

@Override
public void connectObjectProperty(FbxObject object, String property) {
    // (FbxAnimCurveNode)
    if (object instanceof FbxAnimCurveNode) {
        FbxAnimCurveNode curveNode = (FbxAnimCurveNode) object;
        if (property.equals("Lcl Translation") || property.equals("Lcl Rotation") || property.equals("Lcl Scaling")) {
            List<FbxAnimCurveNode> curveNodes = propertyToAnimCurveMap.get(property);
            if (curveNodes == null) {
                curveNodes = new ArrayList<FbxAnimCurveNode>();
                curveNodes.add(curveNode);
                propertyToAnimCurveMap.put(property, curveNodes);
            }
            curveNodes.add(curveNode);
            // Make sure the curve knows about it animating
            // this node as well. 
            curveNode.addInfluencedNode(this, property);
        } else {
            logger.log(Level.WARNING, "Animating the property ''{0}'' is not " + "supported. Ignoring.", property);
        }
    } else {
        unsupportedConnectObjectProperty(object, property);
    }
}
Also used : FbxAnimCurveNode(com.jme3.scene.plugins.fbx.anim.FbxAnimCurveNode)

Aggregations

FbxElement (com.jme3.scene.plugins.fbx.file.FbxElement)3 FbxObject (com.jme3.scene.plugins.fbx.obj.FbxObject)3 FbxObject (com.jme3.scene.plugins.fbx.objects.FbxObject)3 FbxId (com.jme3.scene.plugins.fbx.file.FbxId)2 FbxAnimNode (com.jme3.scene.plugins.fbx.objects.FbxAnimNode)2 FbxNode (com.jme3.scene.plugins.fbx.objects.FbxNode)2 HashMap (java.util.HashMap)2 Animation (com.jme3.animation.Animation)1 Bone (com.jme3.animation.Bone)1 BoneTrack (com.jme3.animation.BoneTrack)1 Track (com.jme3.animation.Track)1 Material (com.jme3.material.Material)1 Matrix4f (com.jme3.math.Matrix4f)1 Quaternion (com.jme3.math.Quaternion)1 Vector3f (com.jme3.math.Vector3f)1 Geometry (com.jme3.scene.Geometry)1 AnimInverval (com.jme3.scene.plugins.fbx.AnimationList.AnimInverval)1 FbxAnimCurveNode (com.jme3.scene.plugins.fbx.anim.FbxAnimCurveNode)1 FbxBindPose (com.jme3.scene.plugins.fbx.anim.FbxBindPose)1 FbxNode (com.jme3.scene.plugins.fbx.node.FbxNode)1