10

我是 XNA 的新手,我正在创建一个简单的游戏。抱歉,这可能真的很简单,但我找不到任何帮助。游戏中有一艘船是我用 Blender 制作的,我希望能够通过旋转船的 X、Y 和 Z 轴来控制这艘船。这是我的代码:

protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
  RotationMatrix = Matrix.CreateRotationY(MathHelper.PiOver2) * Matrix.CreateRotationY    (rotationY) * Matrix.CreateRotationX(rotationX) * Matrix.CreateRotationZ(rotationZ);

        Matrix shipTransformMatrix = RotationMatrix * Matrix.CreateTranslation(ship.Position);

                        DrawModel(ship.Model, shipTransformMatrix, ship.Transforms);
        // TODO: Add your drawing code here


        base.Draw(gameTime);
    }

    public  void DrawModel(Model model, Matrix modelTransform, Matrix[] absoluteBoneTransforms)
    {
        //Draw the model, a model can have multiple meshes, so loop
        foreach (ModelMesh mesh in model.Meshes)
        {
            //This is where the mesh orientation is set
            foreach (BasicEffect effect in mesh.Effects)
            {

                effect.World = absoluteBoneTransforms[mesh.ParentBone.Index] * modelTransform;
                effect.Projection = projectionMatrix;
                effect.View = viewMatrix;

            }

            //Draw the mesh, will use the effects set above.
            mesh.Draw();
        }
    }

这将旋转船,但不会沿着船的轴旋转。如果我旋转 Y 轴(通过改变 rotationY 的值),船将沿其 Y 轴旋转。但是如果我旋转 X 或 Z 轴,船会根据世界的 X 和 Z 轴旋转,而不是它自己的。我怎样才能让船绕着自己的轴旋转?我需要对矩阵做一些不同的事情吗?谢谢

4

3 回答 3

6

使用 CreateRotationX、CreateRotationY 和 CreateRotationZ 都可以应用围绕世界或全局轴的旋转。这意味着它会导致您的对象仅围绕世界/全局轴旋转,而不是您的对象的局部轴。

使用 CreateFromAxisAngle 允许您输入您想要的任何旋转轴,包括飞船自己的局部轴。

然而,您的整体旋转范式将需要转变,因为例如围绕任意轴(如船的 Up)的旋转可能会同时导致 3 个角度值中的任何一个发生变化。跟踪所有这些是不必要的困难。有一个更简单的方法:

只需以矩阵(或四元数)形式而不是 3 个角度存储旋转。

于 2012-06-11T15:59:36.023 回答
2

编辑:在下面给史蒂夫一些功劳(很好的回答伙伴,自从我做了很多 3D 数学以来已经有一段时间了)。

本教程将向您展示如何设置史蒂夫建议的内容!

http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series1/Rotation__-_translation.php

原帖:

我相信你必须在你的 BasicEffect 循环中创建一个 effect.Rotation。

我相信所有这些都包含在 MSDN 的基本教程中。您的代码甚至看起来像是来自那里。

http://msdn.microsoft.com/en-us/library/bb203897(v=xnagamestudio.31)

如果没有,请查看此链接,Reimer 涵盖了所有值得了解的 3D 内容:

http://www.riemers.net/eng/Tutorials/XNA/Csharp/series1.php

于 2012-06-11T15:20:24.910 回答
1

这是我最终做的事情,以防其他人像我一样被卡住:

Matrix RotationMatrix;
//every time I wanted to rotate around an axis, I would do something like this:
protected void rotateY()
    {
        RotationMatrix *= Matrix.CreateFromAxisAngle(RotationMatrix.Up, MathHelper.ToRadians(1.0f));
        //For the X axis I used RotationMatrix.Right, and for the Z RotationMatrix.Forward
    }
protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);


    Matrix shipTransformMatrix = RotationMatrix * Matrix.CreateTranslation(ship.Position);

                    DrawModel(ship.Model, shipTransformMatrix, ship.Transforms);
    // TODO: Add your drawing code here


    base.Draw(gameTime);
}

public  void DrawModel(Model model, Matrix modelTransform, Matrix[] absoluteBoneTransforms)
{
    //Draw the model, a model can have multiple meshes, so loop
    foreach (ModelMesh mesh in model.Meshes)
    {
        //This is where the mesh orientation is set
        foreach (BasicEffect effect in mesh.Effects)
        {

            effect.World = absoluteBoneTransforms[mesh.ParentBone.Index] * modelTransform;
            effect.Projection = projectionMatrix;
            effect.View = viewMatrix;

        }

        //Draw the mesh, will use the effects set above.
        mesh.Draw();
    }
}
于 2012-06-11T22:02:15.903 回答