C++ 如何在DirectX中规范化模型大小?

C++ 如何在DirectX中规范化模型大小?,c++,3d,directx,normalization,wavefront,C++,3d,Directx,Normalization,Wavefront,我在DirectX中创建了一个简单的“引擎”,可以从.obj文件加载和渲染模型。对于我创建的对象,它可以正常工作,例如坐标在-1.0到1.0范围内的简单立方体。然而,加载一个使用不同单位且坐标在-2k到2k范围内的模型会导致一个巨大的东西,它甚至不能完全适合深度缓冲区,所以我看到一个巨大的腿或类似的效果 我记得在某个地方读到过关于它的文章,但最近我读了很多DX的东西,我记不起它在哪里或是什么了。所以我的问题是,假设我希望能够加载不同的模型,使用不同的单元,那么最好的方法是什么来确保它们都具有相似

我在DirectX中创建了一个简单的“引擎”,可以从.obj文件加载和渲染模型。对于我创建的对象,它可以正常工作,例如坐标在-1.0到1.0范围内的简单立方体。然而,加载一个使用不同单位且坐标在-2k到2k范围内的模型会导致一个巨大的东西,它甚至不能完全适合深度缓冲区,所以我看到一个巨大的腿或类似的效果

我记得在某个地方读到过关于它的文章,但最近我读了很多DX的东西,我记不起它在哪里或是什么了。所以我的问题是,假设我希望能够加载不同的模型,使用不同的单元,那么最好的方法是什么来确保它们都具有相似的大小,并且很好地适合屏幕


我可以尝试在加载对象时转换这些值,但可能还有更多的DirectX方法使用变换矩阵或着色器?

最简单的方法是找到模型包含最大范围的组件,并使用该值均匀缩放模型。要找到最大范围,请计算模型边界框(除非wavefront obj.文件已经提供了边界框,但您可能仍想验证它),并使用框尺寸作为要比较的范围。这将使所有导入的模型缩小到单位范围

例如,如果您有一个边界框覆盖374*820*512个单位的模型,则最大的边界框是Y轴820,因此您只需将其缩小820(将所有组件除以820)。这可以通过统一的缩放矩阵方便地实现,如果我没有弄错的话,可以使用
D3DXMatrixScaling
初始化该矩阵。 假设边界框由两个向量(最大和最小顶点)给出,计算这些向量的差,然后选取最大值,并将其逆作为矩阵的比例因子

D3DMatrix mScale;
D3DVector mx, mn;
obj->getBoundingBox(&mn,&mx);
float scale = 1.0 / max(mx.x - mn.x, max(mx.y - mn.y, mx.z -mn.z));
D3DXMatrixScaling( &mScale, scale, scale,scale);
剩下要做的就是在渲染管道中插入矩阵

关于边界框的计算,应该在模型的所有顶点上进行一个简单的循环,保持最小和最大分量(彼此独立),这样做

D3DVector mn, mx;
mn.x = mn.y = mn.z = MAX_FLOAT;
mx.x = mx.y = mx.z = - MAX_FLOAT;
for (int i = 0; i < numVertices ; i++) {
   mn.x = min(mn.x, vertex[i].x);
   mn.y = min(mn.y, vertex[i].y);
   mn.z = min(mn.z, vertex[i].z);
  // same for mx using max
}
D3DVector-mn,mx;
mn.x=mn.y=mn.z=MAX_FLOAT;
mx.x=mx.y=mx.z=-MAX\u FLOAT;
对于(int i=0;i

当然,如果视图覆盖的面积大于单位框,则可能需要使用一些缩放因子(但显然这就是您正在使用的)。

缩放通常作为顶点从模型空间转换到世界空间的一种方式进行。然后将该矩阵乘以视图矩阵和投影矩阵,形成最终的变换。Tim的答案是正确的,尽管他所说的比例差异会很快失去浮点精度。是的,这会起作用,但在仔细考虑之后,我想我只需要在3D软件中缩放我的模型,让代码保持现在的状态。我不是D3D用户,可能我给出的代码示例中显示了这一点,但我认为我的想法是正确的,如果一次显示一个模型。如果要显示多个,我认为在加载模型后进行一次缩放,或者像您所说的那样,使用外部软件,会更有效。