Es gibt verschiedene Arten 3D Inhalte mit Actionscript darzustellen. Für einfache grundlegende Darstellungen gibt es einmal die AS3 Möglichkeiten von Actionscript. Will man komplexere Dinge darstellen kann man auf verschiedene Frameworkszurückgreifen, beispielsweise Papervision 3D, welche die Funktionalitäten und Möglichkeiten erweitern. In der Flash IDE gibt es auch ein paar 3D Werkzeuge für die Positionierung und Drehung im Raum.
Hilfe bei Adobe
in derAdobe Hilfe ist alles sehr schön erklärt hier einige wichtige Punkte:
Um ein zweidimensionales in ein dreidimensionales Anzeigeobjekt zu konvertieren, können Sie seine z-Eigenschaft explizit auf einen numerischen Wert setzen.
leaf.x = 100; leaf.y = 50; leaf.z = -30;
Auch die Drehung im 3dimensionalen Raum lässt sich definieren:
myMc.rotationX=20; myMc.rotationY=20; myMc.rotationZ=20;
root.transform.perspectiveProjection.fieldOfView=180;
Dadurch können Sie erreichen, dass ein dreidimensionales Anzeigeobjekt, das sich dem Betrachter nähert, größer erscheint und ein Objekt, das sich entfernt, kleiner. Bei einem niedrigen fieldOfView-Wert werden die Objekte nur wenig verkleinert und scheinen sich nur leicht in den Hintergrund zu bewegen. Bei einem hohen fieldOfView-Wert werden die Objekte stärker verzerrt und auch der Eindruck von Bewegung ist stärker. Der Höchstwert von 180 Grad resultiert in einem extremen Fischauge-Kameralinseneffekt.
root.transform.perspectiveProjection.projectionCenter=new Point(mouseX,mouseY);
Der Fluchtpunkt auf den scheinbar alle perspektivischen Linien führen.
root.transform.perspectiveProjection.focalLength=mouseX;
Die Eigenschaft focalLength repräsentiert die Brennweite, also den Abstand zwischen dem Standort des Betrachters (0,0,0) und dem Bildschirm. Eine lange Brennweite ist wie ein Teleobjektiv mit Nahsicht und verkürzten Entfernungen zwischen den Objekten. Eine kurze Brennweite ist wie ein Weitwinkelobjektiv.
Im folgenden Beispiel müssen ein paar MCs mit 3D Eigenschaften hinzugefügt werden. Außerdem sollte auch der Hintergrund nicht leer sein, da sonst MouseMove nicht funktioniert.
function moveCenter(evt:MouseEvent):void { root.transform.perspectiveProjection.projectionCenter=new Point(mouseX,mouseY); } this.addEventListener(MouseEvent.MOUSE_MOVE, moveCenter);
Auch dieses Beispiel gibt es in ähnlicher Form auf der oben erwähnten Adobe Seite. Es geht um die Anordnung auf der Z-Achse, gemäß der 3D Position im Raum. Vorraussetzung ist eine MovieClip Klasse namens Ellipse.
var faces:Array = new Array(); for (var i:uint=0; i<10; i++) { var ellip:Ellipse = new Ellipse(); ellip.x=100; ellip.y=50*i+30; ellip.z=50*i+20; faces.push(ellip); addChild(ellip); } function ReorderChildren(evt:MouseEvent):void { root.transform.perspectiveProjection.projectionCenter=new Point(mouseX,mouseY); for (var ind:uint = 0; ind < faces.length; ind++) { faces[ind].z=faces[ind].transform.getRelativeMatrix3D(root).position.z; trace(faces[ind].transform.getRelativeMatrix3D(root).position.z); this.removeChild(faces[ind]); } faces.sortOn("z", Array.NUMERIC | Array.DESCENDING); for (ind = 0; ind < faces.length; ind++) { this.addChild(faces[ind]); } } this.addEventListener(MouseEvent.MOUSE_DOWN, ReorderChildren);
Papervision ist ein Framework (Klassenstruktur), welches als open Source Project von vielen Codern erstellt, verändert und erweitert wird. Von daher gibt es verschiedene Versionen. Einige Coder verfolgen einen eigenen Weg, der eventuell von anderen weiterverfolgt wird oder irgendwo endet. So kann man sich diese Versionen wie den Stamm und die Äste eines Baumes vorstellen. Neben dem Stamm (Trunk), der die Hauptlinie oder die herkömmlichen Versionen eines Programmes repräsentiert, gibt es eben auch verschiedene Abzweigungen, Äste (branch).
Es gibt sehr viele Tutorials zu Papervision. Es macht Sinn darauf zu achten, dass das Tutorial zur aktuellesten Version von Papervision passt. Um einen Überblick zu erhalten, welche Version nun die "aktuelleste" ist, kann man sich das Hilfsmittel Turtoise SVN zur Hilfe nehmen, welches den Download managed. Wie das funktioniert wird bei madvertices anschaulich erklärt.
Für den Einstieg empfehle ich folgende Seiten:
http://www.packtpub.com/ Buchtipp
Legt euch irgendwo einen Ordner an, in dem ihr alle Klassen, die ihr öfter benötigt hinterlegt. Legt euch innerhalb dieses Ordners einen Ordner an und nennt ihn beispielsweise "papervision3D".
Nun könnt ihr entweder eure Klassen im Netz runterladen und dort entpacken oder ihr nehmt das Tool Turtoise SVN http://tortoisesvn.net/downloads und installiert es. Dann klickt ihr mit rechter Maustaste auf den Ordner "papervision3D" und wählt "SVN Checkout" Gebt beispielsweise folgende Adresse ein und klickt auf okay.
http://papervision3d.googlecode.com/svn/trunk/ Die Adresse findet ihr bei http://code.google.com/p/papervision3d/source/checkout
Nachdem alle Dateien runtergeladen worden sind, müsst ihr diese nur noch in Flash importieren. Vorsicht ist geboten, wenn man neuere Versionen von Papervison läd. Hierbei muss man natürlich darauf achten, dass alte Projekte mit neueren Versionen nicht funktionieren.
Geht auf Berabeiten / Voreinstellungen / Actionscript / Actionscript 3, Klickt auf das Pluszeichen und gebt den Pfad zu dem "papervision3D" Ordner auf eurer Festplatte an. Dann könnt ihr die Import Anweisungen aus meinen Klassendateien genauso übernehmen. Anhand der Import Anweisung könnt ihr auch die Ordnerstruktur erkennen, die in dem "papervision3D" Ordner liegt.
Zum Beispiel: eine Import Anweisung auf das ColorMaterial müsste so aussehen:
import org.papervision3d.materials.ColorMaterial;
Es folgen die wichtigsten Importanweisungen für die Darstellung einer einfachen Fläche (Plane). Mit der Klasse BasicView kann man auf diese Importanweisungen verzichten, da diese in BasicView enthalten sind.
import flash.display.Sprite; import flash.events.Event; import org.papervision3d.view.Viewport3D; import org.papervision3d.scenes.Scene3D; import org.papervision3d.cameras.Camera3D; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.render.BasicRenderEngine;
Schauen wir uns diese Klassen mal in den Referenzen an:
Viewport3D
viewport = new Viewport3D(Breite, Höhe, autoScaleToStage, interactive);
scaleToStage (boolean) Standard=false passt sich der Größe der Bühne an, wenn die Bühnengröße sich verändert
interactive (boolean) Standard= false, bestimmt ob Viewport auf MouseEvents hört, wenn man einen InteractiveSceneManager erstellt.
Scene3D
Eine Szene in der alle Objekte gerendert werden
Camera3D
Camera3D(fov:Number = 60, near:Number = 10, far:Number = 5000, useCulling:Boolean = false, useProjection:Boolean = false)
fov: Field of View oder Focus
materials
Hierzu gibt es ein ausführliches Tutorial bei madvertices
objects.primitives
object.primitves sind verschiedene Grundformen wie Plane (Fläche), cube (Würfel), cone(Zylinder) etc.
render
Mit render.BasicRenderEngine werden 3D Sachen gerendert oder sichtbar gemacht. Beispiel:
private var renderer:BasicRenderEngine;
renderer = new BasicRenderEngine();
Normalerweise wird in einer onEnterFrame Anweisung die render-Anweisung ausgeführt:
renderer.renderScene(scene, camera, viewport);
Hier nun eine Documentklasse namens Plain1. In der Bibliothek der fla muss sich ein MovieClip mit Klassennamen "quad" befinden. Dieser wird als Material für das Plane Objekt benutzt.
package { import flash.display.Sprite; import flash.events.Event; import flash.geom.Rectangle; import org.papervision3d.view.Viewport3D; import org.papervision3d.scenes.Scene3D; import org.papervision3d.cameras.Camera3D; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.MovieMaterial; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.render.BasicRenderEngine; public class Plane1 extends Sprite { private var viewport:Viewport3D; private var scene:Scene3D; private var camera:Camera3D; private var material:MovieMaterial; private var primitive:Plane; private var renderer:BasicRenderEngine; //ein MovieClip in der Bibliothek mit Klassennamen "quad" private var mcMaterial:quad = new quad(); public function Plane1():void { //viewport = new BasicRenderEngine(Breite, Höhe, autoScaleToStage, interactive); viewport=new Viewport3D(550,400,false,true); addChild(viewport); //instanziiert eine Scene3D Instanz scene = new Scene3D(); //instanziiert eine Camera3D Instanz camera = new Camera3D(); //renderer zeichnete die Scene auf die Bühne renderer = new BasicRenderEngine(); //MovieMaterial, doubleSided zeichnet das Material auf beide Seite der Plane Instanz material=new MovieMaterial(mcMaterial,false,true,true); material.doubleSided=true; material.smooth=true; //primitive = new Plane(material applied to object, width, height, wSegments, hSegments); primitive=new Plane(material,400,400,3,3); scene.addChild(primitive); // enterFrame event listener addEventListener(Event.ENTER_FRAME, onEnterFrame); //definieren der EnterFrame Methode um Ansicht zu aktualisieren function onEnterFrame(e:Event):void { var yDist:Number=mouseY-stage.stageHeight*0.5; var xDist:Number=(360/stage.stageWidth)*mouseX; primitive.rotationY=xDist; primitive.rotationX+=yDist*0.02; renderer.renderScene(scene, camera, viewport); } } } }
BasicView
BasicView ist eine Klasse oder ein Template, welche die Grundeinstellungen für ein papervision3D Projekt zur Verfügung stellt. Es enthält viewport, scene, camera, and renderer, siehe Referenzen Näheres zu Basic View siehe madvertices
package { import flash.events.Event; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.view.BasicView; /** * ... * @author Charlie Schulze, charlie[at]woveninteractive[dot]com */ public class Plane2 extends BasicView { protected var plane:Plane; protected var colorMaterial:ColorMaterial; public function Plane2():void { super(); //material erschaffen mit Eigenschaft doubleSided=true colorMaterial = new ColorMaterial(0xFF0000, .5); colorMaterial.doubleSided = true; //Plane Instanz und colorMaterial, Breite und Höhe zuweisen plane = new Plane(colorMaterial, 400,400); scene.addChild(plane); // rendering starten startRendering(); } override protected function onRenderTick(event:Event = null):void { super.onRenderTick(event); //plane drehen, yaw, pitch, roll = Drehung auf Achsen plane.yaw(2); } } }
Im folgenden Beispiel einer Dokumentenklasse werden 4 verschiedene Materialarten zugewiesen.
MovieAssetMaterial erwartet den Klassennamen eines in der Bibliothek befindlichen Movieclips als String oder den Instanznamen eines MCs (nicht als String).
BitmapFileMaterial erwartet eine URL, die auf das Bild verweist.
package { import flash.events.Event; import org.papervision3d.materials.*; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.view.BasicView; public class Material1 extends BasicView { protected var plane1:Plane; protected var plane2:Plane; protected var plane3:Plane; protected var plane4:Plane; protected var colorMaterial:ColorMaterial; protected var wireframeMaterial:WireframeMaterial; protected var movieAssetMaterial:MovieAssetMaterial; protected var bitmapFileMaterial:BitmapFileMaterial; public function Material1():void { super(); //material erschaffen mit Eigenschaft doubleSided=true colorMaterial=new ColorMaterial(0xFF0000,.5); colorMaterial.doubleSided=true; wireframeMaterial=new WireframeMaterial(0xff22aa); wireframeMaterial.doubleSided=true; //myMaterial Klassenname (linkage Id) des Movieclips movieAssetMaterial=new MovieAssetMaterial("myMaterial",false); movieAssetMaterial.animated=true; movieAssetMaterial.doubleSided=true; movieAssetMaterial.smooth=true; //url auf ein Bild bitmapFileMaterial=new BitmapFileMaterial("http://www.on-design.de/images/smallich.jpg"); bitmapFileMaterial.doubleSided=true; //Plane Instanz und colorMaterial, Breite und Höhe zuweisen plane1=new Plane(colorMaterial,100,100); plane2=new Plane(wireframeMaterial,100,100,5,5); plane3=new Plane(movieAssetMaterial,100,100); plane4=new Plane(bitmapFileMaterial,100,100); plane1.x=-200; plane2.x=-70; plane3.x=40; plane4.x=200; scene.addChild(plane1); scene.addChild(plane2); scene.addChild(plane3); scene.addChild(plane4); camera.focus=20; // rendering starten startRendering(); } override protected function onRenderTick(event:Event = null):void { super.onRenderTick(event); //plane drehen, yaw, pitch, roll = Drehung auf Achsen plane1.yaw(2); plane2.roll(2); plane3.pitch(2); plane4.yaw(2); plane4.roll(2); plane4.pitch(2); } } }
sphere = new Sphere(material applied to object, radius, wSegments, hSegments);
package { import flash.events.Event; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.materials.*; import org.papervision3d.view.BasicView; public class Sphere1 extends BasicView { private var sphere:Sphere; protected var movieAssetMaterial:MovieAssetMaterial; public function Sphere1():void { super(); //material erschaffen mit Eigenschaft doubleSided=true movieAssetMaterial=new MovieAssetMaterial("myMaterial"); movieAssetMaterial.smooth=true; //sphere = new Sphere(material applied to object, radius, wSegments, hSegments); sphere=new Sphere(movieAssetMaterial,150,10,10); scene.addChild(sphere); camera.focus=20; // rendering starten startRendering(); } override protected function onRenderTick(event:Event=null):void { super.onRenderTick(event); var xDist:Number=mouseX-stage.stageWidth*0.5; var yDist:Number=mouseY-stage.stageHeight*0.5; sphere.rotationY+=xDist*0.02; sphere.rotationX+=yDist*0.02; } } }
cylinder = new Cylinder(material applied to object, radius, height, wSegments, hSegments, topRadius);
package { import flash.events.Event; import org.papervision3d.objects.primitives.Cylinder; import org.papervision3d.materials.*; import org.papervision3d.view.BasicView; public class Cylinder1 extends BasicView { private var cylinder:Cylinder; protected var movieAssetMaterial:MovieAssetMaterial; public function Cylinder1():void { super(); //material erschaffen mit Eigenschaft doubleSided=true movieAssetMaterial=new MovieAssetMaterial("myMaterial"); movieAssetMaterial.smooth=true; //cylinder = new Sphere(material applied to object, radius, wSegments, hSegments); cylinder = new Cylinder(movieAssetMaterial, 120, 250, 8, 3, 120); scene.addChild(cylinder); scene.addChild(cylinder); camera.focus=20; // rendering starten startRendering(); } override protected function onRenderTick(event:Event=null):void { super.onRenderTick(event); var xDist:Number=mouseX-stage.stageWidth*0.5; var yDist:Number=mouseY-stage.stageHeight*0.5; cylinder.rotationY+=xDist*0.02; cylinder.rotationX+=yDist*0.02; } } }
cone = new Cone(material applied to object, radius, height, wSegments, hSegments, topRadius);
package { import flash.events.Event; import org.papervision3d.objects.primitives.Cone; import org.papervision3d.materials.*; import org.papervision3d.view.BasicView; public class Cone1 extends BasicView { private var cone:Cone; protected var movieAssetMaterial:MovieAssetMaterial; public function Cone1():void { super(); //material erschaffen mit Eigenschaft doubleSided=true movieAssetMaterial=new MovieAssetMaterial("myMaterial"); movieAssetMaterial.smooth=true; //cone cone=new Cone(movieAssetMaterial,120,250,8,3); scene.addChild(cone); camera.focus=20; // rendering starten startRendering(); } override protected function onRenderTick(event:Event=null):void { super.onRenderTick(event); var xDist:Number=mouseX-stage.stageWidth*0.5; var yDist:Number=mouseY-stage.stageHeight*0.5; cone.rotationY+=xDist*0.02; cone.rotationX+=yDist*0.02; } } }
Hier erstellen wir einen Würfel (Cube). In der Bibliothek der fla befinden sich MovieClips mit den Klassennamen face1, face2...etc. Diese werden für die MaterialList des Cubes benötigt.
package { import flash.events.Event; import org.papervision3d.materials.*; import org.papervision3d.materials.utils.*; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.view.BasicView; /** * ... * @author Michael Albers, mail[at]pastorpixel[dot]de */ public class Cube1 extends BasicView { protected var cube:Cube; public function Cube1():void { super(); //material für jede Seite erschaffen var mm1:MovieAssetMaterial=new MovieAssetMaterial("face1"); mm1.smooth=true; var mm2:MovieAssetMaterial=new MovieAssetMaterial("face2"); mm2.smooth=true; var mm3:MovieAssetMaterial=new MovieAssetMaterial("face3"); mm3.smooth=true; var mm4:MovieAssetMaterial=new MovieAssetMaterial("face4"); mm4.smooth=true; var mm5:MovieAssetMaterial=new MovieAssetMaterial("face5"); mm5.smooth=true; var mm6:MovieAssetMaterial=new MovieAssetMaterial("face6"); mm6.smooth=true; //Cube Instanz MaterialList für jede Seite, Breite, Höhe, Tiefe, verices/Flächen zuweisen cube=new Cube(new MaterialsList({front:mm1,left:mm2,right:mm3,top:mm4,bottom:mm5,back:mm6}),200,200,200,10,10); scene.addChild(cube); camera.focus=30; // rendering starten startRendering(); } override protected function onRenderTick(event:Event = null):void { super.onRenderTick(event); //cube drehen var xDist:Number=mouseX-stage.stageWidth*0.5; var yDist:Number=mouseY-stage.stageHeight*0.5; cube.rotationY+=xDist*0.02; cube.rotationX+=yDist*0.02; } } }
Die MaterialsList könnte man auch in einer Schleife erzeugen. Hier der Konstruktor des gleichen Beispiels mit einer for-Schleife
public function Cube2():void { super(); //Array mit den Bezeichnungen der Seiten von Cube var sides:Array=new Array("front","back","left","right","top","bottom"); matList= new MaterialsList(); //die MC Klassennamen in der Bibliothek , welche die Bilder enthalten //heißen face1, face2....face6 //addMaterial(MaterialsObject3D, Name hier die Seiten des Cubes) for (var i:uint=1; i<=6; i++) { matList.addMaterial( new MovieAssetMaterial("face"+String(i)), sides[(i-1)] ); } //MaterialsList, Breite, Höhe, Tiefe, Anzahl der Flächen cube=new Cube(matList,200,200,200,10,10); scene.addChild(cube); camera.focus=30; // rendering starten startRendering(); }
Es gibt die Möglichkeit die 3D-Objekte mit Click-Events zu versehen. Diese Möglichkeit wird später vorgestellt. Vorab habe ich hier eine Möglichkeit erstellt das Material anklickbar zu machen. Es wird zuerst eine Instanz einer MovieClip-Klasse aus der Bibliothek erstellt, welche später für eine Instanz von MovieMaterial benötigt wird. Das Ganze wird jeweils 6 mal gemacht für alle Flächen des Würfels. In den folgenden Erklärungen beschränke ich mich auf eine Instanz. Ich habe in diesem Beispiel auf Schleifen verzichtet, damit es etwas einfacher zu verstehen ist.
var f1:face1 = new face1();
Diese wird mit addChild() auf die Bühne gebracht und dann unsichtbar gemacht, da der Movieclip nicht auf der Bühne sichtbar sein soll, sonder nur innerhalb des Materials.
addChild(f1);
f1.visible=false;
Nun wird eine Instanz von MovieMaterial erstellt und die Movieclip Instanz dort zugewiesen. Außerdem wird der Movieclip Instanz "f1" der Event Listener zugewiesen, der die entsprechende Funktion aufruft, "faceClick1" (siehe unten);
var mm1:MovieMaterial=new MovieMaterial(f1,false,false,true);
mm1.interactive=true;
f1.addEventListener(MouseEvent.CLICK, faceClick1);
function faceClick1(evt:MouseEvent):void { navigateToURL( new URLRequest("http://www.on-design.de/jukeart/illu/darx.html")); }
Eine Cube Instanz wird erzeugt welche eine MaterialsList bekommt, in der alle Instanzen von MovieMaterial zugewiesen werden.
cube=new Cube(new MaterialsList({front:mm1,left:mm2,right:mm3,top:mm4,bottom:mm5,back:mm6}),400,400,400,10,10);
scene.addChild(cube);
package { import flash.display.Sprite; import flash.events.*; import flash.events.MouseEvent; import flash.net.navigateToURL; import flash.net.URLRequest; import org.papervision3d.view.Viewport3D; import org.papervision3d.scenes.Scene3D; import org.papervision3d.cameras.Camera3D; import org.papervision3d.materials.MovieMaterial; import org.papervision3d.materials.*; import org.papervision3d.materials.utils.*; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.render.BasicRenderEngine; public class Cube3 extends Sprite { protected var cube:Cube; protected var matList:MaterialsList; private var viewport:Viewport3D; private var scene:Scene3D; private var camera:Camera3D; private var renderer:BasicRenderEngine; public function Cube3():void { //viewport = new BasicRenderEngine(width, height, scaleToStage, interactive); viewport=new Viewport3D(550,400,false,true); addChild(viewport); //instantiates a Scene3D instance scene = new Scene3D(); //instantiates a Camera3D instance camera = new Camera3D(); //renderer draws the scene to the stage renderer = new BasicRenderEngine(); //die MC Klassennamen in der Bibliothek , welche die Bilder enthalten //heißen face1, face2....face6 var f1:face1 = new face1(); var f2:face2 = new face2(); var f3:face3 = new face3(); var f4:face4 = new face4(); var f5:face5 = new face5(); var f6:face6 = new face6(); addChild(f1); addChild(f2); addChild(f3); addChild(f4); addChild(f5); addChild(f6); f1.visible=false; f2.visible=false; f3.visible=false; f4.visible=false; f5.visible=false; f6.visible=false; var mm1:MovieMaterial=new MovieMaterial(f1,false,false,true); var mm2:MovieMaterial=new MovieMaterial(f2,false,false,true); var mm3:MovieMaterial=new MovieMaterial(f3,false,false,true); var mm4:MovieMaterial=new MovieMaterial(f4,false,false,true); var mm5:MovieMaterial=new MovieMaterial(f5,false,false,true); var mm6:MovieMaterial=new MovieMaterial(f6,false,false,true); mm1.interactive=true; mm2.interactive=true; mm3.interactive=true; mm4.interactive=true; mm5.interactive=true; mm6.interactive=true; f1.addEventListener(MouseEvent.CLICK, faceClick1); function faceClick1(evt:MouseEvent):void { navigateToURL( new URLRequest("http://www.on-design.de/jukeart/illu/darx.html"),"_self"); } f2.addEventListener(MouseEvent.CLICK, faceClick2); function faceClick2(evt:MouseEvent):void { navigateToURL( new URLRequest("http://www.on-design.de/jukeart/illu/conc3.html"),"_self"); } f3.addEventListener(MouseEvent.CLICK, faceClick3); function faceClick3(evt:MouseEvent):void { navigateToURL( new URLRequest("http://www.on-design.de/jukeart/illu/guitbal1.html"),"_self"); } f4.addEventListener(MouseEvent.CLICK, faceClick4); function faceClick4(evt:MouseEvent):void { navigateToURL( new URLRequest("http://www.on-design.de/jukeart/illu/conc2.html"),"_self"); } f5.addEventListener(MouseEvent.CLICK, faceClick5); function faceClick5(evt:MouseEvent):void { navigateToURL( new URLRequest("http://www.on-design.de/jukeart/illu/conc1.html"),"_self"); } f6.addEventListener(MouseEvent.CLICK, faceClick6); function faceClick6(evt:MouseEvent):void { navigateToURL( new URLRequest("http://www.on-design.de/jukeart/illu/guitbal2.html"),"_self"); } cube=new Cube(new MaterialsList({front:mm1,left:mm2,right:mm3,top:mm4,bottom:mm5,back:mm6}),400,400,400,10,10); scene.addChild(cube); addEventListener(Event.ENTER_FRAME, onEnterFrame); function onEnterFrame(e:Event):void { var xDist:Number=mouseX-stage.stageWidth*0.5; var yDist:Number=mouseY-stage.stageHeight*0.5; cube.rotationY+=xDist*0.02; cube.rotationX+=yDist*0.02; renderer.renderScene(scene, camera, viewport); } } } }
Hier ein fast identisches Beispiel mit dem Unterschied, dass anstatt des ellenlangen Codes eine for-Schleife eingesetzt wird. Einen Unterschied gibt es auch in der fla. Hier gibt es nur eine Movieclip Klasse die alle Bilder enthält. Der Klassenname ist "Cover". Die Bilder liegen in den ersten 6 Schlüsselbildern der Zeitleiste.
package { import flash.display.Sprite; import flash.events.*; import flash.events.MouseEvent; import flash.net.navigateToURL; import flash.net.URLRequest; import flash.display.*; import flash.utils.*; import org.papervision3d.view.Viewport3D; import org.papervision3d.scenes.Scene3D; import org.papervision3d.cameras.Camera3D; import org.papervision3d.materials.MovieMaterial; import org.papervision3d.materials.*; import org.papervision3d.materials.utils.*; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.render.BasicRenderEngine; public class Cube4 extends Sprite { protected var cube:Cube; protected var matList:MaterialsList; private var viewport:Viewport3D; private var scene:Scene3D; private var camera:Camera3D; private var renderer:BasicRenderEngine; public function Cube4():void { viewport=new Viewport3D(550,400,false,true); addChild(viewport); scene = new Scene3D(); camera = new Camera3D(); renderer = new BasicRenderEngine(); //Array mit den Bezeichnungen der Seiten von Cube var sides:Array=new Array("front","back","left","right","top","bottom"); matList= new MaterialsList(); //in der Bibliothek gibt es eine MovieClip Klasse "Cover" //dort liegen die 6 Bilder für die Seiten des Cubes in den //ersten 6 Schlüsselbildern for (var i:uint=1; i<=6; i++) { var face:Cover= new Cover(); face.gotoAndStop(i); face.name="f"+String(i); addChild(face); face.visible=false; face.addEventListener(MouseEvent.CLICK, faceClick); var mm:MovieMaterial=new MovieMaterial(getChildByName("f"+String(i)),false,false,true); mm.interactive=true; matList.addMaterial(mm, sides[(i-1)] ); } cube=new Cube(matList,400,400,400,5,5); scene.addChild(cube); var links:Array = new Array(); links["f1"]="http://www.on-design.de/jukeart/illu/conc1.html"; links["f2"]="http://www.on-design.de/jukeart/illu/conc2.html"; links["f3"]="http://www.on-design.de/jukeart/illu/conc3.html"; links["f4"]="http://www.on-design.de/jukeart/illu/darx.html"; links["f5"]="http://www.on-design.de/jukeart/illu/guitbal1.html"; links["f6"]="http://www.on-design.de/jukeart/illu/guitbal2.html"; //evt.target.name oder face.name="f"+String(i); //wird für den Index des "links" Arrays genutzt function faceClick(evt:MouseEvent):void { trace("ich wurde geklickt "+evt.target.name); navigateToURL(new URLRequest(links[String(evt.target.name)]),"_self"); } addEventListener(Event.ENTER_FRAME, onEnterFrame); function onEnterFrame(e:Event):void { var xDist:Number=mouseX-stage.stageWidth*0.5; var yDist:Number=mouseY-stage.stageHeight*0.5; cube.rotationY+=xDist*0.02; cube.rotationX+=yDist*0.02; renderer.renderScene(scene, camera, viewport); } } } }
In dieser Bilder Gallerie kommen einige Techniken zusammen. In einer XML-Datei sind Links zu Bildern gespeichert, die in den Flashfilm geladen werden. Zu jedem Bild gibt es noch einen Link auf eine Webseite, die beim Klick auf das Bild aufgerufen wird.
Hier die XML Datei:
<? version ="1.0" encoding ="utf-8"?>
<images>
<image url="images/image1.jpg" link="http://www.on-design.de/jukeart/illu/conc1.html"/>
<image url="images/image2.jpg" link="http://www.on-design.de/jukeart/illu/conc2.html" />
<image url="images/image3.jpg" link="http://www.on-design.de/jukeart/illu/conc3.html" />
<image url="images/image4.jpg" link="http://www.on-design.de/jukeart/illu/darx.html" />
<image url="images/image5.jpg" link="http://www.on-design.de/jukeart/illu/guitbal1.html" />
<image url="images/image6.jpg" link="http://www.on-design.de/jukeart/illu/guitbal2.html" />
<image url="images/image7.jpg" link="http://www.on-design.de/jukeart/illu/angst.html" />
<image url="images/image8.jpg" link="http://www.on-design.de/jukeart/illu/arbeit.html" />
<image url="images/image9.jpg" link="http://www.on-design.de/jukeart/illu/last.html" />
<image url="images/image10.jpg" link="http://www.on-design.de/jukeart/illu/sunlife.html" />
<image url="images/image11.jpg" link="http://www.on-design.de/jukeart/illu/lilith.html" />
<image url="images/image12.jpg" link="http://www.on-design.de/jukeart/illu/mumie.html" />
<image url="images/image13.jpg" link="http://www.on-design.de/jukeart/illu/skarbaeus.html" />
<image url="images/image14.jpg" link="http://www.on-design.de/jukeart/illu/traum.html" />
</images>
package { import flash.display.Sprite; import flash.events.Event; import flash.net.navigateToURL; import flash.net.URLRequest; import flash.net.URLLoader; import org.papervision3d.view.Viewport3D; import org.papervision3d.scenes.Scene3D; import org.papervision3d.cameras.Camera3D; import org.papervision3d.materials.MovieAssetMaterial; import org.papervision3d.materials.BitmapFileMaterial; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.objects.*; import org.papervision3d.events.InteractiveScene3DEvent; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.events.FileLoadEvent; public class activePlane extends Sprite { private var viewport:Viewport3D; private var scene:Scene3D; private var camera:Camera3D; private var movieAssetMaterial:BitmapFileMaterial; private var sphere:Plane; private var renderer:BasicRenderEngine; private var planes:Vector.=new Vector. ; private var numImages:int; private var centerObject:DisplayObject3D=new DisplayObject3D ; private var urlLoader:URLLoader; private var urls:Array=new Array ; public function activePlane():void { viewport=new Viewport3D(800,600,false,true); addChild(viewport); scene=new Scene3D ; camera=new Camera3D ; renderer=new BasicRenderEngine ; loadXML(); } private function loadXML():void { urlLoader=new URLLoader(new URLRequest("images.xml")); urlLoader.addEventListener(Event.COMPLETE,onXMLLoaded); } private function onXMLLoaded(event:Event):void { var xml:XML=new XML(event.target.data); var images:XMLList=xml.image; numImages=images.length(); for (var i:int=0; i< numImages; i++) { var url:String=images[i].@url; urls[i]=images[i].@link; var material:BitmapFileMaterial=new BitmapFileMaterial(url); material.precise=true; material.interactive=true; material.addEventListener(FileLoadEvent.LOAD_COMPLETE,onMaterialLoaded); } } private function onMaterialLoaded(event:FileLoadEvent):void { var material:BitmapFileMaterial=event.target as BitmapFileMaterial; material.interactive=true; var plane:Plane=new Plane(material); planes.push(plane); scene.addChild(plane); renderer.renderScene(scene,camera,viewport); if (planes.length==numImages) { createCarousel(); } } private function createCarousel():void { var radius:int=950; scene.addChild(centerObject); for (var i:int=0; i < numImages; i++) { var plane:Plane=planes[i]; plane.name=String(i); plane.rotationY=360/numImages*i; plane.moveForward(radius); plane.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS,onPress); centerObject.addChild(plane); } function onPress(e:InteractiveScene3DEvent):void { trace("ich wurde geklickt"+urls[int(e.target.name)]); navigateToURL(new URLRequest(urls[int(e.target.name)])); } addEventListener(Event.ENTER_FRAME,onEnterFrame); } private function onEnterFrame(e:Event):void { centerObject.yaw(viewport.containerSprite.mouseX*0.007); camera.y=viewport.containerSprite.mouseY*2; camera.z=110; renderer.renderScene(scene,camera,viewport); } } }
Material mit Shatteneffekt. Auch dieses Beispiel ist von Madvertices.
package { import flash.events.Event; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.materials.*; import org.papervision3d.view.BasicView; //um FlashShadeMaterial zu nutzen muss PointLight3D object importiert und instanziiert werden. import org.papervision3d.lights.PointLight3D; //Importiere die FlatShadeMaterial Klasse import org.papervision3d.materials.shadematerials.FlatShadeMaterial; public class SphereShader extends BasicView { private var sphere:Sphere; protected var movieAssetMaterial:MovieAssetMaterial; //Declare a FlatShadeMaterial instance private var flat:FlatShadeMaterial; //Declare a PointLight3D instance private var light:PointLight3D; public function SphereShader():void { super(); //PointLight3D Instanz // Parameter for PointLight3D = (showLight) //z und y Koordinaten von light werden gesetzt, //um eine Distanz zum Objekt zu schaffen light=new PointLight3D(true); light.z=-800; light.y=300; //FlatShadeMaterial Instanz //FlatShadeMaterial Parameter = (PointLight3D, Diffuse Color, Ambient Color) flat=new FlatShadeMaterial(light,0xFFFFFF,0x444444); //FlatShadeMaterial wird new Sphere zugewiesen sphere=new Sphere(flat,150,18,18); scene.addChild(sphere); camera.focus=20; // rendering starten startRendering(); } override protected function onRenderTick(event:Event=null):void { super.onRenderTick(event); var xDist:Number=mouseX-stage.stageWidth*0.5; var yDist:Number=mouseY-stage.stageHeight*0.5; sphere.rotationY+=xDist*0.02; sphere.rotationX+=yDist*0.02; } } }
Mit dem GouraudShader kann man Bildtextur und Licht kombinieren. Das folgende Beispiel habe ich in leicht veränderter Form von madvertices übernommen.
Folgende Importfunktionen werden zusätzlich benötigt:
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.materials.MovieMaterial;
import org.papervision3d.materials.shaders.GouraudShader;
import org.papervision3d.materials.shaders.ShadedMaterial;
Die Sache funktioniert folgendermaßen: Ich instanziiere eine MovieClip Klasse aus der Bibliothek. Diese wird für die Instanz von MovieMaterial gebraucht. Außerdem wird ein Light instanziiert, welches für die Instanz des GouradShaders gebraucht wird. Aus diesen beiden Dingen wird das ShadedMaterial gebildet, welches der Sphere Instanz zugewiesen wird.
MaterialMc | Light |
MovieMaterial | GouraudShader |
shadedMaterial | |
Sphere |
private var materialMc:MaterialMc; materialMc = new MaterialMc(); |
private var light:PointLight3D; light = new PointLight3D(); |
mMat = new MovieMaterial(materialMc, false, false, true); | gShader = new GouraudShader(light, 0xFFFFFF, 0x111111, 30); |
gMaterial = new ShadedMaterial(mMat, gShader); | |
sphere = new Sphere(gMaterial, 250, 18, 18); |
package { //nach einem Beispiel von: //http://www.madvertices.com/2009/02/pv3d-shader-materials-deeper.html import flash.display.Sprite; import flash.display.StageScaleMode; import flash.events.Event; import org.papervision3d.cameras.CameraType; import org.papervision3d.lights.PointLight3D; import org.papervision3d.materials.MovieMaterial; import org.papervision3d.materials.shaders.GouraudShader; import org.papervision3d.materials.shaders.ShadedMaterial; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.view.BasicView; public class GShader extends Sprite { //MaterialMc ist eine Movieclipklasse in der Bibliothek private var materialMc:MaterialMc = new MaterialMc(); private var mMat:MovieMaterial; private var gShader:GouraudShader; private var gMaterial:ShadedMaterial; private var light:PointLight3D; private var sphere:Sphere; private var view:BasicView; public function GShader() { stage.scaleMode=StageScaleMode.NO_SCALE; view=new BasicView(530,300,false,true,CameraType.FREE); light = new PointLight3D(); mMat=new MovieMaterial(materialMc,false,false,true); gShader=new GouraudShader(light,0xFFFFFF,0x111111,30); gMaterial=new ShadedMaterial(mMat,gShader); sphere=new Sphere(gMaterial,250,18,18); view.scene.addChild(light); view.scene.addChild(sphere); addChild(view); //view.x = 200; addEventListener(Event.ENTER_FRAME, onRenderViewport); } private function onRenderViewport(e:Event):void { view.singleRender(); var xDist:Number=mouseX-stage.stageWidth*0.5; var yDist:Number=mouseY-stage.stageHeight*0.5; sphere.rotationY+=xDist*0.02; sphere.rotationX+=yDist*0.02; //sphere.yaw(2); light.x = (mouseX - 250) * 5; light.y = -((mouseY - 150) * 5); } } }