随着父对象旋转而移动子对象

本文关键字:对象 移动 旋转 | 更新日期: 2023-09-27 18:28:22

我在尝试同时移动简单模型时遇到了问题。我有20个较小的模型附在一个较大的模型上。它本质上是一个带有多个外部大炮的飞碟。我看到过其他问题,比如这个,看起来几乎是我想要的。然而,这只是创建了绘制转换。实际上,我需要在三维空间中移动子模型,因为它们可以独立销毁,因此需要碰撞检测。以下是我如何旋转父级(在Update()函数中):

angle += 0.15f;
RotationMatrix = Matrix.CreateRotationX(MathHelper.PiOver2) * Matrix.CreateRotationZ(MathHelper.ToRadians(angle) * MathHelper.PiOver2);

我尝试了很多解决方案,但定位总是不正确,所以它们看起来并不是很依恋。这是我得到的最接近的:

cannons[x].RotationMatrix = Matrix.CreateRotationX(MathHelper.PiOver2) * 
Matrix.CreateRotationZ(MathHelper.ToRadians(angle + cannons[x].angle) * 
MathHelper.PiOver2);
cannons[x].position.X = (float)(Math.Cos(MathHelper.ToRadians(angle + cannons[x].originAngle) *
 MathHelper.PiOver2) * 475) + position.X;
cannons[x].position.Y = (float)(Math.Sin(MathHelper.ToRadians(angle + cannons[x].originAngle) *
 MathHelper.PiOver2) * 475) + position.Y;

我在那个代码中做错了什么?或者,如果我的方法完全错误,那么正确的方法是什么?

随着父对象旋转而移动子对象

您应该对所有内容使用矩阵转换。

class Physics {
 public Vector3 Traslation;
 public Vector3 Scale;
 public Quaternion Rotation;
 public Physics Parent;
 public List<Physics> Children;
 public Matrix World;

 public Update() {
      World =   Matrix.CreateScale(Scale) 
              * Matrix.CreateFromQuaternion(Rotation) 
              * Matrix.CreateTranslation;
      if (Parent!=null) {
         World *= Parent.World ;
      }    
      foreach (var child in children) child.Update();         
 }
}

意识到这段代码并没有经过优化,可以改进。

通过这种方式,您应该有一个用于大型模型的Physics对象和20个用于小型模型的Physical对象,通过Parent属性附加到大型模型。

如果您需要在绝对坐标下对对象进行Traslation、Rotation和Scale,则可以使用Matrix.Dompose方法,尽管将World矩阵传递到着色器以变换顶点要好得多。