Notes on <Papervision 3D Essentials> - 02

来源:互联网 发布:简便算法公式 编辑:程序博客网 时间:2024/06/08 08:51

Interactivity:

There are two kinds of interactivity: object interactivity and material interactivity.


And there is one point to notice:

Notice that you need to set both viewport and material interactivity to true. A common mistake is that only one of these values is set to true, resulting in no interactivity at all.


As below is a sample of material interactivity, the code is from the archieve in company with book

package {import flash.display.MovieClip;import flash.events.Event;import flash.events.MouseEvent;import flash.geom.Rectangle;import flash.text.TextField;import org.papervision3d.materials.MovieAssetMaterial;import org.papervision3d.materials.utils.PrecisionMode;import org.papervision3d.objects.primitives.Plane;import org.papervision3d.view.BasicView;public class InteractiveMaterial extends BasicView{private var plane:Plane;public function InteractiveMaterial(){stage.frameRate = 40;init();startRendering();}private function init():void{viewport.interactive = true;var material:MovieAssetMaterial = new MovieAssetMaterial("material",false,true,false,true);material.doubleSided = true;material.rect = new Rectangle(0,0,200,200);material.smooth = true;material.precisionMode = PrecisionMode.STABLE;material.interactive = true;MovieClip(MovieClip(material.movie).getChildByName("btn")).mouseChildren = false;MovieClip(material.movie).getChildByName("btn").addEventListener(MouseEvent.CLICK,click);MovieClip(material.movie).getChildByName("btn").addEventListener(MouseEvent.MOUSE_OVER,mouseOver);MovieClip(material.movie).getChildByName("btn").addEventListener(MouseEvent.MOUSE_OUT,mouseOut);plane = new Plane(material,500,500);scene.addChild(plane);}private function click(e:MouseEvent):void{var buttonText:TextField = MovieClip(e.target).getChildByName("label") as TextField;switch(buttonText.text){case "start":buttonText.text = "stop";MovieClip( MovieClip(e.target).parent ).play();break;default:buttonText.text = "start";MovieClip( MovieClip(e.target).parent ).stop();}}private function mouseOver(e:MouseEvent):void{viewport.buttonMode = true;}private function mouseOut(e:MouseEvent):void{viewport.buttonMode = false;}override protected function onRenderTick(e:Event=null):void{plane.localRotationY++;super.onRenderTick();}}}


material-interactivity

I have updated the pv3d lib version, it now not Great White version, but later than that, and localRotationY is available now.

And, material.movie is referencing to the MovieClip object which is used as material. This seems to be the only way to access it.



And next up is the interactivity of 3D object:

package {import flash.events.Event;import org.papervision3d.events.InteractiveScene3DEvent;import org.papervision3d.materials.ColorMaterial;import org.papervision3d.objects.primitives.Plane;import org.papervision3d.view.BasicView;public class ObjectInteractivity extends BasicView{public function ObjectInteractivity(){stage.frameRate = 40;init();startRendering();}private function init():void{viewport.interactive = true;var material:ColorMaterial = new ColorMaterial();material.doubleSided = true;material.interactive = true;var plane:Plane = new Plane(material);plane.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK,click);scene.addChild(plane);}private function click(e:InteractiveScene3DEvent):void{e.displayObject3D.localRotationY +=12;}override protected function onRenderTick(e:Event=null):void{super.onRenderTick();}}}


object-interactivity


To keep track of the event occurred on the 3d object, you should listen to the events defined by InteractiveScene3DEvent with PV3D, and use e.displayObject3D to access the object.


Tiling:

package {import flash.events.Event;import org.papervision3d.events.FileLoadEvent;import org.papervision3d.materials.BitmapFileMaterial;import org.papervision3d.objects.primitives.Plane;import org.papervision3d.view.BasicView;public class MaterialTiling extends BasicView{public function MaterialTiling(){stage.frameRate = 40;init();startRendering();}private function init():void{var material:BitmapFileMaterial = new BitmapFileMaterial("assets/tile.jpg");material.addEventListener(FileLoadEvent.LOAD_COMPLETE,loadComplete);var plane:Plane = new Plane(material,1024,512);scene.addChild(plane);}private function loadComplete(e:FileLoadEvent):void{var material:BitmapFileMaterial = BitmapFileMaterial(e.target);material.tiled = true;material.maxU = 8;material.maxV = 4;}override protected function onRenderTick(e:Event=null):void{super.onRenderTick();}}}


tiling-material


Flipping:


The first part is about flipping a MovieClip as material, the trick is: flip the MC by setting a negative scale value, and create another Sprite to contain it, and then use the container as material.


The the author disscussed about how to flip bitmap materials:

package {import flash.events.Event;import org.papervision3d.events.FileLoadEvent;import org.papervision3d.materials.BitmapFileMaterial;import org.papervision3d.materials.utils.BitmapMaterialTools;import org.papervision3d.materials.utils.MaterialsList;import org.papervision3d.objects.primitives.Cube;import org.papervision3d.view.BasicView;public class MaterialFlipping extends BasicView{public function MaterialFlipping(){stage.frameRate = 40;init();startRendering();}private function init():void{var frontMat:BitmapFileMaterial = new BitmapFileMaterial("assets/front.jpg");var backMat:BitmapFileMaterial = new BitmapFileMaterial("assets/back.jpg");var leftMat:BitmapFileMaterial = new BitmapFileMaterial("assets/left.jpg");var rightMat:BitmapFileMaterial = new BitmapFileMaterial("assets/right.jpg");var topMat:BitmapFileMaterial = new BitmapFileMaterial("assets/top.jpg");var bottomMat:BitmapFileMaterial = new BitmapFileMaterial("assets/bottom.jpg");frontMat.addEventListener(FileLoadEvent.LOAD_COMPLETE,loadComplete);backMat.addEventListener(FileLoadEvent.LOAD_COMPLETE,loadComplete);leftMat.addEventListener(FileLoadEvent.LOAD_COMPLETE,loadComplete);rightMat.addEventListener(FileLoadEvent.LOAD_COMPLETE,loadComplete);topMat.addEventListener(FileLoadEvent.LOAD_COMPLETE,loadComplete);bottomMat.addEventListener(FileLoadEvent.LOAD_COMPLETE,loadComplete);var materialsList:MaterialsList = new MaterialsList();materialsList.addMaterial(frontMat,"front");materialsList.addMaterial(backMat,"back");materialsList.addMaterial(leftMat,"left");materialsList.addMaterial(rightMat,"right");materialsList.addMaterial(topMat,"top");materialsList.addMaterial(bottomMat,"bottom");var cube:Cube = new Cube(materialsList,800,800,800,5,5,5);scene.addChild(cube);}private function loadComplete(e:FileLoadEvent):void{var material:BitmapFileMaterial = BitmapFileMaterial(e.target);material.opposite = true;BitmapMaterialTools.mirrorBitmapX(material.bitmap);}override protected function onRenderTick(e:Event=null):void{super.onRenderTick();}}}


To better understand the function of BitmapMaterialTools.mirrorBitmapX(), we had better comment out the line: BitmapMaterialTools.mirrorBitmapX(material.bitmap);

The difference as below:

flip-bitmap

non-flip-bitmap


And if we comment out the line:material.opposite = true; we will see only back face:

no-opposite

Setting opposite to true makes us can look through the back face.


The final example - Carousel:


carousel


This is the code from the file in company with book, but it has some problems:


on click event is responded, and ROLL_OVER event on the image plane is not responded, and no ROLL_OUT event dispatched!