Hi all
I have a small but (at least for me) a useful enhancement. In blender simple key-frame animations can record location, rotation and scale for each axis separately and the user is free to record key-frames for certain axis only. The allows animations to be conveniently reused on multiple objects, if e.g. they move all along the x axis but have different y&z values.
However, the JME blender import currently initializes location, rotation and scale with a zero Vector3f / identity Quaternion, thus the position in the SpatialTrack will be incorrect.
To correct this and make animations behave in JME as they do in Blender I’ve created a patch for the Ipo class which initializes location, rotation & scale with the object’s transform instead of using zero values.
@Kaelthas
I’ve tested it for animations but not bones and I’d be glad if you could review this and push it to the core, because I think it would be nice if animations behave in JME as they do in Blender
Cheers!
This is the patch:
[java]
From b8920c46f9e7c69c0725d6e8601400557b71e9e5 Mon Sep 17 00:00:00 2001
Date: Wed, 1 Jan 2014 16:55:39 +0100
Subject: [PATCH] Use the object’s local transform for the initial IPO track
values to achieve the same behaviour as in Blender
…/plugins/blender/animations/ArmatureHelper.java | 4 ±
…/jme3/scene/plugins/blender/animations/Ipo.java | 45 ++++++++++++++++±----
…/plugins/blender/animations/1f252995fdd6493ba6a24b192d89d1f95b38937eIpoHelper.java | 3 ±
…/blender/modifiers/ObjectAnimationModifier.java | 2 ±
4 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.java
index 0864a12…6903c21 100644
— a/engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.java
+++ b/engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.java
@@ -183,7 +183,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
Bone bone = skeleton.getBone(boneIndex);
Ipo ipo = new Ipo(bezierCurves, fixUpAxis, blenderContext.getBlenderVersion());
-
tracks.add((BoneTrack) ipo.calculateTrack(boneIndex, bone.getLocalRotation(), 0, ipo.getLastFrame(), fps, false));
-
tracks.add((BoneTrack) ipo.calculateTrack(boneIndex, bone.getLocalPosition(), bone.getLocalRotation(), bone.getLocalScale(), 0, ipo.getLastFrame(), fps, false)); } } this.equaliseBoneTracks(tracks);
@@ -221,7 +221,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
Bone bone = skeleton.getBone(boneIndex);
Ipo ipo = ipoHelper.fromIpoStructure(ipoStructure, blenderContext);
if (ipo != null) {
-
tracks.add((BoneTrack) ipo.calculateTrack(boneIndex, bone.getLocalRotation(), 0, ipo.getLastFrame(), fps, false));
-
tracks.add((BoneTrack) ipo.calculateTrack(boneIndex, bone.getLocalPosition(), bone.getLocalRotation(), bone.getLocalScale(), 0, ipo.getLastFrame(), fps, false)); } } }
diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java b/engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java
index 423c87f…e412460 100644
— a/engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java
+++ b/engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java
@@ -115,40 +115,64 @@ public class Ipo {
* 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 localQuaternionRotation
-
* @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 firs frame of tracks (inclusive)
-
* 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 diference is important because it appears that bones
-
* 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, Quaternion localQuaternionRotation, int startFrame, int stopFrame, int fps, boolean spatialTrack) {
-
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[3];
-
float[] translation = new float[] {
-
localTranslation.x,
-
localTranslation.y,
-
localTranslation.z
-
};
-
Quaternion[] rotations = new Quaternion[framesAmount + 1];
-
float[] quaternionRotation = new float[] { 0, 0, 0, 1 };
-
float[] objectRotation = new float[3];
-
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[] { 1.0f, 1.0f, 1.0f };
-
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; if(spatialTrack && fixUpAxis) { yIndex = 2;
@@ -160,6 +184,9 @@ public class Ipo {
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()) {
@@ -222,7 +249,7 @@ public class Ipo {
LOGGER.log(Level.WARNING, “Unknown ipo curve type: {0}.”, bezierCurves[j].getType());
}
}
-
translations[index] = localQuaternionRotation.multLocal(new Vector3f(translation[0], translation[1], translation[2]));
-
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]); }
diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/animations/IpoHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/animations/IpoHelper.java
index 5dbf923…a65f4e9 100644
— a/engine/src/blender/com/jme3/scene/plugins/blender/animations/IpoHelper.java
+++ b/engine/src/blender/com/jme3/scene/plugins/blender/animations/IpoHelper.java
@@ -2,6 +2,7 @@ package com.jme3.scene.plugins.blender.animations;
import com.jme3.animation.BoneTrack;
import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
import com.jme3.scene.plugins.blender.BlenderContext;
import com.jme3.scene.plugins.blender.curves.BezierCurve;
@@ -186,7 +187,7 @@ public class IpoHelper extends AbstractBlenderHelper {
}
@Override
-
public BoneTrack calculateTrack(int boneIndex, Quaternion localQuaternionRotation, int startFrame, int stopFrame, int fps, boolean boneTrack) {
-
public BoneTrack calculateTrack(int boneIndex, Vector3f localTranslation, Quaternion localRotation, Vector3f localScale, int startFrame, int stopFrame, int fps, boolean boneTrack) { throw new IllegalStateException("Constatnt ipo object cannot be used for calculating bone tracks!"); }
}
diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ObjectAnimationModifier.java b/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ObjectAnimationModifier.java
index 0895a0d…8f21afe 100644
— a/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ObjectAnimationModifier.java
+++ b/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ObjectAnimationModifier.java
@@ -53,7 +53,7 @@ import com.jme3.scene.plugins.blender.file.BlenderFileException;Spatial object = (Spatial) blenderContext.getLoadedFeature(objectOMA, LoadedFeatureDataType.LOADED_FEATURE); // calculating track
-
SpatialTrack track = (SpatialTrack) ipo.calculateTrack(-1, object.getLocalRotation(), 0, ipo.getLastFrame(), fps, true);
-
SpatialTrack track = (SpatialTrack) ipo.calculateTrack(-1, object.getLocalTranslation(), object.getLocalRotation(), object.getLocalScale(), 0, ipo.getLastFrame(), fps, true); Animation animation = new Animation(objectAnimationName, ipo.getLastFrame() / (float) fps); animation.setTracks(new SpatialTrack[] { track });
–
1.8.3.2
[/java]