Anim8or Community
General Category => General Anim8or Forum => Topic started by: SubDrag on April 19, 2014, 02:09:46 am

I'm trying to convert some animation data into .an8 format, for use by anim8or. My original data is stored in euler angles, where you rotation each joint by X, then Y, then Z.
Unfortunately, setting anim8or rotations for a joint angle to that, doesn't get the correct rotation. How are anim8or rotations stored for joint angles, and how do I convert it?
For example, euler angles of 0 X, 90 Y, 90 Z do not yield correct rotations in anim8or. Below yields the wrong ones.
jointangle { "1113" "X"
track {
floatkey { 0 0 0 0 "C" }
floatkey { 15 0 0 0 "C" }
floatkey { 54 0 0 0 "C" }
floatkey { 67 0 0 0 "C" }
floatkey { 89 0 0 0 "C" }
}
}
jointangle { "1113" "Y"
track {
floatkey { 0 90 0 0 "C" }
floatkey { 15 90 0 0 "C" }
floatkey { 54 90 0 0 "C" }
floatkey { 67 90 0 0 "C" }
floatkey { 89 90 0 0 "C" }
}
}
jointangle { "1113" "Z"
track {
floatkey { 0 90 0 0 "C" }
floatkey { 15 90 0 0 "C" }
floatkey { 54 90 0 0 "C" }
floatkey { 67 90 0 0 "C" }
floatkey { 89 90 0 0 "C" }
}
}
My bone structure, is composed of 0 sized joints, and bones connecting each 0 length joint, and all rotations are around just joints.
Using these axes in my source data:
(http://x3dgraphics.com/examples/X3dForWebAuthors/Chapter03Grouping/CoordinateAxes.WhiteBackground.png)

Hi SubDrag, are you sure the animation data is in euler angles and not quaternions? Anim8or stores animations in euler angles (XYZ). In the floatkey block, it's { <frame #> <euler angle> <knot values/types/misc> }
I tested the (0, 90, 90) rotation on a figure's bones, and in the object editor on a cylinder, and they both behave as expected. Can you attach an example animation dataset and the desired outcome?
Also, other programs sometimes flip or switch one or more Axis'. Make sure you're actually translating the right ones.

It doesn't appear to be euler angles, at least, not the axes I'm using. Here is my sample file.
I am setting a "leaf" part, at a joint "bone" 14, to 90,90,0.0. In order to make it match what it should be, you would need to set 90,90,0. But there's not a simple pattern.
It should look like "expected.png". It results in anim8orresult.png. Also, weird, for that same part 14, is that (anim8or angles only) 90,90,90 is equal in anim8or to 0,0,90, which shouldn't be true if euler. If it were true euler, this would not be true.
Below are my tests of correct euler, vs anim8or.
Expected Anim8or needed to match
90,90,0 90,90,0
90,90,0 90,90,0
90,90,0 90,90,0
90,90,0 90,90,0
90,0,90 90,0,90
90,0,90 90,0,90
90,0,90 90,0,90
90,0,90 90,0,90
0,0,90 90,90,90 0,0,90
You can also see, that the FBX file (imported into a tool, such as XSI), with those rotations matches my picture...so anim8or isn't straight euler.
Anipov tool, open source, does not convert the rotations properly either to milkshape format, even when "fixed" in anim8or. So this doesn't seem well known unfortunately.

This is bone 14 in figure mode and front view.
Y blue to the right same direction as the bone
X green to the bottom of the screen
Z pink toward the user
right handed
Is this what you are using?

Honestly, Anim8or's orientation system always drives me nuts when trying to implement code around it. My observations:
 Orientations in shape properties in the object editor are PitchYawRoll. However, Edit>Rotate is different, doing AxisAngle rotations (as far as I can tell). If you set Edit>Rotate>Custom... to (45, 45, 45), you get different results than if you individually did (45, 0, 0), (0, 45, 0), (0, 0, 45) or any combination of those (I've tried every 45/45 combination, nothing matches (45, 45, 45). Shape PYR orientations are stored as Quaternions in the .an8 file. My assumption is that Anim8or converts PYR to Quaternions internally and uses Quaternions for transformations, then converts back to PYR for user reference.
 The figure editor uses PYR (stored as Quaternions). The sequence editor uses AxisAngle (stored as angles). Again, I have no idea how to convert between these two.
I'm going to be diving into the figure/sequence editor parts of the .an8 file soon, since loading animations is my next goal for the 3D viewer and .an8 file converter. Hopefully I can figure it out then, but it'd be awesome if someone in the know could shed light on how Anim8or converts between PYR, Quaternions, and AxisAngle values.

This is bone 14 in figure mode and front view.
Y blue to the right same direction as the bone
X green to the bottom of the screen
Z pink toward the user
right handed
Is this what you are using?
Hmm, wait, so the euler rotations are relative to the bone orientation? It seems almost perpendicular? Which faces the bone?

Each bone has its own axis system.
The global system is transformed by all the parents.
You should read this chapter of the manual:
http://www.anim8or.com/learn/manual/6_sequence_editor.html
especially this section:
http://www.anim8or.com/learn/manual/6_sequence_editor.html#making_a_key_pose
Reduce the size of your bone 14 and zoom in to see the axis.
If I remember well you have to select the bone and click on the show the axis button.

Does it use the same orientation as the bone's orientation (ie. relative to its parent?)? So it's like, taking the normal XYZ axis, rotating to bone orientation, then rotating euler from that? For my part 14, what did that equate to, for the XYZ directions?
To go from absolute euler, I suppose you need to, rotate the rotations by the rotation from axis to bone orientation...I think

Don't understand your question,but let me explain how I
see it and lets hope it helps.
With Euler if you do a X rotation of the bone,the YZ axis also
are rotated.When you do the Y rotation,it's relative to the new
location of the Y axis and the XZ axis also
are rotated.When you do the Z rotation,it's relative to the new
location of the Z axis and the XY axis also
are rotated.The final axis location is transfered to the child bone.
Rotate a bone in Anim8or with the axis shown,you'll see what
I mean.
I've never done a converter,but I would say:
both side should be Euler with order of rotation XYZ
system axis both right handed
first bone(root bone in Anim8or) aligned with Y axis before any rotation is applied(could that
be your problem?)
If something is different you need to correct the data.
Hope I didn't forget anything.

I get the concept, but unfortunately I'm very stuck on the math :( Does anyone have any help? basically, my angles are in euler XYZ, assuming normal axes, but anim8or's rotations are euler, but about the bone's orientation. I can't figure out how to convert.

I'm still stuck here, is there anyone who can help? Somehow I need to take euler XYZ, not relative to previous bone, and convert it to relative to bone for Anim8or.

I've been having similar problems with halflife SMD format. I've tried a bunch of stuff, but no luck either

Can't you add together all the orientations of the chain of parents to the root bone, to get the global orientation? Sorry, I think the same configuration is required in Collada files, but only barely touched on it with my converter before I took a break from it.

i thought anim8or stores rotations relative to the parent.

Converting other animation files to Anim8or is complicated not because of the math, but because the other animation formats have different skeleton standards and frames of reference. The first hurdle in converting formats is finding a way to correlate the foreign skeleton to an Anim8or skeleton. I found this to be the most challenging part because of two things: (1) most foreign formats use joints and Anim8or uses bones, and (2) the reference frames of foreign formats differs from Anim8or's. Once you solve the correspondence of foreign joints/bones to Anim8or's bones, you must deduce the the difference in world reference frames and rotate the skeleton into Anim8or's world reference frame.
The next challenge is deducing the reference frame of the foreign bone's orientation. In Anim8or, the orientation of each bone is relative to the parent (BVH and SMD are similar in that respect), but the reference frame in Anim8or is yaxis along the bone, lefthanded axis system. What is the foreign format reference frame axis system?
The foreign format's often give Euler angles for orientation, but does it use XYZ, YXZ, ZYX or other order? This must be deduced. Internally, Anim8or uses quaternions, so Euler to quaternion conversions must be done. The math for this conversion is different depending on what the world and local reference frame axis systems are.
These problems, coupled with the braintwisting nonintuitiveness of quaternions will make your brain explode! Each part of the conversion of a foreign format to Anim8or's is dependent on the previous part. You can get all but one step correct and the result will look as wrong as getting them all wrong.
The math (and code for the math) itself is fairly straightforward. Pretty much everything you need to know mathwise can be found on Martin Baker's site http://www.euclideanspace.com/maths/geometry/ (http://www.euclideanspace.com/maths/geometry/)

Sorry I was gone for a week, thanks for the reply! I'm trying to go from FBX format into anim8or format. It seems like XYZ euler angles in FBX. I sort of deduced similar to what you had, but I'm getting lost in getting from my euler, adjusted to the relative to parent bone. Not sure if you have done something similar and have at least pseudocode on how to do the conversion? I can't figure out the math to go from my euler, such as 15, 30, 45, to an euler relative to parent bone. Please help! Maybe assuming have parent's bone quaternion, and your XYZ euler relative to parent, how to go to anim8or XYZ.
I was able to get the skeleton fine translated, it's just the keyframe angles themselves that won't translate. I made a 0 sized node, which matched the way I had the FBX, in between bones, and those were used for rotations. I believe the issue is just translating rotations properly.
Here's my attempt at least...
FBX: http://goldeneyevault.com/priv/an8conversionattempt/animation.fbx
An8 (skeleton nodes):
FBX: http://goldeneyevault.com/priv/an8conversionattempt/animation.an8

Perhaps someone can help, I feel like sort of closer, perhaps the piece I am missing is still, how anim8or stores its angles.
I have a quaternion at a bone (absolute quaternion, basically, I trawled the hierarchy), that I'm doing rotation in anim8or of:
x 0.52576530 float
y 0.084034257 float
z 0.40772036 float
w 0.74180400 float
Off of this bone, in FBX format, a rotation (Euler XYZ of 58.675510 y=33.600880 z=38.327244), yields in anim8or 30 60 90, which matches and works great. However, converting to anim8or also always yields a second solution for anim8or, in this case, 150 120 140. I cannot figure out why in anim8or, that set of angles yields a different rotation visually. The quaternions should be identical (or 360 degrees off). Maybe someone can explain why those two rotations do not yield identical results about that bone, that would be very helpful!
I've attached the sample an8, go to sequence mode, then use this part:
(http://i.gyazo.com/5eb037b1a7ee0618fee8614318542c73.png)

Quaternions encode more than Euler angles. There are two unit queternions for a given Euler orientation. If you interpolate between q1 and q2 using the shortest path it traces a great circle path on the unit sphere. For example a path from New York to London across the Atlantic Ocean. If you substitute q2' (the alternate quaternion for q2) the shortest path in quaternion space is the long way around the sphere over the Pacific Ocean. So one way to think of it is that queternions encode a directional bias as well as an orientation.
When I return home in mid July I'll post a detailed description of what is happening but it's too difficult to do with a tablet.

maybe could you put something on how anim8or handles quaternions? maybe like a short example on drawing the bones in opengl

Yes, I'll post the code to convert to and from Euler angles, interpolate quaternion angles, etc.

Here's a short note on quaternions that might help explain why you're getting some whacky rotations in your .an8 files:
Quaternions and Anim8or (http://www.anim8or.com/learn/technical/quaternions_and_anim8or/quaternions_and_anim8or.htm)
I hope this explanation makes quaternions a bit clearer. Let me know if you have any questions. I'll be posting some source code a bit later.

Hi Steve, thanks for the writeup on quaternions :)

Hi Steve, just wanted to link you to another post.
http://www.anim8or.com/smf/index.php/topic,3953.msg38744.html#msg38744
I think Sub did get Quaternuions fixed but we ended up with another problem as described in the post.
Unless there is an easier way?
Trev