第三章的基类
先写一个基类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/