Search Unity

Weird tangents at Keyframe creation

Discussion in 'Editor & General Support' started by n0mad, Oct 11, 2010.

  1. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Hello,

    Am I the only one to experience weird tangents at Keyframe creation by script ?

    All I'm performing is an AnimationCurve copy, with just a value shifting for certain keyframes.
    My copy method is creating a brand new Keyframe, from scratch, by leeching the original values. So there is no inherited properties at all that could interfere.

    As you can see in the picture attached, tangents are going crazy in the new keyframes. I've tried with forcing inTangent/outTangent to 0, tried without specifying them at all, and tried with copying them from their original.
    All the solutions lead to this weird behavior (which leads me to think it's a bug, as even 0 degree tangents would still contain these "hickups").

    Reporting it as a bug right now, but did any of you experienced this ?

    It's as if at some random times, the copied keyframe would force itself to take the original tangent values, whatever we are inputting. We can clearly see that problematic tangents have the exact same angle as the original keyframes.



    edit : As soon as I manually touch any tangent modifier in the Animation editor, all the hickups disappear instantly and return back to a normal state. But I can't rely on a manual solution, as there are more than 400 animation clips...
     

    Attached Files:

    Last edited: Oct 12, 2010
  2. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    In addition, I noticed that Unity docs make a reference to :

    But when I leech the FBX curve properties, they are :

    It worked perfectly with these "m_Local" prefixes prior to Unity 3.0, though. And it doesn't work if I write "local" prefixes instead in the animationCurves.

    Is it a documentation error ?
     
    Last edited: Oct 12, 2010
  3. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Well after some investigation, it really looks like the internal Transform combining function, as explained in the AnimationCurve.SetCurve() doc ("For performance reasons Transform position, rotation and scale can only be animated as one property"), does mess up with the Euler Rotation tangent generation.

    Kind of problematic :/
     
  4. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    precision : I have also tried to force a tangent smoothing with AnimationCurve.SmoothTangents() function on each keyframe of each new curve, but still no good.
     
  5. JFo

    JFo

    Joined:
    Dec 9, 2007
    Posts:
    217
  6. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Wow ..... 1 year old problem ?????

    Oh crap, that's a serious, serious issue then ...
    What I don't understand is that this tangent weirdness didn't happen at all in Unity iPhone 1.7 at all (I was using the exact same generation script).

    I admit I'm suddenly very worried to see that this problem remains one year later, as animation is a huge feature for any modern game.
     
    Last edited: Oct 12, 2010
  7. JFo

    JFo

    Joined:
    Dec 9, 2007
    Posts:
    217
    The possibility to get this fixed is better if you are able to send a bug report with example case where the problem is producible.

    Then you can send mail to support to ask more about the situation. Be aware, that there seem to be currently one week delay in support,
    so better act sooner than later..
     
  8. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Yep I filed a bug as soon as yesterday night.
    Didn't include anything else but this thread's first post, as the tangent problem is so generic it should happen any time one would want to create keyframes by Editor scripting.

    As it's been a year since the problem has been running, I can't help but worry much. So in case they do not priorize this bug, I'll just try to port the keyframe generation directly in Cinema 4D COFFEE, and then import the baked FBX without any Unity Asset PostProcessing.

    But still ... Did they even back you up since last year on this issue ??
     
  9. JFo

    JFo

    Joined:
    Dec 9, 2007
    Posts:
    217
    No, we didn't get any proper answer to this particular problem as there were other problems like crashing Animation Curve Editor, strange quaternion rotations etc. and we had limited time to invest in this bug, so we decided not to use Animation Curves at all in our product...

    It's a shame as it seems to be very good idea but if it doesn't work, what can you do..? Hope you'll get things sorted out!
     
  10. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Thank you :)
    I'll share any feedback from Unity.

    Wish you the best too.
     
  11. Paulius-Liekis

    Paulius-Liekis

    Joined:
    Aug 31, 2009
    Posts:
    672
    JFo problem (at least the first one) seems to be caused by the fact that curves are stored as quaternions, but displayed as eulers (or something like that). I'm not 100% sure about the second one - I would like to see the bug report on it. As I understand you reported the crash, but not the curve but itself, right? If not, do you still have the case number?

    n0mad, could you post your case number here?

    My usual recommendation is: if you're doing something funky with rotation angles you better of by animating some custom property and then applying it to your transform yourself in some script, because animating rotations might be complicated due to quaternion->euler->quaternion conversion. I'm not saying we want to live with these bugs - no, please submit them and we will try to address them, but I'm saying that you have to understand what's going on behind all conversions. This also means that you should never experience such problems with scale or position as there are no conversions involved.
     
  12. JFo

    JFo

    Joined:
    Dec 9, 2007
    Posts:
    217
    Hi Paulius! Thanks for popping in..

    Sorry if this is going to OT.. The crashing case (295628) seems to be closed, so hope it is fixed now. The problem with animation curves and quaternions was the main problem and we never get sorted it out, so we do the character animation directly without curves.

    Anyway, the bug shown in this thread and the thread I linked is something we didn't get any response and unfortunately we couldn't extract the relevant part from our code base. As our showstopper with curves was that quaternion problem, we didn't invest more effort to sort this
    spikes-in-curves case any further and went on with our own solution..

    It seems the n0mad have similar problems as us had as based on the curve naming he is working with character animations also..

    BR, Juha
     
  13. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Thank you Paulius for your very welcomed feedback.

    Bug submitted with Case 377865. I didn't attached any AnimationCurve, unfortunately, guessing it would be systematically reproducable (writing in "m_LocalRotation" x/y/z/w quaternion channels directly).

    I understand that the bug might happen during eulerAngles conversion, but may I insist on the important fact that the very same AnimationCurves treatment didn't have any bug in Unity iPhone (1.7.x). I could write "m_LocalRotation" channels directly and see a perfect animation result, without any weird behavior. I hope it can help Unity team to find a quicker solution, based on this working version.

    Well I'll try to stick with external software solution until then.

    Thank you for tapping our back ;)

    edit :
    Yeah sorry for the "bone_ass" naming, I didn't find any relative short equivalent :p
     
    Last edited: Oct 12, 2010
  14. Paulius-Liekis

    Paulius-Liekis

    Joined:
    Aug 31, 2009
    Posts:
    672
    It should be fixed then. I hate to hear that people who submit bugs do not get response. We are aware of this problem in Unity and we're trying to get better at this :)

    Yet again I think we're better at forum watch now than we were a year ago - we have people who make sure that complex issues are not left unanswered. Anyway you should have in mind that submitting a bug in such case is way higher chance that the issue won't left behind, because we have to deal with each bug - either solve it or postpone it. And it's not the same with forum threads - you can just forget them :)


    Now back to the topic again....
     
  15. Paulius-Liekis

    Paulius-Liekis

    Joined:
    Aug 31, 2009
    Posts:
    672
    I'll deal with this issue with n0mad on fogbuz in private and I'll update this thread when I'll have more details.
     
  16. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    I'll have access to my work station in approximately 5 hours, if any game object is needed.
    Thank you sir, you're awesomely awesome.
     
  17. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Feedback sent by mail, thanks.

    On a sidenote, I noticed :

    Yes, exactly, I do not experience any problem with position and scale, only with rotations.

    But I still fail to see what an quaternion->euler->quaternion conversion would have to do with tangents ? :)
    Tangents values are logically separate from channel data (localrotation, etc), so it shouldn't be interfered ?
     
    Last edited: Oct 12, 2010
  18. Paulius-Liekis

    Paulius-Liekis

    Joined:
    Aug 31, 2009
    Posts:
    672
    To anyone who is following this thread: I found that problem was in the way quaternions were constructed (on users side). If you're doing smart thing with quaternions I would really recommend reading about quaternion double coverage: http://mollyrocket.com/837
    Another problem was how quaternions are converted to euler angles, but it's nothing to do with how Unity works - it's general ambiguity of converting quaternions to euler angles and back: there is two-to-many relationship between quaternions and euler angles (one quaternion can be converted to infinite number of euler anlges and a set of euler angles can be converted to two quaternions), so Unity just makes it's best guess. Of course you could argue that it could make sure that euler angle curves are continuous, but that can cause problems in other cases. So I would call this "by design".
     
  19. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Yup, thank you Paulius for your awesome support (even if there are still some issues like "360° jumping to more than 360°" angle conversion).

    I still don't understand why there was no problem with iPhone Unity 1.7, though :)
     
  20. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    After a bit of searching, I found this post by Joachim :

    http://forum.unity3d.com/threads/1774-Euler-angles-inaccurate?highlight=Quaternion.Dot#8

    He proposes a function that can tell the angle between two rotations.
    Here, the basic idea of my problem is to copy the mirror image of a bone rotation to another bone (longer explanation here).

    for example, copy Bone_right_leg rotation to Bone_left_leg, but mirrored on the viewport X axis (the equivalent of a X-Axis -1 multiplication).

    My method is :

    1) store the Bone_right_leg and Bone_left_leg rest rotations (or unanimated, or bindposes, if you prefer)
    2) at each keyframe of an animation, calculate how much rotation Bone_right_leg has from its rest state.
    3) Apply this effective rotation to Bone_left_leg, with a 1/-1 factor on each axis, depending on its mirror axis dependancy (for some bones, a X mirroring would consider to revert the opposite bone's X and Y axis transformations, for some others, would be Y and Z, etc)

    So basically, as it seems like errors here come from euler conversion, this leads me to 2 questions :
    1) Is there a way to calculate a rotation from the difference of Rotation_A and Rotation_B, but in a Quaternion format (without ever using eulers) ?
    2) What is the right way to apply a euler(X, Y, Z) multiplication factor to a Quaternion (without ever using euler conversion once again) ?
    Matrices maybe ?

    Thank you for your attention, I'm still engineering the problem, and will share any solution found.
     
    Last edited: Oct 14, 2010
  21. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Update :

    Thanks to a well hidden www.gamedev.net thread, I found a way to determine the difference between 2 quaternions (i.e the rotation between 2 rotations) :

    q' = q1·¹ x q2

    So, with Unity, it would be :

    Quaternion.Inverse(q1)*q2;

    It will allow me to never ever use Euler conversion in the process, and then precisely determine if the weird tangents come from this conversion, or something else.


    edit : now remains one big unknown ... now that I have this "in-between rotation", how can I apply a Quaternion.Inverse() just on a single euler Axis, without ever using any Euler conversion ? :/

    Like :
    If calculated quaternion1.eulerAngles is Vector3(10, 90, 30), how do I then turn it to be Vector3(10, -90, -30) ?


    edit 2 : lol ok, I just realized it was as simple as multiplying the axis factor by quaternion.x, quaternion.y, or quaternion.z, and leaving quaternion.w as it is.
     
    Last edited: Oct 14, 2010
  22. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Case Solved !!!!

    Thanks to Paulius and his very dedicated explanations about Quaternions, I have understood its principles, and managed to find a clean calculation for mirroring a bone.

    Here is the idea, considering _xFactor, _yFactor, _zFactor have been explained previously :

    mirror_rotation = Quaternion.Inverse(boneToCopy_BindposeRotation) * boneToCopy_AnimatedRotation;
    mirror_rotation = new Quaternion(mirror_rotation.x * _xFactor, mirror_rotation.y * _yFactor, mirror_rotation.z * _zFactor, mirror_rotation.w);
    boneToChange_rotation =boneToChange_BindPoseRotation * (mirror_rotation);


    And ... that's all :D

    Mirrors are perfectly clean, with no delta at all from original.

    Thank you all, see ya later !


    Benjamin
     
    Last edited: Dec 17, 2010