Bugfix: properly importing object animations where not all axes are being animated by the ipo curves (provided by arpagaus - thanks a lot :) ).

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10952 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
experimental
Kae..pl 11 years ago
parent 4e98d0e13d
commit 6708cf0d7f
  1. 4
      engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.java
  2. 36
      engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java
  3. 9
      engine/src/blender/com/jme3/scene/plugins/blender/animations/IpoHelper.java
  4. 4
      engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ObjectAnimationModifier.java

@ -183,7 +183,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
Bone bone = skeleton.getBone(boneIndex); Bone bone = skeleton.getBone(boneIndex);
Ipo ipo = new Ipo(bezierCurves, fixUpAxis, blenderContext.getBlenderVersion()); 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); this.equaliseBoneTracks(tracks);
@ -221,7 +221,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
Bone bone = skeleton.getBone(boneIndex); Bone bone = skeleton.getBone(boneIndex);
Ipo ipo = ipoHelper.fromIpoStructure(ipoStructure, blenderContext); Ipo ipo = ipoHelper.fromIpoStructure(ipoStructure, blenderContext);
if (ipo != null) { 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));
} }
} }
} }

@ -115,23 +115,29 @@ public class Ipo {
* the index of the target for which the method calculates the * the index of the target for which the method calculates the
* tracks IMPORTANT! Aet to -1 (or any negative number) if you * tracks IMPORTANT! Aet to -1 (or any negative number) if you
* want to load spatial animation. * 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 local rotation of the object/bone that will be animated by
* the track * the track
* @param localScale
* the local scale of the object/bone that will be animated by
* the track
* @param startFrame * @param startFrame
* the firs frame of tracks (inclusive) * the first frame of tracks (inclusive)
* @param stopFrame * @param stopFrame
* the last frame of the tracks (inclusive) * the last frame of the tracks (inclusive)
* @param fps * @param fps
* frame rate (frames per second) * frame rate (frames per second)
* @param spatialTrack * @param spatialTrack
* this flag indicates if the track belongs to a spatial or to a * 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) * in blender have the same type of coordinate system (Y as UP)
* as jme while other features have different one (Z is UP) * as jme while other features have different one (Z is UP)
* @return bone track for the specified bone * @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) { if (calculatedTrack == null) {
// preparing data for track // preparing data for track
int framesAmount = stopFrame - startFrame; int framesAmount = stopFrame - startFrame;
@ -139,18 +145,18 @@ public class Ipo {
float[] times = new float[framesAmount + 1]; float[] times = new float[framesAmount + 1];
Vector3f[] translations = new Vector3f[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]; Quaternion[] rotations = new Quaternion[framesAmount + 1];
float[] quaternionRotation = new float[] { 0, 0, 0, 1 }; float[] quaternionRotation = new float[] { localRotation.getX(), localRotation.getY(), localRotation.getZ(), localRotation.getW(), };
float[] objectRotation = new float[3]; float[] objectRotation = localRotation.toAngles(null);
Vector3f[] scales = new Vector3f[framesAmount + 1]; 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; float degreeToRadiansFactor = 1;
if (blenderVersion < 250) {// in blender earlier than 2.50 the values are stored in degrees 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 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; int yIndex = 1, zIndex = 2;
if(spatialTrack && fixUpAxis) { if (spatialTrack && fixUpAxis) {
yIndex = 2; yIndex = 2;
zIndex = 1; zIndex = 1;
} }
@ -163,12 +169,12 @@ public class Ipo {
for (int j = 0; j < bezierCurves.length; ++j) { for (int j = 0; j < bezierCurves.length; ++j) {
double value = bezierCurves[j].evaluate(frame, BezierCurve.Y_VALUE); double value = bezierCurves[j].evaluate(frame, BezierCurve.Y_VALUE);
switch (bezierCurves[j].getType()) { switch (bezierCurves[j].getType()) {
// LOCATION // LOCATION
case AC_LOC_X: case AC_LOC_X:
translation[0] = (float) value; translation[0] = (float) value;
break; break;
case AC_LOC_Y: case AC_LOC_Y:
if(fixUpAxis && value != 0) { if (fixUpAxis && value != 0) {
value = -value; value = -value;
} }
translation[yIndex] = (float) value; translation[yIndex] = (float) value;
@ -182,7 +188,7 @@ public class Ipo {
objectRotation[0] = (float) value * degreeToRadiansFactor; objectRotation[0] = (float) value * degreeToRadiansFactor;
break; break;
case OB_ROT_Y: case OB_ROT_Y:
if(fixUpAxis && value != 0) { if (fixUpAxis && value != 0) {
value = -value; value = -value;
} }
objectRotation[yIndex] = (float) value * degreeToRadiansFactor; objectRotation[yIndex] = (float) value * degreeToRadiansFactor;
@ -210,10 +216,10 @@ public class Ipo {
quaternionRotation[0] = (float) value; quaternionRotation[0] = (float) value;
break; break;
case AC_QUAT_Y: case AC_QUAT_Y:
if(fixUpAxis && value != 0) { if (fixUpAxis && value != 0) {
value = -value; value = -value;
} }
quaternionRotation[yIndex] = (float)value; quaternionRotation[yIndex] = (float) value;
break; break;
case AC_QUAT_Z: case AC_QUAT_Z:
quaternionRotation[zIndex] = (float) value; quaternionRotation[zIndex] = (float) value;
@ -222,7 +228,7 @@ public class Ipo {
LOGGER.log(Level.WARNING, "Unknown ipo curve type: {0}.", bezierCurves[j].getType()); 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]); 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]); scales[index] = new Vector3f(scale[0], scale[1], scale[2]);
} }

@ -1,7 +1,11 @@
package com.jme3.scene.plugins.blender.animations; package com.jme3.scene.plugins.blender.animations;
import java.util.List;
import java.util.logging.Logger;
import com.jme3.animation.BoneTrack; import com.jme3.animation.BoneTrack;
import com.jme3.math.Quaternion; import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.plugins.blender.AbstractBlenderHelper; import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
import com.jme3.scene.plugins.blender.BlenderContext; import com.jme3.scene.plugins.blender.BlenderContext;
import com.jme3.scene.plugins.blender.curves.BezierCurve; import com.jme3.scene.plugins.blender.curves.BezierCurve;
@ -11,9 +15,6 @@ import com.jme3.scene.plugins.blender.file.FileBlockHeader;
import com.jme3.scene.plugins.blender.file.Pointer; import com.jme3.scene.plugins.blender.file.Pointer;
import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.file.Structure;
import java.util.List;
import java.util.logging.Logger;
/** /**
* This class helps to compute values from interpolation curves for features * This class helps to compute values from interpolation curves for features
* like animation or constraint influence. The curves are 3rd degree bezier * like animation or constraint influence. The curves are 3rd degree bezier
@ -186,7 +187,7 @@ public class IpoHelper extends AbstractBlenderHelper {
} }
@Override @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!"); throw new IllegalStateException("Constatnt ipo object cannot be used for calculating bone tracks!");
} }
} }

@ -26,7 +26,7 @@ import com.jme3.scene.plugins.blender.file.BlenderFileException;
private static final Logger LOGGER = Logger.getLogger(ObjectAnimationModifier.class.getName()); private static final Logger LOGGER = Logger.getLogger(ObjectAnimationModifier.class.getName());
/** Loaded animation data. */ /** Loaded animation data. */
private AnimationData animationData; private AnimationData animationData;
/** /**
* This constructor reads animation of the object itself (without bones) and * This constructor reads animation of the object itself (without bones) and
@ -53,7 +53,7 @@ import com.jme3.scene.plugins.blender.file.BlenderFileException;
Spatial object = (Spatial) blenderContext.getLoadedFeature(objectOMA, LoadedFeatureDataType.LOADED_FEATURE); Spatial object = (Spatial) blenderContext.getLoadedFeature(objectOMA, LoadedFeatureDataType.LOADED_FEATURE);
// calculating track // 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 animation = new Animation(objectAnimationName, ipo.getLastFrame() / (float) fps);
animation.setTracks(new SpatialTrack[] { track }); animation.setTracks(new SpatialTrack[] { track });

Loading…
Cancel
Save