|
|
|
Paolo Cignoni |
|
cignoni@iei.pi.cnr.it |
|
http://vcg.iei.pi.cnr.it/~cignoni |
|
|
|
21 novembre 2001 |
|
|
|
|
The shape of the asteroids is randomly generated |
|
The ship class include side movement member
functions |
|
The mesh class can manage colors and smoothed
normals |
|
|
|
|
Uso struttura mesh |
|
Si parte da una mesh semplice (un tetraedro) e
si suddivide ogni triangolo in quattro triangoli piu’ piccoli |
|
|
|
|
|
|
Ogni nuovo punto p viene spostato dalla sua
posizione lungo la retta cm-p di una quantita’ casuale dipendente dalle
posizioni di p1 e p2 |
|
|
|
|
|
|
|
|
|
Point3f mp=(p0+p1)/2.0; |
|
float r=(Distance(p0,BC)+Distance(p1,BC))/2.0; |
|
float l=Distance(p0,p1); // Edge Lenght |
|
l=l*strenght; |
|
srand48(seed + p0.Hash() + p1.Hash()); |
|
// Displacement depends only on the two vertexes
p0,p1 |
|
float d=drand48()-0.5f; |
|
mp=BC+Normalize(mp-BC)*(r+d*l/2.0); |
|
|
|
|
|
Per faccia |
|
prodotto vettore di due
edge della faccia
(attenti alla regola
della mano destra) |
|
Per vertice |
|
sfruttando la conoscenza della geometria
dell’oggetto (e.g. una sfera) |
|
mediando le normali
tra le facce che incidono
su un dato vertice |
|
|
|
|
|
Nella nostra struttura Mesh non abbiamo modo di
sapere quali facce condividono uno stesso vertice. |
|
Per mediare le normali occorre fare
un’unificazione dei vertici. |
|
Puo’ essere fatta in maniera implicita facendo
uso dei container associativi delle STL. |
|
|
|
|
|
|
Una map<key,data> è un Associative Container che associa
oggetti di tipo Key con oggetti di tipo Data. |
|
Il modo più semplice di pensare una map è
considerarlo come un vettore i cui elementi sono indiciati da oggetti di
tipo key invece che interi. |
|
STL incoraggia la metafora permettendo l’uso
delle [] per accedere agli elementi della map. |
|
|
|
|
|
Nel nostro caso occorre una |
|
map<vertici,normali> NN; |
|
e il codice per sommare tutte le normali
incidenti in un vertice diventa: |
|
|
|
map<Point3f,Point3f> NN; //the
vertex->normal map |
|
vector<Triangle>::iterator i; |
|
int j; |
|
|
|
// accumulate normals per vertex |
|
for(i=T.begin();i!=T.end();++i) |
|
for(j=0;j<3;++j) |
|
NN[(*i).v[j]]+=(*i).n[j]; |
|
|
|
|
|
|
Bounding objects |
|
Collision Detection |
|
Esplosioni |
|
|
|
|
|
|
|
Occorre capire quando un proiettile colpisce un
asteroide e quando un asteroide investe l’astronave |
|
si potrebbe risolvere calcolando l’intersezione
di ogni singolo triangolo dell’asteroide con ogni singolo triangolo
dell’astronave |
|
La soluzione esatta del problema non ci importa
(in questo caso) |
|
Si utilizza al posto dell’astronave e
dell’asteroide una loro rappresentazione MOLTO approssimata |
|
|
|
|
Per ogni GameObj si tiene una bounding sphere
(sfera di contenimento)
che racchiude
l’oggetto stesso. |
|
|
|
|
|
|
|
|
La collisione si controlla solo tra le varie
bounding spheres: |
|
bool GameObj::Collide(GameObj *o){ |
|
B.c = p; |
|
o->B.c = o->p; |
|
return B.Intersect(o->B); |
|
} |
|
dove |
|
|
|
inline bool Sphere3f::Intersect(
Sphere3f const & s) const { |
|
if((c-s.c).Norm()< r+s.r) return
true; |
|
else return false; |
|
} |
|
|
|
|
|
|
|
|
Un’approssimazione migliore puo venire
dall’utilizzo di gerarchie di bounding object, che approssimano l’oggetto
in maniera sempre migliore |
|
|
|
|
|
|
|
Nel gioco useremo solo bounding sphere semplici
(per ora). |
|
|
|
|
|
Realizzate tramite un disco trasparente al
centro e giallo opaco ai bordi, che cresce. Realizzato con una singola
triangle_fan |
|
|
|
All’interno dell’esplosione
si vedono gli altri oggetti |
|
piu’ esplosioni si sommano bene |
|
|
|
|
|
In opengl il colore e’ una quadrupla <r,g,b,a> |
|
dove a alpha o opacita’ |
|
alpha==1 totalmente opaco |
|
alpha==0 totalmente trasparente |
|
quando si disegna un triangolo trasparente il
suo colore viene mixato con il colore del fondo. Opengl permette di
decidere come viene mescolato: |
|
glBlendFunc(GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA) |
|
fa si che il colore risultante da un triangolo
con alpha = a sia colore_tri * a + colore_fondo *(1-a) |
|
|
|
|
|
cambiando l’ordine con cui si disegna gli
oggetti semitrasparenti cambia il risultato. Ad es: |
|
Se il
depth buffering e’ abilitato se disegno prima un vetro e poi gli oggetti
dietro non vedo i secondi (il depth test ne impedisce il disegno) |
|
Soluzione corretta disegnando gli oggetti semi
trasparenti in ordine di profondita’ |
|
|
|
|
|
Asteroide Frattale3D |
|
Modificare la class AstFract3D : public Ast in
maniera tale che la perturbazione del punto sia fatta a caso sul piano
perpendicolare all’edge da dividere anziche’ nella direzione centro di
massa -- splitpoint |
|
|
|
|
|
Nuovo proiettile con esplosione finale
FireBallBullet |
|
Il proiettile si comporta normalmente per 3 sec
poi esplode lanciando +50 proiettilini a raggiera che pero’ durano solo 0.5
sec. (e.g. tipo fuoco d’artificio). |
|
hint: i proiettilini secondari non sono nuovi
gameobj ma solo semplici righe disegnate dalla FireBallBullet::Draw. in
compenso varia il raggio del bounding sphere del bullet in questione... |
|
|
|
|
|
Esplosioni con luci |
|
Ogni esplosione genera una Opengl light
posizionata nel punto dell’esplosione per la durata dell’esplosione. |
|
hint: in opengl le luci sono limitate (in genere
8). Far sì che le esplosioni usino solo tre luci tenendo un vettorino
statico di classe per sapere quale delle tre e’ libera. |
|