6

私は 3D グラフィック エンジンを作成していますが、要件の 1 つは、Valve のソース エンジンのように動作するロープです。

したがって、ソース エンジンでは、ロープのセクションは方向軸に沿って回転してカメラの方を向くクワッドです。そのため、ロープのセクションが +Z 方向にある場合、Z 軸に沿って回転し、顔がカメラに面するようになります。カメラの中心位置。

現時点では、ロープのセクションが定義されているので、素敵な曲線のロープを作成できますが、現在、方向ベクトルに沿ってロープを回転させるマトリックスを構築しようとしています。

このビルボード テクニックに基づいて、ビルボード スプライトをレンダリングするためのマトリックスが既にあり ます

私のロープは複数のセクションで構成されており、各セクションは 2 つの三角形で構成される長方形です。上で述べたように、位置とセクションを完璧にすることができます。多くの問題を引き起こしているのは、カメラの方を向く回転です。

これは OpenGL ES2 であり、C で記述されています。

私は Doom 3 のビーム レンダリング コードを Model_beam.cpp で調べました。そこで使用されている方法は、行列を使用するのではなく、法線に基づいてオフセットを計算することです。そのため、C コードで同様の手法を作成しました。少なくともそれは機能します。 、今必要なだけ機能します。

したがって、これも理解しようとしている人のために、カメラの位置に対してロープの中間点の外積を使用し、それを正規化し、それをロープの幅に掛けてから、構築するときに結果のベクトルの + または - 方向に各頂点をオフセットします。

これは完璧ではないので、さらに助けていただければ幸いです。

ありがとうございました

4

1 に答える 1

1

OpenGL のビルボードに関するこの関連する stackoverflow の投稿を チェックてください。テクニックの重要なポイントは次のとおりです。

void billboardCylindricalBegin(
                float camX, float camY, float camZ,
                float objPosX, float objPosY, float objPosZ) {

        float lookAt[3],objToCamProj[3],upAux[3];
        float modelview[16],angleCosine;

        glPushMatrix();

    // objToCamProj is the vector in world coordinates from the 
    // local origin to the camera projected in the XZ plane
        objToCamProj[0] = camX - objPosX ;
        objToCamProj[1] = 0;
        objToCamProj[2] = camZ - objPosZ ;

    // This is the original lookAt vector for the object 
    // in world coordinates
        lookAt[0] = 0;
        lookAt[1] = 0;
        lookAt[2] = 1;


    // normalize both vectors to get the cosine directly afterwards
        mathsNormalize(objToCamProj);

    // easy fix to determine wether the angle is negative or positive
    // for positive angles upAux will be a vector pointing in the 
    // positive y direction, otherwise upAux will point downwards
    // effectively reversing the rotation.

        mathsCrossProduct(upAux,lookAt,objToCamProj);

    // compute the angle
        angleCosine = mathsInnerProduct(lookAt,objToCamProj);

    // perform the rotation. The if statement is used for stability reasons
    // if the lookAt and objToCamProj vectors are too close together then 
    // |angleCosine| could be bigger than 1 due to lack of precision
       if ((angleCosine < 0.99990) && (angleCosine > -0.9999))
          glRotatef(acos(angleCosine)*180/3.14,upAux[0], upAux[1], upAux[2]);   
    }
于 2013-10-07T23:21:14.330 に答える