Virtual Picture Viewer Un progetto in XVR per la visualizzazione di immagini in 3D L'idea ● Riproporre in chiave 3D uno strumento per la gestione di fotografie che consenta di interagire con le immagini mediante: – Visualizzazione ● In primo piano, zoom, carrellate... – Traslazione – Rotazione – Scalatura – Catalogazione in album – Importazione ed eliminazione L'ambiente L'ambiente (2) ● Realizzato con Blender Texture Procedurali Multilivello Full Render: ● ● ● ● Color Lighting Shading Ambient Occlusion Baking Texture Finale Monolivello Gli oggetti interattivi ● Scrivania ● Bacheca ● ● ● – Cestino Immagini Parzialmente implementato: ● Album Non implementati: – Archivio – Post-it Strutture dati ● ● Classe Picture – Informazioni sull'“oggetto foto” nella scena (Object, Mesh, Texture, FileName, Material) – Informazioni logiche (Location, RelativePosition, yRotation, xRotation, DestPos, DestXRot) – Flags (Highlighted, Selected, Moving) Classe List – Wrapper di Array ● ● Add, Remove, RemoveAll, Contains, Size... Interfaccia Enumeration – HasNext(), Next() Immagini ● ● ● ● Rettangoli con texture ● – – – – Locazioni – Sulla scrivania – “Appese” in bacheca – Nel cestino – Nell'album Contenitori (List): ● ● Pictures SelectedPictures AlbumPictures DeletedPictures SelectedP ⊂ P P, AlbumP e DeletedP mutuamente esclusivi Gestione legata al piano in cui si trovano Invisibili se si trovano nel cestino/album Pick correlation ● Utilizzata per Selezione e Drag&Drop ● Implementata mediante ray casting ● Funzione bool Select(obj,&PoI) – determina se l'oggetto è intersecato dal segmento che lega i due punti di coordinate video [mx,my,0] e [mx,my,1], con mx,my coordinate del mouse – Determina anche il Punto di Intersezione Selezione ● Obiettivo: – ● riprodurre i meccanismi classici dei sistemi operativi Selezione esplicita mediante – Click sulla foto ● – Area di selezione ● ● Si scansiona Pictures finché non si trova una foto per cui Select valga true. Si cercano tutte le immagini che intersecano una SelectBox Selezione implicita in caso di “uscita” dal cestino o dall'album Deselezione ● ● ● Avviene contestualmente alla Selezione – se nessuna foto viene cliccata – o per le foto che si trovano al di fuori dell'area di selezione Per la [de]selezione mediante click è implementato anche il “CTRL-click” Avviene anche implicitamente quando una foto viene spostata nel cestino o nell'album Area di selezione ● ● SelectArea – Rettangolo visibile e translucido – Usato per la visualizzazione SelectBox – Parallelepipedo invisibile – Usato per calcolare le collisioni ● Come avviene: – Calcolo dello StartingPoint mediante ray casting sulla scrivania e sulla bacheca – Spostamento e ridimensionamento di SelectArea/Box in base al PoI ScaleFactor = [ |SP.xPoI.x|, |SP.y-Poi.y|, 1 ] Area di selezione (2) y y SelectionArea x StartingPoint PoI 0,0,0 0,0,0 1,1,1 1,1,1 Point of Intersection SP x SelectionArea Object coordinates, World Coordinates ActivePicture ● È sempre l'ultima immagine selezionata ● È VOID se nessuna immagine è selezionata ● Ruolo chiave per tutte le operazioni – ● Si applicano solo alle immagini selezionate che giacciono sullo stesso piano (scrivania o bacheca) di ActivePicture Ogni volta che cambia si ricalcolano: – PicturesBounds = {minX, minY, maxX, maxY}, ovvero il rettangolo minimo che racchiude tutti i centri delle immagini selezionate – PlaneBounds, ovvero il rettangolo che rappresenta il limiti della scrivania [bacheca] Traslazione ● Trascinando un'immagine (quella attiva) si traslano tutte le immagini selezionate (che giacciono sullo stesso piano): – On mouse click: si determina la Active Picture – On mouse drag: ● ● Si ricalcola PoI su ActivePicture Si calcola il vettore di traslazione: p0 = gluProject(pointOfIntersection); vec0 = [Mouse.X, viewport[3]-1-Mouse.Y, p0[2]]; tVec = gluUnProject(vec0)-activePicture.Pos; Traslazione (2) ● ● Si applica il vettore di traslazione a tutte le immagini selezionate, a patto che PictureBounds+tVec rimanga entro PlaneBounds Se tale vincolo non è violato: – Si modificano le posizioni delle immagini – Si aggiorna PictureBounds Drag & Drop ● Difficile da aggiungere all'implementazione attuale – ● (immagini vincolate al piano in cui si trovano) Sono state aggiunte chiamate a: – MoveToDesk (risp. Board, Trash, Album) quando, “on mouse release”, il cursore si trova sulla scrivania (risp. Bacheca, cestino, album) – Le immagini sono comunque vincolate ma il feedback è reso attraverso un'enfatizzazione degli “oggetti di arrivo” Rotazione-y ● Intorno all'asse y dell'immagine – ● Si calcola il pivot come il punto centrale del PictureBounds – ● Ovvero ortogonale al piano su cui giace Il pivot “globale” deve essere convertito in pivot “locale” (WorldToLocal) per ogni immagine Si applica Rotate a tutte le immagini che non escano fuori dai PlaneBounds Rotazione-y (2) ● Al termine della rotazione la si “fissa” con SetRotation(xRotation); Rotate(yRotation); ● ● yRotation: variabile di Picture aggiornata durante la rotazione e si aggiorna la posizione delle immagini: mat = Object.GetModelMatrix(); finalPos = [mat[12], mat[13], mat[14]]; WorldToLocal(MyObj,point) { var mat = MyObj.GetModelMatrix(); var inv = MatrixInverse_4(mat); var world = vector(4); world.xyz = point; world.w = 1; var local = MatrixMultiplyVector_4(inv,world); return local.xyz; } Rotazione-x ● Intorno all'asse x dell'immagine ● Per allinearla alla scrivania o alla bacheca ● Si imposta prima la rotazione sull'asse x e si ruota poi intorno all'asse y: SetRotation(90, 1,0,0); Rotate(yRotation, 0,1,0); Scalatura ● ● Non è implementata in XVR la scalatura con pivot Si scalano tutte le immagini selezionate (sullo stesso piano di ActivePicture) di un fattore ScaleFactor = 1 - offsetX Movimento delle immagini ● Transizione animata da una locazione all'altra – Si impostano le variabili di Rotazione e Posizione finali in base alla posizione dell'immagine relativa al piano in cui si trova ● – (RelativePos viene calcolata ad ogni “mouse release”) Ad ogni frame, per ogni immagine: ● ● Si chiama la funzione Move che sposta l'immagine interpolando dalla posizione attuale a quella finale, finché tale destinazione non è raggiunta Se la destinazione è il cestino o l'album l'immagine “scompare” non appena la raggiunge ● Gestito da un'istanza di PictureMover ● Durante la transizione non si può interagire con l'immagine Picture::Move() tempPos = speed * GetPosition() + (1.0-speed) * DestPos; SetPosition(tempPos); xRotation = speed * xRotation + (1.0-speed) * destXRot; SetRotation(xRotation,1,0,0); distPos = ((tempPos[0]-destPos[0])^2)+((tempPos[1]destPos[1])^2)+((tempPos[2]-destPos[2])^2); distRot = abs(xRotation-destXRot); if (distPos<epsilonPos && distRot<epsilonRot) return true; else return false; CameraHandler ● È un wrapper per CVmCamera che ne estende le funzionalità per implementare le “carrellate” – Analago al movimento delle immagini: ● Alcune funzioni impostano Posizione e Direzione finali della telecamera – ● ● Sulla scrivania, sulla bacheca, su un'immagine... Una funzione chiamata ad ogni frame interpola dalla posizione attuale a quella finale Contiene anche CameraMoveMouse per il movimento svincolato della telecamera PictureBillboard ● ● ● Usato per visualizzare in primo piano le immagini contenute nel cestino o nell'album Aggiusta la dimensione del billboard in base alle dimensioni del viewport e alle proporzioni della foto ogni volta che visualizza una nuova immagine Ha un riferimento ad un'istanza di PictureMover per “muovere” le immagini da una locazione all'altra Importazione ● ● Singola immagine – Tramite tag HTML <input type=”file”> – Si esegue il download del file (anche remoto) – Si crea una nuova istanza di Picture e si aggiunge a Pictures Cartella di immagini – Selezione cartella tramite controllo ActiveX che accede al File System e popup HTML-JavaScript che visualizza un file browser – Per l'aggiunta dei file si appoggia a DLL esterna “File System Wrapper” ● ● Ottiene la lista dei file della cartella Per ogni file si agisce come per la singola immagine