在 XNA 中旋转 3D 模型
本文关键字:3D 模型 旋转 XNA | 更新日期: 2023-09-27 18:36:55
我是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 轴(通过更改 RotateY 的值),船将沿其 Y 轴旋转。但是如果我旋转 X 或 Z 轴,飞船会根据世界的 X 轴和 Z 轴旋转,而不是它自己的轴。如何使飞船在自己的轴上旋转?我需要对矩阵做一些不同的事情吗?谢谢
使用 CreateRotationX、CreateRotationY 和 CreateRotationZ 都应用全球或全局轴的旋转。这意味着它会导致对象仅围绕世界/全局轴旋转,而不是对象的局部轴。
使用CreateFromAxisAngle可以输入所需的任何旋转轴,包括船舶自己的局部轴。
但是,需要改变整体旋转范式,因为围绕任意轴(例如船舶的Up)旋转可能会导致3个角度值中的任何一个同时发生变化。跟踪所有这一切都是不必要的困难。有一种更简单的方法:
只需以矩阵(或四元数)形式存储旋转,而不是 3 个角度。
编辑:在下面给史蒂夫一些功劳(很棒的答案伙伴,自从我做了很多 3D 数学以来已经有一段时间了)。
本教程将向您展示如何设置史蒂夫的建议!
http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series1/Rotation_-_translation.php
原文:
我相信你必须创造一种效果。BasicEffect循环中的旋转。
我相信,所有这些都在MSDN的基本教程中有所介绍。你的代码甚至看起来像是来自那里。
http://msdn.microsoft.com/en-us/library/bb203897(v=xnagamestudio.31)
如果没有,请查看此链接,Reimer 涵盖了 3D 中值得了解的所有内容:
http://www.riemers.net/eng/Tutorials/XNA/Csharp/series1.php
以下是我最终所做的,以防其他人像我一样陷入困境:
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();
}
}