This is an old revision of the document!
In aceasta tema, veti avea de realizat un joc in care jucatorul controleaza un elicopter ce se deplaseaza pe suprafata unui asteroid deluros. Misiunea jucatorului este sa culeaga mai multe mostre dintr-o resursa speciala ce se gaseste pe acest asteroid, ce are forma unui copacel. Controlul jocului este in totalitate cu butonul dreapta de la mouse. Acest buton este utilizat pentru selectia pozitiei de destinatie pentru deplasarea elicopterului si pentru selectia copacilor de pe asteroid.
Puteți viziona mai jos un filmuleț demonstrativ cu o aplicație construită pe baza framework-ului de laborator, care acoperă cerințele.
Rezultatul este doar un efect vizual ce curbează geometria în jurul personajului, astfel că acesta poate ajunge la limita geometriei lumii, altfel spus la capătul ei și să și depășească acest capăt :) . De asemenea, este important de menționat că pentru calculele de iluminare NU se ține cont de calculele de creare a curburii geometriei.
Realizeaza curburii obiectelor din lume se realizează la pasul de desenare a obiectelor din scenă. Acest efect se creează prin modificarea componentei y a coordonatelor pentru toate vârfurile obiectelor din lume. Procesul este realizat în vertex shader. Componenta y a tuturor vârfurilor se modifică după cum urmează:
$$ Pozitie_{v_y} = Pozitie_{v_y} - \|{Pozitie_{personaj}-Pozitie_v}\|^2 \cdot factorCurbura $$
Factorul de curbură este proporțional cu dimensiunea obiectelor din lume. Pentru demo-ul de mai sus, este utilizat un factor de 0.02.
Geometria elicopterului poate fi vizualizata in animatia de mai jos.
Geometria elicopterului este compusa din doua cuburi redimensionate neuniform pentru a defini cabina si coada elicopterului, impreuna cu 4 cuburi, de asemenea redimensionate neuniform pentru a reprezenta cele 2 elice. Geometria cabinei si a cozii are o culoare diferita de cea a elicelor.
Dupa cum se poate vedea si in imaginea de mai sus, cele 2 elice au o animatie continua de rotatie.
Geometria marcajului destinatie pentru elicopter poate fi vizualizata in imaginea de mai jos.
Paralelipipedul din partea superioara este obtinut prin redimensionarea neuniforma a unui cub. Acesta are o animatie continua de oscilatie in directia sus-jos.
In partea de jos a marcajului, se afla un disc de cerc ce se afla putin de-asupra terenului. Acest disc ia forma zonei de teren pe care se afla pentru a pastra un rezultat vizual placut.
Geometria copacului se realizeaza prin desenarea unei ierarhii de paralelipipede cu mai multe niveluri, unde fiecare la fiecare nivel, se deseneaza un paralelipiped redimensionat uniform, rotit si translatat in capatul paralelipipedului de la nivelul anterior. Pentru a finaliza desenarea, se aplica la final toate transformarile utilizate in desenarea paralelipipedului de la nivelul anterior. Rezultatul se poate vedea in imaginea de mai jos.
La fiecare nivel al ierarhiei de paralelipipede, se deseneaza 3 ramuri de ierarhie, fiecare rotita la 120 de grade fata de axa OY, una fata de cealalta. Pentru copacul din imagine, s-au utilizat 6 niveluri ale ierarhiei de paralelipipede.
Pentru colorarea copacului, se utilizeaza procesul de mapare cilindrica. Se folosesc 2 texturi, una pentru trunchiul copacului si una pentru foliajul coroanei. Pentru a calcula coordonatele de textura in varfurile geometriei ce descrie copacul, se utilizeaza procesul de mapare cilindrica ce are urmatoarele formule:
$$ u = \frac{1}{2\pi}arctan(z/x) \\ v = \frac{y}{treeHeight} $$
unde u si v sunt componentele x si y ale coordonatei de textura si (x, y, z) reprezinta componentele coordonatei varfului in spatiul lumii.
Suplimentar, pentru imbunatatirea calitatii vizuale, desenarea se realizeaza dupa cum urmeaza:
Rezultatul poate fi vizualizat in imaginea de mai jos.
TODO: Descriere generala
În situația în care se utilizează framework-ul de laborator, pentru desenarea geometriei din perspectiva camerei observator, se poate utiliza obiectul de tip Camera
, după cum urmeaza:
auto camera = GetSceneCamera(); // pozitia relativa a camerei fata de pozitia personajului glm::vec3 relativeCameraPosition = ...; // playerPosition este pozitia in lume a personajului controlat de jucator camera->SetPositionAndRotation( playerPosition + relativeCameraPosition, glm::quatLookAt(-glm::normalize(relativeCameraPosition), glm::vec3(0, 1, 0)) );
Pentru a orienta geometria personajului în direcția de deplasare, se utilizează o matrice de rotație în jurul axei OY. În situația în care se cunoaște direcția de deplasare, unghiul de rotație se poate calcula după cum urmează:
$$ unghi = arctan(\frac{directie_x}{directie_z}) $$
atan2()
pentru calcularea arctangentei.
plane50.obj
. Geometria suport trebuie generata din cod si trebuie sa aiba cel putin 10000 de varfuri.