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.

Using quaternions, I'm having trouble moving my model in its facing direction. Currently the model moves can move in all cardinal directions with no problems. The problem comes when I rotate the move as it still travelling in the direction of world space. Meaning, if I'm moving forward, backward or any other direction while rotating the model, the model acts like its a figure skater spinning while traveling in the same direction.

How do I update the direction of travel proper with the facing direction of the model?

Rotates model on Y-axis:

        Yaw = pController.ThumbSticks.Right.X * MathHelper.ToRadians(speedAngleMAX);            
        AddRotation = Quaternion.CreateFromYawPitchRoll(yaw, 0, 0);
        ModelLoad.MRotation *= AddRotation;
        MOrientation = Matrix.CreateFromQuaternion(ModelLoad.MRotation);

Moves model forward:

        // Move Forward
        if (pController.IsButtonDown(Buttons.LeftThumbstickUp))
        {
            SpeedX = (float)(Math.Sin(ModelLoad.ModelRotation)) * FWDSpeedMax * pController.ThumbSticks.Left.Y * (float)gameTime.ElapsedGameTime.TotalSeconds;
            SpeedZ = (float)(Math.Cos(ModelLoad.ModelRotation)) * FWDSpeedMax * pController.ThumbSticks.Left.Y * (float)gameTime.ElapsedGameTime.TotalSeconds;
            // Update model position
            ModelLoad._modelPos += Vector3.Forward * SpeedZ;
            ModelLoad._modelPos += Vector3.Left * SpeedX;
        }
share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

The problem stems from these lines:

        ModelLoad._modelPos += Vector3.Forward * SpeedZ;
        ModelLoad._modelPos += Vector3.Left * SpeedX;

Both Vector3.Forward and Vector3.Left are in world space, while you'd rather have the controller change the direction in the (rotated) object space of the model.

The easiest solution (warning: Don't know XNA that good to know if it is the fastest solution as well) would be to calculate the displacement as above, then rotate it with the quaternion (or in 2D space, complex number) describing the model orientation, then adding that to change the model position:

Vector3 Displacement = Vector3.Forward * SpeedZ + Vector3.Left * SpeedX;
ModelLoad._modelPos += Vector3.Transform(Displacement, ModelLoad.MRotation);

As a side note, your current calculations for SpeedX and SpeedY don't take into account varying frame rates. If the execution of them is bound to display frame rate, it's better to use "time since last frame" as a multiplier for both to ensure the same speed regardless of processing power and current frame rate.

See also this question for a possibly related problem (and solution thereof): Moving a rotated model in XNA

share|improve this answer
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.