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