1
\$\begingroup\$

I want to animate Model1 (an aicraft) and I want an object, Model2 (a sphere), to follow it in translation and rotation, as it is a part of this aircraft.

With the following code (I use one or two tutorials to write it) everything seems good when you just change just one angle at the time. The sphere gently follows the aircraft, but if you change more than one angle at the same time, everything goes wrong.

I wonder if it's not a gimbal lock problem? But I use quaternions? Or maybe I haven't understood all this stuff?

My code is below:

protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

    // Command input to airplane
        float yokeUpDown = 0.0f;
        float yokeRightLeft = 0.0f;
        float RollRotation = 0.01f;


      //make quaternion rotation matrix of airplane
        Quaternion additionalAircraftRotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), yokeUpDown) * Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), yokeRightLeft) *Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), RollRotation);

    //increase or decrease aircraft rotation
        spacecraftRotation = spacecraftRotation * additionalAircraftRotation;

    // make vector3 sphere angle rotation
        sphereAngle.X = sphereAngle.X + yokeUpDown;
        sphereAngle.Y = sphereAngle.Y + yokeRightLeft;
        sphereAngle.Z = sphereAngle.Z + RollRotation;


    // make rotation quaternion for sphere
        Quaternion additionalSphereRotation = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), sphereAngle.X) * Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), sphereAngle.Y) * Quaternion.CreateFromAxisAngle(new Vector3(1,0, 0), sphereAngle.Z);

    //relative position of the sphere to the aircraft
        Vector3 translationSphere = new Vector3(-distance_Aircraft_Sphere, 0,0);


        translationSphere = Vector3.Transform(translationSphere, additionalSphereRotation);



        sphereposition = aircraftposition + translationSphere;


        // “VectorToAdd” = direction of the airplane
        Vector3 rotatedAircraftVector = Vector3.Transform(vectorToAdd, spacecraftRotation);

        aircraftposition += moveSpeedAircraft * rotatedAircraftVector;

        sphereposition += moveSpeedAircraft * rotatedAircraftVector;




}
enter code here
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$
I wonder if it's not a gimbal lock problem? But I use quaternions?

Yes, your code has a Gimbal Lock problem, since you use Euler Angles. There is a lot of myth out there about Gimbal Locks and how to prevent them. You can also have Gimbal Locks using quaternions, if you use them the way you do. The key is not to store the rotation around each axis separately and not to apply one after another, your code does it here:

    Quaternion additionalAircraftRotation = 
        Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), yokeUpDown) * 
        Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), yokeRightLeft) *
        Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), RollRotation);

    Quaternion additionalSphereRotation = 
        Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), sphereAngle.X) *  
        Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), sphereAngle.Y) * 
        Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), sphereAngle.Z);

The solution is not to use Euler Angles. {yokeUpDown, yokeRightLeft, RollRotation} and sphereAngle are Euler Angles. Rather store them as matrices or quaternions, basically any representation of orientation/rotation will do, except Euler Angles.

Also this code does not do what you want, you can't just add Euler-Angles to combine 2 rotations:

    // make vector3 sphere angle rotation
    sphereAngle.X = sphereAngle.X + yokeUpDown;
    sphereAngle.Y = sphereAngle.Y + yokeRightLeft;
    sphereAngle.Z = sphereAngle.Z + RollRotation;
\$\endgroup\$
5
  • \$\begingroup\$ So, what would the OP's code look like with your fixes? \$\endgroup\$
    – Nate
    Commented Jul 27, 2011 at 20:47
  • \$\begingroup\$ @Nate sphereAngle and {yokeUpDown, yokeRightLeft, RollRotation} would be Quaternions/Matrices/Axis-Angles in the first place, rather than Euler Angles. \$\endgroup\$ Commented Jul 27, 2011 at 20:54
  • \$\begingroup\$ Ok, I would try this tomorow, Thanks a lot, JeanGil \$\endgroup\$
    – jeangil
    Commented Jul 27, 2011 at 22:29
  • \$\begingroup\$ @jeangil tell us if you need help replacing the euler angles, just shoot if you have any doubts \$\endgroup\$ Commented Jul 31, 2011 at 9:02
  • 1
    \$\begingroup\$ Hi Maik, I try to solve this pb without any success and I let one month pass before going back to this, I havn't understdand very well how to replace Euler Angles with Quaternion/Matrices/Axis angles, Can you show just on one axis please ? Thanks a lot, Jeangil \$\endgroup\$
    – jeangil
    Commented Sep 7, 2011 at 21:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .