Away3D学习笔记-元素点选
在Flash里调试影片总是很慢很慢,关掉actionscript的警告信息后,速度似乎的确快了一点,勉强可以承受。
研究Away3D卡在物体点选上,总找不到合适的监听函数一劳永逸地解决所有物体的精确点选,后来在某国外blog上看到一个球面点选的例子,但代码已经过时了,不再适用于3.6.0,于是根据他提供的思路,自己摸索了一下,搞定了点选问题。
其实3.6.0把每次鼠标点中的对象和点中的几何元素都传给了MouseEvent3D对象,而通常我们只适用它的target或者object属性,却忽略了表示几何元素的elementVO属性。
elementVO在Aawy3D中一个重要继承是faceVO,faceVO中的face属性就是当前选中的三角形,faceVO的其他属性在Away3D的文档中没有解释,源代码中也没有一行注释,可能是还处于半开发阶段。不过face类能用就行。
面是所有几何体的基础,任何几何体都是由若干个三角形面组成的。在Away3D中要实现灵活的图形绘制,也一定会和face类打交道。
face类的重要属性有material(材质,可以是任何材质对象),normal(面的法向量),v0,v1,v2(三角形面的三个点,按逆时针定义的),以及xyz三方向的最大和最小坐标maxX,minX....
如果要构造一个face,直接设置三个点是无效的,需要调用face类的moveTo,lineTo,curveTo方法,这些方法类似于graphics中的对应方法。绘制各边的顺序没有要求,可以顺时针也可以逆时针,但最后一定要封闭。有一种例外就是在一个已存在的face旁边构造face,利用已有face的一条边,则新构造的face可以不封闭。
回到物体点选的问题上,了解了face类之后,点选就很好做了,代码是这样的,很简短:
package { import away3d.cameras.Camera3D; import away3d.containers.Scene3D; import away3d.containers.View3D; import away3d.core.base.Face; import away3d.core.vos.FaceVO; import away3d.events.MouseEvent3D; import away3d.materials.WireColorMaterial; import away3d.primitives.Sphere; import flash.display.Sprite; [SWF(backgroundColor = "#000000", frameRate = "100", quality = "LOW", width = "800", height = "600")] public class test extends Sprite { private var scene:Scene3D; private var camera:Camera3D; private var view:View3D; public function test() { scene = new Scene3D(); camera = new Camera3D(); view = new View3D(); view.camera = camera; view.scene = scene; addChild(view); camera.z = -800; camera.x = 0; camera.y = 0; var sp:Sphere = new Sphere(); sp.material = new WireColorMaterial(0x000000, { wireColor:0xffffff } ); sp.radius = 200; sp.segmentsH = 20; sp.segmentsW = 20; sp.useHandCursor = true; sp.addEventListener(MouseEvent3D.MOUSE_DOWN, onmd); scene.addChild(sp); addEventListener(Event.ENTER_FRAME, onEnter); } private function onmd(e:MouseEvent3D):void { var fv:FaceVO = e.elementVO; if (fv.face.material != null) { fv.face.material = null; }else { fv.face.material = new WireColorMaterial(0xff0000, { wireColor:0xffffff } ); } } private function onEnter(e:Event):void { view.render(); } } }