Euler Angle Compression

I realize this is probably more of a math question than C++ question but I figured I might as well try asking here too since it is in the context of a C++ tool, someone here might know of an existing C++ library that does something like this, and I also imagine that people who are good at C++ are probably decent at math or at least much better at it than me. I suck at math and usually rely on ChatGPT for such things but in this case it's not providing good enough results for me.

CONTEXT FOR THE QUESTION

I'm porting animations between two video games from the same developer that use mostly the same skeleton and coordinate system. So in general, data can be ported from the source to destination exactly as it is. However, while both games use Euler angles to represent bone rotation data, the source game uses all 3 angles for every bone, but the destination game only allows for 2 angles for some of the bones while the remaining angle is always 0.

For now I'm specifically interested in character arms that mainly consist of the following bones: shoulder, upper arm, forearm. Shoulder uses 2 angles (pitch, roll), upper arm uses 3 angles (yaw, pitch, roll), forearm uses 2 angles (yaw, pitch). Angle order for all the bones is YXZ (yaw, pitch, roll).

THE QUESTION

Having data for all 3 angles for all 3 arm bones from the source game, how do I convert it to the destination game's format by discarding shoulder's yaw data and forearm's roll data but modifying all the remaining data to achieve the best possible visual match to the original animation?

Is it at all possible to calculate something like this? I'm thinking it should be possible since the games share a lot of animations that look the same visually. So the developers must have had some kind of way to discard some of the data and compensate for it by modifying other values.

I have managed to do it manually for one frame by experimenting with different values but obviously it's not viable to do if for every frame in many animations.

For example, in this frame the original data is (in degrees, the order is yaw, pitch, roll):
Shoulder 4.22, -11.25, -105.47
Upper arm -11.25, -29.53, -45.00
Forearm 21.09, -30.94, -111.09

My modified data:
Shoulder 0.00, -11.25, -105.47
Upper arm 49.22, -29.53, -45.00
Forearm -105.47, -98.44, 0.00

What the result looks like (look at the left arm only). Of course, it won't be an exact match but something like this is close enough for me if I can automate the process.

https://i.sstatic.net/XWepsVJc.gif
is this not just the standard 3d to 2d that is used in 3d graphics which display on a 2d screen?
that is just done with matrix transforms & projection tricks. Its well known -- try looking it up from that side (as if you were writing your own graphics engine)
It looks to me like the rotations are simply discarding a coordinate from the transformations?

Assuming a 3-vector for the bone rotations, the transformation matrix is the same — except you do not rotate the axis that remains stationary.


Projection onto a 2D surface is a different transformation, but uses the same-sized transformation matrix. The way you set it up is a little tricky, though.


Any decent OpenGL-based renderer will have this kind of stuff built-in. You don’t even have to pretend the 3D stuff is 2D — just give it to OGL and it’ll do the projections for you. You’d only need to mess with the rotations in the 3D space.
Registered users can post here. Sign in or register to post.