我从0开始学习Away3D,就先从官网开始开始吧!在官网,首先下Away3D的包。在官网有基础教程,可以先去下载下来,在Flash builder 里边运行起来看看效果,了解Away3D的构建流程。
熟悉练习了几天,就把构建基础的3D流程写下来,当做笔记使用。
首先,我们要定义变量。有视口(View),场景(Scene),相机(Camera),相机控制器(Controller),灯光(LightPicker),材质(Material),模型(Gemotery),网格(Mesh)。
刚接触这个,分得有点细,可能有些东西还没包裹进来。
初始化程序,先设定对其方式,以及缩放方式。一般都是不缩放,左上对其。然后初始化各个模块。一般是从视口开始,然后到控制器,灯光,模型,网格.
stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; Init();
private function Init():void { InitEngine(); InitMatrial(); InitMesh(); InitListener(); }
初始化视口这里。先new 一个场景,再new 一个相机,然后new 一个视口。设置视口的antiAlias属性抗锯齿。将视口添加到舞台。如果不添加到舞台,后边会报错。将视口的场景和相机指定给之前创建的场景和相机。虚拟的3D camera通过模型的透视图来调整zoom,focus和position属性。通过建立一个场景控制器,一般用HoverController。来观看3D世界。HoverController通过控制x轴方向和y轴方向的旋转来控制摄像机的角度。
1:HoverController 摄像机围绕某点旋转。这个我们经常用来坐360度环绕某点查看某3D物体。或者制作360度全景图。
2 FirstPersonController。第一人称视角控制器。这个可以完美的模拟出以第一视角漫游。
这里有一些文章关于这些的说明:http://bbs.9ria.com/thread-141148-1-1.html http://www.narkii.com/club/thread-261415-1.html
private function InitEngine():void { _scene = new Scene3D(); _camera = new Camera3D(); _view = new View3D(); _view.antiAlias = 4; _view.scene = _scene; _view.camera = _camera; addChild(_view); _controller = new HoverController(_camera); _controller.panAngle =45; _controller.tiltAngle =15; _controller.distance =800; }
private function InitMatrial():void { var _videoTexture:VideoTexture = new VideoTexture("../embeds/Eric.flv",256,256,true,true); _planeMaterial = new TextureMaterial(_videoTexture); }
private function InitMesh():void { var radious:int = 270; var angle:int =90; for(var i:int =0 ;i <6 ;i++) { var _planeGeometry:PlaneGeometry = new PlaneGeometry(radious *2 ,radious *2,1,1,true,false); _planeGeometry.doubleSided = true; _planeGeometry.yUp = false; var _plane:Mesh = new Mesh(_planeGeometry,_planeMaterial); if (i < 4) { _plane.x = accurateNumber(radious * Math.sin((angle * i) / 180 * Math.PI), 1); _plane.z = accurateNumber(radious * Math.cos((angle * i) / 180 * Math.PI), 1); if(i%2==0) _plane.rotationY = 180-angle * i; else _plane.rotationY = -angle * i; } else { if (i == 4) { _plane.rotationX = angle; _plane.y = radious; } else { _plane.rotationX = -angle; _plane.y = -radious; } } _cubeVector.push(_plane); _scene.addChild(_plane); } }
private function InitListener():void { addEventListener(Event.ENTER_FRAME,enterHandler); stage.addEventListener(Event.RESIZE,resizeHandler); stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler); stage.addEventListener(MouseEvent.MOUSE_UP,mouseUpHandler); stage.addEventListener(MouseEvent.MOUSE_WHEEL,mouseWhellHandler); } private function enterHandler(e:Event):void { if(_move) { _controller.panAngle = 0.3 *(stage.mouseX - _lastMouseX) + _lastPanAngle; _controller.tiltAngle = 0.3 * (stage.mouseY - _lastMouseY) + _lastTiltAngle; } _controller.update(); _view.render(); } private function resizeHandler(e:Event = null):void { _view.width = stage.stageWidth; _view.height = stage.stageHeight; } private function mouseDownHandler(e:MouseEvent):void { _move = true; _lastPanAngle = _controller.panAngle; _lastTiltAngle = _controller.tiltAngle; _lastMouseX = stage.mouseX; _lastMouseY = stage.mouseY; } private function mouseUpHandler(e:MouseEvent):void { _move = false; } private function mouseWhellHandler(e:MouseEvent):void { if (e.delta < 0) //向下滚动 { _controller.distance += 10; } else { _controller.distance -= 10; } }
创建模型的时候,我们很容易想到立方体,圆柱体,椎体等几何体。这里也有。在这里可以创建你想要的这些基本模型。不过,有时候,面还是很好用的,就是Plane,它也是一个模型。不过用面,你可以自己构成更多的几何体。调整x,y,z,调整rotation就可以实现更多的几何体。
在材质那里。我们提供的图片的宽高都必须是2的n次幂。网上有它的说法。
对于away3D的坐标系,个人觉得是左手坐标系。网上也有说法。知道坐标系后,先确定一个面,然后去调整,旋转,就可以实现多个几何体了。
下边贴出完整的代码,这个是通过6个面拼成的一个立方体视频盒子。
还有,away3D里边的运动,我们可以用TweenMax,TweenLite这些第三方类。移动摄像机,去围绕一个对象旋转,就可以把整个对象看清楚了。
package { import away3d.cameras.Camera3D; import away3d.containers.Scene3D; import away3d.containers.View3D; import away3d.controllers.HoverController; import away3d.entities.Mesh; import away3d.materials.TextureMaterial; import away3d.primitives.PlaneGeometry; import away3d.textures.VideoTexture; import com.greensock.TweenMax; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.MouseEvent; [SWF(width = "1280" , height = "720" , frameRate = "60")] public class CubePlane extends Sprite { private var _view:View3D; private var _scene:Scene3D; private var _camera:Camera3D; private var _controller:HoverController; private var _planeMaterial:TextureMaterial; private var _cubeVector:Vector.<Mesh> = new Vector.<Mesh>(); private var _move:Boolean = false; private var _lastPanAngle:Number; private var _lastTiltAngle:Number; private var _lastMouseX:Number; private var _lastMouseY:Number; private var _timeTween:TweenMax; private var _timeAppearAnimation:Number; private var cameraInfoVector:Vector.<Array> = Vector.<Array>([[0, 0, 800], [90, 0, 800], [180, 0, 800], [270, 0, 800], [180, 90, 500], [180, -90, 500]]) public function CubePlane() { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; Init(); } private function Init():void { InitEngine(); InitMatrial(); InitMesh(); InitListener(); //appearAnimation(); } private function InitEngine():void { _scene = new Scene3D(); _camera = new Camera3D(); _view = new View3D(); _view.antiAlias = 4; _view.scene = _scene; _view.camera = _camera; addChild(_view); _controller = new HoverController(_camera); _controller.panAngle =45; _controller.tiltAngle =15; _controller.distance =800; } private function InitMatrial():void { var _videoTexture:VideoTexture = new VideoTexture("../embeds/Eric.flv",256,256,true,true); _planeMaterial = new TextureMaterial(_videoTexture); } private function InitMesh():void { var radious:int = 270; var angle:int =90; for(var i:int =0 ;i <6 ;i++) { var _planeGeometry:PlaneGeometry = new PlaneGeometry(radious *2 ,radious *2,1,1,true,false); _planeGeometry.doubleSided = true; _planeGeometry.yUp = false; var _plane:Mesh = new Mesh(_planeGeometry,_planeMaterial); if (i < 4) { _plane.x = accurateNumber(radious * Math.sin((angle * i) / 180 * Math.PI), 1); _plane.z = accurateNumber(radious * Math.cos((angle * i) / 180 * Math.PI), 1); if(i%2==0) _plane.rotationY = 180-angle * i; else _plane.rotationY = -angle * i; } else { if (i == 4) { _plane.rotationX = angle; _plane.y = radious; } else { _plane.rotationX = -angle; _plane.y = -radious; } } _cubeVector.push(_plane); _scene.addChild(_plane); } } /** * num传入的浮点数,deg小数点精度,如2代表小数点后两位 */ private function accurateNumber(num:Number, deg:int):Number { var degNum:Number = Math.pow(0.1, deg); return Math.round(num / degNum) * degNum; } private function InitListener():void { addEventListener(Event.ENTER_FRAME,enterHandler); stage.addEventListener(Event.RESIZE,resizeHandler); stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler); stage.addEventListener(MouseEvent.MOUSE_UP,mouseUpHandler); stage.addEventListener(MouseEvent.MOUSE_WHEEL,mouseWhellHandler); } private function enterHandler(e:Event):void { if(_move) { _controller.panAngle = 0.3 *(stage.mouseX - _lastMouseX) + _lastPanAngle; _controller.tiltAngle = 0.3 * (stage.mouseY - _lastMouseY) + _lastTiltAngle; } _controller.update(); _view.render(); } private function resizeHandler(e:Event = null):void { _view.width = stage.stageWidth; _view.height = stage.stageHeight; } private function mouseDownHandler(e:MouseEvent):void { _move = true; _lastPanAngle = _controller.panAngle; _lastTiltAngle = _controller.tiltAngle; _lastMouseX = stage.mouseX; _lastMouseY = stage.mouseY; } private function mouseUpHandler(e:MouseEvent):void { _move = false; } private function mouseWhellHandler(e:MouseEvent):void { if (e.delta < 0) //向下滚动 { _controller.distance += 10; } else { _controller.distance -= 10; } } private function appearAnimation():void { _timeTween=TweenMax.to(_controller, _timeAppearAnimation, {panAngle: cameraInfoVector[0][0], tiltAngle: cameraInfoVector[0][1], distance: cameraInfoVector[0][2], onComplete: effectAnimation}); } private function effectAnimation():void { //settingDelayTimeVector的长度和真实加载的图片个数相同 // if (tweenIndex == settingDelayTimeVector.length + 1) // { // stopTween(); // return; // } // // tweenPlaneIndex = tweenIndex % planeNum; // effectTween(); // tweenIndex++; } } }