martedì 14 aprile 2009

3d.1) Xna tutorial 3d: Introduzione

Rieccomi dopo un paio di settimane di silenzio, torno con piacere a raccontarvi qualcosa di (spero) interessante su XNA.

Video Anteprima:


Con l'ultimo post avevo chiuso una breve guida sullo sviluppo di un semplice videogame in 2d, chi ha seguito la guida ha potuto notare non si trattava di un videogame poi così semplice da strutturare!!
Con il post di questa sera introdurrò l'argomento che forse vi interessa di più ... il 3D in Xna. Evito premesse troppo lunghe che tanto non interessano a nessuno e passo al sodo!

3D XNA
Fino ad ora abbiamo trattato grafica in due dimensioni X e Y, dove disegnare un oggetto sullo schermo è molto simile a posizionare un elemento su una lavagna, naturalmente possiamo limitarci solo a definire 2 coordinate spaziali. Nell'ambito 3d, come è facile immaginare, andremo ad aggiungere l'informazione di profondità della scena:
Il sistema di coordinate 3d aggiunge l'elemento Z = profondità, mentre per quanto riguarda le coordinate X e Y il discorso rimane invariato X = Posizione orizzontale Y = Posizione Verticale.
Un piccolo appunto sulla profondità:
Il sistema di coordinate utilizzato in XNA si chiama "Right Handed Coordinate System" e indica che il valore profondità aumenta procedendo nella direzione che ipoteticamente andrebbe dal monitor -> verso voi e diminuisce nella direzione opposta.

Per capire perchè questo tipo di sistema è chiamato right handed seguite queste regole :
1) rivolgete il palmo della mano destra verso di voi e aprite la mano
2) immaginate che il vostro pollice sia l'asse delle X
3) immaginate che il vostro indice sia l'asse delle Y
4) ora piegate il medio verso di voi ... questo sarà l'asse delle Z ... che viene appunto "verso di voi"

Se provate a fare la stessa cosa con la mano sinistra, partendo dal punto due, vedrete che per avere il pollice associato alle X e l'indice alle Y dovrete girare il palmo verso il monitor e così anche il medio... in questo caso stiamo utilizzando un "Left Handed Coordinate System"... dove l'asse Z aumenta di valore andando "dentro al monitor" e diminuisce "uscendo verso di voi".

Le Matrici:
Sono una nozione fondamentale per tutto quello che riguarda la matematica 3d, si tratta di un ragruppamento di valori per righe e colonne e rappresentano uno strumento importantissimo in quanto sono indispensabili per effettuare operazioni come trasformazioni, rotazioni e ridimensionamenti di oggetti nello spazio, ottimizzando il numero di operazioni necessarrie per effettuare questi calcoli (vedi moltiplicazione di matrici) .
Questo argomento andrebbe trattato con molta cura per essere pienamente comprensibile e non è questo il posto giusto per avere tutte queste info ... vi rimando a un veloce studio qui

La parola di wikipedia:
http://it.wikipedia.org/wiki/Matrice

Un tutorial in italiano... con molte immagini:
http://www.clickitaliansoftware.net/hosted/vgcgroup/Tutorials/TutorialZip/TutoMatrici/index.htm#A24

L'approfondimento del tutorial sopra riferimento a trasfromazioni/rotazioni/ridimensionanti:
http://www.clickitaliansoftware.net/hosted/vgcgroup/Tutorials/TutorialZip/TutoTrasformazioni/index.htm#A34

Spero di riuscire a scrivere un tutorial su questo argomento prendendo spunto da un ottimo libro che ho utilizzato per directX che trattava le basi della matematica 3d in modo molto semplice.

Dopo questa poco utile presentazione delle matrici vi tiro un pò su di morale dicendovi che XNA ha delle ottime funzioni che ci aiuteranno nell'utilizzo delle matrici senza doversi addentrare più di tanto in questo argomento e che esiste proprio una classe chiamata Matrix che ha tutto quello che serve.


Le Camere:
Un altro elemento che differenzia il 2d dal 3d è come viene interpretata la posizione di un elemento.
Se ipotizzassimo di avere un oggetto in X = 0, Y= 0, Z = 0 (quindi sull'origine degli assi) verrebbe spontaneo pensare che l'oggetto venga visualizzato al centro del nostro monitor. In realtà, per determinare dove l'oggetto verrà visualizzato, subentra un secondo fattore... la Camera.
La camera è l'elemento attraverso il quale viene definito il punto di vista dal quale osserviamo la scena ed è caratterizata principalmente da una posizione e da un orientamento...immaginate una stanza e voi con in mano una qualsiasi telecamera, la camerà sarà posizionata in qualche parte dello spazio e avrà una direzione verso la quale è rivolto l'obbiettivo.

Utilizzando l'immagine sopra immaginate che la nostra camera sia il punto azzurro (coordinate possibili : X= 10 Z = 10 Y = 10) se l'obbiettivo (target) fosse in 0,0,0 voi vedresta l'0ggetto posizionato sull'intersezione degli assi, al centro del monitor. Cambiando la posizione del target questo si sposterebbe dalla posizione centrale. Mentre muovendo la camera, l'oggetto rimarrebbe sempre al centro del vostro schermo dato che l'obbiettivo risiede proprio sull'oggetto.
Oltre a informazioni di posizione possiamo naturalmente far ruotare la nostra camera, il che farà inesorabilmente modificare la visualizzazione del nostro oggetto.

Guardate la "video anteprima" a inizio post per capire meglio quello che sto cercando di spiegarvi :
Abbiamo, tanto per cambiare, un'astronave (Viper Mk II) presa da Battlestar Galactica (modello da warehouse di sketchup e trasformato in un formato leggibile dalla Pipeline di XNA tramite un apposito tool ). Come potete vedere la camera ruota intorno all'oggetto e su se stessa. Il risultato è una diversa visualizzazione dell'astronave.

Da queste righe capiamo dunque che per definire una camera nello spazio sono necessari 3 parametri:
1) Posizione della camera
2) Posizione del Target
3) Verso superiore della camera: un vettore che indica quale direzione è il lato "sopra" della camera. In assenza di rotazioni questo lato sarebbe X= 0, Y= 1, Z= 0 (vedremo meglio questo elemento nel tutorial dedicato alla creazione di una camera tra qualche post).

Ora per conoscere e capire altri concetti legati alle camere guardate questa immagine (Fonte: wikipedia http://en.wikipedia.org/wiki/Viewing_frustum).





Questa immagine rappresenta quello che viene chiamato Viewing Frustum, ed è essenzialmente un metodo per rappresentare quello che effettivamente viene colto dalla camera, per farla brevissima, se un oggetto si trova all'interno del solido evidenziato, l'oggetto sarà visibile nella scena.
Per definire questo solido occorrono 4 parametri che tecnicamente si chiamano :
1) Field of view: l'angolo di visualizzazione (ampiezza dei tratti che escono dalla camera)
2) Aspect Ratio: le proporzioni di visualizzazione (per esempio 800X600...1024X768....16:9)
3) Near plane: la distanza del primo pannello del solido (che indica quando un oggetto può essere vicino alla camera senza essere visualizzato e da dove inizierà la visualizzazione)
4) Far Plane : Il piano posto di fronte al near plane che indica la fine del solido di visualizzazione... la base della piramide tronca chiamata Viewing Frustum.


Matrici World, View e Projection:
Abbiamo ipotizzato di avere un oggetto al centro del nostro sistema di coordinate, per definire in che modo l'oggetto viene posizionato nel sistema viene utilizzata una matrice chiamata World.
Lo scopo di questa matrice è di definire il posizionamento dell'oggetto nello spazio identificando dunque anche rotazioni e ridimensionamenti.
La matrice View e la matrice projection vengono invece utilizzate per definire la camera. PEr quanto riguarda la matrice View viene creata utilizzando un particolare metodo di XNA (CreatePerspectiveFieldOfView) che prende in ingresso 3 parametri:
Posizione della camera, Posizione del target e vettore Up ... che guardacaso sono proprio i parametri che abbiamo definito qualche riga sopra.
La matrice Projection invece indica come viene creata la proiezione di quanto catturato dalla camera e come presentare a monitor questa proiezione.
La funzione associata a questa matrice è la CreatePerspectiveFieldOfView e prende come parametri gli altri 4 che vi ho presentato sopra parlandovi del frustum (field of view, aspect ratio, near plane, far plane).

Per quanto riguarda la teoria vi ho mostrato a grandi linee tutto quello che serve per poter seguire i prossimi tutorial. Nel prossimo post inizieremo a scrivere il primo codice per disegnare quelle che vengono chiamate "primitive" e vedremo all'azione una camera.

A prestissimo!

2 commenti:

Unknown ha detto...

Ciao,
risorsa molto interessante.
l'unica cose è che per la matrice VIEW si usa il metodo "CreateLookAt" e non il "CreatePerspectiveFieldOfView"

Anonimo ha detto...

giusto

Posta un commento