2009-05-18 9 views
0

3次元モデルはどのようにユニット単位で処理されますか?
私はビューポートに収まりたいと思っているランダムなモデルを持っていますが、サイズが大きすぎるかどうかわからない場合は、中間になるように変換する必要があります。
私は、それは独自の起源です。ビューポートに適合する3Dモデル

答えて

0

申し訳ありません、あなたの質問は非常に不明です。私はあなたがビューポートに3Dモデルを集中させたいと思う。これは、モデルの境界ボックスを計算することで実現できます。これを行うには、すべてのポリゴンをトラバースし、最小/最大X/Y/Z座標を取得します。点(min_x,min_y,min_z)(max_x,max_y,max_z)によって与えられる境界ボックスには、モデル全体が含まれます。今度は、このボックスの中心を見てモデルの中心を合わせることができます。さらにいくつかの計算(あなたのFOVに依存します)では、ビューポート内で左/右/上/下ボーダーを取得することもできます。

+0

私は、インターネット上のランダムなモデルをgrabedと私は学習のためのOpenGLでそれを見せたかったが、私は何も見えませんが、少しひねることにより、私はいくつかの動きを見ることができるので、私はそれを拡張しようとしましたそれはちょっといいですね。だから私はあなたが私の見解に合っていると言ったように、モデル境界をどのように得ることができるのか知りたかったのです – CiNN

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) 

、球がフルで表示することを可能にする世界の位置を決定 - シンプルな幾何学はこれを決定します。

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()を呼び出して、境界ボックスの中央を通過します。 Voila!オブジェクトは、世界のどこに関係なく、ビューポートの中央に配置されます。

これは常にカメラの軸を揃えているので、カメラをモデル空間に変換し、半径を減算して中心を再度見たい場合があります。それからあなたは常にモデルの裏側を見ています。キーは常に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()); 
     } 
    } 
    } 
} 
関連する問題