2009-05-18 29 views
0

3D模型如何處理單位明智?
當我有一個隨機模型,我想適合我的觀點端口我不知道如果它太大或沒有,如果我需要翻譯它在中間...
我認爲一個3D對象可能有它是自己的原產地。適用於視口的3d模型

回答

0

對不起,你的問題很不清楚。我想你想把一個3D模型放到一個視口中。您可以通過計算模型的邊界框來實現此目的。爲此,遍歷所有多邊形並獲取最小/最大X/Y/Z座標。由點(min_x,min_y,min_z)(max_x,max_y,max_z)給出的邊界框將包含整個模型。現在,您可以通過查看此框的中心來對模型進行居中。通過一些進一步的計算(取決於您的FOV),您還可以在視口內獲取左/右/上/下邊框。

+0

我grabed在互聯網上隨機模型,我想表明它在OpenGL學習,但我看不到任何東西,但通過調整一點我可以看到一些運動,所以我想它的規模下來,它好一點,所以我想知道我怎麼能像你說的模型範圍,以適合我的觀點模型 – CiNN 2009-05-18 13:55:27

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空間中的某處計算出模型的邊界框。

接下來通過取最大值來計算它的半徑(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是Visual的副本,或者繪製它的位置。

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()); 
     } 
    } 
    } 
}