Three.js: Animation system - keyframing (Euler) rotation doesn't work

Created on 8 May 2017  路  11Comments  路  Source: mrdoob/three.js

Codepen, see lines 42 - 51

Essentially, this keyframe works as expected:

const kf = new THREE.NumberKeyframeTrack( '.quaternion', [ 0, 1, 2 ], [  0, 0, 0, 1, Math.PI / 2, 0, Math.PI / 2, 1, 0, 0, 0, 1 ] );

while this keyframe does nothing

const kf = new THREE.NumberKeyframeTrack( '.rotation', [ 0, 1, 2 ], [  0, 0, 0, Math.PI, 0, Math.PI / 2, 0, 0, 0 ] );

Note: Also tested position and scale keyframes which also work as expected.

Three.js version
  • [ x ] Dev
  • [ x ] r85
Question

All 11 comments

To be honest, I鈥檓 not very surprised that this doesn鈥檛 work (since interpolating Euler angles is something which one generally doesn鈥檛 want to do).

BTW: To make the quaternion work correctly (the animation is quite different) you would have to use THREE.QuaternionKeyFrameTrack instead of THREE.NumberKeyFrameTrack (and I think it should better be THREE.VectorKeyFrameTrack for the position, but that changes only the type, not the functionality).

interpolating Euler angles is something which one generally doesn鈥檛 want to do

Because of Gimbal lock? In this case I just wanted to interpolate around a single axis, so that shouldn't be an issue.

I've updated the example to use QuaternionKeyFrameTrack, thanks.

I think it should better be THREE.VectorKeyFrameTrack for the position, but that changes only the type, not the functionality)

I was following the code from the example misc animation keys.

Perhaps we should update that to include one of each type of KeyFrameTrack?

Because of Gimbal lock?

Not only because of Gimbal lock. There are some visual demos on youtube which show the difference (I'm sure, I didn't find the best ones in my quick search):
https://www.youtube.com/watch?v=hBn2-gLe-Ts
https://www.youtube.com/watch?v=bnINsb0we7g
https://www.youtube.com/watch?v=0VAc_G79POE ( <- 馃槈 )

In this case I just wanted to interpolate around a single axis, so that shouldn't be an issue.

You tried to rotate around the x and z axis simultaneously (this is what you are actually doing when rotating around an arbitrary axis with Euler angles). So your use case is similar to the youtube demos.

I was following the code from the example misc animation keys.

If you make a console.log(scene.animations[0].tracks) in webgl_animation_scene , you can see how position and scale are usually stored in VectorKeyFrameTracks.

Perhaps we should update that to include one of each type of KeyFrameTrack?

I agree. I think it would be a good idea to use the usual pattern in that example, too.

You tried to rotate around the x and z axis simultaneously (this is what you are actually doing when rotating around an arbitrary axis with Euler angles). So your use case is similar to the youtube demos.

In the codepen, yes. Not in my actual app, but in any case I've switched to quaternions there now so it doesn't matter either way. Thanks for the videos though, good to know!

But I think two things should come of this issue:
First, we should find out if the rotation kf not working is intentional. If so there should be a warning or documentation to say this. If not, we should fix it.

Second, we should improve that example.

I think the reason might simply be that it was not implemented since it is not relevant?

If you make a console.log(propertyMixers[0].binding.resolvedProperty._order) in this place you can for example see that the x value of each second render loop is taken as the Euler _order which makes no sense and can't work because it would have to be a string like 'XYZ'.

And of course I fully agree to your two proposals.

Hmm... so I've had a bit of time to look into this and yes, interpolating Euler rotations is often problematic.
But nonetheless it seems strange to not support it, and particularly so without any kind of warning - there are cases where it will be fine (for example my case of only needing to rotate around a single axis).

Do other libraries / engines allow interpolating Euler angles? Perhaps the best thing to do here is figure out what the common practice is and follow that.

If you make a console.log(propertyMixers[0].binding.resolvedProperty._order) ...

Right. So it seems like it is probably not intentional, but rather doesn't work because one of the properties is a string and all properties for NumberKeyFrameTrack or VectorKeyframeTrack are taken together and lerped. So rotation would have to be added to PropertyBindings.js as a special case where the .order property is skipped. It looks like there is already one special case in that file, for MorphTargetInfluences, here.

I am not yet convinced at all that Euler angles interpolation should be implemented only for this special case. But as I wrote above I absolutely agree that there should be a warning, and a hint in the docs.

I am not yet convinced at all that Euler angles interpolation should be implemented only for this special case. But as I wrote above I absolutely agree that there should be a warning, and a hint in the docs.

Agreed.

How about just deleting these two lines?
https://github.com/mrdoob/three.js/blob/master/src/math/Euler.js#L303
https://github.com/mrdoob/three.js/blob/master/src/math/Euler.js#L319
Do they really serve any purpose? Deleting them does allow Euler interpolation to "work" with all the problems already described above.

Do they really serve any purpose?

They definitely do.

Could you elaborate just a bit on what that is? At times, we have seen this code attempt to force a string into a float array element and also attempt to add it past the end of the array. In such similar cases, it causes crashing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

donmccurdy picture donmccurdy  路  3Comments

makc picture makc  路  3Comments

akshaysrin picture akshaysrin  路  3Comments

danieljack picture danieljack  路  3Comments

yqrashawn picture yqrashawn  路  3Comments