第三章的基類
先寫一個基類Chapter03SampleBase.as,位於flash3dbook.ch03包內。后面的例子都會在它的基礎上擴展。
這個基類定義了三個保護成員變量:_view, _cube1, _cube2;四個保護成員函數:_createView(), _createScene(), _createCamera()和_onEnterFrame()。在_createScene()函數中,生成了一個Trident(三叉線)類型的trident實例和兩個Cube。
=========================================
[更新:2011-10-14 16:40]
創建和使用視圖
_vew = new View3D();
addChild(_view);
為了顯示場景和里面的物體,需要調用View3D的render()方法。通常,每幀都需要調用render(),只有這樣,才能持續的更新顯示場景。如下所示:
protected function _onEnterFrame(e:Event):void
{
_view.render();
}
居中放置消失點(vanishing point)
視圖的x,y坐標定義了所有透視圖的中心點。在三維圖形學中,這個點稱為消失點(vanishing point)。
視圖的默認位置是在舞台的(0,0),也就是左上角。為了得到平衡的透視效果,最好把視圖放置於舞台中心點。
_view.x = 400;
_view.y = 300;
裁剪視圖
Away3D里負責裁剪視圖的類位於away3d.core.clip包內。與場景和攝像機一樣,視圖初始化時,會創建一個默認的裁剪實例,作為視圖的clipping屬性。clipping類代表了許多不同的裁剪方式,但都可以用minX, maxX, minY和maxY定義視圖的邊界。
默認情況的clipping屬性是RectangleClipping類,邊界是無限的。此時舞台的邊界就是視圖邊界。
為了將視圖限制到更小的區域,可以重新設置clipping邊界的尺寸。比如:
_view.clipping.minX = -100;
_view.clipping.maxX = 100;
_view.clipping.minY = -100;
_view.clipping.maxY = 100;
上面的代碼定義了一個200x200的視圖,中心點是消失點。
也可以先定義一個RectangleClipping對象,設置好他的尺寸,然后賦值給clipping屬性:
var clipping:RectangleClipping = new RectangleClipping();
clipping.minX = -100;
clipping.maxX = 100;
clipping.minY = -100;
clipping.maxY = 100;
_view.clipping = clipping;
管理場景
Scene3D類可以包含嵌套的三維物體的層級結構。這種樹狀圖通常稱為場景圖(scene graph)。
添加刪除物體
Away3D中大部分可以渲染的物體都繼承自Object3D基類。可以使用addChild和removeChild添加至場景。
獲取場景中的三維物體
獲取ObjectContainer3D實例的子元素,可以使用它的children屬性。返回值是一個數組,包含所有的三維子物體,從而可以得到一些有用的信息。比如,children數組的length屬性,可以用來表示子元素的個數。
如果知道一個子元素添加入場景的順序,可以通過它的索引來獲取。比如
var cube:Cube = _view.scene.children[0];
另外,也可以通過物體的名字來獲取。
Away3D沒有提供getChildIndex()和setChildIndex()。因為Away3D提供了Z軸自動排序功能,其中的Object3D的索引值是不斷變化的。
使用嵌套三維物體
所有的Object3D物體都有一個parent屬性,指向包含他們的ObjectContainer3D實例。每個三維物體只能有一個parent。
三維空間的移動,旋轉和縮放
在場景圖中,所有物體的坐標都是相對於它的父級容器的,而不是相對於世界坐標。這種安排稱之為層級坐標系統(hierarchical coordinate system),經常在圖形設計軟件中使用。
當繞多個軸旋轉物體時,旋轉操作的順序十分重要。這在三維中叫做gimbal lock。
把容器當做樞紐(pivots)
如果沒有深厚的數學功底,圍繞空間任意點旋轉物體不是個簡單的操作。但是,如果使用容器當做樞紐,可以大大降低難度。
在Away3D中,rotationX, rotationY, rotationZ屬性分別表示繞x軸,y軸和z軸的旋轉角度。對於內部創建的原始幾何體,它們的坐標系原點位於幾何體中心。
創建使用攝像機
Away3D提供了好幾種攝像機,均位於away3d.cameras包內。攝像機定義了zoom和focus屬性,它們可以影響場景的透視效果。每種攝像機都能提供不同的運動軌跡。
最基本的攝像機是Camera3D,View3D初始化時會自動創建一個,作為View3D的camera屬性。這種攝像機放置在Z軸-1000的位置,正對着場景的原點,能產生標准的正面視圖。
Camera3D物體
我們可以自定義攝像機。
var camera:Camera3D = new Camera3D();
camera.x = 0;
camera.y = 0;
camera.z = -1000;
_view.camera = camera;
移動攝像機
直接設置攝像機的x,y和z屬性就可。
旋轉攝像機
攝像機的旋轉使用它的rotationX,rotationY和rotationZ屬性,和普通的三維物體相同。比如:
camera.rotationY = 10;
調整zoom和focus屬性
Away3D的攝像機有很多真實照相機的屬性,比如zoom,focus和lens等。這里只討論zoom和focus。lens較為復雜,會在后面詳細描述。
camera.zoom = 10;
camera.focus = 100;
zoom和攝像機的放大倍數密切相關。zoom越大,放大倍數也越大。
focus屬性和實際鏡頭的焦距不同,在Away3D中,它指攝像機位置和視平面的距離。focus越小,攝像機離視平面越近,視角越寬廣,類似於廣角鏡頭,有較大的畸變。
使用lookAt()瞄准物體
通常,移動攝像機時,鏡頭都會對准場景中的某感興趣的物體。實時計算攝像機的旋轉角度並不是一件容易的事情,所以,貼心的Away3D為每個攝像機類都編寫了lookAt()函數,為開發者提供便利。
lookAt()函數需要一個位置向量,類型是away3d.math.Number3D,當做攝像機對准的位置坐標。比如:
camera.lookAt(new Number3D(0, 0, 0));
[注:因為3D in Flash這本書出版的時候,使用的是較舊的版本Away3D v3.5,最新的版本v3.6中,已取消Number3D類型,並以flash.geom.Vector3D代替]
通常我們更希望把攝像頭對准一個物體,而不僅僅是一個位置坐標。所有的3D物體都有一個position屬性,代表了該物體在本地坐標系的位置向量。這個屬性可以用在lookAt()函數中。比如,我們想注視_cube2,可以這么寫:
camera.lookAt(_cube2.position);
Camera3D的lookAt()函數繼承自Object3D類,這意味着,所有Away3D的任意3D物體都可以旋轉指向某一空間向量。然而,它的實際用途通常只用於操控攝像頭。
TargetCamera3D對象
大部分的Away3D項目,場景都是動態變化的。有時候,為了始終顯示某一物體,需要將攝像頭始終對准它。如果你看過上一小節,可能會想到每幀都使用lookAt()實現這個功能。
你想的沒錯。但是因為這個功能在Away3D中經常遇到,所以有個專門的類TargetCamera3D專門負責這個。它的target屬性告訴TargetCamera3D的跟蹤目標,在隨后的渲染中,攝像機的角度會自動調整。
我們可以創建另外一個Chapter03SampleBase的子類:
var camera:TargetCamera3D = new TargetCamera3D();
camera.z = -1000;
camera.target = _cube2;
_view.camera = camera;
為了驗證TargetCamera3D對象自動調用自身的lookAt()函數,我們可以添加一些動作:
protected override function _onEnterFrame(e:Event):void
{
_view.camera.y = -(stage.mouseY - stage.stageHeight/2);
_view.camera.y = (stage.mouseY - stage.stageHeight/2);
_view.render();
}
HoverCamera3D對象
在一些Flash 3D應用中,用戶為了查看物體的各個側面,可以環繞該物體旋轉攝像機。HoverCamera3D類是這類交互的理想選擇,因為它會自動計算環繞軌道的路徑和攝像機角度,減少了開發者的開發難度,還提供了一些額外功能。
HoverCamera3D繼承自TargetCamera3D,並添加了一些新的功能。我們可以這樣使用它:
_hoverCamera = new HoverCamera();
_hoverCamera.distance = 2000;
_hoverCamera.tiltAngle = 10;
_view.camera = _hoverCamera;
在_onEnterFrame偵聽函數中,可以這樣刷新它:
_hoverCamera.panAngle = stage.mouseX - stage.stageWidth/2;
_hoverCamera.hover();
_view.render();
涉及到的屬性有distance,tiltAngle和panAngle。使用兩個角度和一個長度來定義空間的一個坐標點,這種系統叫做極坐標系統(polar coordinates)。
真實的攝像機的位置和旋轉角度,是通過調用hover()函數得到的。
你可能已經注意到,在攝像機運動過程中,有一些慣性阻力現象。這是因為HoverCamera3D在更新位置是使用了緩動。緩動程度可以通過steps屬性調節。默認值是8,數值越大,運動越平滑。比如:
hoverCamera.steps = 16;
轉自:http://blog.163.com/liuzhuan_1986/blog/static/2577961020119811562297/