旋转相关模型的正确方法

Proper way of rotating related models

我想画一个汽车模型,它由两部分组成,车身和轮胎。每个都是单独的 *.OBJ 文件中的单独模型,每个模型都是使用单独的 drawcall 绘制的。

初图看起来还行,一切似乎都排好了:

但是,当我开始旋转时,一切都坏了:

每个对象都以相同的方式转换(使用 XNAMath 的平移、缩放和旋转矩阵)并且每个对象在世界中都有自己的位置 space。

我认为这里的问题是旋转的 "anchor points"。

还有一个附带问题,你们知道什么是表示此类结构的正确方法吗?现在这是两个独立的实例,但如果我想添加内部装饰、镜子等,最好为所有对象制作一些具有共同属性的容器 class,对吗?

看来你的矩阵串联是错误的。因为您将不同的模型添加到一个大模型中,所以您应该这样做:

  1. 单个零件的每个网格的顶点都在 [-1,1] 范围内,对于 x,y,z
  2. 将对象空间中的每个部分移动到它的位置 w.r.t 汽车(缩放、旋转、移动),通常对象空间的 x、y、z 范围为 [-1,1]。即轮胎可能应该按比例缩小并移至车身底部。
  3. 将具有一个世界矩阵的整车移动到场景中的最终位置(缩放、旋转、移动)。在这里,您可以对汽车进行真正的缩放、旋转或平移,以将其放置在最终场景中。
  4. 这是通过将 WorldMatrix 与所有部分的每个 ObjectSpace 矩阵相乘来完成的。
  5. 因此,对于每个对象,您都会得到一个具有以下结构的矩阵链: LocalSpace of carPart -> ObjectSpace of car -> WorldSpace in the Scene => (ObjectSpaceMatrix * WorldMatrix for every part of the car).

在您的模型中,您的汽车零件似乎在范围 [0,1] 内。因为缩放是从 (0,0,0) 开始的,所以您会向一个方向获得这种典型的过度运动。要么更改网格中的顶点,要么首先使用 [-0.5,-0.5,-0.5] 平移对象部分以确保对象居中并且缩放正确。

下面是一些你可以使用的结构的伪代码:

class CarPart
{
    Float4x4 ObjectSpaceMatrix;  //matrix moves part to its position in the "CarObjectSpace" withing range[-1,1]
    Mesh Instance;
}

class Car
{
    Float4x4 WorldSpaceMatrix; //matrix moves complete mesh inside the scene

    CarPart Tires;
    CarPart Body;
    CarPart Engine;
    ...
}

void render()
{
     Float4x4 FinalTiresMatrix = Car.Tires.ObjectSpaceMatrix * Car.WorldSpaceMatrix;
     Float4x4 BodyTiresMatrix = Car.Body.ObjectSpaceMatrix * Car.WorldSpaceMatrix;
    ...
}

希望对您有所帮助, 祝你好运!