如何在 XNA 中围绕网格的局部轴旋转网格

  • 本文关键字:网格 局部 旋转 XNA c# xna
  • 更新时间 :
  • 英文 :


我的游戏中有一个对象,它有几个网格体,当我尝试以任何一种方式旋转任一网格体时,它只围绕世界轴旋转它,而不是它的局部轴。我在类构造函数中有一个rotation = Matrix.Identity。每个网格都附加了此类。那么这个类还包含方法:

...
public Matrix Transform{ get; set; }
public void Rotate(Vector3 newRot)
{
    rotation = Matrix.Identity;
    rotation *= Matrix.CreateFromAxisAngle(rotation.Up, MathHelper.ToRadians(newRot.X));
    rotation *= Matrix.CreateFromAxisAngle(rotation.Right, MathHelper.ToRadians(newRot.Y));
    rotation *= Matrix.CreateFromAxisAngle(rotation.Forward, MathHelper.ToRadians(newRot.Z));
    CreateMatrix();
}
private void CreateMatrix()
{
    Transform = Matrix.CreateScale(scale) * rotation * Matrix.CreateTranslation(Position);
}
...

现在 Draw() 方法:

foreach (MeshProperties mesh in model.meshes)
{
    foreach (BasicEffect effect in mesh.Mesh.Effects)//Where Mesh is a ModelMesh that this class contains information about
    {
        effect.View = cam.view;
        effect.Projection = cam.projection;
        effect.World = mesh.Transform;
        effect.EnableDefaultLighting();
    }
    mesh.Mesh.Draw();
}

编辑:恐怕要么我在某个地方搞砸了,要么你的 tehnique 不起作用,这就是我所做的。每当我移动整个对象(父对象)时,我都会将其Vector3 Position;设置为该新值。我还Vector3 Position;每个网格属性设置为该值。然后在 MeshProperties 的CreateMatrix()中,我这样做了:

...
Transform = RotationMatrix * Matrix.CreateScale(x, y, z) * RotationMatrix * Matrix.CreateTranslation(Position) * Matrix.CreateTranslation(Parent.Position);
...

哪里:

public void Rotate(Vector3 newRot)
{
    Rotation = newRot;
    RotationMatrix = Matrix.CreateFromAxisAngle(Transform.Up,          MathHelper.ToRadians(Rotation.X)) * 
    Matrix.CreateFromAxisAngle(Transform.Forward, MathHelper.ToRadians(Rotation.Z)) * 
    Matrix.CreateFromAxisAngle(Transform.Right, MathHelper.ToRadians(Rotation.Y));
}

Rotation Vector3. RotationMatrixTransform 都设置为在构造函数中Matrix.Identity

问题是,如果我尝试旋转例如 Y 轴,他应该在"静止不动"时绕圈旋转。但他在旋转时四处走动。

我不完全确定这是你想要的。我假设这里有一个对象,一些网格和位置偏离主对象位置的位置和方向,并且您希望相对于父对象围绕其局部轴旋转子对象。

Matrix.CreateTranslation(-Parent.Position) *                  //Move mesh back...
Matric.CreateTranslation(-Mesh.PositionOffset) *              //...to object space
Matrix.CreateFromAxisAngle(Mesh.LocalAxis, AngleToRotateBy) * //Now rotate around your axis
Matrix.CreateTranslation(Mesh.PositionOffset) *               //Move the mesh...
Matrix.CreateTranslation(Parent.Position);                    //...back to world space

当然,您通常会存储一个变换矩阵,该矩阵一步将网格从对象空间转换为世界空间,并且您还将存储反向。您还可以始终将网格存储在对象坐标中,并且仅将其移动到世界坐标中进行渲染。这会稍微简化一些事情:

Matrix.CreateFromAxisAngle(Mesh.LocalAxis, AngleToRotateBy) * //We're already in object space, so just rotate
ObjectToWorldTransform *
Matrix.CreateTranslation(Parent.Position);

我认为您可以简单地将示例中的Mesh.Transform设置为此并全部设置。

我希望这就是你要找的!

问题是,当我将模型导出为 .FBX 枢轴点不在模型中心。从而使模型在旋转时移动。

最新更新