1

このドキュメントに従って .3ds インポーターを実装しようとしていますが、.3ds ファイルでは提供されないため、頂点法線を計算する必要がある段階に近づいています。Javaコードは次のとおりです。

/* 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(...)はテスト済みで、正常に動作します。このコードの結果を以下に示します (最初の画像)。たとえば、2 番目のイメージでは、モデルのすべての法線が同じで、光源の方を向いています。

問題は、法線を適切に計算する方法です。

生成された法線 すべての頂点には (1,0,0) 法線があります

4

2 に答える 2

0

この情報は私の知る限り正しいものであり、私にとってはうまくいきました。平面上の任意の 3 点 A、B、C について、A から開始し、次に B、最後に C の場合、法線は次のようになります。

ここで、(B - A) と (C - B) はそれぞれ 2 つのベクトルを減算し、X 記号は 2 つのベクトルの外積を求めることを表します。ポイントの順序は非常に重要で、法線方向を決定します。A、B、C が反時計回りに編成されている場合、それらの法線はソリッドの外側を向きます。外積とは何かを知りたい場合、任意の点 P と Q について、それらの外積は次のようになります。

法線ベクトルに対してよく行われるもう 1 つのことは、それが正規化されることです。これにより、法線ベクトルの大きさが 1 に等しくなり、扱いやすくなります。方程式は次のとおりです。

ドットは内積を表します。内積が何かわからない場合は、次の図で説明させてください。点 P と Q の内積 (スカラー値) は次のとおりです。

サーフェス法線が得られたので、頂点を共有するサーフェスの法線を平均化することで、各頂点の頂点法線を適切に計算できます。私はその式を持っていませんが、頂点法線を見つけるには、重み付けされた方法と重み付けされていない方法の 2 つの方法があることを知っています。加重アプローチでは各サーフェスの面積を計算しますが、非加重アプローチでは計算しません。

この情報がお役に立てば幸いです。残りの情報は私の領域を超えているため、残りはあなたまたは他の誰かに任せます。おそらく、私は戻ってきて、この質問についてもう少し調査します。

于 2013-07-08T02:30:05.073 に答える