Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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
share|improve this question
add comment

1 Answer

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;
share|improve this answer
    
So, what would the OP's code look like with your fixes? –  Nate Jul 27 '11 at 20:47
    
@Nate sphereAngle and {yokeUpDown, yokeRightLeft, RollRotation} would be Quaternions/Matrices/Axis-Angles in the first place, rather than Euler Angles. –  Maik Semder Jul 27 '11 at 20:54
    
Ok, I would try this tomorow, Thanks a lot, JeanGil –  jeangil Jul 27 '11 at 22:29
    
@jeangil tell us if you need help replacing the euler angles, just shoot if you have any doubts –  Maik Semder Jul 31 '11 at 9:02
    
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 –  jeangil Sep 7 '11 at 21:16
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.