Closed der-On closed 8 years ago
First, why this happens: each key frame is a fully independent "pose" - that is, a rotation from the origin coordinate system to...something. Each key frame is -not- stored relative to its previous key frame.
Therefore:
This first case can be fixed by setting the axis to match its neighbors when the angle is 0.
This case -might- sometimes be fixable for two key frames by transforming both key frames by an arbitrary static rotation, such that the resulting rotation between key frames is constant-axis. The static transformation could then be merged with the static rotation. Note that if there is a dynamic translation, this would have to be translated too! Yikes.
Of coarse, there might simply be multiple arbitrary-angle rotations. in this case the only real solution is to decompose into multiple animations (or change X-Plane).
TODO: find out what the typical interpolation mode is for bones.
From talking to Alex: -Blender 2.49 appears to -only- support quaternion interpolation of pose bones. -Jonathan's exporter will only export a quaternion correctly when there is only one axis for all non-zero rotations.
Therefore we can probably:
Ondrej: if you can create a function that takes an axis-angle key frame table and "fixes" it (or returns some kind of failure for un-exportable) I can try to implement something equivalent to Jonathan's logic.
Will the exporter export the same thing as blender 2.49 without having to implement such non-quarternion rotations? Seems like it at least worked well enough to create something visible that appeared to work. On Oct 22, 2015 9:48 PM, "bsupnik" notifications@github.com wrote:
From talking to Alex: -Blender 2.49 appears to -only- support quaternion interpolation of pose bones. -Jonathan's exporter will only export a quaternion correctly when there is only one axis for all non-zero rotations.
Therefore we can probably:
- Convert all quaternions to axis-angle.
- For all axis-angle, correctly 'fix' the axis when 2a. The angle is 0 - pick another axis that someone else is using and 2b. The axis is opposite direction - the axis and angle can both be reversed.
Ondrej: if you can create a function that takes an axis-angle key frame table and "fixes" it (or returns some kind of failure for un-exportable) I can try to implement something equivalent to Jonathan's logic.
— Reply to this email directly or view it on GitHub https://github.com/der-On/XPlane2Blender/issues/142#issuecomment-150407201 .
Our expectation is that a Blender model from 2.49, once imported and forward converted using a one-time script, will export the same as 2.49, assuming quaternion-interpolated pose bones from 2.49.
In this particular case, I don't think the forward conversion script will do anything - we will be able to export the composition directly.
Are the bones and keys different now than from 2.49? Or do you use the same procedures? On Oct 24, 2015 10:28 PM, "bsupnik" notifications@github.com wrote:
Our expectation is that a Blender model from 2.49, once imported and forward converted using a one-time script, will export the same as 2.49, assuming quaternion-interpolated pose bones from 2.49.
In this particular case, I don't think the forward conversion script will do anything - we will be able to export the composition directly.
— Reply to this email directly or view it on GitHub https://github.com/der-On/XPlane2Blender/issues/142#issuecomment-150889276 .
The already shipping 2.70 exporter does not work the same as 2.49. When we are done with this animation upgrade, 2.70's capabilities will be a -superset- of 2.49, so you will have the option of:
It will not be legal to use a quaternion interpolation with 3 or more key frames where the axis of rotation is not consistent. This case (inconsistent) axis causes problems in the existing 2.49 exporter, so there is no "unsupported" case in the new exporter that is supported in the old one.
The math for converting a quaternion to axis-angle:
http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/
angle = 2 * acos(qw) x = qx / sqrt(1-qw_qw) y = qy / sqrt(1-qw_qw) z = qz / sqrt(1-qw*qw)
Special cases: First normalize the quaternion, such that qw is not negative and not more than 1 (that is, is in [0..1]). If qw is 1 then we have a singularity, but this is also angle = 0, so ... use angle = 0, axis = 0,0,1. The axis is arbitrary - since there is no rotation. We can "fix" angle mismatches later - see the next comment.
Otherwise, simply plug in this equation to get the axis angle from above. When done, normalize x,y,z for X-Plane. (Note: is the axis already normalized?)
Dealing with axis-angle mismatches:
Set our reference axis to undefined.
For each key frame: If rotation angle is 0, continue else if the reference axis is undefined set reference axis = this keyframe's axis else if the reference is equal to this axis continue else if the reference axis is opposite this axis invert axis and direction of this keyframe else error failure: we have at least two conflicting axes in a single key frame table - throw
if reference axis is still none: reference axis = 0,0,1 # note: in this case maybe we could have optimized out the rotate?!?
for each key frame set the axis to the reference axis
@bsupnik awesome. Will implement asap.
I think we need to do the following to make axis angle work:
find keyframe pairs where the axis changes. Inject 3rd keyframe between them which has axis of second keyframe. The angle has to recomputed to match the new axis however.
special case is initial and second keyframe:
if the initial keyframe and the next have differing axis, first keyframe should have axis of second keyframe (this is basically just an optimization of the injecting case)
Hi Ondrej,
I do not agree with this.
If -after the algorithm above- every key frame uses the same axis, we don't need to split anything - we can just write out the table.
If after the algorithm above the axes do not match, then no amount of key frame injection is going to solve the problem, because the rotation is not one that can be represented with a single axis-angle key-frame animation in X-Plane.
Two key frames isn't the special case - "all the same axis" is the special case.
Let's not get into building multiple animations out of a single weirdly-key-framed axis animation unless we get strong test data that shows this is needed.
But actually even in the simple test cases we have now, axis are different in each keyframe. Do we need some kind of conversion into our common axis?
Uh oh..that's pretty worrying. What's the test case name?
An example: tests/animation/TestCase4.blend
-> layer 11
@bsupnik Please comment on this.
Who made this test case? This looks like it should clearly be some kind of Euler but was converted to axis-angle representation? This isn't the kind of rotation you'd get off of a bone.
Problem: If creating keyframes and rotating within the viewport, blender tends to create different axis for each keyframe for quaternions and axis-angle rotations.