"поэтому я попытался уменьшить его"
Лучшее, что можно сделать в этой ситуации, это вообще не трансформировать вашу модель! Оставь это. То, что вы хотите изменить, это ваша камера.
Сначала вычислите ограничивающую рамку вашей модели где-нибудь в трехмерном пространстве.
Затем вычислите его радиус, взяв максимум (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() );
}
}
}
}