Differences

This shows you the differences between two versions of the page.

Link to this comparison view

egc:teme:2022:02 [2022/11/20 00:39]
bogdan.vasile2211
egc:teme:2022:02 [2022/12/08 19:21] (current)
andrei.lambru
Line 1: Line 1:
-<​hidden>​ +======= Tema 2 - Car Race ======= 
-===== Tema 2 - Car Race =====+
   * **Responsabili:​** Vlad Drăghici, Cristi Lambru, Bogdan Vasile   * **Responsabili:​** Vlad Drăghici, Cristi Lambru, Bogdan Vasile
   * **Lansare:​** 21 noiembrie 2022   * **Lansare:​** 21 noiembrie 2022
-  * **Termen de predare:​** ​11 decembrie 2022, ora 23:59+  * **Termen de predare:​** ​16 decembrie 2022, ora 23:59
   * **Regulament:​** [[egc:​teme:​regulament|]]   * **Regulament:​** [[egc:​teme:​regulament|]]
   * **Notă: Orice informație ce nu a fost acoperită în acest document este la latitudinea voastră!**   * **Notă: Orice informație ce nu a fost acoperită în acest document este la latitudinea voastră!**
Line 21: Line 20:
  
  
-==== Pista cursei ====+===== Pista cursei ​=====
  
 Pentru a genera o pistă pe care să meargă mașina, este nevoie inițial de o mulțime de puncte care să o definească. Mulțimea este formată din puncte în planul XOZ (2D) și poate fi obținută folosind orice tool (chiar și foaia si pixul). Pentru exemplul următor s-a folosit Geogebra (https://​www.geogebra.org/​classic). Pentru a genera o pistă pe care să meargă mașina, este nevoie inițial de o mulțime de puncte care să o definească. Mulțimea este formată din puncte în planul XOZ (2D) și poate fi obținută folosind orice tool (chiar și foaia si pixul). Pentru exemplul următor s-a folosit Geogebra (https://​www.geogebra.org/​classic).
  
 {{ :​egc:​teme:​2022:​punctalapista.png?​700 | }} {{ :​egc:​teme:​2022:​punctalapista.png?​700 | }}
 +Menționăm că pista de curse din demo este una complexă. Pentru simplitate, în toate explicațiile ce vor urma se va folosi o pistă generată de un număr mic de puncte.
 +
  
 <note important>​ <note important>​
 Pista trebuie să respecte 2 condiții: Pista trebuie să respecte 2 condiții:
   - Să nu existe niciun unghi drept între oricare 2 segmente consecutive   - Să nu existe niciun unghi drept între oricare 2 segmente consecutive
-  - Să fie o curbă ​concavă+  - Să fie un poligon ​concav
  
 {{ :​egc:​teme:​2022:​concave.png?​600 |}} {{ :​egc:​teme:​2022:​concave.png?​600 |}}
Line 38: Line 39:
 </​note>​ </​note>​
  
-=== Generare geometrie pistă ===+==== Generare geometrie pistă ​====
  
  
-Geometria pistei de curse trebuie generată prin asamblare din cod. Nu se poate crea geometria într-un software extern ​si importa ​in aplicatie.+Geometria pistei de curse trebuie generată prin asamblare din cod. Nu se poate crea geometria într-un software extern ​și importa ​în aplicație.
  
 <​note>​ <​note>​
  
-Explicația care urmează este o recomandare de generare a geometriei pistei, dar aceasta poate fi asamblata ​în orice fel, atât timp cât sunt respectate cele 2 restrictii.+Explicația care urmează este o recomandare de generare a geometriei pistei, dar aceasta poate fi asamblată ​în orice fel, atât timp cât sunt respectate cele 2 restricții de mai sus.
 </​note>​ </​note>​
  
-Generarea pistei de curse se realizează ​conform pașilor de mai jos. O reprezentare vizuală a rezultatelor este prezentată în continuare.+Generarea pistei de curse se poate realiza ​conform pașilor de mai jos. O reprezentare vizuală a rezultatelor este prezentată în continuare.
   - Se creează punctele unui poligon ce definește pista de curse. Noi am folosit Geogebra.   - Se creează punctele unui poligon ce definește pista de curse. Noi am folosit Geogebra.
   - Se creează două seturi de puncte suplimentare,​ în interiorul și exteriorul poligonului ce  definește pista. Punctele se pot crea de-alungul perpendicularei fiecărui segment. Acest proces este detaliat mai jos.   - Se creează două seturi de puncte suplimentare,​ în interiorul și exteriorul poligonului ce  definește pista. Punctele se pot crea de-alungul perpendicularei fiecărui segment. Acest proces este detaliat mai jos.
-  - Se creeaza ​muchiile dintre punctele poligoanului interior și exterior.+  - Se creează ​muchiile dintre punctele poligoanului interior și exterior.
   - Se generează triunghiurile dintre punctele celor două poligoane. Triunghiurile se creează într-un singur obiect de tip mesh.   - Se generează triunghiurile dintre punctele celor două poligoane. Triunghiurile se creează într-un singur obiect de tip mesh.
  
Line 69: Line 70:
 Să presupunem că avem 2 puncte consecutive P1(x1, 0, z1), P2(x2, 0, z2) din mulțimea de puncte care definește traseul: Să presupunem că avem 2 puncte consecutive P1(x1, 0, z1), P2(x2, 0, z2) din mulțimea de puncte care definește traseul:
   - Se determină vectorul direcție de la P1 către P2 notat D (negru in poza).   - Se determină vectorul direcție de la P1 către P2 notat D (negru in poza).
-  - Se determină vectorul perpendicular ​la D notat P (verde in poza): P = cross(D, UP), UP fiind vectorul perpendicular ​la planul XOZ. +  - Se determină vectorul perpendicular ​pe D notat P (verde in poza): P = cross(D, UP), UP fiind vectorul perpendicular ​pe planul XOZ. 
-  - Folosind vectorul P și P1 putem să obținem punctele exterioare / interioare (Roșu și Albastru): R = P1 + distRoșu * P, A = P1 - distAlbastru * P.+  - Folosind vectorul P și poziția ​P1 putem să obținem punctele exterioare / interioare (Roșu și Albastru): R = P1 + distRoșu * P, A = P1 - distAlbastru * P.
  
 $$ $$
Line 88: Line 89:
  
  
-Astfel, dacă aplicăm același lucru pentru ​mai multe segmente, obținem noile mulțimi de puncte exterioare / interioare:+Astfel, dacă aplicăm același lucru pentru ​toate segmentele, obținem noile mulțimi de puncte exterioare / interioare:
  
  
Line 106: Line 107:
  
  
-=== Deplasare obstacole dinamice ===+==== Deplasare obstacole dinamice ​====
  
  
  
-Pe pistă, pe lângă mașina jucătorului,​ trebuie să se miște ​și alte mașini (adversari). Aceștia se mișcă pe un traseu predefinit paralel cu mulțimea generatoare de pistă. Acest traseu se poate obține cu tehnica prezentată mai sus.+Pe pistă, pe lângă mașina jucătorului,​ trebuie să se deplaseze ​și alte mașini (adversari). Aceștia se deplasează pe un traseu predefinit paralel cu mulțimea generatoare de pistă. Acest traseu se poate obține cu tehnica prezentată mai sus.
  
-=== Generare copăcei lângă pistă ===+==== Generare copăcei lângă pistă ​====
  
-Pe lângă pistă se află copăcei ​ca obstacole și elemente decorative. Constant pe ecran trebuie să se vadă cel puțin un copac (necesită densitate mare de copaci). Copacii nu trebuie să blocheze pista.+Pe lângă pistă se află copăcei ​cu scop decorativ. Constant pe ecran trebuie să se vadă cel puțin un copac (necesită densitate mare de copaci). Copacii nu trebuie să blocheze pista.
  
-=== Control mașină ===+===== Control mașină ​=====
  
-Dintre toate mașinile create pe pistă, una dintre ele va trebui să o alegeți ca fiind mașina jucătorului. ​+Dintre toate mașinile create pe pistă, ​pe una dintre ele va trebui să o alegeți ca fiind mașina jucătorului. ​
 Aceasta poate fi controlată folosind tastele **W, A, S, D**, unde W-S reprezintă mișcarea față-spate,​ iar A-D va schimba orientarea mașinii (detaliat mai jos). Aceasta poate fi controlată folosind tastele **W, A, S, D**, unde W-S reprezintă mișcarea față-spate,​ iar A-D va schimba orientarea mașinii (detaliat mai jos).
  
Line 128: Line 129:
 {{ :​egc:​teme:​2022:​lateral_rot_example.gif?​direct&​400 |}} {{ :​egc:​teme:​2022:​lateral_rot_example.gif?​direct&​400 |}}
  
-Pentru a păstra poziția camerei la mișcarea față-spate (W-S) în spatele playerului, la aceeași distanță, două alternative ar fi: +Pentru a păstra ​**poziția camerei ​la aceeași distanță în spatele mașinii**, ​la mișcarea față-spate (W-S), două alternative ar fi: 
-  * Actualizarea poziției camerei odată cu cea a playerului, la fiecare input valid. +  * Actualizarea poziției camerei odată cu cea a mașinii, la fiecare input valid. 
-  * Actualizarea constantă (deci în Update(), fără verificări) a poziției camerei ca fiind: poziția ​playerului ​la care se adaugă un offset (acel offset fiind distanța pe care camera o păstrează față de player). +  * Actualizarea constantă (deci în Update(), fără verificări) a poziției camerei ca fiind: poziția ​mașinii ​la care se adaugă un offset (acel offset fiind distanța pe care camera o păstrează față de mașină). 
  
 Deplsarea față-spate (W-S) va implica mișcarea mașinii în funcție de rotația camerei, astfel încât comportamentul dorit să fie asemănător cu exemplul de mai jos: Deplsarea față-spate (W-S) va implica mișcarea mașinii în funcție de rotația camerei, astfel încât comportamentul dorit să fie asemănător cu exemplul de mai jos:
Line 149: Line 150:
 {{ :​egc:​teme:​2022:​final_control.gif?​direct&​400 |}} {{ :​egc:​teme:​2022:​final_control.gif?​direct&​400 |}}
  
-=== Verificare mașină dacă se află pe pistă ===+==== Verificare mașină dacă se află pe pistă ​====
  
 Pentru a verifica dacă mașina se află pe pistă, avem la dispoziție mai multe posibilități. Pentru simplitate, vom considera suficient dacă se verifică doar centrul mașinii să se afle în interiorul pistei. Orice soluție ce oferă o verificare corectă a acestei informații este bună. Pentru a verifica dacă mașina se află pe pistă, avem la dispoziție mai multe posibilități. Pentru simplitate, vom considera suficient dacă se verifică doar centrul mașinii să se afle în interiorul pistei. Orice soluție ce oferă o verificare corectă a acestei informații este bună.
Line 166: Line 167:
 </​note>​ </​note>​
  
-=== Verificare coliziuni obstacole dinamice ===+==== Verificare coliziuni obstacole dinamice ​====
  
 Pentru a avea niște interacțiune cu mașiniile inamice, va trebui să le puteți "​detecta"​. Această detectare presupune o verificare a poziției mașinii jucătorului în raport cu fiecare mașină inamică. Pentru a realiza acest lucru, cel mai simplu mod pe care vi-l recomandăm este o verificare de coliziune [[https://​developer.mozilla.org/​en-US/​docs/​Games/​Techniques/​3D_collision_detection|sferă-sferă]]:​ Pentru a avea niște interacțiune cu mașiniile inamice, va trebui să le puteți "​detecta"​. Această detectare presupune o verificare a poziției mașinii jucătorului în raport cu fiecare mașină inamică. Pentru a realiza acest lucru, cel mai simplu mod pe care vi-l recomandăm este o verificare de coliziune [[https://​developer.mozilla.org/​en-US/​docs/​Games/​Techniques/​3D_collision_detection|sferă-sferă]]:​
Line 174: Line 175:
 În cazul nostru particular, sferele ar avea centrul în centrul mașinii, iar raza acesteia presupune distanță de verificare de coliziune. În cazul nostru particular, sferele ar avea centrul în centrul mașinii, iar raza acesteia presupune distanță de verificare de coliziune.
  
-==== Minimap ====+În momentul în care este dectată intersecția dintre mașina controlată de jucător și un obstacol dinamic, mașina jucătorului trebuie să se oprească. Orice tastă apasată pentru controlul deplasării sau rotației nu mai trebuie să modifice poziția sau orientarea mașinii. Acest efect de oprire dispare în momentul în care nu mai există intersecție. 
 +===== Minimap ​=====
  
 În unul din colțurile ecranului (nu contează ce colț, noi am ales dreapta-jos pentru a fi mai ușor de vizualizat dar puteți alege orice poziție), va trebui să randați și un **minimap**. ​ În unul din colțurile ecranului (nu contează ce colț, noi am ales dreapta-jos pentru a fi mai ușor de vizualizat dar puteți alege orice poziție), va trebui să randați și un **minimap**. ​
Line 186: Line 188:
  
 Pentru a putea vedea de sus scena (cum este prezentat și în exemplul de mai jos), ar trebui să se întâmple următoarele lucruri: Pentru a putea vedea de sus scena (cum este prezentat și în exemplul de mai jos), ar trebui să se întâmple următoarele lucruri:
-  * Mutarea poziției camerei deasupra ​playerului ​(și prin urmare și poziția centrului camerei); +  * Mutarea poziției camerei deasupra ​mașinii ​(și prin urmare și poziția centrului camerei); 
-  * Din moment ce se dorește o vedere de asamblu ​asupra unei bucăți din traseu, se va trece camera într-o **proiecție ortografică** folosind funcția:+  * Din moment ce se dorește o vedere de ansamblu ​asupra unei bucăți din traseu, se va trece camera într-o **proiecție ortografică** folosind funcția:
 <code cpp> <code cpp>
 glm::​ortho(float left, float right, float bottom, float top, float zNear, float zFar) glm::​ortho(float left, float right, float bottom, float top, float zNear, float zFar)
 </​code>​ </​code>​
-  * Minimap-ul nu vede lumea curbată, deci nu uitați să dezactivați curbura din shader pentru elementele randate aici! 
  
 {{ :​egc:​teme:​2022:​minimap_ex.gif?​direct&​400 |}} {{ :​egc:​teme:​2022:​minimap_ex.gif?​direct&​400 |}}
Line 197: Line 198:
 <note important>​**Atenție!** Observați că rotația camerei nu se mai păstrează,​ dar deplasarea ei în funcție de jucător **da**!</​note>​ <note important>​**Atenție!** Observați că rotația camerei nu se mai păstrează,​ dar deplasarea ei în funcție de jucător **da**!</​note>​
  
-==== Curbură teren ====+===== Curbură teren =====
  
  
-=== Crearea curburii din shader ===+==== Crearea curburii din shader ​====
  
 Realizeaza curburii terenului se realizează la pasul de desenare a obiectelor din scenă. Acest efect se creează prin modificarea componentei y a coordonatelor pentru toți vertecșii obiectelor din scenă. Procesul este realizat în vertex shader. Componenta y a tuturor vertecșilor se modifică după cum urmează. Realizeaza curburii terenului se realizează la pasul de desenare a obiectelor din scenă. Acest efect se creează prin modificarea componentei y a coordonatelor pentru toți vertecșii obiectelor din scenă. Procesul este realizat în vertex shader. Componenta y a tuturor vertecșilor se modifică după cum urmează.
Line 213: Line 214:
   * $Pos_v$ - poziția în spațiul lume a vertexului procesat de vertex shader   * $Pos_v$ - poziția în spațiul lume a vertexului procesat de vertex shader
   * $Pos_{car}$ - poziția în spațiul lume a mașinii controlate de jucător   * $Pos_{car}$ - poziția în spațiul lume a mașinii controlate de jucător
-  * $Pos_{v_y}$ - componenta y a vertexului+  * $Pos_{v_y}$ - componenta y a poziției ​vertexului
   * $scaleFactor$ - un factor de scalare ce controlează curbura terenului   * $scaleFactor$ - un factor de scalare ce controlează curbura terenului
 </​note>​ </​note>​
Line 222: Line 223:
 {{ :​egc:​teme:​2022:​curve_scale_example.gif?​direct&​400 |}} {{ :​egc:​teme:​2022:​curve_scale_example.gif?​direct&​400 |}}
  
-=== Densitate de triunghiuri teren ===+==== Densitate de triunghiuri teren ====
  
 Deoarece realizarea curburii terenului este un proces ce modifică pozițiile vertecșilor,​ rezultatul vizual este influențat de densitatea de triunghiuri ale terenului. Cu cât terenul are o densitate mai mare de triunghiuri,​ cu atât efectul de curbura este mai natural. O densitate mică produce un rezultat vizual mai '​pătrățos'​. O comparație între rezultatele celor două poate fi vizualizată mai jos. În stânga este prezentat rezultatul pentru o densitate mică și în dreapta pentru o densitate mare. Deoarece realizarea curburii terenului este un proces ce modifică pozițiile vertecșilor,​ rezultatul vizual este influențat de densitatea de triunghiuri ale terenului. Cu cât terenul are o densitate mai mare de triunghiuri,​ cu atât efectul de curbura este mai natural. O densitate mică produce un rezultat vizual mai '​pătrățos'​. O comparație între rezultatele celor două poate fi vizualizată mai jos. În stânga este prezentat rezultatul pentru o densitate mică și în dreapta pentru o densitate mare.
Line 235: Line 236:
  
  
-==== Funcționalități obligatorii (150 puncte) ====+===== Funcționalități obligatorii (150 puncte) ​=====
   * Teren 40p   * Teren 40p
     * Generare geometrie teren iarbă și pistă 30p     * Generare geometrie teren iarbă și pistă 30p
Line 268: Line 269:
  
  
-==== Exemple de funcționalități bonus ====+===== Exemple de funcționalități bonus =====
 <note warning>​Orice funționalitate suplimentară implementată (care nu este inclusă în cerințele obligatorii) poate fi considerată ca punctaj bonus dacă este suficient de complexă. Funcționlitățile bonus se iau în considerare doar dacă funcționalitățile obligatorii au fost realizate.</​note>​ <note warning>​Orice funționalitate suplimentară implementată (care nu este inclusă în cerințele obligatorii) poate fi considerată ca punctaj bonus dacă este suficient de complexă. Funcționlitățile bonus se iau în considerare doar dacă funcționalitățile obligatorii au fost realizate.</​note>​
   * Finalizarea jocului de curse de mașini. Realizarea verificării dacă a fost parcursă toată pista și cuantificarea numărului de tururi parcurse. Păstrarea timpului necesar parcurgerii fiecărui tur și finalizarea intrecerii după parcurgerea unui anumit număr de tururi. Afișarea unui UI ce conține numărul de tururi rămase de parcurs. Pentru a verifica dacă s-a parcurs un tur, se pot folosi puncte de verificare de-alungul traseului.   * Finalizarea jocului de curse de mașini. Realizarea verificării dacă a fost parcursă toată pista și cuantificarea numărului de tururi parcurse. Păstrarea timpului necesar parcurgerii fiecărui tur și finalizarea intrecerii după parcurgerea unui anumit număr de tururi. Afișarea unui UI ce conține numărul de tururi rămase de parcurs. Pentru a verifica dacă s-a parcurs un tur, se pot folosi puncte de verificare de-alungul traseului.
Line 278: Line 279:
   * Adăugarea de pickups care odată lovite, oferă jucătorului diferite bonusuri (de exemplu, o creștere în viteză sau un control mai bun al vehiculului).   * Adăugarea de pickups care odată lovite, oferă jucătorului diferite bonusuri (de exemplu, o creștere în viteză sau un control mai bun al vehiculului).
  
-==== Întrebări și răspunsuri ====+===== Întrebări și răspunsuri ​=====
 Pentru întrebări vom folosi forumurile de pe moodle. Orice nu este menționat în temă este la latitudinea fiecărui student! Pentru întrebări vom folosi forumurile de pe moodle. Orice nu este menționat în temă este la latitudinea fiecărui student!
  
-==== Notare ====+===== Notare ​=====
 Baremul este orientativ. Fiecare asistent are o anumită libertate în evaluarea temelor (de exemplu, să dea punctaj parțial pentru implementarea incompletă a unei funcționalități sau să scadă pentru hard coding). Același lucru este valabil atât pentru funcționalitățile obligatorii,​ cât și pentru bonusuri. Baremul este orientativ. Fiecare asistent are o anumită libertate în evaluarea temelor (de exemplu, să dea punctaj parțial pentru implementarea incompletă a unei funcționalități sau să scadă pentru hard coding). Același lucru este valabil atât pentru funcționalitățile obligatorii,​ cât și pentru bonusuri.
  
Line 287: Line 288:
 Tema trebuie încărcată pe moodle. Pentru a fi punctată, tema trebuie prezentată la laborator. Vor exista laboratoare speciale de prezentare a temelor (care vor fi anunțate).</​note>​ Tema trebuie încărcată pe moodle. Pentru a fi punctată, tema trebuie prezentată la laborator. Vor exista laboratoare speciale de prezentare a temelor (care vor fi anunțate).</​note>​
  
-==== Indicații suplimentare ====+===== Indicații suplimentare ​=====
 Tema va fi implementată în OpenGL și C++. Este indicat să folosiți framework-ul și Visual Studio. Tema va fi implementată în OpenGL și C++. Este indicat să folosiți framework-ul și Visual Studio.
  
 <​note>​Pentru implementarea temei, în folderul **src/​lab_m1** puteți crea un nou folder, de exemplu **Tema2**, cu fișierele **Tema2.cpp** și **Tema2.h** (pentru implementare POO, este indicat să aveți și alte fișiere). Pentru a vedea fișierele nou create în Visual Studio în Solution Explorer, apăsați click dreapta pe filtrul **lab_m1** și selectați **Add→New Filter**. După ce creați un nou filtru, de exemplu **Tema2**, dați click dreapta și selectați **Add→Existing Item**. Astfel adăugați toate fișierele din folderul nou creat. În fișierul **lab_list.h** trebuie adăugată și calea către header-ul temei. De exemplu: **#include “lab_m1/​Tema2/​Tema2.h”**</​note>​ <​note>​Pentru implementarea temei, în folderul **src/​lab_m1** puteți crea un nou folder, de exemplu **Tema2**, cu fișierele **Tema2.cpp** și **Tema2.h** (pentru implementare POO, este indicat să aveți și alte fișiere). Pentru a vedea fișierele nou create în Visual Studio în Solution Explorer, apăsați click dreapta pe filtrul **lab_m1** și selectați **Add→New Filter**. După ce creați un nou filtru, de exemplu **Tema2**, dați click dreapta și selectați **Add→Existing Item**. Astfel adăugați toate fișierele din folderul nou creat. În fișierul **lab_list.h** trebuie adăugată și calea către header-ul temei. De exemplu: **#include “lab_m1/​Tema2/​Tema2.h”**</​note>​
  
-==== Arhivarea Proiectului ====+===== Arhivarea Proiectului ​=====
 <​note>​ <​note>​
   * În mod normal arhiva trebuie să conțină toate resursele necesare compilării și rulării   * În mod normal arhiva trebuie să conțină toate resursele necesare compilării și rulării
Line 300: Line 301:
   * În cazul în care arhiva tot depășește limita de 50MB (nu ar trebui), puteți să ștergeți și folderul __**/​deps**__ sau __**/​assets**__ întrucât se pot adăuga la testare. Nu este recomandat să faceți acest lucru întrucât îngreunează mult testarea în cazul în care versiunea curentă a bibliotecilor/​resurselor diferă de versiunea utilizată la momentul scrierii temei.   * În cazul în care arhiva tot depășește limita de 50MB (nu ar trebui), puteți să ștergeți și folderul __**/​deps**__ sau __**/​assets**__ întrucât se pot adăuga la testare. Nu este recomandat să faceți acest lucru întrucât îngreunează mult testarea în cazul în care versiunea curentă a bibliotecilor/​resurselor diferă de versiunea utilizată la momentul scrierii temei.
 </​note>​ </​note>​
-</​hidden>​ 
  
egc/teme/2022/02.1668897548.txt.gz · Last modified: 2022/11/20 00:39 by bogdan.vasile2211
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0