PDA

View Full Version : Opengl, matrici di trasformazione


Maverick18
03-12-2007, 15:28
Sto facendo un mini space invaders per smanettare un po' con opengl (in c), in vista dell'esame di grafica computazionale. Il problema č che non riesco a creare il proiettile nella stessa posizione della navicella e nello stesso tempo a visualizzarlo su un altro sistema di riferimento. Come faccio a procurarmi la matrice di trasformazione della navicella in modo da moltiplicarla col quella del proiettile ?

variabilepippo
03-12-2007, 15:33
Potresti prendere spunto dal codice di Space Invaders GL (http://spaceinvadersgl.sourceforge.net/).

http://spaceinvadersgl.sourceforge.net/scr2big.jpg

okay
03-12-2007, 15:42
Sto facendo un mini space invaders per smanettare un po' con opengl (in c), in vista dell'esame di grafica computazionale. Il problema č che non riesco a creare il proiettile nella stessa posizione della navicella e nello stesso tempo a visualizzarlo su un altro sistema di riferimento. Come faccio a procurarmi la matrice di trasformazione della navicella in modo da moltiplicarla col quella del proiettile ?

la matrice di trasformazione della navicella e del proiettile non centra nulla.

Innanzitutto: stai lavorando in 2d o 3d?

Il proiettile deve avere una sua matrice indentitą per renderizzarlo nella scena.

poi non si capisce cosa vuoi fare: vuoi renderizzare un proiettile insieme alla navicella oppure vuoi che il proiettile vada contro la navicella?


Se vuoi che il proiettile sia alla stessa posizione, in world space, della navicella devi assegnare al proiettile le stesse coordinate.


poi come hai creato la navicella e il proiettile?... l'hai fatti come mesh.x?

ti posso aiutare nel limite ma considera che uso directx ma se sono calcoli vettoriali ti posso aiutare ma devi spoiegare bene cosa vuoi fare.

okay
03-12-2007, 15:47
...Il problema č che non riesco a creare il proiettile nella stessa posizione della navicella e nello stesso tempo a visualizzarlo su un altro sistema di riferimento...

il sistema di riferimento deve essere lo stesso se no o la navicella o il proiettile saranno in posizioni assurde.


...Come faccio a procurarmi la matrice di trasformazione della navicella in modo da moltiplicarla col quella del proiettile ?...

Se la navicella č renderizzata a video nello spazio dovresti sapere la sua matrice identitą e di trasformazione a meno che stai lavorando su codice non tuo.

allora 2d o 3d?

come sono fatti la navicella e il proiettile in .x (mesh) oppure sono texture per il 2d?

Maverick18
03-12-2007, 15:47
la matrice di trasformazione della navicella e del proiettile non centra nulla.

Innanzitutto: stai lavorando in 2d o 3d?

Il proiettile deve avere una sua matrice indentitą per renderizzarlo nella scena.

poi non si capisce cosa vuoi fare: vuoi renderizzare un proiettile insieme alla navicella oppure vuoi che il proiettile vada contro la navicella?


Se vuoi che il proiettile sia alla stessa posizione, in world space, della navicella devi assegnare al proiettile le stesse coordinate.


poi come hai creato la navicella e il proiettile?... l'hai fatti come mesh.x?

ti posso aiutare nel limite ma considera che uso directx ma se sono calcoli vettoriali ti posso aiutare ma devi spoiegare bene cosa vuoi fare.

Mi sono spiegato decisamente male.
Lavoro in 2D, la mia navicella č un triangolo bidimensionale. Vorrei che la navicella sparasse un proiettile(un triangolino) da un vertice del triangolo.
Il mio problema sta nel fatto che non riesco a trattare navicella e proiettile come due entitą diverse e nello stesso tempo rappresentarle in sistemi di riferimento diversi. (il proiettile deve avere come sistema di riferimento inziale, il sistema di riferimento della navicella al momento dello sparo)

okay
03-12-2007, 15:57
Mi sono spiegato decisamente male.
Lavoro in 2D, la mia navicella č un triangolo bidimensionale. Vorrei che la navicella sparasse un proiettile(un triangolino) da un vertice del triangolo.
Il mio problema sta nel fatto che non riesco a trattare navicella e proiettile come due entitą diverse e nello stesso tempo rappresentarle in sistemi di riferimento diversi. (il proiettile deve avere come sistema di riferimento inziale, il sistema di riferimento della navicella al momento dello sparo)

allora 2d.

la navicella deve avere coordinate xy per esempio pos_navicella(10, 28)

non devi far altro che dare le coordinate al proiettile a pos_proiettile(10, 28)

poi muovi il proiettile sulla y pos_proiettile(x,y)+=0.1f

Considera che la navicella si muove sulla x ora nel momento in cui spari visualizzi il proiettile alle coordinate di dove si trovava la navicella al momento dello sparo per esempio (13,28) ora muovi e renderizzi il proiettile a coordinate iniziali (13,28) aumentando solo la y tipo:
pos_proiettile(x,y)+=0.1f //y=28.01
pos_proiettile(x,y)+=0.1f //y=28.02
pos_proiettile(x,y)+=0.1f //y=28.03
pos_proiettile(x,y)+=0.1f //y=28.04
pos_proiettile(x,y)+=0.1f //y=28.05

ecc ecc

se c'č una collisione con astronave nemica (collisione) allora esegui l'esplosione facendo sparire l'astronave colpita (metti a 0 i.ma posizione della matrice) se č simile a space invader 2d


Edit:

ogni oggetto deve avere la sua matrice identitą come quella della navicella per essere renderizzato che stiano nello stesso sistema di riferimento.

Maverick18
03-12-2007, 16:12
Il mio problema non sono le posizioni, ma le matrici in sč, non capisco nč come utilizzarle nč come ottenerle.

Premetto che per ora la mia navicella si muove in questo modo:

se premo 'w' o 's' : traslo sist. rif. su asse y
se premo 'a' o 'd' : ruoto sist. rif su asse z
se non tocco nulla la navicella resta ferma.

Fin qui nessun problema, il problema nasce quando devo inserire il proiettile. Come faccio ad adottare per il proiettile lo stesso sistema di riferimento della navicella ? Con glPushMatrix() e glPopMatrix() riesco a mettere da parte la matrice della navicella, e a operare su una sua copia, ma il proiettile a quel punto diventa parte del sistema di riferimento della navicella.

Invece vorrei fare cosģ:
salvarmi la matrice della navicella, moltiplicare quest'ultima per la matrice identitą del proiettile, disegnare il proiettile.

Forse non č questo il metodo esatto ?

okay
03-12-2007, 16:31
Il mio problema non sono le posizioni, ma le matrici in sč, non capisco nč come utilizzarle nč come ottenerle.

Premetto che per ora la mia navicella si muove in questo modo:

se premo 'w' o 's' : traslo sist. rif. su asse y
se premo 'a' o 'd' : ruoto sist. rif su asse z
se non tocco nulla la navicella resta ferma.

Fin qui nessun problema, il problema nasce quando devo inserire il proiettile. Come faccio ad adottare per il proiettile lo stesso sistema di riferimento della navicella ? Con glPushMatrix() e glPopMatrix() riesco a mettere da parte la matrice della navicella, e a operare su una sua copia, ma il proiettile a quel punto diventa parte del sistema di riferimento della navicella.

Invece vorrei fare cosģ:
salvarmi la matrice della navicella, moltiplicare quest'ultima per la matrice identitą del proiettile, disegnare il proiettile.

Forse non č questo il metodo esatto ?

te lo ripeto:
la navicella ha la sua matrice e non serve moltiplicarla o averne una copia.
Non puoi assegnare la matrice della navicella al proiettile solo per dargli le stesse coordinate, il proiettile si muoverebbe insieme alla navicella.

il proiettile deve avere, come la navicella, una sua propria matrice identitą

in directx per esempio si usa questo per le matrici identitą (per farti capire):

D3DXVECTOR3 Position(0,0,0)
D3DXVECTOR3 posNavicella(30,0,18)

D3DXMATRIX Navicella
D3DXMATRIX proiettile

D3DXMatrixTranslation(&Navicella, posNav.x, posNav.y, posNav.z);
SetTrasform(Navicella) //renderizzo a video
/*
if sparo prendo la posizione della navicella e la passo a proiettile
Position=posNav
*/
if(sparo){
Position.y+=0.1f;
D3DXMatrixTranslation(&proiettile, Position.x, Position.y, Position.z);
SetTrasform(proiettile) //renderizzo a video
}

come vedi devi avere 2 matrici una per la navicella e una per il proiettile
eccole:
D3DXMATRIX Navicella
D3DXMATRIX proiettile

per il proiettile invece puoi fare delle copie ma riguarda solo l'immaggine e la copia ha sempre una matrice identitą propria es:

D3DXVECTOR3* Position[8] //proiettili

puoi usare la stessa matrice per renderizzare il triangolo del proiettile cosģ:
D3DXMatrixTranslation(&proiettile, Position[0].x, Position[0].y, Position[0].z);
SetTrasform(proiettile) //renderizzo a video
D3DXMatrixTranslation(&proiettile, Position[1].x, Position[1].y, Position[1].z);
SetTrasform(proiettile) //renderizzo a video
D3DXMatrixTranslation(&proiettile, Position[2].x, Position[2].y, Position[2].z);
SetTrasform(proiettile) //renderizzo a video

...questi sono 3 proiettili sparati e visualizzati dalla stessa matrice identitą ma le loro coordinate sono differenti in definitiva i 3 proiettili verranno renderizzati con la stessa immagine ma a coordinare differenti tutti 3 insieme.



spero di essere stati chiaro.

questo con le dx ma con le opengl la tecnica č la stessa cambiano solo le istruzioni.


ciao

Maverick18
03-12-2007, 16:40
te lo ripeto:
la navicella ha la sua matrice e non serve moltiplicarla o averne una copia.
Non puoi assegnare la matrice della navicella al proiettile solo per dargli le stesse coordinate, il proiettile si muoverebbe insieme alla navicella.


Non voglio assegnarla, vorrei solo moltiplicarla per ottenere la posizione della navicella.

in directx per esempio si usa questo per le matrici identitą (per farti capire):
questo con le dx ma con le opengl la tecnica č la stessa cambiano solo le istruzioni.


Sģ, questo ragionamento l'avevo fatto anch'io, ma per ora non ho trovato istruzioni per farlo allora mi sono buttato sulle matrici. Sto facendo un po' di confusione :)
Grazie per l'aiuto, appena risolvo ti dico.

okay
03-12-2007, 16:51
Non voglio assegnarla, vorrei solo moltiplicarla per ottenere la posizione della navicella.


Sģ, questo ragionamento l'avevo fatto anch'io, ma per ora non ho trovato istruzioni per farlo allora mi sono buttato sulle matrici. Sto facendo un po' di confusione :)
Grazie per l'aiuto, appena risolvo ti dico.

in opengl si usa:

primo triangolo renderizzato (navicella)
glBegin (GL_TRIANGLES);
glTranslatef (nx, ny, nz); //posizione
glVertex3fv (&Data.Verts.Pos);
glEnd ();

secondo triangolo renderizzato (proiettile)
glBegin (GL_TRIANGLES);
glTranslatef (px, py, pz); //posizione
glVertex3fv (&DataVerts.Pos);
glEnd ();

fek
03-12-2007, 17:01
Invece vorrei fare cosģ:
salvarmi la matrice della navicella, moltiplicare quest'ultima per la matrice identitą del proiettile, disegnare il proiettile.


Il problema e' abbastanza semplice ed e' indipendente dalla libreria che usi o dall'essere in 3D o 2D. E' un semplice problema di geometria.

Associa ad ogni oggetto una sua matrice che ne definisce l'orientamento e la posizione nel mondo. Se vuoi l'interpretazione matematica, stai costruendo una matrice che porta dal sistema di riferimento locale dell'oggetto al sistema di riferimento del mondo. Questa e' la matrice che OpenGL o D3D "usera'" in qualche modo per disegnare l'oggetto.

Quindi la tua navicella avra' una matrice di trasformazione che chiamiamo N.
Ora vuoi sparare un proiettile che vuoi disegnare, per fare un esempio, mezzo metro di fronte alla navicella. Stai quindi lavorando in questo caso nel sistema locale della navicella, e devi calcolare una matrice che porta dal sistema locale del proiettile (che e' locale rispetto alla navicella) al sistema di riferimento del mondo.

Prima matrice locale del proiettile:
P1 = matrice di traslazione di un metro in avanti (decidi tu l'asse)
N = matrice di trasformazione della navicella che mantieni da qualche parte nel tuo codice (non te la deve restituire OpenGL, la memorizzi tu nell'oggetto navicella)

La matrice di trasformazione P da associare al proiettile diventa:
P = P1 * N;

Passi la matrice P a OpenGL ed hai finito. Il procedimento generale e' che ogni volta che passi da un sistema locale ad un altro, premoltiplichi la matrice di trasformazione.

Nota che il procedimento e' indipendente dall'essere in 2D o in 3D: in 2D hai solo un asse in meno.

D3DXMatrixTranslation(&Navicella, posNav.x, posNav.y, posNav.z);
SetTrasform(Navicella) //renderizzo a video

Uh?!
Questo non e' D3D. SetTransform non renderizza nulla :)

Maverick18
03-12-2007, 18:12
Il problema e' abbastanza semplice ed e' indipendente dalla libreria che usi o dall'essere in 3D o 2D. E' un semplice problema di geometria.

Associa ad ogni oggetto una sua matrice che ne definisce l'orientamento e la posizione nel mondo. Se vuoi l'interpretazione matematica, stai costruendo una matrice che porta dal sistema di riferimento locale dell'oggetto al sistema di riferimento del mondo. Questa e' la matrice che OpenGL o D3D "usera'" in qualche modo per disegnare l'oggetto.

Quindi la tua navicella avra' una matrice di trasformazione che chiamiamo N.
Ora vuoi sparare un proiettile che vuoi disegnare, per fare un esempio, mezzo metro di fronte alla navicella. Stai quindi lavorando in questo caso nel sistema locale della navicella, e devi calcolare una matrice che porta dal sistema locale del proiettile (che e' locale rispetto alla navicella) al sistema di riferimento del mondo.

Prima matrice locale del proiettile:
P1 = matrice di traslazione di un metro in avanti (decidi tu l'asse)
N = matrice di trasformazione della navicella che mantieni da qualche parte nel tuo codice (non te la deve restituire OpenGL, la memorizzi tu nell'oggetto navicella)

La matrice di trasformazione P da associare al proiettile diventa:
P = P1 * N;

Passi la matrice P a OpenGL ed hai finito. Il procedimento generale e' che ogni volta che passi da un sistema locale ad un altro, premoltiplichi la matrice di trasformazione.


Ok, la spiegazione l'ho capita, sono gli argomenti che sto affrontando anche in robotica. E' la parte in grassetto che non comprendevo, pensavo che la matrice mi venisse fornita direttamente da opengl. Quindi le matrici le devo implementare io, poi le elaboro con le varie chiamate. Appena ho tempo ci provo.