Search in sources :

Example 46 with Bone

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

the class AnimationHelper method getTracks250.

/**
     * This method retuns the bone tracks for animation for blender version 2.50
     * and higher.
     * 
     * @param actionStructure
     *            the structure containing the tracks
     * @param blenderContext
     *            the blender context
     * @return a list of tracks for the specified animation
     * @throws BlenderFileException
     *             an exception is thrown when there are problems with the blend
     *             file
     */
private BlenderAction getTracks250(Structure actionStructure, BlenderContext blenderContext) throws BlenderFileException {
    LOGGER.log(Level.FINE, "Getting tracks!");
    Structure groups = (Structure) actionStructure.getFieldValue("groups");
    // bActionGroup
    List<Structure> actionGroups = groups.evaluateListBase();
    BlenderAction blenderAction = new BlenderAction(actionStructure.getName(), blenderContext.getBlenderKey().getFps());
    int lastFrame = 1;
    for (Structure actionGroup : actionGroups) {
        String name = actionGroup.getFieldValue("name").toString();
        List<Structure> channels = ((Structure) actionGroup.getFieldValue("channels")).evaluateListBase();
        BezierCurve[] bezierCurves = new BezierCurve[channels.size()];
        int channelCounter = 0;
        for (Structure c : channels) {
            int type = this.getCurveType(c, blenderContext);
            Pointer pBezTriple = (Pointer) c.getFieldValue("bezt");
            List<Structure> bezTriples = pBezTriple.fetchData();
            bezierCurves[channelCounter++] = new BezierCurve(type, bezTriples, 2);
        }
        Ipo ipo = new Ipo(bezierCurves, fixUpAxis, blenderContext.getBlenderVersion());
        lastFrame = Math.max(lastFrame, ipo.getLastFrame());
        blenderAction.featuresTracks.put(name, ipo);
    }
    blenderAction.stopFrame = lastFrame;
    return blenderAction;
}
Also used : ConstIpo(com.jme3.scene.plugins.blender.animations.Ipo.ConstIpo) Pointer(com.jme3.scene.plugins.blender.file.Pointer) Structure(com.jme3.scene.plugins.blender.file.Structure) BezierCurve(com.jme3.scene.plugins.blender.curves.BezierCurve)

Example 47 with Bone

use of com.jme3.animation.Bone 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)

Example 48 with Bone

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

the class RagdollUtils method setTransform.

/**
     * Updates a bone position and rotation.
     * if the child bones are not in the bone list this means, they are not associated with a physic shape.
     * So they have to be updated
     * @param bone the bone
     * @param pos the position
     * @param rot the rotation
     */
public static void setTransform(Bone bone, Vector3f pos, Quaternion rot, boolean restoreBoneControl, Set<String> boneList) {
    //we ensure that we have the control
    if (restoreBoneControl) {
        bone.setUserControl(true);
    }
    //we set te user transforms of the bone
    bone.setUserTransformsInModelSpace(pos, rot);
    for (Bone childBone : bone.getChildren()) {
        //each child bone that is not in the list is updated
        if (!boneList.contains(childBone.getName())) {
            Transform t = childBone.getCombinedTransform(pos, rot);
            setTransform(childBone, t.getTranslation(), t.getRotation(), restoreBoneControl, boneList);
        }
    }
    //we give back the control to the keyframed animation
    if (restoreBoneControl) {
        bone.setUserControl(false);
    }
}
Also used : Bone(com.jme3.animation.Bone) Transform(com.jme3.math.Transform)

Example 49 with Bone

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

the class RagdollUtils method makeShapeFromVerticeWeights.

/**
     * Create a hull collision shape from linked vertices to this bone.
     * 
     * @param model
     * @param boneIndices
     * @param initialScale
     * @param initialPosition
     * @param weightThreshold
     * @return 
     */
public static HullCollisionShape makeShapeFromVerticeWeights(Spatial model, List<Integer> boneIndices, Vector3f initialScale, Vector3f initialPosition, float weightThreshold) {
    ArrayList<Float> points = new ArrayList<Float>();
    if (model instanceof Geometry) {
        Geometry g = (Geometry) model;
        for (Integer index : boneIndices) {
            points.addAll(getPoints(g.getMesh(), index, initialScale, initialPosition, weightThreshold));
        }
    } else if (model instanceof Node) {
        Node node = (Node) model;
        for (Spatial s : node.getChildren()) {
            if (s instanceof Geometry) {
                Geometry g = (Geometry) s;
                for (Integer index : boneIndices) {
                    points.addAll(getPoints(g.getMesh(), index, initialScale, initialPosition, weightThreshold));
                }
            }
        }
    }
    float[] p = new float[points.size()];
    for (int i = 0; i < points.size(); i++) {
        p[i] = points.get(i);
    }
    return new HullCollisionShape(p);
}
Also used : Geometry(com.jme3.scene.Geometry) Spatial(com.jme3.scene.Spatial) Node(com.jme3.scene.Node) HullCollisionShape(com.jme3.bullet.collision.shapes.HullCollisionShape) SixDofJoint(com.jme3.bullet.joints.SixDofJoint)

Example 50 with Bone

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

the class RagdollUtils method makeShapeFromPointMap.

/**
     * Create a hull collision shape from linked vertices to this bone.
     * Vertices have to be previoulsly gathered in a map using buildPointMap method
     * 
     * @param pointsMap
     * @param boneIndices
     * @param initialScale
     * @param initialPosition
     * @return 
     */
public static HullCollisionShape makeShapeFromPointMap(Map<Integer, List<Float>> pointsMap, List<Integer> boneIndices, Vector3f initialScale, Vector3f initialPosition) {
    ArrayList<Float> points = new ArrayList<Float>();
    for (Integer index : boneIndices) {
        List<Float> l = pointsMap.get(index);
        if (l != null) {
            for (int i = 0; i < l.size(); i += 3) {
                Vector3f pos = new Vector3f();
                pos.x = l.get(i);
                pos.y = l.get(i + 1);
                pos.z = l.get(i + 2);
                pos.subtractLocal(initialPosition).multLocal(initialScale);
                points.add(pos.x);
                points.add(pos.y);
                points.add(pos.z);
            }
        }
    }
    float[] p = new float[points.size()];
    for (int i = 0; i < points.size(); i++) {
        p[i] = points.get(i);
    }
    return new HullCollisionShape(p);
}
Also used : Vector3f(com.jme3.math.Vector3f) HullCollisionShape(com.jme3.bullet.collision.shapes.HullCollisionShape) SixDofJoint(com.jme3.bullet.joints.SixDofJoint)

Aggregations

Bone (com.jme3.animation.Bone)35 Vector3f (com.jme3.math.Vector3f)25 Quaternion (com.jme3.math.Quaternion)17 TempVars (com.jme3.util.TempVars)13 SixDofJoint (com.jme3.bullet.joints.SixDofJoint)10 FloatBuffer (java.nio.FloatBuffer)10 VertexBuffer (com.jme3.scene.VertexBuffer)8 HashMap (java.util.HashMap)8 Skeleton (com.jme3.animation.Skeleton)7 Matrix4f (com.jme3.math.Matrix4f)7 Transform (com.jme3.math.Transform)7 BoneContext (com.jme3.scene.plugins.blender.animations.BoneContext)7 ByteBuffer (java.nio.ByteBuffer)7 BoneTrack (com.jme3.animation.BoneTrack)6 Structure (com.jme3.scene.plugins.blender.file.Structure)6 ArrayList (java.util.ArrayList)6 AnimControl (com.jme3.animation.AnimControl)5 Spatial (com.jme3.scene.Spatial)5 Map (java.util.Map)5 Animation (com.jme3.animation.Animation)4