Possible bugfix for animation translations in Blender importer

Hi,

I believe I have a fix for a bug in the Blender importer for animated bone translations. I was importing a model from a recent version of Blender (2.65) and I noticed a problem with the animation - bone track rotations converted accurately but bone translations warped my model in unexpected ways. I isolated the problem with a simple animation where a cube drops down into another. When this animation played back in JME the bone was moving in the Z axis rather than the Y axis. This is a bug in com/jme3/scene/plugins/blender/animations/Ipo.java because ‘calculateTrack’ is not respecting the FixUpAxis flag when it’s not a spatialTrack. The code should be;

[java]
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 (fixUpAxis) {
translation[2] = (float) -value;
} else {
translation[1] = (float) value;
}
break;
case AC_LOC_Z:
translation[fixUpAxis ? 1 : 2] = (float) value;
break;

                                            // ROTATION (used with object animation)
                                            // the value here is in degrees divided by 10 (so in
                                            // example: 9 = PI/2)
                                            case OB_ROT_X:
                                                    objectRotation[0] = (float) value * degreeToRadiansFactor;
                                                    break;
                                            case OB_ROT_Y:
                                                    if (fixUpAxis) {
                                                            objectRotation[2] = (float) -value * degreeToRadiansFactor;
                                                    } else {
                                                            objectRotation[1] = (float) value * degreeToRadiansFactor;
                                                    }
                                                    break;
                                            case OB_ROT_Z:
                                                    objectRotation[fixUpAxis ? 1 : 2] = (float) value * degreeToRadiansFactor;
                                                    break;

                                            // SIZE
                                            case AC_SIZE_X:
                                                    scale[0] = (float) value;
                                                    break;
                                            case AC_SIZE_Y:
                                                    if (fixUpAxis) {
                                                            scale[2] = (float) value;
                                                    } else {
                                                            scale[1] = (float) value;
                                                    }
                                                    break;
                                            case AC_SIZE_Z:
                                                    scale[fixUpAxis ? 1 : 2] = (float) value;
                                                    break;

[/java]

I removed spatialTrack from the up axis correction test. I’m not sure why spatial tracks were being treated differently, but my test animation was now at least being translated in the correct axis with this change.

My original model was still not animating correctly however, and I isolated another problem with the following test model;

I animated this to drop the top box into the bottom box, but when played back in JME the box fell at a 45 degree angle (the same as the bone rotation). Taking a wild guess at how to fix this, I passed the bone quaternion rotation into the ‘calculateTrack’ method of Ipo.java via a ‘localQuaternionRotation’ parameter and multiplied the bone quaternion with the translation vector and then the animation worked as expected;

[java]
default:
LOGGER.warning("Unknown ipo curve type: " + bezierCurves[j].getType());
}
}

                            // (Original code)
                            // translations[index] = new Vector3f(translation[0], translation[1], translation[2]);

                            // The translation multiplied by the local bone quaternion which seems to
                            // be how Blender does translations.
                            if (localQuaternionRotation != null) {
                                    translations[index] = localQuaternionRotation.multLocal(new Vector3f(translation[0], translation[1], translation[2]));
                            } else {
                                    translations[index] = 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]);

[/java]

I have no idea if these changes are the result of changes in Blender or if animation translations have always been broken in JME. I don’t have the capability to test this and I’m a huge JME and Blender novice anyway. But I thought I’d post this because this information might be useful to the Blender importer developer.

5 Likes

Thanks, I’m sure @Kaelthas will find this interesting :slight_smile:

Thanks a lot Tobias for finding it.

Thanks to your code and test model I applied the fix.
Hope it will work fine now :wink:

3 Likes