2012-12-29 44 views
1

我在DirectX中創建了一個簡單的「引擎」,它可以從.obj文件加載和渲染模型。對於我創建的對象,例如一個簡單的立方體,座標在-1.0到1.0範圍內。然而,加載一個使用不同單位並且座標在-2k到2k範圍內的模型會導致巨大的東西,甚至不能完全適應深度緩衝區,所以我看到一條巨大的腿或類似的效果。如何在DirectX中規範模型大小?

我記得有關它的地方,但最近我經歷了很多DX的東西,我不記得它在哪裏或它是什麼。所以我的問題是,假設我希望能夠加載使用不同單位的不同模型,那麼確保它們都具有相似尺寸並很好地適應屏幕的最佳方法是什麼?

我可以嘗試加載對象時轉換值,但也許有更多的DirectX方式使用轉換矩陣或着色器?

+0

縮放通常是作爲[世界變換](http://msdn.microsoft.com/en-us/library/windows/desktop/bb206365.aspx)完成的,其中頂點從模型空間轉換到世界空間。然後將該矩陣乘以視圖和投影矩陣以形成最終變換。 – IInspectable

+0

蒂姆的回答是正確的,雖然他說的規模懸殊,他說他會很快失去浮點精度。 – user805547

回答

2

最簡單的方法是找到模型中哪個組件包含最大範圍,並使用該值來統一縮放模型。要找到最大範圍,請計算模型邊界框(除非wavefront obj。文件已經提供了該邊界框,但也許您想要驗證它),並使用框尺寸作爲範圍進行比較。這會將所有導入的模型縮小到單位範圍。例如,如果您有一個邊框覆蓋374 * 820 * 512單位的模型,其中最大的一個是820的Y軸,所以您只需將其縮小820(將所有組件劃分爲820)。這可以通過統一的縮放矩陣來實現,如果我沒有弄錯,可以用D3DXMatrixScaling進行初始化。 假設邊界框由2個向量(最大和最小頂點)給出,計算這些向量的差值,然後選取最大值,並將其反比作爲縮放因子用於矩陣。

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 
} 

當然,你可能需要,如果你的看法覆蓋除單元箱體較大面積使用一些比例因子(但顯然這是你使用的是什麼)。

+0

是的,這是行得通的,但在給了它第二個想法之後,我想我會在3D軟件中縮放我的模型,並保留現在的代碼。 – jaho

+0

我不是D3D的用戶,也許它顯示在我給出的代碼示例中,但是我認爲我的想法是站得住的,如果您一次只顯示一個模型。如果您顯示的內容很多,我認爲在加載模型後縮放一次會更有效率,或者像您說的那樣,使用外部軟件。 – didierc