English (UK)

Tratto da programmazione.it scritto da Dario Guadagno

In questa ultima parte si analizzerà come utilizzare le classi fornite per importare o esportare scene in VRML. Le due classi relative all’interfacciamento con file e creazioni in VRML sono: VRML97Saver e VRML97Loader.

La prima, come si può intuire dal nome, consente di salvare gli ambienti creati in Java3D come file VRML, mediante una conversione che, attraversando tutto lo scene graph, individua i nodi rilevanti e li trasforma in istruzioni VRML (a loro volta scritte sotto forma di nodi, che generano un albero che descrive una scena tridimensionale). La sintassi da utilizzare è la seguente:

import cv97.j3d.*;
...
BranchGroup j3dBranchGroup = ...
VRML97Saver saver = new VRML97Saver();
saver.setBranchGroup(j3dBranchGroup);
saver.save(“nomeScena.wrl”);

Il codice indicato consente di esportare in formato standard VRML la scena corrispondente al content branch radicato nel j3dBranchGroup. L’ambiente salvato sarà visibile con qualunque strumento in grado di aprire file VRML.

Funzionamento analogo, ma chiaramente inverso, è quello della classe VRML97Loader, che consente di aprire un file VRML, convertirne il contenuto in un insieme di nodi Java3D, e trasformarli in un content branch radicato in un unico BranchGroup, che quindi può essere utilizzato per le normali operazioni previste da Java3D relative agli ambienti tridimensionali. La sintassi per utilizzare la suddetta classe è la seguente:

import cv97.j3d.loader.*;
...
Canvas3D c3d = ...
VRML97Loader wrlLoader = new VRML97Loader(c3d);
Scene s = wrlLoader.load(“nomeScena.wrl”);
BranchGroup sgGroup = s.getSceneGroup();

Il loader viene inizializzato con la Canvas3D, che contiene l’universo in cui si sta lavorando per la creazione di un ambiente 3D. L’importazione di una scena descritta in VRML avviene in due fasi: dapprima, utilizzando il metodo load(), si carica il file .wrl che rappresenta la scena e si ottiene così una com.sun.j3d.loaders.Scene corrispondente al file caricato; poi, utilizzando il metodo getSceneGroup(), si ottiene il BranchGroup in cui è radicato il content branch, che descrive la scena sotto forma di istruzioni e nodi in Java3D.

L’oggetto sgGroup ottenuto potrà, quindi, essere utilizzato nel codice Java che segue la sua istanziazione come un qualsiasi BranchGroup, per cui potranno essere aggiunti ulteriori nodi come suoi figli, potrà essere associato ad un nodo gruppo (BranchGroup o TransformGroup) padre, o potrà essere inserito nell’universo su cui si sta lavorando, per consentire la visualizzazione della scena che sgGroup rappresenta.

Lo scorso settembre è stato annunciato che, finalmente dopo ben otto anni di silenzio assoluto, verrà rilasciata la versione aggiornata del linguaggio HTML. Si passerà quindi dalla release 4 del 1999 alla release 5. La nuova versione aggiungerà nuovi comandi al linguaggio, per venire incontro alle esigenze degli sviluppatori di integrare materiale multimediale e altro nelle pagine web. Ciò nonostante la vecchia versione sarà ancora valida al 100% e rimane alla fin fine la struttura portante di ogni pagina. Pubblichiamo qui una quick reference guide del linguaggio, per avere sempre a portata di mano comandi e parametri disponibili nella vecchia versione.

Solitamente, dopo aver scaricato ogni sorta di ben di dio da poter caricare nel proprio cellulare, sorge la fatidica domanda: e se ora facessi qualcosa io? Il proposito è lodevole, ma non privo di ostacoli. Per scrivere un gioco java per cellulari bisogna cimentarsi con la j2me, che volenti o nolenti, significa programmare. Ciò nonostante java è stato realizzato con due obiettivi principali: funzionare su qualsiasi dispositivo ed essere di facile apprendimento. Senza essere ipocriti, java è e rimane un linguaggio di programmazione a tutti gli effetti, ma con qualche buon esempio anche chi non è un buon programmatore ma è armato di pazienza e impegno è in grado di ottenere qualche soddisfazione.

Per poter apprendere in modo rapido i rudimenti di Java consiglio di leggere la guida che presenta HTML.it. Qui trovate invece una guida specifica per J2ME.

Il compilatore Java2, necessario per lo sviluppo dell'applicazione si scarica gratuitamente dal sito di Sun Microsystems. Similmente il pacchetto aggiuntivo J2ME. Scrivere dal Blocco Note di Windows è possibile, ma non è il massimo per chi si avvicina a Java per la prima volta. Ci si deve quindi appoggiare a degli IDE, dei programmi che ci assistono nella stesura del codice. Se vogliamo restare in casa Sun possiamo scaricare NetBeans, altrimenti anche Eclipse fa al caso nostro. Infine abbiamo bisogno di avere qualche esempio pronto da sviscerare per vedere come funziona il tutto. Qui trovate qualcosina che per iniziare è certamente d'aiuto.

Tratto da programmazione.it scritto da Dario Guadagno

In questo articolo, vedremo come esportare il lavoro fatto con Java3D in formati standard e quindi particolarmente portabili, come VRML e la sua evoluzione X3D. Il package CyberX3D è un sottoinsieme della libreria CyberGarage, realizzata dal programmatore giapponese Satoshi Konno, contenente un insieme di classi e metodi orientati alla realtà virtuale ed alla programmazione in grafica 3D.

Satoshi Konno, nato nel 1972 a Tokyo, lavora da anni nell’ambito della programmazione di sistemi in realtà virtuale, e dal 1996 ha iniziato a lavorare al CyberGarage, un insieme di prodotti ideati per semplificare o ottimizzare la programmazione di ambienti tridimensionali. La libreria CyberGarage, oltre a CyberX3D (scritto sia per programmatori Java che C++), contiene anche altri package interessanti, alcuni dei quali persino premiati da diversi riconoscimenti attestanti l’eccellente qualità.

Rilasciato nel 2003, CyberX3D è un package per programmatori Java che intendono interoperare con file e ambienti VRML o X3D. Utilizzando CyberX3D è possibile creare o utilizzare, in maniera piuttosto semplificata, classi e metodi per leggere/scrivere file VRML o X3D, reperire o modificare informazioni relative allo scene graph di un ambiente 3D, disegnare scene tridimensionali da esportare in uno dei suddetti formati.

L’utilizzo del package è subordinato alla presenza nel proprio sistema della piattaforma Java 2 Standard Edition e delle API Java3D. L’installazione di CyberX3D avviene, facilmente, copiando il package nella directory del Run Time Environment della JVM.

Tratto da programmazione.it, scritto da Dario Guadagno

In quest'ultima parte, tratteremo alcuni problemi che si potrebbero verificare durante la scrittura di programmi in grafica 3D in ambiente Java, e saranno spiegati alcuni dettagli relativi al motore 3D.

Come accennato nella prima parte dell'articolo, Java3D si appoggia su librerie native, per cui è da esse che deriva le proprie feature principali, mentre non è in grado di fornire supporto per alcune funzionalità, come la gestione delle ombre o delle texture animate, superfici trasparenti o specchi). Tuttavia, queste non sono limitazioni di Java3D, ma delle librerie native. Le operazioni citate sono infatti molto dispendiose in termini di risorse e non vengono utilizzate in grafica 3D in tempo reale. È lecito aspettarsi che quando l’evoluzione tecnologica porterà gli standard 3D a supportare questo tipo di caratteristiche, anche Java3D ne fornirà il supporto.

Java3D non è però solo un semplice wrapper su API esistenti: il suo motore si occupa anche di ottimizzazioni e operazioni aggiuntive che non sono previste nelle API native. Il runtime engine sceglie l’ordine di attraversamento dell’albero e non è limitato ad una direzione di tipo sinistra-destra o sopra-sotto, quindi può utilizzare strategie per l'ottimizzazione della visualizzazione. La rappresentazione di un'immagine tridimensionale avviene seguendo il seguente schema:

  • definizione del view volume, ovvero della porzione di spazio visibile all’utente;
  • rendering: conversione del view volume in un’immagine 2D;
  • rasterization: l’immagine viene convertita in una griglia di pixel;
  • shading: viene impostato il colore dei pixel.

Tutte le suddette operazioni sono eseguite direttamente, e in maniera trasparente a programmatore ed utente, dalla Java Virtual Machine, che immediatamente dopo, mostra l’effettiva scena attiva, pronta all’eventuale interazione. Ulteriori problematiche potrebbero essere connesse ad altre due segnalazioni: le classi di Java 3D non sono serializzabili e, come noto, richiedono un notevole impiego di risorse. Quest'ultimo punto, in particolare, merita una cura in più: se da un lato, chiaramente, esso determina un rallentamento nelle prestazioni, peraltro piuttosto lieve e sicuramente accettabile, dall'altro, in caso di scene particolarmente complesse e cariche di oggetti, può addirittura causare il crash dell'applicazione per problemi di insufficienza di memoria (Out of Memory Error).

Il problema si presenta perché, di default, la JVM ricorre ad un heap di dimensioni contenute, ideale per la maggior parte delle applicazioni eseguite, ma non sufficiente nel caso di sistemi più complessi. È possibile aggirare tale rischio ampliando l’heap a disposizione della JVM, specificando dei parametri aggiuntivi all’atto di mandare in esecuzione l'applicazione. Il progetto, in generale, presenta una certa semplicità d’uso anche se dà l’idea di essere stato sviluppato un po’ in disparte rispetto alle altre tecnologie Java. L’incompatibilità con Swing ne è un esempio (come la classe Locale che trova un duplicato in java.util) che potrebbe frenare progetti ambiziosi su Java3D.

Nonostante alcune limitazioni e complessità aggiuntive, comunque, è indubbio che Java3D sia un potentissimo strumento a disposizione dei programmatori Java. Le Api completano l’offerta della piattaforma, introducendo un elemento chiave quale la grafica 3D e fornendo un'ulteriore preziosa funzionalità all'intera tecnologia Java.

Tratto da programmazione.it, scritto da Dario Guadagno

Una soluzione alternativa per gestire gli eventi può essere ottenuta sfruttando il fatto che la Canvas3D, in quanto Component, è una possibile sorgente di eventi. Da ciò, catturando gli eventi generati dalla Canvas3D, e quindi le interazioni dell'utente con la scena, e sfruttando i metodi offerti dalla classe PickCanvas, che restituisce un riferimento all'oggetto (il nodo dell'albero) su cui l'utente ha cliccato, è possibile simulare una gestione di eventi basata sulle interazioni con gli oggetti 3D della scena.

Per lavorare in tal senso, d'altra parte, è bene ricordare che gli oggetti "interattivi" devono essere pick-reportable, cioè devono poter essere letti dal PickCanvas:

nodo3d.setCapability(TransformGroup.ENABLE_PICK_REPORTING);

Qualora si voglia gestire la possibilità di spostare/rimuovere oggetti dall'albero della scena in seguito a qualche interazione, essi devono anche essere detachable, cioè rimuovibili dallo Scene Graph, oppure devono consentire la lettura e scrittura delle loro proprietà all'interno dell'albero:

nodo3d.setCapability(BranchGroup.ALLOW_DETACH); //rende l'oggetto detachable

/* Lettura e modifica delle trasformazioni */
nodo3d.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
nodo3d.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

/* Lettura e modifica dei figli nel sottoalbero radicato nel nodo oggetto3d */
nodo3d.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
nodo3d.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
nodo3d.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);

Una volta definita la scena e le eventuali interazioni, basterà rendere visibile il frame che contiene la Canvas3D per visualizzare la nostra prima scena tridimensionale. Con le prime tre parti di questo articolo sono stati mostrati gli aspetti fondamentali della programmazione in Java 3D.

Tratto da programmazione.it, scritto da Dario Guadagno

La scena, di default, indipendentemente dalle dimensioni del frame che la contiene, ha larghezza 2, il punto più a sinistra è posto alla coordinata -1 e l’estremo a destra è alla coordinata +1; al centro del frame è posta l’origine e l’asse della profondità è orientato secondo il verso “uscente” dallo schermo. L'asse dell'altezza ha dimensione calcolata in rapporto alla larghezza: ad esempio, se un frame ha altezza doppia rispetto alla larghezza, il punto più alto del frame avrà coordinata 2, e il più basso -2.

È possibile definire delle reazioni ai movimenti del mouse nella scena (specializzazioni della classe MouseBehavior), o alle specifiche interazioni su un oggetto 3D (specializzazioni della classe PickMouseBehavior), ma il meccanismo non è semplicissimo ed è certamente più macchinoso di quanto non accada con la normale gestione ad eventi. D'altra parte, alcune convenzioni adottate da Java 3D sono facilmente utilizzabili e permettono di gestire i movimenti "continui" degli oggetti tridimensionali, come la traslazione o la rotazione:

  • pressione del pulsante sinistro del mouse e trascinamento, per la rotazione di un oggetto, gestita dalla classe PickRotateBehavior.
  • Pressione del pulsante destro del mouse e trascinamento, per lo spostamento di un oggetto lungo l’asse orizzontale o verticale, gestita dalla classe PickTranslateBehavior.
  • Pressione del pulsante sinistro del mouse e, contemporaneamente, del tasto ALT della tastiera (tale combinazione equivale alla pressione del pulsante centrale nei mouse three button) e trascinamento, per avvicinare o allontanare un oggetto (spostamento lungo l’asse della profondità), gestita dalla classe PickZoomBehavior).

Le scelte relative ai componenti tridimensionali di una scena sono dovute anche al fatto che, chiaramente, i cambiamenti a runtime di un ambiente tridimensionali sono ben più “pesanti” di quelli all’interno di applicazioni 2D. Limitare e standardizzare i movimenti e rendere più "statici" gli oggetti alleggerisce il lavoro a runtime del motore 3D.

Tratto da programmazione.it, scritto da Dario Guadagno

Le API Java 3D sono una libreria di classi e metodi specifiche per la realizzazione di applicazioni dotate di interfaccia grafica tridimensionale. Java 3D consente la produzione in tempo reale di grafica 3D tramite un insieme di API omogenee e multipiattaforma. Queste non si occupano del rendering a basso livello delle immagini: questa operazione è delegata dal motore di rendering di Java 3D alle librerie native della piattaforma sottostante, come OpenGL e Direct3D.

L'installazione delle API può avvenire semplicemente eseguendo il comodo tool autoinstallante scaricabile dal sito di Sun Microsystems. In Java 3D, il concetto fondamentale è quello dello scene graph: un albero a cui si appendono tutti gli oggetti della scena 3D, intendendo con tale termine non solo gli elementi da visualizzare, ma anche le istruzioni per rappresentarli.

L’albero è radicato nell’Universo Virtuale (Virtual Universe) che, a sua volta, ha uno o più figli Locale (letteralmente, dei luoghi all’interno dell’universo), che rappresentano le scene tridimensionali. Lo scene graph viene percorso dal motore di Java 3D per trovare i dati per creare l'immagine, perciò qualsiasi cosa si desideri abbia un'influenza sulla scena va messa nello scene graph.

Da ogni nodo Locale partono due rami (branches) principali: il content branch e il view branch: il primo contiene gli oggetti da visualizzare, il loro colore, dove sono messi nello spazio e tutte le altre informazioni rilevanti; il secondo contiene tutto quello che riguarda “il vedere” la scena, ad esempio i dispositivi di input/output, punto di vista ecc.

La creazione dell’Universo Virtuale, del contesto locale e di tutti gli aspetti relativi al view branch può essere effettuata automaticamente utilizzando la classe SimpleUniverse fornita di default dal package, in com.sun.j3d.utils.universe.*

Il disegno tridimensionale viene creato all'interno di un oggetto Canvas3D, che è un'estensione della classe Component, per cui può semplicemente essere aggiunto ad un frame; tuttavia, non è un container, quindi non può contenere altri componenti. La Canvas3D viene creata a partire dal view branch, e riempita, quindi, con gli elementi del content branch. Gli oggetti tridimensionali immessi nella scena, in effetti, non sono altro che dei rendering delle immagini descritte dai nodi, per cui, non è possibile associare degli eventi da catturare e gestire, secondo la normale programmazione a eventi di Java, ma è possibile definire dei behavior, cioè delle reazioni degli oggetti tridimensionali all'interazione dell'utente con la scena.

Come detto, quindi, ogni elemento della scena, sia esso un oggetto 3D, una luce o una qualsiasi entità che definisca le modalità di visualizzazione dell'ambiente, non è altro che un nodo del grafo della scena. Due nodi, tuttavia, hanno una funzione particolare: i BranchGroup, radici di sottoalberi di oggetti con proprietà comuni, e i TransformGroup, che definiscono delle trasformazioni (rotazioni, spostamenti lungo uno degli assi ecc.) associate a tutti gli elementi del loro sottoalbero.

Le foglie dello Scene Graph sono, tipicamente, gli oggetti fisici che popolano la scena.

Continua la serie sulle possibilità offerte dagli ambienti di sviluppo per estendere le proprie funzionalità, con una piccola parentesi non totalmente in tema, ma decisamente interessante per completare quanto detto nel precedente articolo riguardo la stesura di moduli per NetBeans grazie alle sue feature.

Chi di voi non ha pasticciato almeno una volta con le macro di Microsoft Office alzi la mano e faccia un esame di coscienza; tutti gli altri ricorderanno benissimo come da molti anni, grazie alle API della suddetta suite, sia possibile con poche righe di Visual Basic scrivere delle utilissime funzioni per i vari programmi di Office con tanto di editor di GUI e di sorgente — come in una versione Express del Visual Studio — nell'amabile logica di programmazione orientata agli eventi.

Finalmente anche OpenOffice.org dalla versione 2.0.4 e StarOffice — versione estesa e commerciale di OpenOffice.org — come avviene per le varie distribuzioni di editor basate su Eclipse, dalla 8 update 4, ha deciso di offrire le stesse possibilità; chiaramente con il linguaggio di programmazione Java, alla base di OpenOffice.org, ed un interessante modulo per NetBeans: OpenOffice.org API plugin. Pare infatti che questo plug-in permetta, grazie al riconoscimento e all'utilizzo delle API di OpenOffice.org, di ottimizzare la produttività per lo sviluppo delle nuove estensioni (file .oxt) per la suite di office automation.

Sul blog ufficiale di Sun Microsystems troviamo infatti l'interessante tutorial “Developing OpenOffice extensions using Java and NetBeans”, che illustra le operazioni fondamentali per giungere al nostro scopo utilizzando NetBeans 6, il JDK 6, OpenOffice.org 2.0.4 e l'OpenOffice.org SDK. Il tutorial si conclude con un paio di brevi video dimostrativi.

Come segnalato anche nel citato documento, è possibile vedere la presentazione della nuova infrastruttura ad estensioni di OpenOffice.org presentata all'OpenOffice.org Conference o, meglio ancora, leggere sul wiki di OpenOffice.org come sia possibile integrare l'IDE e la suite di office automation prodotti da Sun. Dopo questa parentesi, nel prossimo articolo concluderemo la serie in corso, osservando come sia possibile estendere le funzionalità di un ulteriore ambiente di sviluppo Java-based.

Tratto da programmare.it di Pierpaolo Cira

© 2007 - 2019 Bruno Tessaro. My life in the web. All right reserved.