Laboratorio di Grafica Interattiva A.A. 2002-3

Esercizio 7

Argomento

Ancora trasformazioni in OpenGL. Ancora selezione interattiva di oggetti in OpenGL, modifica della geometria della scena.

Files

Nessun nuovo file, si continua da quelli dell'esercitazione precedente.

Esercitazione guidata

Prima tappa

Gestite la rotazione del singolo solido nel seguente modo:

Per poter eseguire la sequenza di rotazioni nell'ordine specificato, non basta memorizzare un angolo per ogni asse. Bisogna accumulare le rotazioni in una matrice man mano che l'utente le immette, poi durante il disegno usare questa matrice per eseguire in un colpo solo tutte le rotazioni accumulate.

L'istruzione OpenGL glMultMatrix permette di concatenare alla matrice corrente una matrice esplicitamente memorizzata in un array. Vale la solita regola dell'ordine di esecuzione inverso: OpenGL eseguira' PRIMA la trasformazione corrispondente a questa matrice e POI le trasformazioni che gia' erano presenti nello stato.

dove matrice e' un array di 16 GLfloat oppure GLdouble (a seconda della forma usata).

Abbiamo una matrice ausiliaria per ogni solido che memorizza le sue rotazioni. Bisogna gestire questa matrice:

Per gestire la matrice usiamo le funzioni messe a disposizione da OpenGL, con un trucco.
OpenGL presume che si lavori sulla matrice corrente modelview o projection, qui noi vogliamo lavorare su una matrice "nostra" memorizzata in un array. Il trucco usa il top dello stack delle matrici come area temporanea di lavoro per costruire e modificare la nostra matrice. Ogni volta che vogliamo agire sulla nostra matrice

Quindi le due operazioni che occorrono:

Seconda tappa

Date all'utente la possibilita' di selezionare, oltre che un solido, anche una faccia su quel solido. La faccia e' quella su cui e' avvenuto il click. Evidenziate la faccia cliccata in qualche modo.

Occorre usare una gerarchia di nomi a due livelli. Ogni primitiva GL_POLYGON ha due nomi:

Mentre nell'esercitazione precedente agivamo sullo stack dei nomi con glLoadName (che equivale a pop seguito da push) qui forse per chiarezza e' meglio usare pop e push espliciti: Non e' necessario che i nomi dei solidi e quelli delle facce siano insiemi di valori disgiunti, per esempio possono essere i nomi dei solidi da 0 a 4 (se abbiamo 5 solidi) e quelli delle facce da 0 a N (se abbiamo N facce nel solido).

Quando, al ritorno in rendering mode, leggete lo hit record, ci trovate due nomi: uno di solido e uno di faccia, memorizzati nell'ordine dal fondo verso la cima dello stack. Questo significa PRIMA il nome del solido e POI quello della faccia.

Compito

Permettete all'utente di modificare la geometria della scena con la seguente operazione di editing:

Questa non e' una semplice operazione di visualizzazione. E' necessario cambiare le coordinate dei punti nella struttura dati e rifare la display list del solido.

Il vettore normale (nx,ny,nz) ad un triangolo di vertici p1=(x1,y1,z1), p2=(x2,y2,z1), p3=(x3,y3,z3) si calcola con la seguente formula:

  nx = dy12*dz13 - dz12*dy13;
  ny = dz12*dx13 - dx12*dz13;
  nz = dx12*dy13 - dy12*dx13;
dove
  dx12 = x1-x2; dy12 = y1-y2; dz12 = z1-z2;
  dx13 = x1-x3; dy13 = y1-y3; dz13 = z1-z3;
e i valori nx,ny,nz vanno poi normalizzati dividendoli per la lunghezza del vettore (nx,ny,nz).
Il vettore normale ad una faccia non triangolare e' uguale alla normale al triangolo formato dai primi tre vertici non allineati della faccia.