Papervision3D 教學 part 3.2 -- 子母視窗
想嚐試製作子母視窗的感覺,建立了兩個 Camera3D,但是並無法透過 camera2 看到 scene,然後輸出在另外一個 MC 上,或許有方法可以做到,我還需要找找看。而以下我的作法是,用 camera2 先將 scene 輸出一次,並且立即讀取其 BiemapData 將之繪製到另外一個 MC 子視窗中,然後立刻改以 camera 將 scene 重新輸出一次。程式碼如下:
package {import flash.display.*;import flash.events.*;import flash.utils.*;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*;import org.papervision3d.materials.*;import flash.geom.Rectangle;import flash.geom.Matrix;[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class T3step2 extends Sprite{private static var PI:Number = Math.PI;private static var TH:Number = PI / 180;private var container:Sprite;private var scene:Scene3D;private var camera:Camera3D;private var camera2:Camera3D;private var rootNode:DisplayObject3D;private var du:Number = 0;private var photoCount:int = 9;private var movingRadius:int = 1000;private var movingHeight:int = 500;private var timer:Timer;private var childWindowScreen:Sprite;private var bd:BitmapData;private var matrix:Matrix;private var bmp:Bitmap;public function T3step2(){ // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D);}private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.y = movingHeight; camera.z = -movingRadius; camera.zoom = 10; camera.focus = 100; camera2 = new Camera3D(); camera2.y = movingHeight; camera2.z = -movingRadius; camera2.zoom = 10; camera2.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); var ground:DisplayObject3D = rootNode.addChild(new Plane(new ColorMaterial(0xffcc00), 500, 500, 3, 3), "ground"); ground.rotationX = -90; var item:DisplayObject3D = new DisplayObject3D(); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:0, z:-50}), "p1"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:90, x:-50}), "p2"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:-90, x:50}), "p3"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:180, z:50}), "p4"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationX:90, y:-50}), "p5"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationX:-90, y:50}), "p6"); item.y = 150; rootNode.addChild(item, "item"); /* timer = new Timer(1000, 0); timer.addEventListener(TimerEvent.TIMER, onTimer); timer.start(); */ //子母視窗 var childWindow:Sprite = new Sprite(); addChild(childWindow); var childWindowBorder:Sprite = new Sprite(); childWindow.addChild(childWindowBorder); childWindowBorder.graphics.lineStyle(2, 0xffffff); childWindowBorder.graphics.drawRect(0, 0, 100, 100); childWindowScreen = new Sprite(); childWindow.addChild(childWindowScreen); childWindow.x = 300; childWindow.y = 300;}private function loop3D(event:Event):void{ //物體本身旋轉 var item:DisplayObject3D = rootNode.getChildByName("item"); if(item!=null){ item.rotationX++; item.rotationY++; item.rotationZ++; } //carema2先將畫面記錄下來 scene.renderCamera(camera2); bd = new BitmapData(400, 400, false, 0x0000ff); matrix = new Matrix(); matrix.translate(200, 200); matrix.scale(0.25, 0.25); bd.draw(scene.container, matrix); if(bmp!=null){ childWindowScreen.removeChild(bmp); } bmp = new Bitmap(bd); childWindowScreen.addChild(bmp); bd = null; //改用carema旋轉輸出 du++; if(du==360)du=0; var newX:Number = movingRadius * formatNum(Math.cos(du*TH), 3); var newZ:Number = movingRadius * formatNum(Math.sin(du*TH), 3); camera.x = newX; camera.z = newZ; scene.renderCamera(camera);}private function formatNum(num:Number, cnt:Number):Number{ return Math.round(num * Math.pow(10, cnt)) / Math.pow(10, cnt);}private function onTimer(event:TimerEvent):void{ var item:DisplayObject3D = rootNode.getChildByName("item"); if(item!=null){ var pName:String = "p" + (Math.floor(Math.random()*6)+1); var p:DisplayObject3D = item.getChildByName(pName); if(p!=null){ p.material = new BitmapFileMaterial(getFileName()); } }}private function getFileName():String{ return "http://ben.rb.chang.googlepages.com/photos"+(Math.floor(Math.random()*photoCount)+1)+".JPG";}}}
測試時,不斷搞到瀏覽器當掉,後來我將 onTimer() 時的切換各面向的貼圖部分拿掉,改善了一點點!此外,若是觀察記憶體消耗的話,會發現他很快就衝到頂點,然後只好等 Gabarge Collection(GC) 自己找時間釋放掉,才會稍微順暢幾秒鐘......$%&@#
等到整個瀏覽器關閉後,就恢復正常了!
看效果!
於 6/13/2007 06:35:00 下午 0 意見
標籤: AS3, Flash, Papervision3D
Papervision3D 教學 part 3 -- 建模
先前的練習,我們都是直接以 PaperVision3D 所提供的基本模型 Cube 來建模,然後你會發現我們貼圖時,會將這個 Cube 的六個面都貼成同樣的材質,但是通常我們的模型上每個面有不同的貼圖,所以以下我做的範例,是先建立一個叫做 item 的 DisplayObject3D,然後在這個 DisplayObject3D 中加入六個 Plane 物件,並為這六個 Plane 進行貼圖,然後將這六個 Plane 組合成 Cube 的六個面向。範例中的其他部分之前提過,包含 camera 照圓心座標旋轉,以及透過 Timer 每隔一秒亂數決定這個我們自製 Cube 中其中一面向換貼圖。程式碼如下:
package {import flash.display.*;import flash.events.*;import flash.utils.*;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*import org.papervision3d.materials.*[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class T3step1 extends Sprite{ private static var PI:Number = Math.PI; private static var TH:Number = PI / 180; private var container:Sprite; private var scene:Scene3D; private var camera:Camera3D; private var rootNode:DisplayObject3D; private var du:Number = 0; private var photoCount:int = 9; private var movingRadius:int = 1000; private var movingHeight:int = 500; private var timer:Timer; public function T3step1() { // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D); } private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.y = movingHeight; camera.z = -movingRadius; camera.zoom = 10; camera.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); var ground:DisplayObject3D = rootNode.addChild(new Plane(new ColorMaterial(0xffcc00), 500, 500, 10, 10), "ground"); ground.rotationX = -90; var item:DisplayObject3D = new DisplayObject3D(); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:0, z:-50}), "p1"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:90, x:-50}), "p2"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:-90, x:50}), "p3"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:180, z:50}), "p4"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationX:90, y:-50}), "p5"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationX:-90, y:50}), "p6"); item.y = 150; rootNode.addChild(item, "item"); timer = new Timer(1000, 0); timer.addEventListener(TimerEvent.TIMER, onTimer); timer.start(); } private function loop3D(event:Event):void{ var item:DisplayObject3D = rootNode.getChildByName("item"); if(item!=null){ item.rotationX++; item.rotationY++; item.rotationZ++; } du++; if(du==360)du=0; var newX:Number = movingRadius * formatNum(Math.cos(du*TH), 3); var newZ:Number = movingRadius * formatNum(Math.sin(du*TH), 3); camera.x = newX; camera.z = newZ; scene.renderCamera(camera); } private function formatNum(num:Number, cnt:Number):Number{ return Math.round(num * Math.pow(10, cnt)) / Math.pow(10, cnt); } private function onTimer(event:TimerEvent):void{ var item:DisplayObject3D = rootNode.getChildByName("item"); if(item!=null){ var pName:String = "p" + (Math.floor(Math.random()*6)+1); var p:DisplayObject3D = item.getChildByName(pName); if(p!=null){ p.material = new BitmapFileMaterial(getFileName()); } } } private function getFileName():String{ return "http://ben.rb.chang.googlepages.com/photos"+(Math.floor(Math.random()*photoCount)+1)+".JPG"; }}}
看效果!
於 6/13/2007 04:22:00 下午 1 意見
標籤: AS3, Flash, Papervision3D
Papervision3D 教學 part 2.3 -- 用外部圖檔做貼圖材質
貼圖材質,除了可以貼純色 (ColorMaterial) 與 BitmapData (BitmapMaterial) 之外,還可以直接拿外部圖檔 (BitmapFileMaterial) 進行貼圖,以下這個範例我就是採用 BitmapFileMaterial 貼圖,並且每隔 3000 微秒就將圖片重新載入貼過!程式碼如下:
package {import flash.display.Sprite;import flash.display.Bitmap;import flash.events.*;import flash.utils.*;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*import org.papervision3d.materials.*[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class T2step4 extends Sprite{ private static var PI:Number = Math.PI; private static var TH:Number = PI / 180; private var container:Sprite; private var scene:Scene3D; private var camera:Camera3D; private var rootNode:DisplayObject3D; private var du:Number = 0; private var movingRadius:int = 2000; private var movingHeight:int = 2000; private var photoIdx:int = 1; private var photoCount:int = 9; private var timer:Timer; public function T2step4() { // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D); addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel); } private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.y = movingHeight; camera.z = -movingRadius; camera.zoom = 10; camera.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); var ground:DisplayObject3D = rootNode.addChild(new Plane(new ColorMaterial(0xffcc00), 500, 500, 10, 10), "ground"); ground.rotationX = -90; var myCube1:DisplayObject3D = rootNode.addChild(new Cube(new BitmapFileMaterial(getFileName()), 100, 100, 100, 1, 1, 1), "myCube1"); myCube1.y = 50; timer = new Timer(3000, 0); timer.addEventListener(TimerEvent.TIMER, onTimer); timer.start(); } private function loop3D(event:Event):void{ /* du++; if(du==360)du=0; */ du = 360 * (this.mouseX / stage.stageWidth); var newX:Number = movingRadius * formatNum(Math.cos(du*TH), 3); var newY:Number = movingHeight; var newZ:Number = movingRadius * formatNum(Math.sin(du*TH), 3); camera.x = newX; camera.y = newY; camera.z = newZ; scene.renderCamera(camera); } private function formatNum(num:Number, cnt:Number):Number{ return Math.round(num * Math.pow(10, cnt)) / Math.pow(10, cnt); } private function onMouseWheel(event:MouseEvent):void{ //event.delta = 3 | -3 movingRadius -= event.delta*10; if(movingRadius<=0)movingRadius=1; movingHeight -= event.delta*10; if(movingHeight<=200)movingHeight=200; } private function onTimer(event:TimerEvent):void{ var myCube1:DisplayObject3D = rootNode.getChildByName("myCube1"); myCube1.material = new BitmapFileMaterial(getFileName()); } private function getFileName():String{ return "http://ben.rb.chang.googlepages.com/photos"+(Math.floor(Math.random()*photoCount)+1)+".JPG"; }}}
測試畫面如下:
同樣的機制,我把先前教過的範例再加上這個週期換圖的效果,感覺又更絢麗了!程式碼如下,每個 Cube 都有自己的 Timer 控制,換圖時間不一定,以亂數決定的!
package {import flash.display.Sprite;import flash.display.Bitmap;import flash.events.Event;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*import org.papervision3d.materials.* import flash.utils.Timer;import flash.events.TimerEvent;[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class Step8 extends Sprite{ private var container:Sprite; private var scene:Scene3D; private var camera:Camera3D; private var rootNode:DisplayObject3D; private var AMOUNT:int = 50; private var rotationSettingArray:Array = new Array(); private var timerArray:Array = new Array(); private var photoCount:int = 9; public function Step8() { // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D); } private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.z = -3000; camera.zoom = 10; camera.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); for(var i:int=0; i<AMOUNT; i++){ var myCube:DisplayObject3D = rootNode.addChild(new Cube(new BitmapFileMaterial(getFileName()), 100, 100, 100, 1, 1, 1), "myCube" + i); myCube.moveBackward(Math.random() * (3000-100/2+1)); if(Math.random()*2>1) myCube.moveLeft(Math.random()*500); else myCube.moveRight(Math.random()*500); if(Math.random()*2>1) myCube.moveUp(Math.random()*500); else myCube.moveDown(Math.random()*500); rotationSettingArray.push({rX:(Math.random()-Math.random())*2 , rY:(Math.random()-Math.random())*2 , rZ:(Math.random()-Math.random())*2}); var timer:Timer = new Timer((Math.round(Math.random()*5)+5)*1000, 0); timer.addEventListener(TimerEvent.TIMER, onTimer); timer.start(); timerArray.push(timer); } } private function loop3D(event:Event):void{ for(var i:int=0; i<AMOUNT; i++){ var myCube:DisplayObject3D = rootNode.getChildByName("myCube" + i); if(myCube!=null){ myCube.rotationX+=rotationSettingArray[i].rX; myCube.rotationY+=rotationSettingArray[i].rY; myCube.rotationZ+=rotationSettingArray[i].rZ; } } scene.renderCamera(camera); } private function onTimer(event:TimerEvent):void{ for(var i:int=0; i<timerArray.length; i++){ if(event.target==timerArray[i]){ var myCube:DisplayObject3D = rootNode.getChildByName("myCube"+i); var fileName:String = getFileName(); trace(fileName); myCube.material = new BitmapFileMaterial(fileName); } } } private function getFileName():String{ return "http://ben.rb.chang.googlepages.com/photos"+(Math.floor(Math.random()*photoCount)+1)+".JPG"; }}}
看效果!
於 6/13/2007 12:47:00 下午 0 意見
標籤: AS3, Flash, Papervision3D
Papervision3D 教學 part 2.2 -- 空照 與滑鼠互動
繼續上一篇的 Camera 操控,這次加上滑鼠,左右移動可以控制 camera 繞著圓心做旋轉,然後滾輪的部份,我會用來同時改變 carema 的高度以及繞圓心旋轉的半徑,程式碼如下:
package {import flash.display.Sprite;import flash.display.Bitmap;import flash.events.*;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*import org.papervision3d.materials.*[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class T2step3 extends Sprite{ private static var PI:Number = Math.PI; private static var TH:Number = PI / 180; [Embed(source="../assets/IMG_1054.JPG")] private var CubeTexture:Class; private var container:Sprite; private var scene:Scene3D; private var camera:Camera3D; private var rootNode:DisplayObject3D; private var du:Number = 0; private var movingRadius:int = 2000; private var movingHeight:int = 2000; public function T2step3() { // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D); addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel); } private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.y = movingHeight; camera.z = -movingRadius; camera.zoom = 10; camera.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); var ground:DisplayObject3D = rootNode.addChild(new Plane(new ColorMaterial(0xffcc00), 500, 500, 10, 10), "ground"); ground.rotationX = -90; var cubeTexture:Bitmap = new CubeTexture() as Bitmap; var myCube1:DisplayObject3D = rootNode.addChild(new Cube(new BitmapMaterial(cubeTexture.bitmapData), 100, 100, 100, 1, 1, 1), "myCube1"); myCube1.y = 50; } private function loop3D(event:Event):void{ /* du++; if(du==360)du=0; */ du = 360 * (this.mouseX / stage.stageWidth); var newX:Number = movingRadius * formatNum(Math.cos(du*TH), 3); var newY:Number = movingHeight; var newZ:Number = movingRadius * formatNum(Math.sin(du*TH), 3); camera.x = newX; camera.y = newY; camera.z = newZ; scene.renderCamera(camera); } private function formatNum(num:Number, cnt:Number):Number{ return Math.round(num * Math.pow(10, cnt)) / Math.pow(10, cnt); } private function onMouseWheel(event:MouseEvent):void{ //event.delta = 3 | -3 movingRadius -= event.delta*10; if(movingRadius<=0)movingRadius=1; movingHeight -= event.delta*10; if(movingHeight<=200)movingHeight=200; }}}
看效果!
於 6/13/2007 10:43:00 上午 6 意見
標籤: AS3, Flash, Papervision3D
Papervision3D 教學 part 2 -- 空照
我第二篇 PaperVision3D 的教學,是針對 Camera 的基本操控,這個範例我將 Camera 移到空中 高度 2000 的位置(y=2000),在 onEnterFrame() 時,會設定 carema 的座標,繞著中心點作旋轉,有點像是衛星移動的感覺。不過若是只對著一個 myCube1 做拍照的話,可能這樣的範例會看不出到底是 myCube1 在自己旋轉,還是 camera 在繞著他旋轉,所以我另外製作了一 Plane 物件名叫 ground 作為地板,預設這個地板是 X-Y 面向的單面,我需要將他順著 X 軸做翻轉,變成 X-Z 面向。
package {import flash.display.Sprite;import flash.display.Bitmap;import flash.events.Event;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*import org.papervision3d.materials.*[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class T2step1 extends Sprite{ private static var PI:Number = Math.PI; private static var TH:Number = PI / 180; [Embed(source="../assets/IMG_1054.JPG")] private var CubeTexture:Class; private var container:Sprite; private var scene:Scene3D; private var camera:Camera3D; private var rootNode:DisplayObject3D; private var du:Number = 0; public function T2step1() { // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D); } private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.y = 2000; camera.z = -2000; camera.zoom = 10; camera.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); var ground:DisplayObject3D = rootNode.addChild(new Plane(new ColorMaterial(0xffcc00), 500, 500, 1, 1), "ground"); ground.rotationX = -90; var cubeTexture:Bitmap = new CubeTexture() as Bitmap; var myCube1:DisplayObject3D = rootNode.addChild(new Cube(new BitmapMaterial(cubeTexture.bitmapData), 100, 100, 100, 1, 1, 1), "myCube1"); myCube1.y = 50; } private function loop3D(event:Event):void{ du++; if(du==360)du=0; var newX:Number = 2000 * formatNum(Math.cos(du*TH), 3); var newZ:Number = 2000 * formatNum(Math.sin(du*TH), 3); camera.x = newX; camera.z = newZ; scene.renderCamera(camera); } private function formatNum(num:Number, cnt:Number):Number{ return Math.round(num * Math.pow(10, cnt)) / Math.pow(10, cnt); }}}
測試畫面如下:
你可能會發現,在 camera 繞著中心旋轉拍攝時,地面 ground 與 myCube1 某些部份會有些重疊衝突的問題,你需要時時想像,其實我們看到的 " 一個面 ",並不是真的由一個面構成,而是由 PV3D engine 將這個面拆成多個三角形拼貼而成的。對於這個問題,我試圖將 myCube1 的高度拉更高一點,從 myCube1.y = 51 一直拉到 100 以上,這個問題會得到改善,但還是會出現重疊三角形。另一種做法也可以改善這個問題,就是將地面的 segments 增加,由原本的 1 改成 10 以上,這樣一來,地面就是由更多的小三角碎片所組成的,而重疊時會造成的破碎感覺會小一點點,不過想必這樣的運算會比較多,所以,就別介意這種視覺問題囉!以下是改過的程式碼:
package {import flash.display.Sprite;import flash.display.Bitmap;import flash.events.Event;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*import org.papervision3d.materials.*[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class T2step2 extends Sprite{ private static var PI:Number = Math.PI; private static var TH:Number = PI / 180; [Embed(source="../assets/IMG_1054.JPG")] private var CubeTexture:Class; private var container:Sprite; private var scene:Scene3D; private var camera:Camera3D; private var rootNode:DisplayObject3D; private var du:Number = 0; public function T2step2() { // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D); } private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.y = 2000; camera.z = -2000; camera.zoom = 10; camera.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); var ground:DisplayObject3D = rootNode.addChild(new Plane(new ColorMaterial(0xffcc00), 500, 500, 10, 10), "ground"); ground.rotationX = -90; var cubeTexture:Bitmap = new CubeTexture() as Bitmap; var myCube1:DisplayObject3D = rootNode.addChild(new Cube(new BitmapMaterial(cubeTexture.bitmapData), 100, 100, 100, 1, 1, 1), "myCube1"); myCube1.y = 50; } private function loop3D(event:Event):void{ du++; if(du==360)du=0; var newX:Number = 2000 * formatNum(Math.cos(du*TH), 3); var newZ:Number = 2000 * formatNum(Math.sin(du*TH), 3); camera.x = newX; camera.z = newZ; scene.renderCamera(camera); } private function formatNum(num:Number, cnt:Number):Number{ return Math.round(num * Math.pow(10, cnt)) / Math.pow(10, cnt); }}}
想嚐試製作子母視窗的感覺,建立了兩個 Camera3D,但是並無法透過 camera2 看到 scene,然後輸出在另外一個 MC 上,或許有方法可以做到,我還需要找找看。而以下我的作法是,用 camera2 先將 scene 輸出一次,並且立即讀取其 BiemapData 將之繪製到另外一個 MC 子視窗中,然後立刻改以 camera 將 scene 重新輸出一次。程式碼如下:
package {import flash.display.*;import flash.events.*;import flash.utils.*;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*;import org.papervision3d.materials.*;import flash.geom.Rectangle;import flash.geom.Matrix;[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class T3step2 extends Sprite{private static var PI:Number = Math.PI;private static var TH:Number = PI / 180;private var container:Sprite;private var scene:Scene3D;private var camera:Camera3D;private var camera2:Camera3D;private var rootNode:DisplayObject3D;private var du:Number = 0;private var photoCount:int = 9;private var movingRadius:int = 1000;private var movingHeight:int = 500;private var timer:Timer;private var childWindowScreen:Sprite;private var bd:BitmapData;private var matrix:Matrix;private var bmp:Bitmap;public function T3step2(){ // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D);}private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.y = movingHeight; camera.z = -movingRadius; camera.zoom = 10; camera.focus = 100; camera2 = new Camera3D(); camera2.y = movingHeight; camera2.z = -movingRadius; camera2.zoom = 10; camera2.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); var ground:DisplayObject3D = rootNode.addChild(new Plane(new ColorMaterial(0xffcc00), 500, 500, 3, 3), "ground"); ground.rotationX = -90; var item:DisplayObject3D = new DisplayObject3D(); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:0, z:-50}), "p1"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:90, x:-50}), "p2"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:-90, x:50}), "p3"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:180, z:50}), "p4"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationX:90, y:-50}), "p5"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationX:-90, y:50}), "p6"); item.y = 150; rootNode.addChild(item, "item"); /* timer = new Timer(1000, 0); timer.addEventListener(TimerEvent.TIMER, onTimer); timer.start(); */ //子母視窗 var childWindow:Sprite = new Sprite(); addChild(childWindow); var childWindowBorder:Sprite = new Sprite(); childWindow.addChild(childWindowBorder); childWindowBorder.graphics.lineStyle(2, 0xffffff); childWindowBorder.graphics.drawRect(0, 0, 100, 100); childWindowScreen = new Sprite(); childWindow.addChild(childWindowScreen); childWindow.x = 300; childWindow.y = 300;}private function loop3D(event:Event):void{ //物體本身旋轉 var item:DisplayObject3D = rootNode.getChildByName("item"); if(item!=null){ item.rotationX++; item.rotationY++; item.rotationZ++; } //carema2先將畫面記錄下來 scene.renderCamera(camera2); bd = new BitmapData(400, 400, false, 0x0000ff); matrix = new Matrix(); matrix.translate(200, 200); matrix.scale(0.25, 0.25); bd.draw(scene.container, matrix); if(bmp!=null){ childWindowScreen.removeChild(bmp); } bmp = new Bitmap(bd); childWindowScreen.addChild(bmp); bd = null; //改用carema旋轉輸出 du++; if(du==360)du=0; var newX:Number = movingRadius * formatNum(Math.cos(du*TH), 3); var newZ:Number = movingRadius * formatNum(Math.sin(du*TH), 3); camera.x = newX; camera.z = newZ; scene.renderCamera(camera);}private function formatNum(num:Number, cnt:Number):Number{ return Math.round(num * Math.pow(10, cnt)) / Math.pow(10, cnt);}private function onTimer(event:TimerEvent):void{ var item:DisplayObject3D = rootNode.getChildByName("item"); if(item!=null){ var pName:String = "p" + (Math.floor(Math.random()*6)+1); var p:DisplayObject3D = item.getChildByName(pName); if(p!=null){ p.material = new BitmapFileMaterial(getFileName()); } }}private function getFileName():String{ return "http://ben.rb.chang.googlepages.com/photos"+(Math.floor(Math.random()*photoCount)+1)+".JPG";}}}
測試時,不斷搞到瀏覽器當掉,後來我將 onTimer() 時的切換各面向的貼圖部分拿掉,改善了一點點!此外,若是觀察記憶體消耗的話,會發現他很快就衝到頂點,然後只好等 Gabarge Collection(GC) 自己找時間釋放掉,才會稍微順暢幾秒鐘......$%&@#
等到整個瀏覽器關閉後,就恢復正常了!
看效果!
於 6/13/2007 06:35:00 下午 0 意見
標籤: AS3, Flash, Papervision3D
Papervision3D 教學 part 3 -- 建模
先前的練習,我們都是直接以 PaperVision3D 所提供的基本模型 Cube 來建模,然後你會發現我們貼圖時,會將這個 Cube 的六個面都貼成同樣的材質,但是通常我們的模型上每個面有不同的貼圖,所以以下我做的範例,是先建立一個叫做 item 的 DisplayObject3D,然後在這個 DisplayObject3D 中加入六個 Plane 物件,並為這六個 Plane 進行貼圖,然後將這六個 Plane 組合成 Cube 的六個面向。範例中的其他部分之前提過,包含 camera 照圓心座標旋轉,以及透過 Timer 每隔一秒亂數決定這個我們自製 Cube 中其中一面向換貼圖。程式碼如下:
package {import flash.display.*;import flash.events.*;import flash.utils.*;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*import org.papervision3d.materials.*[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class T3step1 extends Sprite{ private static var PI:Number = Math.PI; private static var TH:Number = PI / 180; private var container:Sprite; private var scene:Scene3D; private var camera:Camera3D; private var rootNode:DisplayObject3D; private var du:Number = 0; private var photoCount:int = 9; private var movingRadius:int = 1000; private var movingHeight:int = 500; private var timer:Timer; public function T3step1() { // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D); } private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.y = movingHeight; camera.z = -movingRadius; camera.zoom = 10; camera.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); var ground:DisplayObject3D = rootNode.addChild(new Plane(new ColorMaterial(0xffcc00), 500, 500, 10, 10), "ground"); ground.rotationX = -90; var item:DisplayObject3D = new DisplayObject3D(); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:0, z:-50}), "p1"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:90, x:-50}), "p2"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:-90, x:50}), "p3"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationY:180, z:50}), "p4"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationX:90, y:-50}), "p5"); item.addChild(new Plane(new BitmapFileMaterial(getFileName()), 100, 100, 1, 1, {rotationX:-90, y:50}), "p6"); item.y = 150; rootNode.addChild(item, "item"); timer = new Timer(1000, 0); timer.addEventListener(TimerEvent.TIMER, onTimer); timer.start(); } private function loop3D(event:Event):void{ var item:DisplayObject3D = rootNode.getChildByName("item"); if(item!=null){ item.rotationX++; item.rotationY++; item.rotationZ++; } du++; if(du==360)du=0; var newX:Number = movingRadius * formatNum(Math.cos(du*TH), 3); var newZ:Number = movingRadius * formatNum(Math.sin(du*TH), 3); camera.x = newX; camera.z = newZ; scene.renderCamera(camera); } private function formatNum(num:Number, cnt:Number):Number{ return Math.round(num * Math.pow(10, cnt)) / Math.pow(10, cnt); } private function onTimer(event:TimerEvent):void{ var item:DisplayObject3D = rootNode.getChildByName("item"); if(item!=null){ var pName:String = "p" + (Math.floor(Math.random()*6)+1); var p:DisplayObject3D = item.getChildByName(pName); if(p!=null){ p.material = new BitmapFileMaterial(getFileName()); } } } private function getFileName():String{ return "http://ben.rb.chang.googlepages.com/photos"+(Math.floor(Math.random()*photoCount)+1)+".JPG"; }}}
看效果!
於 6/13/2007 04:22:00 下午 1 意見
標籤: AS3, Flash, Papervision3D
Papervision3D 教學 part 2.3 -- 用外部圖檔做貼圖材質
貼圖材質,除了可以貼純色 (ColorMaterial) 與 BitmapData (BitmapMaterial) 之外,還可以直接拿外部圖檔 (BitmapFileMaterial) 進行貼圖,以下這個範例我就是採用 BitmapFileMaterial 貼圖,並且每隔 3000 微秒就將圖片重新載入貼過!程式碼如下:
package {import flash.display.Sprite;import flash.display.Bitmap;import flash.events.*;import flash.utils.*;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*import org.papervision3d.materials.*[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class T2step4 extends Sprite{ private static var PI:Number = Math.PI; private static var TH:Number = PI / 180; private var container:Sprite; private var scene:Scene3D; private var camera:Camera3D; private var rootNode:DisplayObject3D; private var du:Number = 0; private var movingRadius:int = 2000; private var movingHeight:int = 2000; private var photoIdx:int = 1; private var photoCount:int = 9; private var timer:Timer; public function T2step4() { // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D); addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel); } private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.y = movingHeight; camera.z = -movingRadius; camera.zoom = 10; camera.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); var ground:DisplayObject3D = rootNode.addChild(new Plane(new ColorMaterial(0xffcc00), 500, 500, 10, 10), "ground"); ground.rotationX = -90; var myCube1:DisplayObject3D = rootNode.addChild(new Cube(new BitmapFileMaterial(getFileName()), 100, 100, 100, 1, 1, 1), "myCube1"); myCube1.y = 50; timer = new Timer(3000, 0); timer.addEventListener(TimerEvent.TIMER, onTimer); timer.start(); } private function loop3D(event:Event):void{ /* du++; if(du==360)du=0; */ du = 360 * (this.mouseX / stage.stageWidth); var newX:Number = movingRadius * formatNum(Math.cos(du*TH), 3); var newY:Number = movingHeight; var newZ:Number = movingRadius * formatNum(Math.sin(du*TH), 3); camera.x = newX; camera.y = newY; camera.z = newZ; scene.renderCamera(camera); } private function formatNum(num:Number, cnt:Number):Number{ return Math.round(num * Math.pow(10, cnt)) / Math.pow(10, cnt); } private function onMouseWheel(event:MouseEvent):void{ //event.delta = 3 | -3 movingRadius -= event.delta*10; if(movingRadius<=0)movingRadius=1; movingHeight -= event.delta*10; if(movingHeight<=200)movingHeight=200; } private function onTimer(event:TimerEvent):void{ var myCube1:DisplayObject3D = rootNode.getChildByName("myCube1"); myCube1.material = new BitmapFileMaterial(getFileName()); } private function getFileName():String{ return "http://ben.rb.chang.googlepages.com/photos"+(Math.floor(Math.random()*photoCount)+1)+".JPG"; }}}
測試畫面如下:
同樣的機制,我把先前教過的範例再加上這個週期換圖的效果,感覺又更絢麗了!程式碼如下,每個 Cube 都有自己的 Timer 控制,換圖時間不一定,以亂數決定的!
package {import flash.display.Sprite;import flash.display.Bitmap;import flash.events.Event;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*import org.papervision3d.materials.* import flash.utils.Timer;import flash.events.TimerEvent;[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class Step8 extends Sprite{ private var container:Sprite; private var scene:Scene3D; private var camera:Camera3D; private var rootNode:DisplayObject3D; private var AMOUNT:int = 50; private var rotationSettingArray:Array = new Array(); private var timerArray:Array = new Array(); private var photoCount:int = 9; public function Step8() { // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D); } private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.z = -3000; camera.zoom = 10; camera.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); for(var i:int=0; i<AMOUNT; i++){ var myCube:DisplayObject3D = rootNode.addChild(new Cube(new BitmapFileMaterial(getFileName()), 100, 100, 100, 1, 1, 1), "myCube" + i); myCube.moveBackward(Math.random() * (3000-100/2+1)); if(Math.random()*2>1) myCube.moveLeft(Math.random()*500); else myCube.moveRight(Math.random()*500); if(Math.random()*2>1) myCube.moveUp(Math.random()*500); else myCube.moveDown(Math.random()*500); rotationSettingArray.push({rX:(Math.random()-Math.random())*2 , rY:(Math.random()-Math.random())*2 , rZ:(Math.random()-Math.random())*2}); var timer:Timer = new Timer((Math.round(Math.random()*5)+5)*1000, 0); timer.addEventListener(TimerEvent.TIMER, onTimer); timer.start(); timerArray.push(timer); } } private function loop3D(event:Event):void{ for(var i:int=0; i<AMOUNT; i++){ var myCube:DisplayObject3D = rootNode.getChildByName("myCube" + i); if(myCube!=null){ myCube.rotationX+=rotationSettingArray[i].rX; myCube.rotationY+=rotationSettingArray[i].rY; myCube.rotationZ+=rotationSettingArray[i].rZ; } } scene.renderCamera(camera); } private function onTimer(event:TimerEvent):void{ for(var i:int=0; i<timerArray.length; i++){ if(event.target==timerArray[i]){ var myCube:DisplayObject3D = rootNode.getChildByName("myCube"+i); var fileName:String = getFileName(); trace(fileName); myCube.material = new BitmapFileMaterial(fileName); } } } private function getFileName():String{ return "http://ben.rb.chang.googlepages.com/photos"+(Math.floor(Math.random()*photoCount)+1)+".JPG"; }}}
看效果!
於 6/13/2007 12:47:00 下午 0 意見
標籤: AS3, Flash, Papervision3D
Papervision3D 教學 part 2.2 -- 空照 與滑鼠互動
繼續上一篇的 Camera 操控,這次加上滑鼠,左右移動可以控制 camera 繞著圓心做旋轉,然後滾輪的部份,我會用來同時改變 carema 的高度以及繞圓心旋轉的半徑,程式碼如下:
package {import flash.display.Sprite;import flash.display.Bitmap;import flash.events.*;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*import org.papervision3d.materials.*[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class T2step3 extends Sprite{ private static var PI:Number = Math.PI; private static var TH:Number = PI / 180; [Embed(source="../assets/IMG_1054.JPG")] private var CubeTexture:Class; private var container:Sprite; private var scene:Scene3D; private var camera:Camera3D; private var rootNode:DisplayObject3D; private var du:Number = 0; private var movingRadius:int = 2000; private var movingHeight:int = 2000; public function T2step3() { // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D); addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel); } private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.y = movingHeight; camera.z = -movingRadius; camera.zoom = 10; camera.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); var ground:DisplayObject3D = rootNode.addChild(new Plane(new ColorMaterial(0xffcc00), 500, 500, 10, 10), "ground"); ground.rotationX = -90; var cubeTexture:Bitmap = new CubeTexture() as Bitmap; var myCube1:DisplayObject3D = rootNode.addChild(new Cube(new BitmapMaterial(cubeTexture.bitmapData), 100, 100, 100, 1, 1, 1), "myCube1"); myCube1.y = 50; } private function loop3D(event:Event):void{ /* du++; if(du==360)du=0; */ du = 360 * (this.mouseX / stage.stageWidth); var newX:Number = movingRadius * formatNum(Math.cos(du*TH), 3); var newY:Number = movingHeight; var newZ:Number = movingRadius * formatNum(Math.sin(du*TH), 3); camera.x = newX; camera.y = newY; camera.z = newZ; scene.renderCamera(camera); } private function formatNum(num:Number, cnt:Number):Number{ return Math.round(num * Math.pow(10, cnt)) / Math.pow(10, cnt); } private function onMouseWheel(event:MouseEvent):void{ //event.delta = 3 | -3 movingRadius -= event.delta*10; if(movingRadius<=0)movingRadius=1; movingHeight -= event.delta*10; if(movingHeight<=200)movingHeight=200; }}}
看效果!
於 6/13/2007 10:43:00 上午 6 意見
標籤: AS3, Flash, Papervision3D
Papervision3D 教學 part 2 -- 空照
我第二篇 PaperVision3D 的教學,是針對 Camera 的基本操控,這個範例我將 Camera 移到空中 高度 2000 的位置(y=2000),在 onEnterFrame() 時,會設定 carema 的座標,繞著中心點作旋轉,有點像是衛星移動的感覺。不過若是只對著一個 myCube1 做拍照的話,可能這樣的範例會看不出到底是 myCube1 在自己旋轉,還是 camera 在繞著他旋轉,所以我另外製作了一 Plane 物件名叫 ground 作為地板,預設這個地板是 X-Y 面向的單面,我需要將他順著 X 軸做翻轉,變成 X-Z 面向。
package {import flash.display.Sprite;import flash.display.Bitmap;import flash.events.Event;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*import org.papervision3d.materials.*[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class T2step1 extends Sprite{ private static var PI:Number = Math.PI; private static var TH:Number = PI / 180; [Embed(source="../assets/IMG_1054.JPG")] private var CubeTexture:Class; private var container:Sprite; private var scene:Scene3D; private var camera:Camera3D; private var rootNode:DisplayObject3D; private var du:Number = 0; public function T2step1() { // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D); } private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.y = 2000; camera.z = -2000; camera.zoom = 10; camera.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); var ground:DisplayObject3D = rootNode.addChild(new Plane(new ColorMaterial(0xffcc00), 500, 500, 1, 1), "ground"); ground.rotationX = -90; var cubeTexture:Bitmap = new CubeTexture() as Bitmap; var myCube1:DisplayObject3D = rootNode.addChild(new Cube(new BitmapMaterial(cubeTexture.bitmapData), 100, 100, 100, 1, 1, 1), "myCube1"); myCube1.y = 50; } private function loop3D(event:Event):void{ du++; if(du==360)du=0; var newX:Number = 2000 * formatNum(Math.cos(du*TH), 3); var newZ:Number = 2000 * formatNum(Math.sin(du*TH), 3); camera.x = newX; camera.z = newZ; scene.renderCamera(camera); } private function formatNum(num:Number, cnt:Number):Number{ return Math.round(num * Math.pow(10, cnt)) / Math.pow(10, cnt); }}}
測試畫面如下:
你可能會發現,在 camera 繞著中心旋轉拍攝時,地面 ground 與 myCube1 某些部份會有些重疊衝突的問題,你需要時時想像,其實我們看到的 " 一個面 ",並不是真的由一個面構成,而是由 PV3D engine 將這個面拆成多個三角形拼貼而成的。對於這個問題,我試圖將 myCube1 的高度拉更高一點,從 myCube1.y = 51 一直拉到 100 以上,這個問題會得到改善,但還是會出現重疊三角形。另一種做法也可以改善這個問題,就是將地面的 segments 增加,由原本的 1 改成 10 以上,這樣一來,地面就是由更多的小三角碎片所組成的,而重疊時會造成的破碎感覺會小一點點,不過想必這樣的運算會比較多,所以,就別介意這種視覺問題囉!以下是改過的程式碼:
package {import flash.display.Sprite;import flash.display.Bitmap;import flash.events.Event;import org.papervision3d.cameras.Camera3D;import org.papervision3d.scenes.Scene3D;import org.papervision3d.objects.*import org.papervision3d.materials.*[SWF(backgroundColor="#000000", frameRate="60", width="400", height="400")]public class T2step2 extends Sprite{ private static var PI:Number = Math.PI; private static var TH:Number = PI / 180; [Embed(source="../assets/IMG_1054.JPG")] private var CubeTexture:Class; private var container:Sprite; private var scene:Scene3D; private var camera:Camera3D; private var rootNode:DisplayObject3D; private var du:Number = 0; public function T2step2() { // initialize the objects init3D(); // add a listener for the 3D loop addEventListener(Event.ENTER_FRAME, loop3D); } private function init3D():void{ container = new Sprite(); addChild(container); container.x = 200; container.y = 200; scene = new Scene3D(container); camera = new Camera3D(); camera.y = 2000; camera.z = -2000; camera.zoom = 10; camera.focus = 100; rootNode = scene.addChild(new DisplayObject3D("rootNode")); var ground:DisplayObject3D = rootNode.addChild(new Plane(new ColorMaterial(0xffcc00), 500, 500, 10, 10), "ground"); ground.rotationX = -90; var cubeTexture:Bitmap = new CubeTexture() as Bitmap; var myCube1:DisplayObject3D = rootNode.addChild(new Cube(new BitmapMaterial(cubeTexture.bitmapData), 100, 100, 100, 1, 1, 1), "myCube1"); myCube1.y = 50; } private function loop3D(event:Event):void{ du++; if(du==360)du=0; var newX:Number = 2000 * formatNum(Math.cos(du*TH), 3); var newZ:Number = 2000 * formatNum(Math.sin(du*TH), 3); camera.x = newX; camera.z = newZ; scene.renderCamera(camera); } private function formatNum(num:Number, cnt:Number):Number{ return Math.round(num * Math.pow(10, cnt)) / Math.pow(10, cnt); }}}