-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Animation: quaternion vs. axis-angle #144
Comments
we choose axis angle because they can carry rotations > 2 * PI and they convert well to quaternion. |
note that we discussed that in length, but I don't mind re-evaluating options if needed. I use quaternions for interpolations but axis angle also. |
Ah, actually I think I remember some of this conversation 6+ months ago. @RemiArnaud and @tparisi should chime in, but if all our engines are converting to quaternion anyway, we are not getting the benefit of axis-angle and we're doing more client-side work than we'd like. |
Yes, that's exactly what al lot of engines are doing. For example, see Here's how it works in mode detail: the converter keeps does the 'right thing'. The conversion process is not a Most engines have several ways of interpolating values. Could be step, I hope I make sense. But basically, if we the converter can have the
accuracy is definitely a parameter to the converter. Regards On Fri, Oct 18, 2013 at 2:31 PM, Patrick Cozzi notifications@github.comwrote:
|
@tparisi are you also in support of replacing axis-angle with quaternions? |
Sorry for jumping in out of the blue, but I am someone on the internet with an opinion - more specifically, I'm someone who has spent a lot of time addressing angles in runtimes and tools :) I don't think you can argue that Euler with conversion is good enough, or quaternion with Euler is good enough. Sometimes artists need to animate an object through an orientation where Euler angles would introduce gimbal lock, and sometimes artists need to animate an object in a way that is easy to understand as an Euler angle so that the curve can carefully tuned, such as the rotation of a steering wheel, or a propellor on an airplane going through multiple revolutions. In Imath, https://github.com/openexr/openexr/blob/master/IlmBase/Imath/ImathEuler.h , we provided all 24 valid Euler representations because we found over the years that artists would choose the right one for their task at hand. Autodesk made a similar choice. http://download.autodesk.com/us/maya/2010help/API/class_m_euler_rotation.html It's also useful to provide interpolation options such as euler-linear, great-circle-nearest, or slerp. For example, the shortestUnitArc option on the rotate action here - https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKAction_Ref/Reference/Reference.html#//apple_ref/doc/uid/TP40013017 I don't think an approximation scheme will serve you well when you have concatenated rotations. Let's say you have a rig like a snake. o----o----o-----o . If the rotational tolerance at each node is r, and the number of nodes is n, and you are approximating the angles at each node, by the end of the chain, a concatenated transform is going to have an error bound of r^n in the components affected by rotation. In the case of a human it could mean the fingers twitch or move to weird positions. Finally, if you stick with what the artist authored, and you carry the numerical precision all the way through (i.e., they animated in IEEE float, and you run in IEEE float) then the accumulated error would have been visible to them in their authoring environment, and your run time will therefore be true to their intent. |
Yes, this is all true. And this level of complexity and flexibility is is very well handled by formats such as COLLADA. So all the information you are mentioning is available as input to the converter. But this all applies to authoring space, and when the data is processed for run time it looses most if not all its original authoring concepts. glTF is not designed for authoring, it is a final format for visualizing/animating targetting the OpenGL familly API. So, at the end of the day, do not expect the same euler system, interpolation method,keys, IK constraints, ... To exist in glTF it will all be backed in a way that is the best compromise we can come up with between size of data and friendlyness to the API -----Original Message----- Sorry for jumping in out of the blue, but I am someone on the internet with an opinion - more specifically, I'm someone who has spent a lot of time addressing angles in runtimes and tools :) I don't think you can argue that Euler with conversion is good enough, or quaternion with Euler is good enough. Sometimes artists need to animate an object through an orientation where Euler angles would introduce gimbal lock, and sometimes artists need to animate an object in a way that is easy to understand as an Euler angle so that the curve can carefully tuned, such as the rotation of a steering wheel, or a propellor on an airplane going through multiple revolutions. In Imath, https://github.com/openexr/openexr/blob/master/IlmBase/Imath/ImathEuler.h , we provided all 24 valid Euler representations because we found over the years that artists would choose the right one for their task at hand. Autodesk made a similar choice. http://download.autodesk.com/us/maya/2010help/API/class_m_euler_rotation.html It's also useful to provide interpolation options such as euler-linear, great-circle-nearest, or slerp. For example, the shortestUnitArc option on the rotate action here - https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKAction_Ref/Reference/Reference.html#//apple_ref/doc/uid/TP40013017 I don't think an approximation scheme will serve you well when you have concatenated rotations. Let's say you have a rig like a snake. o----o----o-----o . If the rotational tolerance at each node is r, and the number of nodes is n, and you are approximating the angles at each node, by the end of the chain, a concatenated transform is going to have an error bound of r^n in the components affected by rotation. In the case of a human it could mean the fingers twitch or move to weird positions. Finally, if you stick with what the artist authored, and you carry the numerical precision all the way through (i.e., they animated in IEEE float, and you run in IEEE float) then the accumulated error would have been visible to them in their authoring environment, and your run time will therefore be true to their intent. Reply to this email directly or view it on GitHub: |
You can't replace one by another since they are not exactly equivalent. Quaternions will, depending on the dataset, generate more data/keys. Axis-angle will keep the original keys. The real question is how much we want to push in the converter, and how conversion/backing we want. I don't have objections to either of the following choices:
However I would object to:
I hope this make sense. -----Original Message----- @tparisi are you also in support of replacing axis-angle with quaternions? Reply to this email directly or view it on GitHub: |
Thanks for the input @meshula. Yes, @RemiArnaud you have put the right words into what's glTF intention is. My suggestion is to provide both options:
I'd like we agree on this quicky so I move forward on the converter. |
As a side note, maybe we should rename the tool into compiler. A converter is more for a tool that can convert or translate between two equivalent representations. -----Original Message----- Thanks for the input @meshula. Yes, @RemiArnaud you have put the right words into what's glTF intention is. My suggestion is to provide both options:
I'd like we agree on this quicky so I move forward on the converter. Reply to this email directly or view it on GitHub: |
good point. |
Allowing either axis-angle or quaternion essentially covers the use cases I care about at run time :) |
Supporting both does not feel inline with the glTF vision. I opened this issue in the hopes of making the client do less work - the glTF vision - and now we are considering making it do more work. Look at runtime formats for major engines, what percentage of them support more than one representation? Yes, yes, glTF is more broad, but if we become too broad, then we have become an authoring format and have fallen short on the vision. Are there really enough prominent use cases to support both? I would rather stick with one (quaternions with converter support), and then ultimately promote an extension if enough folks find it valuable to have another representation. We can even have converter support for Eulers since it's already there. We can always add to glTF; removing is much harder. |
I am also OK with just quaternions and be conservative. |
How is this more work for the application? Application A want quaternions, ask for quaternions, and deal with quaternions Application B want axis/angle, ask for axis/angle, and deal with axis/angle -----Original Message----- Supporting both does not feel inline with the glTF vision. I opened this issue in the hopes of making the client do less work - the glTF vision - and now we are considering making it do more work. Look at runtime formats for major engines, what percentage of them support more than one representation? Yes, yes, glTF is more broad, but if we become too broad, then we have become an authoring format and have fallen short on the vision. Are there really enough prominent use cases to support both? I would rather stick with one (quaternions with converter support), and then ultimately promote an extension if enough folks find it valuable to have another representation. We can even have converter support for Eulers since it's already there. We can always add to glTF; removing is much harder. Reply to this email directly or view it on GitHub: |
Are there enough prominent uses? Yes. Object tumbling from baked physics sim: quaternion. Angles on a robotic arm: Euler. As Remi says, the application should be able to do the appropriate thing with the appropriate representation, not have to do it's own conversion to or from another representation. The properties of an Euler representation and a quaternion are not the same. |
If we support both, what does a compliant glTF implementation have to implement? Both, unless we fragment the market and they only have to support one. Then the only hope is that everyone is using a Rest3D server that can return the right representation: unlikely and a limitation that I wouldn't impose. So clients would need to support both and that makes it more work - and not inline with what we are trying to achieve unless the motivation is strong enough. |
I am at loss here. We have lots of options in the converter, and will have more. We have profiles coming. Since when does an application have to be able to load all possible combinasions of valid gltf files? If you want to do that, then yes, this is a bit more work than just loading the data you intent for your app. I personally do not see the point to do that, but you are free to do that. Now, why would you want to limit the options on gltf to the ones you want to support in your application? -----Original Message-----
If we support both, what does a compliant glTF implementation have to implement? Both, unless we fragment the market and they only have to support one. Then the only hope is that everyone is using a Rest3D server that can return the right representation: unlikely and a limitation that I wouldn't impose. So clients would need to support both and that makes it more work - and not inline with what we are trying to achieve unless the motivation is strong enough. Reply to this email directly or view it on GitHub: |
@RemiArnaud's point is that glTF is not an inter-exchange format. So adopters may convert assets to fit their needs. But it doesn't mean we can afford or want to specify here more variations of the same concept than what we absolutely need for a V1.0. Always better to be a bit frustrating, get more feedback and open up later. (nothing worse than API legacy:)). Now, I'd like bring back the discussion at the "needs" level and evaluate if there a case at run-time level that really mandates to get axis-angle representation at runtime over quaternions. So here are some facts here:
That's why on a practical matter, I tend to agree with Patrick to start conservative and only with quaternions. Because eventually they lead to more work on converter side and less work for clients which the trade-off that helps us make decisions here. Important Note Note: @RemiArnaud please use GitHub to answer issues:).. mail replies messes up answers... |
A couple more points.
|
I will claim that most if not all vertex shaders are using model matrices at the end. So, why don't we follow that logic and just do matrices? I do know of several engines that do just that, and then apply a compression algorithm specific to matrices to reduce the size of the animation data. It is all a matter of what the application point of view is. Previously someone pointed out that if you want to do robotic arms, and enable the application to do some IK, it is necessary to provide an axis angle, as the axis itself is very important in the math involved for those applications. Also, if your application depend of knowing how many turns you made around the axis, then you can only know that with axis angle. If you just care about interpolation animations, quaternions are just fine (if the converter did a correct job). So we're back to the question about limiting or not the use of the data/applications that glTF targets. If you can't afford (the time) to specify another form of rotation than the one currently in the spec and the converter, then why not keeping what we currently have and working on other issues? Clearly, axis/angle representation has more information than quaternion representation. Many different axis/angle will map to the same quaternion - as quaternions cannot store angles with multiple spins. You already said this. And also say that you want to ignore this fact because it is fine to limit the use case to animations where this information does not matter. So basically say you are ok to reduce the scope of use of glTF. The problem is that I don't see a compeling reason to do that. However I do see it to be a good convenience for the converter to export quaternions for applications that want to use this directly, but not at the cost of reducing the scope of glTF to other applications. PS: Sorry, github web does not work on my phone. I turned off my computer a while ago. I hope this message can be edited on the web to clean it up if needed. -----Original Message----- @RemiArnaud's point is that glTF is not an inter-exchange format. So adopters may convert assets to fit their needs. But it doesn't mean we can afford or want to specify here more variations of the same concept than what we absolutely need for a V1.0. Always better to be a bit frustrating, get more feedback and open up later. (nothing worse than API legacy:)). Now, I'd like bring back the discussion at the "needs" level and evaluate if there a case at run-time level that really mandates to get axis-angle representation at runtime over quaternions. So here are some facts here:
That's why on a practical matter, I tend to agree with Patrick to start conservative and only with quaternions. Because eventually they lead to more work on converter side and less work for clients which the trade-off that helps us make decisions here. Important Note Note: @RemiArnaud please use GitHub to answer issues:).. mail replies messes up answers... Reply to this email directly or view it on GitHub: |
This info is not available in the animations anyway. It's true that the animation with axis-angle will not have to be potentially split in multiple quaternions but it doesn't mean you will be able to know from there what's the maximum angles for IK. And you shouldn't get that info from animations... This kind of info goes outside the scope of animations playback, for instance in
It's the kind of topic that will be welcomed to experiment as extensions in glTF or in later revisions. I understand that's just an example, and there are maybe other more relevant situations, but I am just not convinced with this one for the reasons I just mentioned. |
Why not? All we ate talking about here is interpolation between 2 positions/orientations. How do I go from point A tio point B? What method do I want to apply, and do I have all the necessary input data for the interpolation I want to do. Axis angle have enough information to enable Direct angle interpolation, euler decomposition and interpolation, quaternion lerp, and even IK. Quaternions allow for ... Quaternion lerp. Note that this is not enough information to provide for smooth interpolations, such as bezier and hermite , as then you need additional control points or tangents. So we probably need to add more to cover more use cases. Also, physics engines, another form of controllers do not generally work with quaternions, |
I agree with you and @meshula that for curves the current design will have limitations but we have to start somewhere - but in practice export plugins already samples curves and the more you sample, the smoother you get, no news here right ? Again extensions will be welcomed to handle these cases when absolutely necessary for V1.0 adopters. But overall speaking of glTF V1.0 scope I thought it was clear at least with @pjcozzi , @tparisi and you that we'll put the together the first requirements for animation playback, in a way that takes discretized input and developers just have to interpolate for replay. Where the data comes from and how it was discretized/sampled is all a converter matter at this time. Here:
What do you mean ? that the converter is not currently doing a correct job ? Moreoever, do we agree that for complex animations due to COLLADA stack of transform (see above Important Note) and the fact that glTF just support TRS, (i.e no stack - like most engines) that either you sample/export a axis-angle or quaternion you will end with just an orientation in both cases ? I can send you examples offline if needed to show you one of these Here I am echoing @pjcozzi who has been advocating for quaternion because based on the experience of our implementations (that supports animations) this is the representation that surfaced as commonly used. @ryu2 and @meshula , @bhouston , @donny-dont and everyone reading this... |
@fabrobinet quaternions is fine for pure playback. You can not always properly motionblur a quaternion if it does more than a 360 rotation thought, without some special case code, thus that is one limitation. BTW http://clara.io now exports to glTF in the latest update. |
@bhouston awesome news, I'll try :) I don't know about the motion blur aspect WRT quaternion, I have to think/read up on this. I'll google that... As of now the only thing the converter would do is adding keys (i.e quaternion) to complete full rotation. Thanks for the input ! |
@fabrobinet, the quaternion, motionblur issue is just because quaternions can't represent multiple revolutions. But if you always ensure keyframes are never separated by more than 180 degrees, you can figure out where the previous keyframe was and ensure that one can interpolate properly. If you allow for keyframes to be further than 180 degrees apart it is ambiguous which way the rotation went -- both directions would result in the same quaternion. Basically quaternions can not specify revolutions. See this book page: |
@bhouston ah yes, then that's exactly the issue the converter will take care of when adding keyframes as needed. Thanks ! |
@fabrobinet When debugging Clara.io's glTF converter, remember that we first export to Collada before the glTF conversion. So if there is an issue just export to Collada and see if that file is okay (we just try to import it into Softimage, Maya, 3DS Max, etc...) |
Will you be able to test the converter and a client-side implementation in time for 1.0? If not, we could consider pushing 1.0 or target it for 1.0.1 or an extension. |
Have we decided what we are going to do here? |
Let's stick with axis angle for now... easy to add a |
@pjcozzi close or leave open? |
This is OK-ish, but then we are requiring implementations to convert to quaternion for animation so they can use SLERP (#156). Why not store quaternion initially as I originally said:
@tfili @tparisi is this not feasible given our timeline? If so, why exactly is hard about it? |
@pjcozzi it's super-easy. my importer is already converting from axis-angle so why bother? So do you want to just define I'm good with either. So, I changed my mind: now that we're changing the converter and loaders for 1.0 anyway, we might as well get this right. |
Yes, I think this is all that is needed for the schema change. |
then let's do it |
Looking at some of Fabrice's changes on dev-0.9 that had quaternion changes in it, he was exporting the quaternion as |
Also, we want to mention that quaternions should be unit length. |
Sorry, I mean they have |
Oh x,y,z,w in that order please! |
Ok. I'll change it to that. |
dev-1.0 updated at bb391e0 |
@tparisi once you update the spec we can close this. |
there's actually no language either way about quaternion vs. axis angle. I will add quaternion language. Can you give ma |
@pjcozzi I added language please review. |
Looks good. I made the unit quaternion explicit in 38dc6e8. |
Also mentioned |
I assume this was discussed at length, and, if so, we can just move on; I don't want to slow us down.
Both my implementation and @tparisi's use quaternions for rotation, which means that we have to convert the glTF axis-angle representation to a quaternion. I suspect that most non-trivial implementations will also quaternions, and it's no problem for the converter to output these.
So why did we go with axis-angle? To lower the barrier to entry? Would using quaternions plus having some quaternion-to-rotation-matrix and quaternion-interpolation examples be more in tune with the glTF vision - "avoid client-side work?"
The text was updated successfully, but these errors were encountered: