2013-04-08 66 views
6

我創建一個3D圖形引擎,並要求之一是,在Valve的Source引擎表現得像繩索。Source引擎樣式繩渲染

所以在源碼引擎中,一段繩索是一個沿其方向軸旋轉以面向相機的四邊形,所以如果繩索段在+ Z方向,它將沿着Z軸旋轉,所以它是臉部正對着相機的中心位置。

目前,我已經定義了繩索的部分,這樣我就可以有一個很好的彎曲的繩子,但我現在想建設沿它的方向向量,將其旋轉矩陣。

我已經呈現在此基礎上產生廣告牌廣告牌技術精靈矩陣: Constructing a Billboard Matrix 而此刻我一直在試圖要重組,使右,上,前進矢量匹配繩段的方向向量。

我的繩子由多個部分組成,每個部分都是一個由兩個三角形組成的矩形,正如我上面所說的,我可以獲得完美的位置和部分,這是面對相機的旋轉,導致我很多的問題。

這是在OpenGL ES2和寫入C.

我已經研究了Model_beam.cpp Doom 3的的光束呈現代碼,所使用的方法有所述偏移基於法線計算,而不是使用矩陣,所以我在我的C代碼中創建了一個類似的技術,至少它的作品類似於我現在需要的作品。

因此,對於那些也試圖找出這個問題的人來說,使用繩子中點與攝像機位置的交叉乘積,對其進行歸一化處理,然後將其相乘到想要的繩索寬度,那麼在構造頂點時,將結果向量的+或 - 方向上的每個頂點進行偏移。

進一步幫助將是巨大的,雖然,因爲這是不完美的!

謝謝

+2

要繞特定軸旋轉某個角度,請使用[quaternion](https://en.wikipedia.org/wiki/Quaternion)。 –

+0

我目前使用的四元數,但我不知道如何將它朝着攝像機的位置 –

+4

讓當前矩形/段的正常是'N'旋轉,沿着矩形形狀的軸矢量是'V'。然後,'VxN'會給你第三個矢量'U','U'和'N'形成一個相對於你的繩索段的「水平面」。現在計算'EyePos - C'(其中'C'是矩形的質心)並將其歸一化以得到相機方向'E'。在'UN'飛機上投射'E'以獲得'E''。最後,你想要的旋轉(關於軸'V')是'arccos(N。E')'。 –

回答

1

退房this related stackoverflow post on billboards in OpenGL它引用了lighthouse3d教程,是一個不錯的讀取。以下是該技術的要點:

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]); 
    } 
+0

儘管這個鏈接可能回答這個問題,但最好在這裏包含答案的基本部分,並提供供參考的鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 – Brian

+0

好點Brian。我添加了技術的關鍵 – henderso