1

我正在 XNA 中编写一个飞行模拟器程序(类似于 Star fox 64),但我的旋转出现问题。我的想法是有一个速度矢量和位置矢量。我允许的控件使得欧拉角会引起问题,所以我想使用四元数。

我对图形渲染还不是很熟悉,但我想我可以使用 Quaternion.createFromAxisAngle(vector, roll) (roll 是围绕我的速度向量的旋转),但它不能正常工作。基本上每当我尝试旋转俯仰或偏航时,什么都没有发生。当我滚动时,它可以工作,但不像我预期的那样。这是 createFromAxisAngle 方法的正确使用吗?谢谢。

这是我的船的更新位置代码:

    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)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;
    }
4

2 回答 2

2

您是否坚持将船舶的方位存储为偏航、俯仰和滚动变量?如果没有,将方向存储在四元数或矩阵中将大大简化您的挑战。

在帧结束时,您将向 effect.World 发送一个矩阵,该矩阵表示船的世界空间方向和位置。该矩阵的前向属性恰好与您在此处计算为速度的向量相同。为什么不从 effect.World 中保存该矩阵,然后下一帧简单地围绕它自己的前向向量(用于滚动)旋转该矩阵并根据它自己的(前向属性 * shipSpeed)推进它的平移属性,并将其发送回下一帧的效果。这将使您无法“知道”您的船的实际偏航角、俯仰角和滚动角。但在大多数情况下,在 3D 编程中,如果您认为您需要知道某物的角度,那么您可能走错了路。

如果您愿意,这是一个使用矩阵的片段,可以让您朝着这个方向前进。

//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;
于 2011-08-03T20:12:54.797 回答
2

想要使用 XNA 并在 3D 中旋转东西吗?然后阅读:http ://stevehazen.wordpress.com/2010/02/15/matrix-basics-how-to-step-away-from-storing-an-orientation-as-3-angles/

不能推荐它。

于 2011-08-04T11:31:09.223 回答