Informazioni sull`applet - Dipartimento di Informatica
Transcript
Informazioni sull`applet - Dipartimento di Informatica
Università degli Studi di Bari Facoltà di Scienze MM.FF.NN. Corso di Laurea in Informatica Specialistica Esame di Informatica Grafica IILLLLUUM NEE EE S ON AZZIIO NA O3 MIIN SHHAADDIINNGG DDII UUNN O OGGGGEETTTTO 3D D Bruno Carla Palmisano Grazia Paternoster Maria Giuseppa Prof.ssa Laura Caponetti Anno Accademico 2006/2007 1 IINNDDIICCEE IILLLLU DII U UN OG HA NO GG D...................................................................3 AD GEETTTTO UM DIIN MIIN NG NA GD O 33D AZZIIO ON NEE EE SSH FFO O R M A T O OR OBBBJJJ ...................................................................................................................................4 RM MA AT TO OO SSCCCEEENNNEEE G GRRRAAAPPPHHH ...................................................................................................................................8 IIM M M N T A O N MPPPLLLEEEM MEEEN NT TA AZZZIIIO ON NEEE ..........................................................................................................................15 C CO ON UTTU NC CLLU URRII ............................................................................................19 UPPPPII FFU USSIIO ON NEE EE SSVVIILLU RRIIFFEERRIIM MEEN NTTII ....................................................................................................................................19 2 IILLLLU DII U UN OG 3D HA NO GG D AD GEET UM DIIN MIIN TT NG TO NA GD O3 AZZIIO ON NEE EE SSH Lo scopo del sistema è quello di visualizzare un oggetto tridimensionale evidenziando le interazioni tra le luci e la superficie tenendo conto della natura di più radiazioni luminose incidenti. Tutto il sistema è stato realizzato utilizzando Java3D e la possibilità che esso offre di definire diversi tipi di luce. In java3d esistono diversi tipi luci. L’Ambient Light fornisce luce della stessa intensità in tutte le locazioni e in tutte le direzioni. Rappresenta un modello della luce riflessa dagli altri oggetti dell’ambiente. La ambient light viene in genere usata per illuminare gli oggetti visuali quando non ci sono altre luci o nelle loro zone di ombra. La Diretional Light approssima fonti di luce distanti, come il sole, con raggi che possiedono tutti la stessa direzione. Il vettore L (luce) è costante. La Point Light è una sorgente di luce puntiforme che invia i suoi raggi in tutte le direzioni. L’intensità della luce diminuisce con la distanza e il punto di luce è collocato dello spazio.I vettori luce non sono paralleli. La Spot Light (riflettore) è una sottoclasse di PointLight. Aggiunge una direzione e una concentrazione alla posizione e all’attenuazione di un punto luce. La luce viene irradiata all’interno di un certo angolo di diffusione. Un oggetto visuale può risultare parzialmente illuminato da una Spot Light. L’oggetto tridimensionale è stato realizzato con un file di formato OBJ che viene caricato attraverso una classe loader. In java3D esistono diversi tipi di classi loader. Di seguito riportiamo l’elenco dei loader tutt’oggi disponibili: File Format 3DS COB DEM DXF IOB LWS Description 3D-Studio Caligari trueSpace Digital Elevation Map AutoCAD Drawing Interchange File Imagine Lightwave Scene Format NFF OBJ PDB PLAY SLD VRT VTK WRL WorldToolKit NFF format Wavefront Protein Data Bank PLAY Solid Works (prt and asm files) Superscape VRT Visual Toolkit Virtual Reality Modeling Language Nel nostro progetto è stato utilizzato il formato obj di Wavefront. In Java3d FFOORRM OO ATTO MA OBBJJ Il formato Obj definisce la geometria e altre proprietà per gli oggetti nel Visualizzatore Avanzato di Wavefront. Il file Object può essere usato per trasferire dati geometrici da un applicazione all’altra. E’ utilizzato per memorizzare e scambiare dati 3D ed è uno standard utile per rappresentare dati poligonali in formato ASCII (.obj) oppure in formato binario (.mod). Il formato .obj supporta sia gli oggetti poligonali che gli oggetti free-form. La geometria poligonale usa punti, linee, facce per definire oggetti, mentre la geometri free-form usa curve e superfici. Struttura del file I seguenti tipi di dati con le loro rispettive parole chiave possono essere inclusi all’interno di file .obj. Ne descriviamo alcuni utilizzati dal file obj caricato nel progetto (dragon.obj): 1. Vertex data I vertici sono definiti da quattro coordinate di vertici: a. vertici geometrici (v); Sintassi: v x y z w (istruzione per geometrie poligonali e free form) x y z sono le coordinate x, y, and z per i vertici. Sono numeri floating point che definiscono la posizione del vertice nelle tre dimensioni. 4 w è il peso richiesto per curve e superfici razionali. Se non è specificato nessun valore per w, il default è 1.0. b. vertici della texture (vt); Sintassi: vt u v w (istruzione per geometrie poligonali e free form). Specifica il vertice della texture e le sue coordinate. Una texture 1D richiede solo una coordinata texture u, una texture 2D richiede sia la coordinata u che v, una texture 3D richiede tutte e tre le coordinate: u è il valore per la direzione orizzontale della texture; v è un argomento opzionale ed è il valore della direzione verticale della texture il cui default è 0; w è un argomento opzionale ed è il valore della profondità della texture il cui valore di default è 0. c. normali ai vertici (vn); Sintassi:vn i j k (istruzione per geometrie poligonali e free form). Specifica un vettore normale con componenti i,j,k. Le normali del vertice influiscono sul smooth shading e sul rendering della geometria. Per i poligonile normali del vertice vengono usate al posto delle normali delle facce reali. Per le superfici, le normali del vertici sono interpolate sull’intera superficie e sostituiscono la normale della superficie analitica reale. Quando le normali del vertice sono presenti, esse sostituiscono i gruppi di smoothing. i, j e k sono le coordinate per la normale del vertice e sono numeri floating point. d. vertici dello spazio parametrico (vp); Sintassi: vp u v w (istruzione per geometrie free form). Specifica un punto nello spazio parametrico di una curva o superficie. Punti speciali per le curve richiede un punto di controllo 1D (solo u) nello spazio parametrico della curva. Punti speciali per le superfici richiedono un punto 2D (u e v) nello spazio parametrico della superficie. Punti di controllo per 5 curve non razionali richiedono le coordinate u e v. punti di contrololo per curve razionali richiedono le coordinate u, v e w (peso). u è un punto nello spazio parametrico di una curva o la prima coordinata nello spazio parametrico di una superficie; v è la seconda coordinata nello spazio parametrico di una superficie; w è il peso richiesto per le curve razionali e il suo valore di default è 1.0. 2. Elementi a. face (f); Sintassi: f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 . . .(istruzione per la geometria poligonale). Specifica un elemento face e il suo numero di riferimento del vertice. Opzionalmente si può includere il vertice di texture e i numeri di riferimento della normale del vertice. I numeri di riferimento per i vertici, i vertici della texture, e le normali dal vertice devono essere separate da slash (/). Non c’è spazio tra il numero e lo slash. v è il numero di riferimento per un vertice in un elemento face. Sono richiesti minimo tre vertici, vt è un argomento opzionale ed è un numero di riferimento per un vertice della texture nell’elemento face. Segue sempre il primo slash, vn è un argomento opzionale ed è il numero di riferimento per la normale di un verticedell’elemento face. Esso deve semore seguire il secondo slash. Gli elementi face usano le normali della superficie per indicare il loro orientamento. Se i vertici sono ordinati in senso antiorario intorno al face, sia il face che la normale punteranno all’osservatore. Se il vertice è ordinato in senso orario, entrambi punteranno lontano dall’osservatore. Se vengono assegnati le normali del vertice, essi punteranno nella direzione generale della normale della superficie, altrimenti si otteranno risultati imprevedibili. Se un face ha una texture map assegnato e non ci sono vertici di texture assegnati nella istruzione f , la texture map è ignorata quando l’elemento è visualizzato. 6 3. Gruppi a. group name (g); Sintassi: g group_name1 group_name2 . . . (istruzione per geometrie poligonali e free form) Specifica il nome del gruppo per gli elementi che lo seguono.E’ possiblile avere nomi di gruppi multipli. Se ci sono gruppi multipli su un'unica linea, i dati che lo seguono appartengono a tutti i gruppi. L’informazione del gruppo è opzionale. group_name è il nome del gruppo. Lettere, numeri e combinazioni di lettere e numeri sono accettati per il nome del gruppo. Il valore di default per il nome del gruppo è “default”. b. smoothing group (s); Sinatssi s group_number (istruzione per geometrie poligonali e free form). Imposta lo smoothing group per gli elementi che lo seguono. Se non si vuole usare uno smoothing group, non sia specificato o venga avvalorato con 0. Per visualizzare con lo smooth shading, si deve creare le normali del vertice dopo che è stato assegnato gli smoothing groups. Si possono creare le normali dei vertici con l’istruzione vn. 4. Attributi di display/render a. Material name (usemtl); Sintassi: usemtl material_name (istruzione per geometrie poligonali e freeform). Specifica il nome del materiale per l’elemento che lo segue. Una volta che il materiale viene assegnato esso non può essere cancellato ma può essere solo cambiato. Material name è il nome del materiale. Se il nome non è specificato viene usato un materiale di colore bianco. b. Material library (mtllib); 7 Sintassi: mtllib filename1 filename2 . . . (istruzione per geometrie poligonali e free-form). Specifica il file di libreria per la definizione dei materiali impostati con l’istruzione usemtl. Si possono specificare filename multipli con mtllib. Se filename multipli sono specificati il primo file elencato viene cercato prima della definizione del materiale, il secondo file viene cercato di seguito e così via. Non c’è nessun defaults. SSCCEENNEE G GRRAAPPHH SceneGraph è la struttura dati, utilizzata per memorizzare, organizzare e render l‘informazione di una scena (oggetti, materiali, luci...). Un grafo è una struttura dati composta da nodi ed archi:i nodi in uno scene graph sono oggetti Java3D mentre gli archi rappresentano due diversi tipi di relazione tra oggetti, la relazione parent–child e la relazione reference. In una relazione parent-child un nodo può avere più successori, ma un solo predecessore e la loro relazione costituisce lo scene graph tree. Nella relazione reference c’è una reference che associa un node component con uno scene graph node. I nodi più importanti di uno scene graph sono: Virtual Universe, Locale, Groups, Leaf, NodeComponents. Una istanza della classe VirtualUniverse serve come radice dello scene graph, il cui termine si riferisce ad uno spazio virtuale tridimensionale popolato di oggetti 3D. Un oggetto SimpleUniverse crea uno scene graph contenente un oggetto VirtualUniverse, un oggetto Locale ed un completo view branch graph che definisce un sistema di coordinate nel mondo virtuale. BranchGroup e TransformGroup sono sottoclassi della classe Group. Group è la superclasse usata per specificare posizioni ed orientamenti degli oggetti nell'universo virtuale. Nella rappresentazione grafica dello scene graph,i simboli di Group (cerchi) sono indicati con BG per BranchGroup e TG per TransformGroup. Un nodo Shape3D definisce un oggetto visuale. Esso e' una sottoclasse di Leaf, quindi può essere solo una foglia in uno scene graph. Non contiene 8 informazioni su forma o colore di un oggetto, ma contiene solo informazioni sugli oggetti NodeComponent collegati ad esso. Un nodo Shape3D può riferirsi ad un componente Geometry ed ad un componente Appearance. Shape3D, Light, Behavior e Sound Leaf sono sottoclassi di Leaf. Leaf è la superclasse usata per specificare forme, aspetti, suoni e comportamenti. Un nodo Leaf non può avere successori, ma reference ad oggetti NodeComponent. La classe Node Component class è usata per specificare una varietà di proprietà di un nodo Shape3D, quali Geometria, Texture,Trasparenza e Colore. Un NodeComponent può essere collegato a più di un nodo Shape3D. Nel progetto realizzato, è stato creato un BranchGroup objRoot che ha un nodo figlio di tipo TransformGroup objScale. //Crea la radice del branch graph BranchGroup objRoot = new BranchGroup(); //Crea un Transformgroup per scalare tutti gli oggetti //così che essi appaiano sulla scena TransformGroup objScale = new TransformGroup(); Transform3D t3d = new Transform3D(); t3d.rotY(0.7); t3d.rotX(0.2); t3d.setScale(0.45); objScale.setTransform(t3d); objRoot.addChild(objScale); Al TransformGroup objScale è applicato un Transform3d t3d che definisce gli la scala di rappresentazione e l’inclinazione rispetto all’asse X e Y di tutti i figli di objScale. Il TransformGroup objScale ha cinque nodi figli: due di tipo leaf e tre di tipo group. I nodi di tipo Leaf sono: Background, Light mentre i nodi di tipo group sono due di tipo TransformGroup e uno di tipo SceneGroup. Il nodo Background definisce il background della scena: public Background bg = new Background(bgColor); bg.setCapability(bg.ALLOW_COLOR_WRITE); bg.setCapability(bg.ALLOW_COLOR_READ); bg.setApplicationBounds(bounds); objScale.addChild(bg); 9 il nodo Light definisce la luce ambientale della scena: public AmbientLight aLgt = new AmbientLight(alColor); aLgt.setCapability(aLgt.ALLOW_COLOR_WRITE); aLgt.setCapability(aLgt.ALLOW_COLOR_READ); objScale.addChild(aLgt); Alla luce ambientale sono impostate le proprietà di lettura e scrittura per poterla modificare a runtime. I nodi di tipo group sono i TransformGroup l1RotTrans e l2RotTrans. TransformGroup l1RotTrans = new TransformGroup(); l1RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); objScale.addChild(l1RotTrans); TransformGroup l2RotTrans = new TransformGroup(); l2RotTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); objScale.addChild(l2RotTrans); Ad ognuno di essi viene impostata la proprietà di scrittura sulla trasformazione dell’oggetto appartenente al gruppo. L’altro nodo di tipo group, figlio di objScale, è un oggetto (file in formato obj) importato all’interno della scena. ObjectFile f=new ObjectFile(ObjectFile.RESIZE); try { //Carica il file Scene s=f.load("dragon.obj"); //Inserisce il drago nello SceneGraph objScale.addChild(s.getSceneGroup()); }catch (Exception e) {System.out.println(e);} Il nodo di tipo TransformGroup l1RotTrans ha un nodo figlio di tipo TransformGroup l1Trans e un nodo figlio di tipo Leaf (Behavior) RotationInterpolator rotator1. // Crea un Behavior object che fa ruotare la sfera intorno all'oggetto Transform3D yAxis = new Transform3D(); Alpha rotor1Alpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, 4000, 0, 0, 0, 0, 0); RotationInterpolator rotator1 = new RotationInterpolator(rotor1Alpha, l1RotTrans,yAxis, 0.0f, (float) Math.PI*2.0f); rotator1.setSchedulingBounds(bounds); l1RotTrans.addChild(rotator1); 10 Questo behavior applica una rotazione a tutti gli oggetti contenuti all’interno del transformgroup l1RotTrans. Questa classe definisce un behavior che modifica la componente rotazionale del suo target TransformGroup interpolando linearmente tra una coppia di angoli specifici (usando il valore generato da un oggetto specifico Alpha). L’angolo interpolato è usato per generare una rotazione intorno all’asse Y locale di questo interpolatore. Il nodo TransformGroup l1Trans ha due nodi figli di tipo Leaf: Light e Shape3D. Light è un oggetto di tipo PointLight lgt1. un oggetto PointLight specifica una sorgente di luce attenuata in un unto fissato nello spazio che irradia luce equalmente in tutte le direzioni partendo dalla sorgente di luce. PointLight estende il nodo Light e in aggiunta ha i parametri di locazione e attenuazione. PointLight consente la riflessione diffusa e speculare che dipende di volta in volta dalla rotazione e posizione della superficie. Non contribuisce alla riflessione ambientale. Point3f lPoint = new Point3f(0.0f, 0.0f, 0.0f); Point3f atten = new Point3f(1.0f, 0.0f, 0.0f); lgt1 = new PointLight(lColor1, lPoint, atten); Al nodo Shape3d di tipo Sphere sono applicati due riferimenti: Apperance (appL1) e Geometry (new Sphere(0.15f, appL1)): Appearance appL1 = new Appearance(); appL1.setColoringAttributes(caL1); l1Trans.addChild(new Sphere(0.15f, appL1)); Il TransformGroup l2RotTrans ha un sottoalbero identico al sottoalbero del TransformGroup l1RotTrans ad eccezione del behavior RotationInterpolator che non è presente. Tutte le luci della scena (AmbientLight e le due PointLight) hanno un BoundingSphere bound. bound definisce una regione sferica che è definita da un punto centrale e il raggio: BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0); // Imposta influencing bounds delle luci aLgt.setInfluencingBounds(bounds); lgt1.setInfluencingBounds(bounds); lgt2.setInfluencingBounds(bounds); 11 Per ragioni di spazio ContentBranch graph e ViewBranch graph dello scene graph sono riportati separatamente. Di seguito riportiamo il content branch graph dello scene graph del progetto. 12 ContentBranch Graph Locale BG View Branch Graph TG SG OBJ FILE Background L TG TG B TG S TG L L S BOUNDING SPHERE appearence geometry appearence geometry 13 Di seguito riportiamo il view branch graph dello scene graph del progetto. ViewBranch Graph Locale BG Content Branch Graph TG Viewer VP Phisical Body Canvas 3D Screen 3D Phisical Environment ViewPlatform (VP) è un nodo foglia che crea una vista all’interno di uno scene graph. Il genitore di ViewPlatform specifica la sua locazione, il suo orientamento, e la sua scala all’interno del virtual universe. Viewer contiene le componenti fisiche e virtuali dell’universo Java3D. Canvas3D è la vesione 3D dell’oggetto Canvas dell’Abstract Windowing Toolkit (AWT). Rappresenta una finestra in cui Java 3D disegnerà le immagini. Contiene un riferimento all’oggetto Screen3D e informazioni che descrivono dimensione, forma e posizione dell’oggetto all’interno dell’oggetto Screen3D. Screen3D è un oggetto che contiene informazioni che descrivono proprietà fisiche dello schermo. Java3D inserisce le informazioni sul display in un oggetto 14 separato per evitare la duplicazione delle informazioni sullo schermo all’interno di ogni oggetto Canvas3D che condividono uno schermo comune. PhysicalBody contiene le specifiche principali dell’utente. Gli attributi di questo oggetto sono espressi nel sistema di coordinate di riferimento. L’origine è definito a metà strada tra l’occhio sinistro e destro sul piano della faccia. PhysicalEnvironment contiene le specifiche fisiche tecniche dell’ambiente in cui l’oggetto verrà visualizzato come i dispositivi fisici di output. IIM NEE ON AZZIIO NTTA MEEN MPPLLEEM Il progetto è stato sviluppato all’interno dell’IDE (Integrated Development Environment) Eclipse 3.2 utilizzando la versione 6 di Java e la versione 1.5 di Java3D. La classe realizzata estende una JApplet e consente al progetto di poter essere eseguito sia come applicazione che come applet. La classe principale che è stata realizzata si chiama LightsOnObj3D.java ed estende la classe JApplet. Il main di questa classe è il seguente: public static void main(String[] args) { JApplet applet=new LightsOnObj3D(); JFrame frame=new JFrame("Illuminazione di un oggetto 3D"); frame.getContentPane().add(applet); frame.addWindowListener(new killAdapter()); frame.setVisible(true); frame.setSize(900, 700); applet.init(); applet.start(); } Nel main viene istanziato un oggetto di tipo JFrame frame e un oggetto di tipo JApplet applet chiamando il costruttore della classe LightsOnObj3D al cui content pane è aggiunto l’oggetto applet. Il costruttore della classe contiene la chiamata al metodo init(). Questo metodo, necessario per eseguire un’applicazione come applet crea il contenuto della finestra dell’applet costruendo due pannelli principali: il pannello di sinistra contiene dei pulsanti che consentono di modificare a runtime i colori di sfondo e delle luci mentre, il pannello di destra contiene un oggetto Canvas3D. Infine, il costruttore chiama la funzione crea createSceneGraph che restituisce un oggetto di tipo 15 BranchGroup successivamente aggiunto al SimpleUniverse u per mezzo del metodo addBranchGraph: public Canvas3D c = new Canvas3D(config); public SimpleUniverse u = new SimpleUniverse(c); finestra.add(c); finestra.add(impostacolori, BorderLayout.WEST); BranchGroup scene = createSceneGraph(u); u.addBranchGraph(scene); Il metodo createSceneGraph crea il BranchGroup descritto all’interno del paragrafo precedente “Scene Graph”. Di seguito riportiamo uno screenshot dell’applicazione: Quando viene azionato un qualunque pulsante contenuto nel pannello di sinistra viene creato un oggetto di tipo JColorChooser che consente di scegliere il colore che si desidera applicare al punto luce fermo oppure al punto luce in 16 movimento oppure alla luce ambientale o infine allo sfondo, in base a quale pulsante è stato azionato. Ciò è mostrato nella figura che segue. Ciò è stato realizzato all’interno del seguente frammento di codice in cui è riportata l’azione associata a ciascun pulsante: sferaferma.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { String title=arg0.getActionCommand(); Color colorsphere = JColorChooser.showDialog(new LightsOnObj3D(), "Scegli il colore - "+title, getBackground()); Color3f c1=new Color3f(); c1.set(colorsphere); lgt2.setColor(c1); caL2.setColor(c1); } } ); 17 sferainmovimento.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { String title=arg0.getActionCommand(); Color colorsphere = JColorChooser.showDialog(new LightsOnObj3D(), "Scegli il colore - "+title, getBackground()); Color3f c1=new Color3f(); c1.set(colorsphere); lgt1.setColor(c1); caL1.setColor(c1); } } ); sfondo.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { String title=arg0.getActionCommand(); Color colorsphere = JColorChooser.showDialog(new LightsOnObj3D(), "Scegli il colore - "+title, getBackground()); Color3f c1=new Color3f(); c1.set(colorsphere); bg.setColor(c1); } } ); luceambientale.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { String title=arg0.getActionCommand(); Color colorsphere = JColorChooser.showDialog(new LightsOnObj3D(), "Scegli il colore - "+title, getBackground()); Color3f c1=new Color3f(); c1.set(colorsphere); aLgt.setColor(c1); } }); Il nucleo centrale dell’applicazione realizzata è nel metodo createSceneGraph che crea il BranchGroup aggiunto all’interno dell’area canvas3D contenuta all’interno del SimpleUniverse. Questa funzione implementa i BranchGroup, i TransformGroup e in particolar modo le luci utilizzate all’interno della scena. Le luci che sono state realizzate sono una di tipo AmbientLight e due di tipo PointLight. In particolar modo ciascun oggetto PointLight appartiene a un diverso TransformGroup che contiene anche un oggetto di tipo Sphere. I due oggetti (Sphere e PointLight), appartenendo allo stesso TransformGroup ereditano lo stesso behavior e ciò fa si che l’oggetto di tipo Sphere sembri un punto luce. 18 C CO ON VIILLU UT NC TU CLLU UR UPPPPII FFU RII USSIIO ON NEE EE SSV Il sistema realizzato può essere esteso consentendo all’utente di poter selezionare file object diversi per mezzo di un pulsante “Sfoglia”. Il limite riscontrato nella realizzazione del sistema riguarda fondamentalmente la potenza degli strumenti a nostra disposizione. File object di dimensioni abbastanza elevate hanno reso impossibile poter testare qualsiasi tipo di oggetto 3D trovato. Ciononostante i contenuti acquisiti si sono rivelati positivi e interessanti. R RIIFFEER RIIM MEEN NT TII • FOLEY J.D. VAN DAM A. FEINER S COMPUTER GRAPHICS PRINCIPLES AND PRACTICE • http://www.di.uniba.it/~ig • http://isg.cs.tcd.ie/spheretree/models/ 19