Mi piacerebbe realizzare una piccola e semplice guida per spiegare le nozioni principali di Papervision3D. Non mi reputo certo un esperto di PV3D, ma da un pò di settimane mi sto interessando a questo 3D engine molto performante. Purtroppo non ho trovato molte risorse o una guida definitiva nel blog ufficiale, ma solo tutorials vari. Ispirandomi allora alla guida in inglese che ho trovato dopo mille ricerche, vorrei farne una traduzione in italiano, aggiungendo anche del mio.
Prima d’iniziare vi indico un blog che presenta alcune migliori creazioni in PV3D, un po’ per capire cosa possiamo costruire in Flash 3D.
Installiamo papervision, il modo migliore è descritto qui in italiano, ma è possibile anche copiarsi le cartelle contenenti i file sorgenti (soprattutto la cartella “org”) accanto ai file .fla e, se usate un file actionscript esterno, ai file .as del progetto.
Un consiglio: spesso mi capita di provare dei file sorgenti di esempi 3D realizzati da altri, ma appena avvio il filmato non funziona. In questo caso, il più delle volte, bisogna controllare quale versione di PV3D stiamo utilizzando (la 1.5, la 2.o alpha o beta…). In questa guida utilizzerò una precisa versione: la 2.0 beta, scaricabile da questa fonte ufficiale.
Già in un recente articolo ho trattato le primitive in papervision versione 1.5, le cose non sono di molto cambiate, ma incominciamo qui a presentare il Viewport3D e il BasicRenderEngine, che non avevo appositamente descritto precedentemente per ragioni di conflitto con le versioni.
Il Viewport3D altro non è che la finestra attraverso la quale osserviamo la scena tridimensionale di fronte, certo potremmo anche definire una larghezza, una altezza e delle coordinate per posizionarla dove vogliamo, ma il suo compito è di dirigersi verso gli oggetti 3D e mostrare al meglio la scena. I parametri del Viewport3D sono i seguenti:
function Viewport3D(viewportWidth:Number = 640,
viewportHeight:Number = 480, autoScaleToStage:Boolean = false,
interactive:Boolean = false, autoClipping:Boolean = true,
autoCulling:Boolean = true);
viewportWidth:Number (default = 640) — larghezza
viewportHeight:Number (default = 480) — altezza
autoScaleToStage:Boolean (default = false) — indica se in caso di ridimensionamento dello Stage anche il Viewport deve ridimensionarsi
interactive:Boolean (default = false) — Indica se è possibile aggiungere dei listener degli eventi per mouse, creando una scena interattiva
autoClipping:Boolean (default = true) — Indica se DisplayObject3D esterni al rettangolo del viewport devono essere renderizzati
autoCulling:Boolean (default = true) — Indica se solo gli oggetti di fronte alla camera devono essere renderizzati (ossia quelli nascosti da dietro ad altri oggetti non vengono renderizzati)
Il BasicRenderEngine collega fra loro la Scene3D, il Viewport3D e la Camera3D per poi renderizzarli ed aggiornarli.
function renderScene(scene:SceneObject3D, camera:CameraObject3D, viewPort:Viewport3D);
La definizione di questi 2 classi non è però indispensabile, per avere un risultato immediato ma altrettanto efficace è possibile utilizzare la classe BasicView. Quest’ultima permette la realizzazione veloce e di default di tutte le precedenti classi (viewport, scene, camera) e li renderizza, in più può essere aggiunta a qualsiasi DisplayObject.
BasicView(viewportWidth:Number = 640, viewportHeight:Number = 480, scaleToStage:Boolean = true, interactive:Boolean = false, cameraType:String = "Target")
Parametri
viewportWidth:Number (default = 640) — larghezza del viewport
viewportHeight:Number (default = 480) — altezza viewport
scaleToStage:Boolean (default = true) —Indica se il viewport deve scalare assieme allo stage
interactive:Boolean (default = false) — Indica se la scena deve essere interattiva (riconosce gli eventi del mouse)
interactive:Boolean (default = false) — Indica se la scena deve essere interattiva (riconosce gli eventi del mouse)
cameraType:String (default = “Target” ossia che mira all’origine degli assi) — Indica il tipo di Camera (Camera3D.TYPE)
Mettiamo di lato però il BasicView e seguiamo un tutorial che ci porti alla creazione di qualche primitiva e di alcune linee all’interno di una scena 3D di papervision, il risultato che si vuole raggiungere è questo:
Il progetto viene realizzato con un file di actionscript 3 esterno nominato “esempio1.as”, quindi il file di Flash correlato dovrà indicare soltanto come “classe documento” (nel pannello proprietà in basso) il nome “esempio” senza “.as”. Altro accorgimento: sia tale file di actionscript che i file sorgenti di PV3D devono essere posizionati accanto al file .fla che realizzaremo, in ogni caso sotto trovate i file del progetto già pronti.
package {//importiamo tutte le classi necessarie, sia di Flash sia di PV3D
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;import org.papervision3d.cameras.Camera3D;
import org.papervision3d.core.geom.Lines3D;
import org.papervision3d.core.geom.renderables.Line3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.proto.MaterialObject3D;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.materials.special.LineMaterial;
import org.papervision3d.objects.DisplayObject3D;
//l’asterisco * indica l’importazione di tutte le sottoclassi
import org.papervision3d.objects.primitives.*;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;//estendiamo la clasee come Sprite per acquisirne tutti parametri.
public class esempio1 extends Sprite {private var scene:Scene3D;
private var camera:Camera3D;
private var viewport:Viewport3D;
private var renderer:BasicRenderEngine;public function esempio1() {
// impostiamo lo stage
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;// avviamo la funzione di inizializzazione
init3D();// e creiamo gli oggetti tridimensionale
createScene();// avviamo anche un evento che si ripete ogni fotogramma
this.addEventListener(Event.ENTER_FRAME, loop);
}private function init3D():void {
//creiamo il viewport (abbiamo già visto il significato dei parametri),
//in ogni caso indicando i primi 2 zeri comandiamo a PV3D che vogliamo
//usare l’intero spazio (larghezza ed altezza) messa a disposizione
//dallo stage, l’ultimo parametro indica che non vogliamo realizzare una
//scena interattiva
viewport = new Viewport3D(0, 0, true, false);
addChild(viewport);//creiamo una camera con fov (campo di vista verticale ) di 60°
//(valore di default)
camera = new Camera3D(60);// posizioniamo la camera nello spazio 3D (default = 0, 0, -1000)
camera.x = -100;
camera.y = -100;
camera.z = -500;// indichiamo l’origine degli assi come target della camera, è importante
//indicarlo perchè di default la camera mira lungo l’asse delle Z. La
//funzione DisplayObject3D.ZERO crea un nuovo e vuoto DisplayObject3D
//posizionato precisamente a X=0, Y=0 e Z=0.
camera.target = DisplayObject3D.ZERO;// Creiamo la nuova scena che contiene gli oggetti tridimensionali
scene = new Scene3D();// creiamo un render che alla fine utilizzeremo
renderer = new BasicRenderEngine();
}private function createScene():void {
// Creiamo un semplice materiale (una gabbia) per gli oggetti,
//nei prossimi articoli approfondiremo tale argomento.
var oggettiMateriale:MaterialObject3D = new WireframeMaterial(0xFFFFFF);// Creiamo una sfera con la gabbia, raggio 50 e 10 segmenti
//orizzontali e verticali più sono tali segmenti
//meglio definita sono le curve della sfera
var sphere:Sphere = new Sphere(oggettiMateriale, 50, 10, 10);//posizioniamo la sfera (default = 0, 0, 0)
sphere.x = -100;//realizziamo un cono, con gabbia, raggio base 100, altezza 100 e 9 segmenti
var conoDiEsempio:Cone = new Cone(oggettiMateriale, 100, 150, 9, 9);//posizioniamo il cono e ruotiamolo un pò
conoDiEsempio.x = 150;
conoDiEsempio.rotationX = -20;
conoDiEsempio.rotationY = -34;//Creiamo un materiale per linee e l’oggetto linea3D con tale materiale
var defaultMaterial:LineMaterial = new LineMaterial(0xFFFFFF);
var axes:Lines3D = new Lines3D(defaultMaterial);//Creiamo però anche differenti colori sempre come materiali per linee.
var xAxisMaterial:LineMaterial = new LineMaterial(0xFF0000);
var yAxisMaterial:LineMaterial = new LineMaterial(0×00FF00);
var zAxisMaterial:LineMaterial = new LineMaterial(0×0000FF);//Definiamo un origine dei vertici, serve come primo vertice delle linee
//(che è uguale per tutte le 3 linee che realizzeremo), il secondo vertice
//sarà differente per ognuna delle 3 linee (al fine di creare una figura
//che simuli gli assi cartesiani)
var origin:Vertex3D = new Vertex3D(0, 0, 0);//Creiamo le linee di lunghezza 100 e la spessore 2,
//per ognuna inseriamo differenti materiali.
//function Line3D(instance:Lines3D, material:LineMaterial, spessore:Num,
//vertex0:primo Vertex3D, vertex1:secondo Vertex3D)
var xAxis:Line3D = new Line3D(axes, xAxisMaterial, 2, origin, new Vertex3D(100, 0, 0));
var yAxis:Line3D = new Line3D(axes, yAxisMaterial, 2, origin, new Vertex3D(0, 100, 0));
var zAxis:Line3D = new Line3D(axes, zAxisMaterial, 2, origin, new Vertex3D(0, 0, 100));// Aggiungi le linee al contenitore Lines3D precedentemente realizzato
axes.addLine(xAxis);
axes.addLine(yAxis);
axes.addLine(zAxis);// aggiungi poi gli oggetti e il contenitore di linee alla scena
scene.addChild(conoDiEsempio);
scene.addChild(sphere);
scene.addChild(axes);
}private function loop(event:Event):void {
//renderizziamo la scena (ogni fotogramma) sfruttando il renderer prima creato.
//In questo caso non servirebbe renderizzare ogni fotogramma, perchè non vi sono
//movimenti o interazioni, ma è meglio prendersi questa abitudine.
renderer.renderScene(scene, camera, viewport);
}
}
}
Ottobre 17th, 2008 at 18:44
Grazie mille
Good blog you got going here!
Aprile 2nd, 2009 at 10:36
Ottimo esempio … continuo a leggere