Package com.jme3.scene.plugins.blender.animations

Source Code of com.jme3.scene.plugins.blender.animations.Ipo

package com.jme3.scene.plugins.blender.animations;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.jme3.animation.BoneTrack;
import com.jme3.animation.SpatialTrack;
import com.jme3.animation.Track;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.plugins.blender.curves.BezierCurve;

/**
* This class is used to calculate bezier curves value for the given frames. The
* Ipo (interpolation object) consists of several b-spline curves (connected 3rd
* degree bezier curves) of a different type.
*
* @author Marcin Roguski
*/
public class Ipo {
    private static final Logger LOGGER    = Logger.getLogger(Ipo.class.getName());

    public static final int     AC_LOC_X  = 1;
    public static final int     AC_LOC_Y  = 2;
    public static final int     AC_LOC_Z  = 3;
    public static final int     OB_ROT_X  = 7;
    public static final int     OB_ROT_Y  = 8;
    public static final int     OB_ROT_Z  = 9;
    public static final int     AC_SIZE_X = 13;
    public static final int     AC_SIZE_Y = 14;
    public static final int     AC_SIZE_Z = 15;
    public static final int     AC_QUAT_W = 25;
    public static final int     AC_QUAT_X = 26;
    public static final int     AC_QUAT_Y = 27;
    public static final int     AC_QUAT_Z = 28;

    /** A list of bezier curves for this interpolation object. */
    private BezierCurve[]       bezierCurves;
    /** Each ipo contains one bone track. */
    private Track               calculatedTrack;
    /** This variable indicates if the Y asxis is the UP axis or not. */
    protected boolean           fixUpAxis;
    /**
     * Depending on the blender version rotations are stored in degrees or
     * radians so we need to know the version that is used.
     */
    protected final int         blenderVersion;

    /**
     * Constructor. Stores the bezier curves.
     *
     * @param bezierCurves
     *            a table of bezier curves
     * @param fixUpAxis
     *            indicates if the Y is the up axis or not
     * @param blenderVersion
     *            the blender version that is currently used
     */
    public Ipo(BezierCurve[] bezierCurves, boolean fixUpAxis, int blenderVersion) {
        this.bezierCurves = bezierCurves;
        this.fixUpAxis = fixUpAxis;
        this.blenderVersion = blenderVersion;
    }

    /**
     * This method calculates the ipo value for the first curve.
     *
     * @param frame
     *            the frame for which the value is calculated
     * @return calculated ipo value
     */
    public float calculateValue(int frame) {
        return this.calculateValue(frame, 0);
    }

    /**
     * This method calculates the ipo value for the curve of the specified
     * index. Make sure you do not exceed the curves amount. Alway chech the
     * amount of curves before calling this method.
     *
     * @param frame
     *            the frame for which the value is calculated
     * @param curveIndex
     *            the index of the curve
     * @return calculated ipo value
     */
    public float calculateValue(int frame, int curveIndex) {
        return bezierCurves[curveIndex].evaluate(frame, BezierCurve.Y_VALUE);
    }

    /**
     * This method returns the frame where last bezier triple center point of
     * the specified bezier curve is located.
     *
     * @return the frame number of the last defined bezier triple point for the
     *         specified ipo
     */
    public int getLastFrame() {
        int result = 1;
        for (int i = 0; i < bezierCurves.length; ++i) {
            int tempResult = bezierCurves[i].getLastFrame();
            if (tempResult > result) {
                result = tempResult;
            }
        }
        return result;
    }

    /**
     * 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, 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[] { localTranslation.x, localTranslation.y, localTranslation.z };
            Quaternion[] rotations = new Quaternion[framesAmount + 1];
            float[] quaternionRotation = new float[] { localRotation.getX(), localRotation.getY(), localRotation.getZ(), localRotation.getW(), };
            float[] objectRotation = 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
                degreeToRadiansFactor *= FastMath.DEG_TO_RAD * 10;// the values in blender are divided by 10, so we need to mult it here
            }
            int yIndex = 1, zIndex = 2;
            boolean swapAxes = spatialTrack && fixUpAxis;
            if (swapAxes) {
                yIndex = 2;
                zIndex = 1;
            }

            // calculating track data
            for (int frame = startFrame; frame <= stopFrame; ++frame) {
                int index = frame - startFrame;
                times[index] = index * timeBetweenFrames;// start + (frame - 1) * 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;
                            break;
                        case AC_LOC_Y:
                            if (swapAxes && value != 0) {
                                value = -value;
                            }
                            translation[yIndex] = (float) value;
                            break;
                        case AC_LOC_Z:
                            translation[zIndex] = (float) value;
                            break;

                        // ROTATION (used with object animation)
                        case OB_ROT_X:
                            objectRotation[0] = (float) value * degreeToRadiansFactor;
                            break;
                        case OB_ROT_Y:
                            if (swapAxes && value != 0) {
                                value = -value;
                            }
                            objectRotation[yIndex] = (float) value * degreeToRadiansFactor;
                            break;
                        case OB_ROT_Z:
                            objectRotation[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:
                            quaternionRotation[3] = (float) value;
                            break;
                        case AC_QUAT_X:
                            quaternionRotation[0] = (float) value;
                            break;
                        case AC_QUAT_Y:
                            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());
                    }
                }
                translations[index] = localRotation.multLocal(new Vector3f(translation[0], translation[1], translation[2]));
                rotations[index] = spatialTrack ? new Quaternion().fromAngles(objectRotation) : new Quaternion(quaternionRotation[0], quaternionRotation[1], quaternionRotation[2], quaternionRotation[3]);
                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);
            }
        }
        return calculatedTrack;
    }
}
TOP

Related Classes of com.jme3.scene.plugins.blender.animations.Ipo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.