3D模型如何以单位方式处理?
当我有一个随机模型,我想在我的视图端口,我不知道,如果它太大或不,如果我需要翻译它在中间...
我认为一个3d对象可能有它自己的起源。
答案 0 :(得分:2)
您需要找到一个边界体,一个包围所有对象顶点的形状,用于比对象本身更易于使用的对象。通常使用球体。艺术家可以将球体定义为模型信息的一部分,也可以在运行时进行处理。计算最佳球体非常困难,但您可以使用以下方法获得良好的近似值:
determine the min and max value of each point's x, y and z
for each vertex
min_x = min (min_x, vertex.x)
max_x = max (max_x, vertex.x)
min_y = min (min_y, vertex.y)
max_y = max (max_y, vertex.y)
min_z = min (min_z, vertex.z)
max_z = max (max_z, vertex.z)
sphere centre = (max_x + min_x) / 2, (max_y + min_y) / 2, (max_z + min_z) / 2
sphere radius = distance from centre to (max_x, max_y, max_z)
使用此球体,确定一个允许全部查看球体的世界位置 - 简单几何体将决定这一点。
答案 1 :(得分:0)
对不起,你的问题很不清楚。我想你想要将3D模型居中到视口。您可以通过计算模型的边界框来实现此目的。为此,遍历所有多边形并获得最小/最大X / Y / Z坐标。点(min_x,min_y,min_z)
和(max_x,max_y,max_z)
给出的边界框将包含整个模型。现在,您可以通过查看此框的中心来使模型居中。通过一些进一步的计算(取决于您的FOV),您还可以在视口内获得左/右/上/下边框。
答案 2 :(得分:0)
"所以我试图将其缩小"
在这种情况下,最好的办法就是不要改变你的模型!留下吧。你要改变的是你的相机。
首先在3D空间的某处计算模型的边界框。
接下来通过取max来计算它的半径(aabb.max.x-aabb.min.x,aabb.max.y-aabb.min.y,aabb.max.z-aabb.min.z) 。这是原油,但它完成了工作。
要将对象置于视口中心,请将相机放在对象位置。如果Y是您的前轴,则从Y减去半径。如果Z是前轴,则从中减去半径。减去一个软糖因子让你经过讨厌的近平面,这样你的模型就不会被剪掉。我在我的引擎中使用了一个很好的lookat()方法的四元数。所以调用lookat()并传入边界框的中心。瞧!您的对象在视口中居中,无论它在世界的哪个位置。
这总是将摄像机轴对齐,因此您可能希望获得想象并将摄像机转换为模型空间,减去半径,然后再次查看()中心。然后你总是在看模型的背面。关键始终是lookat()。
这是我的引擎中的一些示例代码。它会检查我们是否正在尝试构建一块静态地形,如果这样,则从高处向下看,或者从光线或静态网格向下看。视觉是在场景中绘制的任何东西,并且有许多不同类型。 Visual :: Instance是视觉的副本,或者绘制它的位置。
void EnvironmentView::frameSelected(){
if( m_tSelection.toInstance() ){
Visual::Instance& I = m_tSelection.toInstance().cast();
Visual* pVisual = I.toVisual();
if( pVisual->isa( StaticTerrain::classid )){
toEditorCamera().toL2W().setPosition( pt3( 0, 0, 50000 ));
toEditorCamera().lookat( pt3( 0 ));
}else if( I.toFlags()->bIsLight ){
Visual::LightInstance& L = static_cast<Visual::LightInstance&>( I );
qst3& L2W = L.toL2W();
const sphere s( L2W.toPosition(), L2W.toScale() );
const f32 y =-(s.toCenter()+s.toRadius()).y();
const f32 z = (s.toCenter()+s.toRadius()).y();
qst3& camL2W = toEditorCamera().toL2W();
camL2W.setPosition(s.toCenter()+pt3( 0, y, z ));//45 deg above
toEditorCamera().lookat( s.toCenter() );
}else{
Mesh::handle hMesh = pVisual->getMesh();
if( hMesh ){
qst3& L2W = m_tSelection.toInstance()->toL2W();
vec4x4 M;
L2W.getMatrix( M );
aabb3 b0 = hMesh->toBounds();
b0.min = M * b0.min;
b0.max = M * b0.max;
aabb3 b1;
b1 += b0.min;
b1 += b0.max;
const sphere s( b1.toSphere() );
const f32 y =-(s.toCenter()+s.toRadius()*2.5f).y();
const f32 z = (s.toCenter()+s.toRadius()*2.5f).y();
qst3& camL2W = toEditorCamera().toL2W();
camL2W.setPosition( L2W.toPosition()+pt3( 0, y, z ));//45 deg above
toEditorCamera().lookat( b1.toOrigin() );
}
}
}
}