• Away3D学习笔记(4)


    第三章的基类

    先写一个基类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属性,它们可以影响场景的透视效果。每种摄像机都能提供不同的运动轨迹。

    最基本的摄像机是Camera3DView3D初始化时会自动创建一个,作为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/

  • 相关阅读:
    变量提升
    前端UI框架和JS类库
    ES6---Map数据结构
    ES6---Set数据结构
    Array.from//Array.of的用法
    闭包的理解和应用场景
    vue-router 的用法
    原型链和作用域链的理解
    WordPress更换了域名 主页、文章、图片路径错误 解决办法
    wordpress 安装新的主题后启动后报错
  • 原文地址:https://www.cnblogs.com/mzbdadou/p/2410031.html
Copyright © 2020-2023  润新知