Search in sources :

Example 6 with Ipo

use of com.jme3.scene.plugins.blender.animations.Ipo in project jmonkeyengine by jMonkeyEngine.

the class Ipo method calculateTrack.

/**
     * This method calculates the value of the curves as a bone track between
     * the specified frames.
     * 
     * @param targetIndex
     *            the index of the target for which the method calculates the
     *            tracks IMPORTANT! Aet to -1 (or any negative number) if you
     *            want to load spatial animation.
     * @param localTranslation
     *            the local translation of the object/bone that will be animated by
     *            the track
     * @param localRotation
     *            the local rotation of the object/bone that will be animated by
     *            the track
     * @param localScale
     *            the local scale of the object/bone that will be animated by
     *            the track
     * @param startFrame
     *            the first frame of tracks (inclusive)
     * @param stopFrame
     *            the last frame of the tracks (inclusive)
     * @param fps
     *            frame rate (frames per second)
     * @param spatialTrack
     *            this flag indicates if the track belongs to a spatial or to a
     *            bone; the difference is important because it appears that bones
     *            in blender have the same type of coordinate system (Y as UP)
     *            as jme while other features have different one (Z is UP)
     * @return bone track for the specified bone
     */
public Track calculateTrack(int targetIndex, BoneContext boneContext, Vector3f localTranslation, Quaternion localRotation, Vector3f localScale, int startFrame, int stopFrame, int fps, boolean spatialTrack) {
    if (calculatedTrack == null) {
        // preparing data for track
        int framesAmount = stopFrame - startFrame;
        float timeBetweenFrames = 1.0f / fps;
        float[] times = new float[framesAmount + 1];
        Vector3f[] translations = new Vector3f[framesAmount + 1];
        float[] translation = new float[3];
        Quaternion[] rotations = new Quaternion[framesAmount + 1];
        float[] quaternionRotation = new float[] { localRotation.getX(), localRotation.getY(), localRotation.getZ(), localRotation.getW() };
        float[] eulerRotation = localRotation.toAngles(null);
        Vector3f[] scales = new Vector3f[framesAmount + 1];
        float[] scale = new float[] { localScale.x, localScale.y, localScale.z };
        float degreeToRadiansFactor = 1;
        if (blenderVersion < 250) {
            // in blender earlier than 2.50 the values are stored in degrees
            // the values in blender are divided by 10, so we need to mult it here
            degreeToRadiansFactor *= FastMath.DEG_TO_RAD * 10;
        }
        int yIndex = 1, zIndex = 2;
        boolean swapAxes = spatialTrack && fixUpAxis;
        if (swapAxes) {
            yIndex = 2;
            zIndex = 1;
        }
        boolean eulerRotationUsed = false, queternionRotationUsed = false;
        // calculating track data
        for (int frame = startFrame; frame <= stopFrame; ++frame) {
            boolean translationSet = false;
            translation[0] = translation[1] = translation[2] = 0;
            int index = frame - startFrame;
            // start + (frame - 1) * timeBetweenFrames;
            times[index] = index * timeBetweenFrames;
            for (int j = 0; j < bezierCurves.length; ++j) {
                double value = bezierCurves[j].evaluate(frame, BezierCurve.Y_VALUE);
                switch(bezierCurves[j].getType()) {
                    // LOCATION
                    case AC_LOC_X:
                        translation[0] = (float) value;
                        translationSet = true;
                        break;
                    case AC_LOC_Y:
                        if (swapAxes && value != 0) {
                            value = -value;
                        }
                        translation[yIndex] = (float) value;
                        translationSet = true;
                        break;
                    case AC_LOC_Z:
                        translation[zIndex] = (float) value;
                        translationSet = true;
                        break;
                    // EULER ROTATION
                    case OB_ROT_X:
                        eulerRotationUsed = true;
                        eulerRotation[0] = (float) value * degreeToRadiansFactor;
                        break;
                    case OB_ROT_Y:
                        eulerRotationUsed = true;
                        if (swapAxes && value != 0) {
                            value = -value;
                        }
                        eulerRotation[yIndex] = (float) value * degreeToRadiansFactor;
                        break;
                    case OB_ROT_Z:
                        eulerRotationUsed = true;
                        eulerRotation[zIndex] = (float) value * degreeToRadiansFactor;
                        break;
                    // SIZE
                    case AC_SIZE_X:
                        scale[0] = (float) value;
                        break;
                    case AC_SIZE_Y:
                        scale[yIndex] = (float) value;
                        break;
                    case AC_SIZE_Z:
                        scale[zIndex] = (float) value;
                        break;
                    // QUATERNION ROTATION (used with bone animation)
                    case AC_QUAT_W:
                        queternionRotationUsed = true;
                        quaternionRotation[3] = (float) value;
                        break;
                    case AC_QUAT_X:
                        queternionRotationUsed = true;
                        quaternionRotation[0] = (float) value;
                        break;
                    case AC_QUAT_Y:
                        queternionRotationUsed = true;
                        if (swapAxes && value != 0) {
                            value = -value;
                        }
                        quaternionRotation[yIndex] = (float) value;
                        break;
                    case AC_QUAT_Z:
                        quaternionRotation[zIndex] = (float) value;
                        break;
                    default:
                        LOGGER.log(Level.WARNING, "Unknown ipo curve type: {0}.", bezierCurves[j].getType());
                }
            }
            if (translationSet) {
                translations[index] = localRotation.multLocal(new Vector3f(translation[0], translation[1], translation[2]));
            } else {
                translations[index] = new Vector3f();
            }
            if (boneContext != null) {
                if (boneContext.getBone().getParent() == null && boneContext.is(BoneContext.NO_LOCAL_LOCATION)) {
                    float temp = translations[index].z;
                    translations[index].z = -translations[index].y;
                    translations[index].y = temp;
                }
            }
            if (queternionRotationUsed) {
                rotations[index] = new Quaternion(quaternionRotation[0], quaternionRotation[1], quaternionRotation[2], quaternionRotation[3]);
            } else {
                rotations[index] = new Quaternion().fromAngles(eulerRotation);
            }
            scales[index] = new Vector3f(scale[0], scale[1], scale[2]);
        }
        if (spatialTrack) {
            calculatedTrack = new SpatialTrack(times, translations, rotations, scales);
        } else {
            calculatedTrack = new BoneTrack(targetIndex, times, translations, rotations, scales);
        }
        if (queternionRotationUsed && eulerRotationUsed) {
            LOGGER.warning("Animation uses both euler and quaternion tracks for rotations. Quaternion rotation is applied. Make sure that this is what you wanted!");
        }
    }
    return calculatedTrack;
}
Also used : SpatialTrack(com.jme3.animation.SpatialTrack) BoneTrack(com.jme3.animation.BoneTrack) Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f)

Aggregations

Pointer (com.jme3.scene.plugins.blender.file.Pointer)5 Structure (com.jme3.scene.plugins.blender.file.Structure)4 ConstIpo (com.jme3.scene.plugins.blender.animations.Ipo.ConstIpo)3 BezierCurve (com.jme3.scene.plugins.blender.curves.BezierCurve)2 BoneTrack (com.jme3.animation.BoneTrack)1 SpatialTrack (com.jme3.animation.SpatialTrack)1 Quaternion (com.jme3.math.Quaternion)1 Vector3f (com.jme3.math.Vector3f)1 AnimationHelper (com.jme3.scene.plugins.blender.animations.AnimationHelper)1 Ipo (com.jme3.scene.plugins.blender.animations.Ipo)1 BlenderInputStream (com.jme3.scene.plugins.blender.file.BlenderInputStream)1 FileBlockHeader (com.jme3.scene.plugins.blender.file.FileBlockHeader)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1