I’m creating an animation editor and I need to be able to save and load euler x,y,z components separately. The user uses eulers to create the keyframes, but they can choose to animate each component separately. The problem is that changing the value of one component will change the values of the other components in the rotation of an object, producing unpredictable results that force all components to be saved instead of just one. This makes it impossible to animate just one component…
So I need help- how can I operate on just one component and save/load that component reliably without requiring saving the other components?
Any help/direction would be appreciated.
I’ve been trying to create an example of what I am trying to accomplish:
Here you can see I have one quaternion that is rotated, and I am decomposing it into the x y and z rotations. However, I can’t figure out how to compose them back into the original Quaternion. I want the bottom Quaternion to match the top one…
Maybe I am going about it the wrong way?
Any help or direction would be appreciated. I need to be able to save the components and interpolate each one separately before loading it back into the object.
One tip: Animating one orientation to another should always be done with quaternions. Use euler angles only to setup a quaternion. But the actual processing of rotation data should always be done with quaternions.
TBH, I’m not sure I can follow your code. You should convert euler angles to quaternions always with
Quaternion.setFromEuler(). There is also
Euler.setFromQuaternion() for the other way around.
Right… I’m trying to use the Euler values to construct the keyframe data which then gets processed into Quaternions.
The problem I am having is that I want the user to be able to key each rotation component (x or y or z) separately…
The reason for this is because it will allow more control and flexibility while animating…
For instance… a user can animate an object rotating about the X component from time 0 to 4, but then have another track rotate the Y from time 2 to 6… this would have the object rotating around the X, then around both X and Y and finally continuing with the Y.
The problem arises when I try to interpolate the values at every frame if say it is 30fps… I need to interpolate the X and Y in this case to the correct rotation relative to the current frame, then pass these to a quaternion that will represent the orientation at that frame and store that in the actual animation action track stuff…
The issue is that Eulers don’t really separate the x y and z rotations, because you need all three to specify the orientation, which is why the values of a Euler flip when the pitch becomes outside of -90/90 degrees.
…So I basically have what… the object’s rotation (THREE.euler or THREE.quaternion)… but that doesn’t describe the rotating around a single X or Y or Z… the euler and quaternion combine all three because it is just an orientation.
So I’m stuck having to put all x,y,z into a single keyframe, which means I can’t interpolate the x or y or z separately before creating the combined orientation of those rotations.
I’m not sure if I’m explaining it well enough- maybe I’ve repeated myself a bit… but hopefully that explains my dilemma…
Maybe I am approaching this the wrong way though? Maybe there is a way to do what I want but in a different way???
when you use a unitary quaternion ( normalized ) it is easy to reverse q = w +xi+yj+zk = cos(alpha / 2 )+ u sin(alpha/2 ) with u = vector normalized of x,y,z axis and alpha= rotation around u .
inverse is q(-1) = w -xi-yj-zk = cos(alpha/2) -usin(alpha/2)
multiplication of quaternion is a sequence of rotation . q = q4q3q2q1 so to reverse previous step
q4(-1)q = q3q2q1 .
and sequence around x,y,z
q(x) = w + xi+0j+0k = cos(alpha/2) + sin(alpha/2) i around axis x
q(y) = w +0i +yj+0k = cos (alpha/2) + sin(alpha/2) j around axis y
q(z) = w + 0i+0j+zk = cos(alpha /2 ) +sin(alpha/2) k around axis z
edit: forget to tell , multiplication of quaternion ( like rotation ) is not commutative ( only associative ) so if you want back you have to store all quaternion use for sequence into an array .
Hey, can you explain why I would need to reverse a quaternion… and which quaternion? What does it mean to reverse a quaternion?
What do you mean when you say the “sequence around x,y,z”?
It looks like you are splitting a quaternion into multiple quaternions? I’m not sure I understand what you are saying…
So let me see if I understand this…
I’ll have to store the quaternion after every modification I make to an object in order to retrieve the current total rotation amounts in the x,y,z axes?
I’ll need to then loop through those, and apply the conjugate of the quaternion in the loop so that it reverses the rotation backwards towards the starting orientation… As I do this, I record the q(x),q(y),q(z) so that I have the sum rotation amount for each axis when I reach the original orientation?
hm… But does this work if each component is intended to be interpolated separately and at different times?
I can see this becoming a mess if I move forward or backward tthrough the timeline as the object plays the animation… the object would match the current frame which is a different orientation… then if I want to add a keyframe between others, or if I want to make a new rotation from an existing rotation which is an interpolated one… I’d have to record a quaternion from the interpolated quaternions? But then if I stop the animation, and the object returns to the identity rotation, then I lose track of the rotations…
sorry but my english is far from good , so it is often difficult for me to understand a question or explain something . The main idea is to understand multiplication of quaternion is not commutative like a sum of vector .
if V = Vzn+Vyn+Vxn+ … + Vz1+Vy1+Vx1
so you can write
V = ( Vzn+…+Vz1)+(Vyn+…+Vy1)+(Vxn+…+Vx1)
cause sum is commutative .
with rotation you can’t do that . the only way is to create a fictive euler rotation ( euler cause is what you are looking for ) of your object3D from your final quaternion .
so you create a var euler = new THREE.Euler( ); for example .
and you set euler with your quaternion final ( qf) . `
euler.setFromQuaternion( qf,‘ZXY’) ;
Edit; about interpolation
q_final = (q_jn) x (…) x (q_j1) x (q_im) x (…) x (q_i1) x (…) x (q_al) x ( …) x q_a1
cause multiplication of quaternion is associative you can write
q_final = ( (q_jn) x…x (q_j1) ) x ( (q_im) x …x (q_i1) ) x (…) x ( (q_al) x … x (q_a1) )
q_final = (q_j) x (q_i) x (…) x (q_a) with
q_j=(q_jn) x ( …) x (q_j1)
q_i=(q_im) x (…) x (q_i1)
q_a=(q_al) x (…) x (q_a1)
and create sequence of euler rotation euler_j.setFromQuaternion( q_j,‘ZXY’ )
hope this help .
I’m trying to get the angles of rotation for the object:
but it seems as though it is incorrect…
Top left mesh is the orientation… The top right mesh shows the incorrect rotation… The bottom 3 meshes show the rotations around each component, x, y, z…
I need to be able to recreate the rotations on a per component basis so that I can animate them separately…
Any help is appreciated…