PV3D中提供了一組專門負責3D交互的類,這些類都是以Interactive為開頭,其中有 InteractiveSprite,InteractiveScene3D,InteractiveSceneManager,InteractiveWireframeMaterial 等等。要實現3D交互功能我們就需要用到這些類。
我們這一講的代碼是基於《入門第3步》當中的Cube代碼修改的,所以如果你可能需要參考《入門第3步》的代碼。
首選,我們需要把3D場景的容器對象,改成InteractiveSprite類型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | //... import org.papervision3d.utils.InteractiveSprite; //... [SWF(width='200',height='200',backgroundColor='0xFFFFFF',frameRate='30')] public class Main extends Sprite { //... private function Init3D():void { //... // 創建3D舞台的容器 _container = new InteractiveSprite(); //原先的代碼:new Sprite(); //... } //... } |
接著我們要把3D舞台改成支持交互操作的InteractiveScene3D類型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | //... import org.papervision3d.scenes.InteractiveScene3D; //... [SWF(width='200',height='200',backgroundColor='0xFFFFFF',frameRate='30')] public class Main extends Sprite { //... private var _scene:InteractiveScene3D; //原先的代碼::MovieScene3D; private function Init3D():void { //... // 創建3D舞台 _scene = new InteractiveScene3D(_container); //原先的代碼:new MovieScene3D(_container); //... } //... } |
比起普通的PV3D動畫程序,PV3D的3D交互程序多了一個InteractiveSceneManager對象,它負責所有的3D事件。所以代碼中需要增加一個私有變量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | //... import org.papervision3d.utils.InteractiveSceneManager; //... [SWF(width='200',height='200',backgroundColor='0xFFFFFF',frameRate='30')] public class Main extends Sprite { //... private var _interactiveSceneManager:InteractiveSceneManager; private function Init3D():void { //... _interactiveSceneManager = _scene.interactiveSceneManager; _interactiveSceneManager.faceLevelMode = true; //註冊3D鼠標事件 _interactiveSceneManager.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, OnObj3DMouseOver); _interactiveSceneManager.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, OnObj3DMouseOut); //... } private function OnObj3DMouseOver(event:InteractiveScene3DEvent):void{ event.face3d.material = this._material2; //換材質,突出顯示被選中的face } private function OnObj3DMouseOut(event:InteractiveScene3DEvent):void{ event.face3d.material = this._material1; //換回原來材質 } //... } |
你可以看到上面的代碼將InteractiveSceneManager對象的faceLevelMode設置成true。這裡需要說明下,PV3D給 InteractiveSceneManager設計了兩種狀態,一種是對象(object)級別的交互,一種是面(face)級別的交互,對象級別的交 互就是只精確到某個對象,比如一個Cube或者一個Plane,而面級別的交互可以精確到PV3D顯示的最小單位face3D,面級別的交互更精確,但是 執行效率比對象級別低很多,所以大家設計交互時需要考慮到這點。
另外代碼中用到的貼圖需要換成支持交互事件的InteractiveWireframeMaterial類型,為了突出顯示,我還另外用了一個InteractiveColorMaterial類型的紅色貼圖。關於材質貼圖的代碼修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import org.papervision3d.materials.InteractiveWireframeMaterial; import org.papervision3d.materials.InteractiveColorMaterial; [SWF(width='200',height='200',backgroundColor='0xFFFFFF',frameRate='30')] public class Main extends Sprite { //... private var _material1:InteractiveWireframeMaterial; private var _material2:InteractiveColorMaterial; private function Init3D():void { //... _material1 = new InteractiveWireframeMaterial(0x000000); _material2 = new InteractiveColorMaterial(0xFF0000); materialList.addMaterial(_material1, "top"); materialList.addMaterial(_material1, "bottom"); materialList.addMaterial(_material1, "front"); materialList.addMaterial(_material1, "back"); materialList.addMaterial(_material1, "left"); materialList.addMaterial(_material1, "right"); //... } //... } |
整個程序的運行效果如下(請把鼠標放上去試試):
這個例子中只實現了face的選擇,並沒有做到Colorfulee問我的選擇Cube某個面的效果,不過通過在鼠標事件中比對材質的id,我們是可以知 道Cube的哪個面被選擇的,不過需要為每個面都示例化一個材質貼圖,不能像示例代碼中那樣幾個面都共享同一個貼圖實例。有興趣的朋友可以自己試試看 。我不希望看我Blog的朋友都變成懶得動手的大懶蟲噢。
今天的學習就到這裡,我想光通過看我的《PV3D入門》是沒辦法完全掌握PV3D的,因為我每一講只能選重點的,或者朋友問得比較多的講,有很多特性我是 沒辦法介紹到的,所以建議大家出來看我的《PV3D入門》外,還可以通過PV3D的幫助文檔,Wiki,或閱讀PV3D源代碼來更深入的瞭解PV3D。
今天的完整示例代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | package { import flash.display.Sprite; import flash.events.Event; import org.papervision3d.cameras.Camera3D; import org.papervision3d.scenes.MovieScene3D; import org.papervision3d.materials.MaterialsList; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.core.proto.MaterialObject3D; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.Cube; //--New-- import org.papervision3d.utils.InteractiveSprite; import org.papervision3d.scenes.InteractiveScene3D; import org.papervision3d.utils.InteractiveSceneManager; import org.papervision3d.events.InteractiveScene3DEvent; import org.papervision3d.materials.InteractiveWireframeMaterial; import org.papervision3d.materials.InteractiveColorMaterial; [SWF(width='200',height='200',backgroundColor='0xFFFFFF',frameRate='30')] public class Main extends Sprite { private var _container :Sprite; private var _scene:InteractiveScene3D; // :MovieScene3D; private var _camera :Camera3D; private var _displayObj:DisplayObject3D; private var _material1:InteractiveWireframeMaterial; private var _material2:InteractiveColorMaterial; private var _interactiveSceneManager:InteractiveSceneManager; public function Main() { Init3D(); } private function Init3D():void { // 創建3D舞台的容器 _container = new InteractiveSprite(); //new Sprite; _container.x = 100; _container.y = 100; addChild( _container ); // 創建3D舞台 _scene = new InteractiveScene3D(_container); // new MovieScene3D( _container ); //--New-- _interactiveSceneManager = _scene.interactiveSceneManager; _interactiveSceneManager.faceLevelMode = true; _interactiveSceneManager.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, OnObj3DMouseOver); _interactiveSceneManager.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, OnObj3DMouseOut); // 創建攝像頭 _camera = new Camera3D(); _camera.z = -500; _camera.zoom = 5; var materialList:MaterialsList = new MaterialsList(); _material1 = new InteractiveWireframeMaterial(0x000000); _material2 = new InteractiveColorMaterial(0xFF0000); materialList.addMaterial(_material1, "top"); materialList.addMaterial(_material1, "bottom"); materialList.addMaterial(_material1, "front"); materialList.addMaterial(_material1, "back"); materialList.addMaterial(_material1, "left"); materialList.addMaterial(_material1, "right"); _displayObj = new Cube(materialList, 128, 128, 128, 2, 2, 2); _scene.addChild(_displayObj); this.addEventListener(Event.ENTER_FRAME, OnEnterFrame); } private function OnEnterFrame(event:Event):void { _displayObj.rotationX += 5; _displayObj.rotationY += 5; _scene.renderCamera(_camera); } private function OnObj3DMouseOver(event:InteractiveScene3DEvent):void{ event.face3d.material = this._material2; } private function OnObj3DMouseOut(event:InteractiveScene3DEvent):void{ event.face3d.material = this._material1; } } } |
- Date Wednesday, 19 Sep 07 at 11:53 pm
- Under Papervision3D教程, Papervision3D, ActionScript
- You can follow any responses to this entry through the RSS 2.0 feed .
- You can leave a response , or trackback from your own site .