旋转相关模型的正确方法
Proper way of rotating related models
我想画一个汽车模型,它由两部分组成,车身和轮胎。每个都是单独的 *.OBJ 文件中的单独模型,每个模型都是使用单独的 drawcall 绘制的。
初图看起来还行,一切似乎都排好了:
但是,当我开始旋转时,一切都坏了:
每个对象都以相同的方式转换(使用 XNAMath 的平移、缩放和旋转矩阵)并且每个对象在世界中都有自己的位置 space。
我认为这里的问题是旋转的 "anchor points"。
- 如何围绕 "anchor point" 旋转对象?
- 应该使用哪个"anchor point"?
- 对两个对象使用公共 "anchor point" 就足够了吗?
还有一个附带问题,你们知道什么是表示此类结构的正确方法吗?现在这是两个独立的实例,但如果我想添加内部装饰、镜子等,最好为所有对象制作一些具有共同属性的容器 class,对吗?
看来你的矩阵串联是错误的。因为您将不同的模型添加到一个大模型中,所以您应该这样做:
- 单个零件的每个网格的顶点都在 [-1,1] 范围内,对于 x,y,z
- 将对象空间中的每个部分移动到它的位置 w.r.t 汽车(缩放、旋转、移动),通常对象空间的 x、y、z 范围为 [-1,1]。即轮胎可能应该按比例缩小并移至车身底部。
- 将具有一个世界矩阵的整车移动到场景中的最终位置(缩放、旋转、移动)。在这里,您可以对汽车进行真正的缩放、旋转或平移,以将其放置在最终场景中。
- 这是通过将 WorldMatrix 与所有部分的每个 ObjectSpace 矩阵相乘来完成的。
- 因此,对于每个对象,您都会得到一个具有以下结构的矩阵链:
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;
...
}
希望对您有所帮助,
祝你好运!
我想画一个汽车模型,它由两部分组成,车身和轮胎。每个都是单独的 *.OBJ 文件中的单独模型,每个模型都是使用单独的 drawcall 绘制的。
初图看起来还行,一切似乎都排好了:
但是,当我开始旋转时,一切都坏了:
每个对象都以相同的方式转换(使用 XNAMath 的平移、缩放和旋转矩阵)并且每个对象在世界中都有自己的位置 space。
我认为这里的问题是旋转的 "anchor points"。
- 如何围绕 "anchor point" 旋转对象?
- 应该使用哪个"anchor point"?
- 对两个对象使用公共 "anchor point" 就足够了吗?
还有一个附带问题,你们知道什么是表示此类结构的正确方法吗?现在这是两个独立的实例,但如果我想添加内部装饰、镜子等,最好为所有对象制作一些具有共同属性的容器 class,对吗?
看来你的矩阵串联是错误的。因为您将不同的模型添加到一个大模型中,所以您应该这样做:
- 单个零件的每个网格的顶点都在 [-1,1] 范围内,对于 x,y,z
- 将对象空间中的每个部分移动到它的位置 w.r.t 汽车(缩放、旋转、移动),通常对象空间的 x、y、z 范围为 [-1,1]。即轮胎可能应该按比例缩小并移至车身底部。
- 将具有一个世界矩阵的整车移动到场景中的最终位置(缩放、旋转、移动)。在这里,您可以对汽车进行真正的缩放、旋转或平移,以将其放置在最终场景中。
- 这是通过将 WorldMatrix 与所有部分的每个 ObjectSpace 矩阵相乘来完成的。
- 因此,对于每个对象,您都会得到一个具有以下结构的矩阵链: 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;
...
}
希望对您有所帮助, 祝你好运!