Search Unity

[SOLVED] Relative orientations. Why this quaternion don't work?

Discussion in 'Scripting' started by mabakay, Oct 3, 2016.

  1. mabakay

    mabakay

    Joined:
    Jun 10, 2016
    Posts:
    20
    Hi, I'm trying to mimic rotation from one object to another but with maintaining rotation difference between them.

    On Start I calculate rotation offset
    Code (CSharp):
    1. _rotationOffset = Cylinder.rotation * Quaternion.Inverse(Box.rotation);
    And on Update I apply parents rotation
    Code (CSharp):
    1. Cylinder.rotation = Box.rotation * _rotationOffset;
    Problem is in case when both rotations aren't compatible (not the same and both are not equal 0,0,0 in euler angles). For example Box has (0,15,0) and Cylinder has (15,0,0). Rotation works just fine but in first frame
    Code (CSharp):
    1. Cylinder.rotation * Quaternion.Inverse(Box.rotation) != Box.rotation * _rotationOffset;
    So Cylinder jumps. I attached very simple example with 5 lines of code. Any knows why it is not working?
     

    Attached Files:

    Last edited: Oct 4, 2016
  2. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    It's working very well with the test scene. When i move or rotate the cube, the cylinder follows on relative distance and angle all the time.
     
  3. mabakay

    mabakay

    Joined:
    Jun 10, 2016
    Posts:
    20
    Really you don't have this effect?

     
    Last edited: Oct 4, 2016
  4. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    I do get that effect it seems... i have no explanation.
     
  5. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Its because Matrix Mulitpilcation is non communative
    Rotation A * Rotation B != Rotation B * Rotation A

    This should be flipped
    Code (CSharp):
    1. _rotationOffset = Cylinder.rotation * Quaternion.Inverse(Box.rotation);
    Code (CSharp):
    1. _rotationOffset = Quaternion.Inverse(Box.rotation) * Cylinder.rotation  ;
    Or in the code you I downloaded from the first zip file change the start function to this:
    Code (CSharp):
    1.  private void Start()
    2.     {
    3.         _positionOffset = To.InverseTransformDirection(To.position - transform.position);
    4.         _rotationOffset =  Quaternion.Inverse(To.rotation)* transform.rotation ;
    5.     }
    Your taking the Cube's current rotaion and rotating by your original rotation, then reversing Cube's original.. This is totally different than Take the Cube's rotation, reverse his original then rotate by your original. It seems like they are the same but it does end up in two different spots. The reason your getting that jitter is that its resetting the cylinder's original rotation so your first equation would work.
     
  6. mabakay

    mabakay

    Joined:
    Jun 10, 2016
    Posts:
    20
    You'r absolutely right! Don't know how I could have missed that. Thumb up for you :)