2013-04-08 11 views
6

Tworzę silnik graficzny 3D, a jednym z wymagań są liny zachowujące się jak w silniku źródłowym Valve.Rdzenie w stylu silnika z rdzeniem źródłowym

Tak więc w silniku źródłowym odcinek liny jest kwadratem, który obraca się wzdłuż swojej osi kierunkowej skierowanej w stronę kamery, więc jeśli odcinek liny znajduje się w kierunku + Z, obraca się wzdłuż osi Z, więc jest twarz jest skierowana w środkową pozycję kamery.

W tej chwili mam zdefiniowane sekcje lin, więc mogę mieć ładną zakrzywioną linę, ale teraz próbuję zbudować matrycę, która obróci ją wzdłuż wektora kierunku.

Mam już matrycę dla renderowania billboard ikonek oparte na tej technice billboarding: Constructing a Billboard Matrix I w tej chwili starałem retool go tak, prawo, góra, przód wektor dopasować segmentu liny kierunek wektora.

Moja lina składa się z wielu sekcji, każda sekcja jest prostokątem złożonym z dwóch trójkątów, jak powiedziałem powyżej, mogę uzyskać idealną pozycję i sekcje, jest to obracanie w stronę kamery, która powoduje wiele problemów.

Jest to OpenGL ES2 i zapisywane w C.

I badano Doom 3 oddawania jest kod wiązki w Model_beam.cpp, zastosowana metoda jest obliczyć przesunięcie na podstawie normalnej zamiast używania matryc, dlatego stworzyłem podobną technikę w moim kodzie C, a ona sama pracuje, przynajmniej to, działa tak długo, jak tego potrzebuję.

Tak więc dla tych, którzy również próbują wymyślić ten jeden, użyj produktu krzyżowego środka liny w stosunku do pozycji kamery, normalizuj to, a następnie pomnóż go do szerokości, którą chcesz, aby lina była , a następnie podczas konstruowania wierzchołków przesuń każdy wierzchołek w kierunku + lub - wektora wynikowego.

Dalsza pomoc byłaby świetna, ponieważ nie jest idealnie!

Dziękuję

+2

Aby obrócić co o pewien kąt wokół określonej osi użyć [kwaternion] (https://en.wikipedia.org/wiki/Quaternion). –

+0

Obecnie używam kwaternionów, ale nie jestem pewien, jak obrócić go w kierunku położenia kamery. –

+4

Niech normalny prostokąt bieżącego/sekcji będzie "N", a wektor wzdłuż osi prostokąta będzie "V". Następnie 'VxN' da ci trzeci wektor' U', z 'U' i' N' tworzącymi "płaszczyznę poziomą" w stosunku do twojej sekcji linowej. Teraz obliczyć 'EyePos - C' (gdzie' C' jest centroidem twojego prostokąta) i znormalizować go, aby uzyskać 'E', kierunek kamery. Projektuj 'E' na płaszczyźnie' UN', aby uzyskać 'E''. Ostatecznie pożądany obrót (wokół osi "V") to "arccos (N. E ')". –

Odpowiedz

1

Wyjazd this related stackoverflow post on billboards in OpenGL on cytuje lighthouse3d samouczek, który jest całkiem dobra lektura. Tutaj są wysunięte punkty techniki:

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

Podczas gdy ten link może odpowiedzieć na pytanie, lepiej umieścić tutaj istotne części odpowiedzi i podać link do odsyłacza. Odpowiedzi dotyczące linków mogą stać się nieprawidłowe, jeśli strona z linkami się zmieni. – Brian

+0

Dobrze, Brian. Dodałem sedno tej techniki ... – henderso

Powiązane problemy