本文主要介绍PV3D中的简单交互。
文本大部分代码建立在Papervision3D入门-创建PV3D基本内置模型(球体,立方体,柱状体等) 一文中的代码上。
PV3D中提供了一组专门负责3D交互的类,这些类都是以Interactive为开头,其中有InteractiveSprite,InteractiveScene3D,InteractiveSceneManager,InteractiveWireframeMaterial 等等。要实现3D交互功能我们就需要用到这些类。
首选,我们需要把3D场景的容器对象,改成InteractiveSprite类型:
// 创建3D舞台的容器
_container = new InteractiveSprite(); //原先的代码:new Sprite();
接着我们要把3D舞台改成支持交互操作的InteractiveScene3D类型:
private var _scene:InteractiveScene3D; //原先的代码::MovieScene3D;
// 创建3D舞台
_scene = new InteractiveScene3D(_container); //原先的代码:new MovieScene3D(_container);
比起普通的PV3D动画程序,PV3D的3D交互程序多了一个InteractiveSceneManager对象,它负责所有的3D事件。所以代码中需要增加一个私有变量:
private var _interactiveSceneManager:InteractiveSceneManager;
private function Init3D():void
{
//...
_interactiveSceneManager = _scene.interactiveSceneManager;
_interactiveSceneManager.faceLevelMode = true;
//注册3D鼠标事件
_interactiveSceneManager.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, OnObj3DMouseOver);
_interactiveSceneManager.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, OnObj3DMouseOut);
//...
}
private function OnObj3DMouseOver(event:InteractiveScene3DEvent):void{
event.face3d.material = this._material2; //换材质,突出显示被选中的face
}
private function OnObj3DMouseOut(event:InteractiveScene3DEvent):void{
event.face3d.material = this._material1; //换回原来材质
}
你可以看到上面的代码将InteractiveSceneManager对象的faceLevelMode设置成true。
这里需要说明下,PV3D给InteractiveSceneManager设计了两种状态,一种是对象(object)级别的交互,一种是面(face)级别的交互,对象级别的交互就是只精确到某个对象,比如一个Cube或者一个Plane,而面级别的交互可以精确到PV3D显示的最小单位face3D,面级别的交互更精确,但是执行效率比对象级别低很多,所以大家设计交互时需要考虑到这点。
另外代码中用到的贴图需要换成支持交互事件的InteractiveWireframeMaterial类型,为了突出显示,我还另外用了一个InteractiveColorMaterial类型的红色贴图。关于材质贴图的代码修改:
private var _material1:InteractiveWireframeMaterial;
private var _material2:InteractiveColorMaterial;
private function Init3D():void {
//...
_material1 = new InteractiveWireframeMaterial(0x000000);
_material2 = new InteractiveColorMaterial(0xFF0000);
materialList.addMaterial(_material1, "top");
materialList.addMaterial(_material1, "bottom");
materialList.addMaterial(_material1, "front");
materialList.addMaterial(_material1, "back");
materialList.addMaterial(_material1, "left");
materialList.addMaterial(_material1, "right");
//...
}
整个程序的运行效果如下(请把鼠标放上去试试):
http://flex.unbe.cn/PV3D/Try07_InteractiveCube/Main.swf
这个例子中只实现了face的选择,并没有做到Colorfulee问我的选择Cube某个面的效果,不过通过在鼠标事件中比对材质的id,我们是可以知道Cube的哪个面被选择的,不过需要为每个面都示例化一个材质贴图,不能像示例代码中那样几个面都共享同一个贴图实例。有兴趣的朋友可以自己试试看。
dmh2002注:本文在原文基础上略有改变,如果需要以上代码的完整源文件,可以参看原文地址。
原文地址:http://www.unbe.cn/blog/?p=325