开发者

XNA Quaternion.createFromAxisAngle

I'm writing a flight simulator program (similar to Star fox 64) in XNA and I'm having an issue with my rotations. My idea is to have a vector for the velocity and vector for the position. The controls I'm allowing make it such that Euler's angles would cause issues so I'm wanting to use Quaternions.

I'm not super familiar with the graphics rendering yet, but I thought I could use Quaternion.createFromAxisAngle(vector, roll) (roll being the rotation around my velocity vector) but it's not working correctly. Basically whenever I try to rotate pitch or yaw, nothing happens. When I roll, it works but not as I would have expected. Is this the proper use of the createFromAxisAngle method? Thanks.

Here is the update position code for my ship:

    public override void UpdatePositions()
    {
        float sinRoll = (float)Math.Sin(roll);
        float cosRoll = (float)Math.Cos(roll);
        float sinPitch = (float)Math.Sin(pitch);
        float cosPitch = (float)Math.Cos(pitch);
        float sinYaw = (float)Math.Sin(yaw);
        float cosYaw = (float开发者_JAVA技巧)Math.Cos(yaw);

        m_Velocity.X = (sinRoll * sinPitch - sinRoll * sinYaw * cosPitch - sinYaw * cosPitch);
        m_Velocity.Y = sinPitch * cosRoll;
        m_Velocity.Z = (sinRoll * sinPitch + sinRoll * cosYaw * cosPitch + cosYaw * cosPitch);
        if (m_Velocity.X == 0 && m_Velocity.Y == 0 && m_Velocity.Z == 0)
            m_Velocity = new Vector3(0f,0f,1f);
        m_Rotation = new Vector3((float)pitch, (float)yaw, (float)roll);

        m_Velocity.Normalize();
        //m_QRotation = Quaternion.CreateFromYawPitchRoll((float)yaw,(float)pitch,(float)roll); This line works for the most part but doesn't allow you to pitch up correctly while banking.
        m_QRotation = Quaternion.CreateFromAxisAngle(m_Velocity,(float)roll);
        m_Velocity = Vector3.Multiply(m_Velocity, shipSpeed);

        m_Position += m_Velocity;
    }


Are you adamant about storing your ship's orientation as yaw, pitch, & roll variables? If not, storing the orientation in a quaternion or matrix will significantly simplify your challenge here.

At the end of the frame, you will send the effect.World a matrix representing the world space orientation & position of the ship. That matrix's forward property happens to be the same vector you calculated here as velocity. Why not save that matrix from the effect.World, then the next frame simply rotate that matrix about it's own forward vector (for roll) and advance it's Translation property based on it's own (forward property * shipSpeed), and sent it back to the effect for next frame. This will disallow you to "know" the actual yaw, pitch, & roll angles of your ship. But for the most part, in 3d programming, if you think you need to know the angle of something, you're probably going about it the wrong way.

Here's a snippet using a matrix to get you going in this direction if you want to.

//class scope field
Matrix orientation = Matrix.Identity;


//in the update
Matrix changesThisFrame = Matrix.Identity;

//for yaw
changesThisFrame *= Matrix.CreatFromAxisAngle(orientation.Up, inputtedYawAmount);//consider tempering the inputted amounts by time since last update.

//for pitch
changesThisFrame *= Matrix.CreateFromAxisAngle(orientation.Right, inputtedPitchAmount);

//for roll
changesThisFrame *= Matrix.CreateFromAxisAngle(orientation.Forward, inputtedRollAmount);

orientation *= changesThisFrame;

orientation.Translation += orientation.Forward * shipSpeed;


//then, somewhere in the ship's draw call

effect.World = orientation;


Want to work with XNA and rotate stuff in 3D? Then read this: http://stevehazen.wordpress.com/2010/02/15/matrix-basics-how-to-step-away-from-storing-an-orientation-as-3-angles/

Can not recommend it enough.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜