2013-07-07 115 views
1

的法線我試圖根據this documentation實現.3DS進口商和我走近階段,當我需要計算頂點的法線,因爲.3DS文件不提供這些服務。這裏是Java代碼:計算.3DS模型

/* Sctructure of vertex array is {x0, y0, z0, x1, y1, z1...} 
* 
* Basically, MathUtils.generateNormal_f(x0,y0,z0, x1,y1,z1, x2,y2,z2) is cross 
* product between (x1-x0, y1-y0, z1-z0) and (x2-x0, y2-y0, z2-z0) */ 

normals = new float[this.vertex.length]; //every vertex has it's own normal 
int n = 0; 
for (int i=0; i<this.index.length; i++){ 
    float[] Normal = MathUtils.generateNormal_f(//getting xyz coords of 1 normal 
      vertex[index[i]*3], vertex[index[i]*3+1], vertex[index[i]*3+2], 
      vertex[index[++i]*3], vertex[index[i]*3+1], vertex[index[i]*3+2], 
      vertex[index[++i]*3], vertex[index[i]*3+1], vertex[index[i]*3+2]); 

    normals[n++] = Normal[0]; 
    normals[n++] = Normal[1]; 
    normals[n++] = Normal[2]; 
} 

方法MathUtils.generateNormal_f(...)測試和工作正常。此代碼的結果可以在下面看到(第一張圖片)。舉例來說,在第二張圖片中,模型的每個法線都是相同的,並指向光源。

的問題是:如何正確計算法線?

Generated normals Every vertex has (1,0,0) normal

回答

1

你法線可能會反轉。

我不記得了3DS格式的非常好,但請檢查您是否可以從文件計算它們的導出和導入法線代替。

P.S.也不要用這樣的魔法:

vertex[index[i]*3], vertex[index[i]*3+1], vertex[index[i]*3+2], 
vertex[index[++i]*3], vertex[index[i]*3+1], vertex[index[i]*3+2], 
vertex[index[++i]*3], vertex[index[i]*3+1], vertex[index[i]*3+2] 

根據參數評估的順序,您將得到不同的結果。更明確地使用[I],[I + 1],[我+ 2]調用時計算正常...

+0

3ds確實沒有法線,整個應用程序是圍繞平滑組計算法線的想法而構建的。其中工作正常,你點給用戶任何其他選項。 – joojaa

+0

1.否,法線不倒置。他們隨便指點。 2. 3ds格式根本不支持法線。 3.不明白你在說什麼巫師和法師:) – TomatoMato

0

此信息是正確的,因爲據我所知,這是爲我工作。對於任何3點A,B和C在一個平面上,正常的,如果我們開始在A,然後B,最後C,將是:

凡(B - A)和( C-B)每個減去兩個向量,並且X符號代表找到兩個向量的叉積。點的順序非常重要,決定了我們的正常方向。如果A,B和C按照逆時針方向組織,那麼它們的正常位置將朝向固體外部。如果你想知道一個跨產品是什麼,那麼對於任意點P和Q,其交叉的產品將是:

,往往是做正常的向量的另一件事是,它是標準化的。這樣做是使法向量的大小等於1,以便更容易處理。這裏的公式:

凡點代表一個點積。如果您不知道點積是什麼,請允許我通過以下說明。對於任何點P和Q,它們的點積,這是一個標量值是:

現在,你有曲面法線,可以適當通過平均出計算每個頂點頂點法線共享該頂點的任何曲面的法線。我沒有這個公式,但我知道有兩種方法可以找到頂點法線:加權和非加權。加權方法涉及計算每個表面的面積,而非加權方法則不包括。

希望,這些信息會幫助你。我把其餘的信息留給你或其他人,因爲剩下的信息超出了我的境界。也許我會回來再研究一下這個問題。