Pubblicato da: Kjow | 18 marzo 2010

Riprogettazione e curiosità.

11/05/2010
(Articolo post datato¹)

Finalmente, passo dopo passo, il tutto comincia a prendere forma.

Build r3596 - Pagina Editor.

Rispetto all’ultimo aggiornamento di questo blog ho fatto passi da gigante… quindi cercherò di riassumere velocemente:

  1. Si è resa necessaria una riprogettazione del programma e quindi ripartire da zero… per creare e testare tutti i componenti e le funzioni che ho in testa, per non sporcare il progetto principale, ho creato diversi programmi satelliti dove in ognuno testavo e sviluppavo una parte senza, però, fare troppa attenzione alla compatibilità/interoperabilità tra loro.
    Ho deciso quindi di raccogliere tutti i progressi in un nuovo ed unico programma, quello candidato ad essere la futura pubblica release. Ne ho approfittato anche per mettere a frutto tutta l’esperienza maturata finora con le varie prove, concentrandomi molto di più sull’ottimizzazione e, sopratutto, su una programmazione ancora più orientata agli oggetti (benchè prima già lo fosse molto).
    Ho anche separato gli argomenti nelle varie unità evitando di creare un unico (o pochi) file monolitici, rendendo non solo più modulare, ma anche più fruibile e leggibile il tutto.
  2. La gestione dell’HUD 3D si è rivelata molto più problematica di quello che sembrava inizialmente. Esistono due vie: una semplice, veloce, ma non performante e quella difficile, lenta, ma performante.
    Inizialmente quella semplice sembrava anche performante e lo sarebbe stato se alla ATI avessero implementato un po’ meglio i loro drivers OpenGL. Infatti questa soluzione con la mia ATI HD4870 che ho nel desktop andava a rilento selezionando alcuni oggetti un po’ più complessi (come il ponte). Nessun problema di performance invece con la nVidia 7600 GO (ben più lenta come prestazioni brute) che ho nel portatile.
    Il primo metodo consisteva nell’utilizzo del “CamInvariance” combinato al “picking” degli oggetti presenti in scena, una funzione integrata in GLScene che permette di rilevare in modo estremamente semplice quali oggetti si trovano sotto al mouse. In pratica il motore fa una conversione delle coordinate 2D del mouse in coordinate 3D proiettando una linea immaginaria dallo schermo verso l’interno della scena e restituendo il primo oggetto incontrato. Facile, veloce, ma lento.
    Il “CamInvariance” invece è un altro sistema molto utile per posizionare oggetti in determinati posti dello schermo senza che questi vengano spostati dalla visuale. In altre parole, permette di visualizzare gli oggetti 3D sullo schermo sempre nella stessa posizione anche spostando/ruotando la camera o gli oggetti del mondo.
    Purtroppo, essendo il “picking” troppo lento con le schede ATI, ho dovuto cambiare approccio e passare ad un ben più complesso “RayCastIntersect“. Questa tecnica permette risultati simili al “picking“, ma lavora in modo completamente differente e solo per gli oggetti che ci interessano; ad ogni ricalcolo della scena quindi va effettuata la verifica se l’oggetto “x” è intersecato con un vettore precalcolato (quindi con un for [o tante chiamate manuali] si deve scorrere una lista di oggetti e verificare se c’è intersezione).
    Tecnica molto potente e performante, ma richiede molta più programmazione, infatti, oltre a dover passare tutti gli oggetti desiderati (niente “tutti gli oggetti presenti“), bisogna calcolare il vettore perpendicolare allo schermo che passa attraverso le coordinate del mouse. Una volta calcolato questo vettore e richiesta la verifica se esiste l’intersezione con un oggetto, bisogna fare attenzione che venga selezionato solo il primo oggetto visibile, ma per fare questo entrano in gioco una serie di “if” che devono escludere eventuali altri controlli se è già stato “incontrato” un altro oggetto. Complicato, ma performante.
    Come se non bastasse, il “RayCastIntersect“, non è compatibile con il “CamInvariance” in quanto quest’ultimo lavora in modo un po’ particolare… non ricalcola la posizione ogni volta, ma “semplicemente” renderizza per ultimo gli oggetti in questa condizione, così da apparire a video in modo indipendente dalla coordinate del sistema.
    Per ovviare a questo problema, mi sono dovuto inventare un sistema di riposizionamento automatico dei pezzi della pista di fronte alla camera. In pratica, attraverso la funzione di conversione delle coordinate 2D in 3D, faccio ricalcolare ad ogni oggetto la propria posizione PRIMA del disegno di ogni frame. Questa funzione, molto potente, permette di spostare gli oggetti a determinate coordinate (compresa la profondità) dello schermo, ma è complessa da gestire in quanto ogni volta che si sposta la camera, si devono spostare tutti gli oggetti desiderati in modo trasparente (non devono vedersi scatti) e sopratutto devono mantenere l’orientamento giusto, altrimenti ruotando la visuale si vedrebbero gli oggetti da sotto!
    Per mantenere l’orientamento corretto ho creato, per ogni oggetto, un vettore che passa dal centro dell’oggetto fino ad un punto bidimensionale subito sopra al bordo superiore dello schermo e fissando questo vettore come “direzione” dell’oggetto.
    Un altro problema è stato quello di animare questi pezzi, simulando lo sfogliare di un catalogo. Dopo prove su prove ho diviso i 12 pezzi (attuali, ma prevedo di aggiungerne altri) in tre gruppi: quelli sopra lo schermo, i quattro visibili e quelli sotto.
    Ogni gruppo ha delle coordinate y (verticale) come target e sommando delle velocità predefinite (per ogni gruppo) posso ottenere 3 tipi di animazione: veloce in entrata e uscita dallo schermo, lento all’interno.
    Il risultato finale è gradevole e abbastanza funzionale… ma abbastanza faticoso da realizzare!
  3. Oltre le scritte dei menu, si è resa necessaria la realizzazione di un’interfaccia per gestire l’editor vero e proprio. Ho cercato di realizzare un qualche cosa di semplice, ma d’impatto e sopratutto funzionale.
    Mi sono quindi immaginato delle icone disegnate in modo semplice, ma simpatiche da vedere che servissero per delle funzioni quali lo scorrere dei pezzi in alto e in basso, fare uno zoom (in/out) sulla pista, spostare la camera tra i vari pezzi che compongono la pista, chiudere la pista comunque sia (anche se non combacia perfettamente) e tornare al menu principale.
    La gestione di questi “GLHUDSprite” non è estremamente complicata, ma è laboriosa e necessita di molte accortezze, come la gestione del mouse “over” (cioè quando il mouse si trova sopra all’immagine o quando esce) che va creata dal nulla o la gestione delle selezioni (quindi il sistema deve sempre sapere quando un’icona è selezionata o no) o ancora la gestione dei pulsanti del mouse (ho creato una classe che gestisca i tre pulsanti principali e che tenga traccia in ogni istante se e quali pulsanti vengono premuti o rilasciati, altrimenti sarebbe impossibile gestire un semplice click del pulsante sinistro del mouse… rileverebbe solo che un pulsante è premuto a tempo indeterminato eseguendo le funzioni associate fin tanto che UN pulsante è premuto [e non che una funzione deve essere eseguita UNA sola volta con la pressione del SOLO il pulsante voluto])
  4. Un po’ di numeri:
    1. Attualmente sono alla build 0.1.0.3596 (amichevolmente detta semplicemente r3596) il che significa che da quando ho iniziato ho effettuato già ben più di 3596 build; visto che inizialmente (all’inizio del progetto, quando ho avviato il blog) non aumentavo il numero di revisione e che tra una build e l’altra faccio svariate decine/centinaia di ricompilazioni… neanche riesco ad immaginare il numero di compilazioni fatte tra progetti satelliti e principali… piano piano tutto prende forma, dal gioco stesso ad un metodo per realizzarlo. Metodo che sicuramente mi tornerà utile in caso di progetti più grandi e con più persone.
    2. Attualmente il progetto è grande 3,79 MB e comprende 43 File e 4 cartelle.
    3. Escludendo le unità di default e dei componenti aggiuntivi come GLScene, ho scritto attualmente 5453 righe di codice.

Vecchia build senza HUD.

¹ Questo articolo è stato post datato in quanto è da considerarsi come un riassunto del lavoro svolto finora, un “apripista” a una nuova serie di articoli di tipologia differente da quella tenuta finora. Dai prossimi articoli andrò ad inserire un “changelog” di ogni versione che compilerò, inserendo inoltre ciò che è stato implementato parzialmente e ciò che andrò ad implementare nel futuro prossimo. Ho già creato, in privato, una serie di changelog delle varie build fatte recentemente che andrò ad inserire nel tempo fino a riallinearmi con il presente.


Risposte

  1. [...] Prima versione riunificata. [...]

  2. [...] Primo approccio per riadattare la gestione e visualizzazione dell’HUD 3D. [...]

  3. [...] bozza di HUD 2D per la gestione dell’editor. Create delle immagini larghe 4 volte più dell’altezza in [...]

  4. [...] riadattamento dell’animazione dei pezzi dell’HUD 3D. Molto spartano, ma funzionale. Nessuna animazione, i pezzi di spostano [...]

  5. [...] Abbozzo animazione pezzi dell’HUD 3D. I pezzi non si fermano e si spostano tutti insieme, ma non contemporaneamente. [...]

  6. [...] e riposizionamento pezzi HUD 3D finito e funzionante, ma non ancora automatizzato al cambio di [...]

  7. [...] HUD 3D apparentemente finito e funzionante. Automatizzato il cambio di risoluzione (dimensioni e posizione). [...]

  8. [...] 2: colorazione in rosso del pezzo non posizionabile (sia nell’HUD 3D, sia nella [...]


Lascia un Commento

Fill in your details below or click an icon to log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Log Out / Modifica )

Foto Twitter

You are commenting using your Twitter account. Log Out / Modifica )

Foto di Facebook

You are commenting using your Facebook account. Log Out / Modifica )

Connecting to %s

Categorie

Follow

Get every new post delivered to your Inbox.