Vediamo ora come è possibile inserire delle immagini come materiali che avvolgano gli oggetti 3D della scena papervision. Ovviamente è possibile applicare anche dei video o dei filmati swf come texture. L’effetto è sicuramente stupefacente e le possibilità di utilizzo vanno aldilà dell’immaginazione.

In questo tutorial ci concentreremo più che altro sull’implementazione della tecnica per il texture mapping in papervision 3D, senza entrare troppo in un discorso estetico o grafico. Inoltre vedremo come applicare degli eventi differenti al CLICK del mouse su ogni oggetto differente ed accenneremo dell’interattività attraverso l’uso della tastiera (precisamente delle frecce).

Il risultato completo che si vuole raggiungere è questo:

Il video presenta il volume a zero per scelta personale, in ogni caso la riproduzione dell’audio del video non pone alcun problema di efficenza.

Vediamo come è sviluppato il progetto. Prima di iniziare l’analisi del codice disposto in un file esterno .as, dobbiamo concentrarci stavolta sul file .fla che andiamo a creare in Adobe Flash. Ovviamente deve essere un file Flash actionscript 3, deve presentare come Classe Documento (nel pannello Proprietà) il nome del file .as che dopo andremo a creare (senza estensione .as).

In più stavolta dobbiamo importare le nostre immagini (o video), che vogliamo trasformare in texture 3D, nella libreria di Flash. Quindi clicchiamo su File - Importa - Importa nella libreria, scegliamo la foto e la inseriamo. Dopodichè bisogna selezionare la foto dalla libreria, cliccare col tasto destro del mouse e premere su “concatenamento”, cliccare ancora su “Esporta per Actionscript” ed inseriamo nella “classe” il nome che utilizzaremo nel codice actionscript per richiamare tale elemento della libreria (in questo caso il nome è “immagine” ed è quello che useremo nel file .as correlato).

Il procedimento è obbligatorio da compiere; in poche parole si attribuisce un nome (riconoscibile da actionscript) alla foto della libreria ed, attraverso questo nome, l’elemento diviene utilizzare nel codice.

Screenshot del procedimento in Flash

Screenshot del procedimento in Flash

Ora possiamo sviluppare il codice:

package {

//autore: www.enricoviola.it/blog
//——————————-
//Guida personale a Papervision3D

//importiamo le classi necessarie
import caurina.transitions.Tweener;

import flash.display.Bitmap;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
//le seguenti 2 classi servono per caricare l’immagine
import flash.display.Loader;
import flash.net.URLRequest;
import flash.display.Sprite;

import org.papervision3d.events.InteractiveScene3DEvent;
//le seguenti 2 classi servono per applicare i materiali agli oggetti
import org.papervision3d.materials.BitmapMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.view.BasicView;
import org.papervision3d.materials.BitmapAssetMaterial;
import org.papervision3d.materials.MovieAssetMaterial;

//riutilizziamo il BasicView per velocizzare
public class esempio5 extends BasicView {

//la BitmapAssetMaterial è una sottoclasse della
//BitmapMaterial che permette il caricamento di istanze
//di immagini presenti nella libreria del file .fla

private var bitmapMaterial:BitmapAssetMaterial = new BitmapAssetMaterial(”immagine”);
//la differenza fra questo materiale e il precedente è nella
//piastrellazione, ossia si indica prima se riempire la texture con
//più facce affiancate, poi quante facce orizzontali e verticali.

private var piastrellatoBitmapMaterial:BitmapAssetMaterial = new BitmapAssetMaterial(”immagine”);
//creiamo una texture con un movieclip presente nella libreria
//di Flash, bisogna sempre collegarla al nome di concatenamento

private var MoviebitmapMaterial:MovieAssetMaterial = new MovieAssetMaterial(”movieclip”, false, true);
//creiamo una texture con un movieclip che include un video presente
//nella libreria, bisogna sempre collegarla al nome di concatenamento

private var VideobitmapMaterial:MovieAssetMaterial = new MovieAssetMaterial(”video”, false, true);

private var cubo:Cube;
private var cono:Cone;
private var sfera:Sphere;
private var cilindro:Cylinder;
private var objectGroup:DisplayObject3D;

//impostiamo come false le variabili booleane utili per avviare
//i movimenti al click di un tasto al trascinamento del mouse.

private var inRotazione:Boolean = false;
private var vaiAvanti:Boolean = false;
private var vaiIndietro:Boolean = false;
private var vaiDestra:Boolean = false;
private var vaiSinistra:Boolean = false;
private var ultimoMouseX:int;
private var ultimoMouseY:int;
private var cameraPitch:Number = 60;
private var cameraYaw:Number = -90;

public function esempio5() {
super(0, 0, true, true);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
init3D();
createScene();
//aggiungiamo i listener per il mouse e
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseGiu);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseSu);
//i listener per la tastiera, in questo caso si creano 2
//listener per il tasto premuto e per quando viene rilasciato
//la funzione “tasto premuto” andrà a verificare il codice del
//tasto premuto ed effettuare differenti azioni per differenti
//tasti premuti.

stage.addEventListener(KeyboardEvent.KEY_DOWN, tastoPremuto);
stage.addEventListener(KeyboardEvent.KEY_UP, tastoRilasciato);

startRendering();
}

private function init3D():void {
camera.z = -500;
//il 1° valore rappresenta la rotazione attorno l’asse
//orizzontale X, il 2° attorno all’asse verticale Y

camera.orbit(60, -90);
}

private function createScene():void {

//attiviamo l’interattività del materiale
bitmapMaterial.interactive = true;

//attiviamo l’interattività del materiale
piastrellatoBitmapMaterial.interactive = true;
piastrellatoBitmapMaterial.tiled = true;
piastrellatoBitmapMaterial.maxU = 3;
piastrellatoBitmapMaterial.maxV = 3;

MoviebitmapMaterial.interactive = true;
VideobitmapMaterial.interactive = true;

//creiamo gli oggetti con i materiali bitmap, il Cubo và
//rivestito, a differenza degli altri oggetti 3D, con un
//materiale della classe “MaterialsList”, per far ciò
//attiviamo la funzione “cuboBitmapMaterial(bitmapMaterial)”
//per trasformare il BitmapAssetMaterial in MaterialsList.

cubo = new Cube(cuboBitmapMaterial(bitmapMaterial), 100, 100, 100);
cubo.x = 175;
//agli altri oggetti 3D possiamo applicare direttamente i materiali
//speciali senza alcuna preventiva trasformazione

cono = new Cone(MoviebitmapMaterial, 50, 100, 10, 10);
cono.x = -50;
sfera = new Sphere(VideobitmapMaterial, 50, 10, 10);
sfera.x =  50;
cilindro = new Cylinder(piastrellatoBitmapMaterial, 50, 100);
cilindro.x = -175;
objectGroup = new DisplayObject3D();
objectGroup.addChild(cubo);
objectGroup.addChild(cono);
objectGroup.addChild(sfera);
objectGroup.addChild(cilindro);
//aggiungiamo dei listener per ognuno degli oggetti, in
//modo da creare un movimento-rimbalzo in 4 direzioni diverse

cubo.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, mouseClick1);
cono.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, mouseClick2);
sfera.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, mouseClick3);
cilindro.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, mouseClick4);

scene.addChild(objectGroup);
}

private function cuboBitmapMaterial(bitmapMaterial:BitmapMaterial):MaterialsList {
//sfruttiamo ora tale funzione per trasformare il BitmapAssetMaterial
//in MaterialsList, adatto ad essere applicato su un cubo

var materialeList:MaterialsList = new MaterialsList();
materialeList.addMaterial(bitmapMaterial, “all”);

//per rendere efficace la funzione cuboBitmapMaterial
//bisogna rielaborare la funzione di creazione del cubo,
//quindi effettua un return del risultato.

return materialeList;
}

override protected function onRenderTick(event:Event=null):void {
//rotazione degli oggetti
cubo.yaw(-3);
cono.yaw(-3);
sfera.yaw(-3);
cilindro.yaw( -3);

//stesso procedimento già analizzato per il trascinamento
//della scena 3D al CLICK mantenuto dal mouse

if (inRotazione) {
var dPitch:Number = (mouseY - ultimoMouseY) / 2;
var dYaw:Number = (mouseX - ultimoMouseX) / 2;
cameraPitch -= dPitch;
cameraYaw -= dYaw;
if (cameraPitch <= 0) {
cameraPitch = 0.1;
} else if (cameraPitch >= 180) {
cameraPitch = 179.9;
}
ultimoMouseX = mouseX;
ultimoMouseY = mouseY;
camera.orbit(cameraPitch, cameraYaw);
}

//inseriamo i movimenti in caso di pressione dei tasti
//freccia della tastiera, vediamo come il movimento avviene
//nell’asse Z (avanti e indietro) e asse X.

if (vaiAvanti) {
camera.z += 5;
}
if (vaiIndietro) {
camera.z -= 5;
}
if (vaiDestra) {
camera.x += 5;
}
if (vaiSinistra) {
camera.x -= 5;
}
//renderizziamo il tutto ogni frame
super.onRenderTick(event);
}

private function mouseGiu(event:MouseEvent):void {
inRotazione = true;
ultimoMouseX = event.stageX;
ultimoMouseY = event.stageY;
}

private function mouseSu(event:MouseEvent):void {
inRotazione = false;
}

//tali funzioni sono richiamate ad ogni CLICK su ogni
//differente oggetto tridimensionale, queste 3 prime
//funzioni spostano l’oggetto verticalmente, le altre 3
//lo spostano lungo l’asse Z

private function mouseClick1(event:InteractiveScene3DEvent):void {
var object:DisplayObject3D = event.displayObject3D;
Tweener.addTween(object, {y:200, time:1, transition:”easeOutSine”, onComplete:function():void {indietroY(object);} });
}
private function indietroY(object:DisplayObject3D):void {
Tweener.addTween(object, {y:0, time:2, transition:”easeOutBounce”});
}
private function mouseClick2(event:InteractiveScene3DEvent):void {
var object:DisplayObject3D = event.displayObject3D;
Tweener.addTween(object, { y: -200, time:1, transition:”easeOutSine”, onComplete:function():void { indietroY(object); } } );
}
private function mouseClick3(event:InteractiveScene3DEvent):void {
var object:DisplayObject3D = event.displayObject3D;
Tweener.addTween(object, { z:200, time:1, transition:”easeOutSine”, onComplete:function():void { indietroX(object); } } );
}
private function indietroX(object:DisplayObject3D):void {
Tweener.addTween(object, {z:0, time:2, transition:”easeOutBounce”});
}
private function mouseClick4(event:InteractiveScene3DEvent):void {
var object:DisplayObject3D = event.displayObject3D;
Tweener.addTween(object, {z:-200, time:1, transition:”easeOutSine”, onComplete:function():void {indietroX(object);} });
}
//funzione di riconoscimento del tasto premuto alla
//pressione di un tasto, si usa la classe flash.ui.Keyboard

private function tastoPremuto(event:KeyboardEvent):void {
switch (event.keyCode) {
case Keyboard.UP :
vaiAvanti = true;
break;
case Keyboard.DOWN :
vaiIndietro = true;
break;
case Keyboard.LEFT :
vaiSinistra = true;
break;
case Keyboard.RIGHT :
vaiDestra = true;
break;
default:
break;
}
}
//al rilascio falsifichiamo le variabili rese vere nella
//funzione tasto premuto per il movimento.

private function tastoRilasciato(event:KeyboardEvent):void {
vaiAvanti = false;
vaiIndietro = false;
vaiDestra = false;
vaiSinistra = false;
}
}
}

File sorgenti del progetto, ricordate di cambiare il link al filmato all’interno componente FLVplayback di Flash, poichè, essendo sistestamato il video on-line, in locale non funziona.

2 risposte to “Papervision 3D - La mia Guida - parte 5 - La texture mapping”

  1. Claudio Says:

    Ciao Enrico,
    ho un dilemma in papervision.
    Qualche giorno fa ho visto un tutorial (sembrava abbastanza semplice) dove spiegavano come non far deformare (o muovere) i materiali quando l’oggetto 3d si muove. Sembrava parlassero di una proprietà ma non ricordo bene.
    Sai come fare? Non riesco più a trovare il tutorial e sono venuto a fare un giro qui da te.
    Grazie
    Cla

  2. admin Says:

    Ciao Claudio,
    forse ti riferisci a questo articolo: http://blog.zupko.info/?p=177
    Se non è questo, non problem, mi ricordo che il questo sito (il grande zupko, espertissimo in PV3D) c’era qualcosa che spiegasse come non deformare i materiali.
    Il problema è che i tutorial qui non sono per niente semplici.
    Spero presto di ritornare con qualche tutorials su Papervision (almeno per riscalare google sull’argomento), speravo che uscisse PVX per riniziare, ma questa nuova release si fà veramente aspettare.
    Bye

Leave a Reply