写了一个建场景的类
glemon (2009-02-11 16:18:09)
为了方便工作,于是写了一个建场景类,每次应用pv3d时,就继承这个类,不需要重复又重复地写那些“基础设施”,感觉蛮方便的,现在拿出来和大家分享一下吧,另外,希望大家可以帮忙完善一下。因为懒,直接COPY过来算了。应用的时候,只需要继承它,并调用一下init和按需要override一些方法就好了。
package
{
import flash.display.Sprite;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.cameras.FreeCamera3D;
import org.papervision3d.core.geom.Vertices3D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;
import flash.events.Event;
public class Mode extends Sprite
{
protected var viewPort:Viewport3D;
protected var renderer:BasicRenderEngine;
protected var scene:Scene3D;
protected var camera:FreeCamera3D;
protected var camPos:Number3D = new Number3D(0,0,-1000); //这是设置或记录camera坐标属性的参数
protected var camRot:Number3D = new Number3D(); //这是设置或记录camera的rotationX,rotationY,rotationZ的参数,x对应roationX,y对应rotationY,z对应rotationZ
protected var camFov:Number3D = new Number3D(60,2,100); //这是设置或记录camera的fov、zoom、focus的参数,x对应fov, y对应zoom, z对应focus
protected var sw:int; //scene的宽度
protected var sh:int; //scene的高度
protected var inited:Boolean=false; //标记三维场景是否已被生成
public function Mode(_act:Boolean=false):void //测试的时候令act=true就可以直接运行代码,而实际应用中,大多数都要在指定的条件下运行代码的,所以设置了一个act方法。
{
if (_act) act();
}
public function act():void //防止在未被加入显示列表时访问stage
{
if (stage) onAddToStage(null);
else addEventListener(Event.ADDED_TO_STAGE, onAddToStage, false, 0, true);
}
public function onAddToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddToStage);
addEventListener(Event.REMOVED_FROM_STAGE, onRemoveFromStage, false, 0, true);
addEventListener(Event.RESIZE, onResize, false, 0, true);
}
public function onRemoveFromStage(e:Event):void
{
removeEventListener(Event.REMOVED_FROM_STAGE, onRemoveFromStage);
}
public function onResize(e:Event):void //在改变视窗大小的时候会触发这个事件,需要的时候override就行
{
}
public function init (w:Number=0,h:Number=0,x:Number=0,y:Number=0,interactive:Boolean=true):void //在应用的时候才调用的方法,一旦被调用,一个三维场景就被生成出来了,当然,你还得向它添加物件,否则只会看到白茫茫一片
{
//stage.scaleMode = "noScale";
onResize(null);
init3D(w,h,x,y);
createObject();
setEvents();
inited = true;
}
// ___________________________________________________________________ init3D
public function init3D(w:Number,h:Number,x:Number,y:Number,interactive:Boolean=true):void //生成三维场景需要的元素——viewport、scene、camera、render
{
// Create viewport
var autoScale:Boolean = false;
if (w == 0 || h == 0)
{
autoScale = true;
sw = stage.stageWidth;
sh = stage.stageHeight;
}
else
{
sw = w;
sh = h;
}
viewPort = new Viewport3D(w, h,autoScale,interactive);
viewPort.x = x;
viewPort.y = y;
this.addChild(viewPort);
// Create scene
scene = new Scene3D();
camera = new FreeCamera3D(camFov.x,camFov.y,camFov.z);
updateCameraPos();
renderer = new BasicRenderEngine();
}
public function setEvents():void
{
this.addEventListener( Event.ENTER_FRAME, loop ,false,0,true);
}
public function removeEvents(exLoop:Boolean=false):void
{
if(!exLoop) this.removeEventListener( Event.ENTER_FRAME, loop );
}
// ___________________________________________________________________ create 3d Object
protected function createObject():void //继承的时候override这个方法,把生成的物件都在这里定义生成就行,很方便的。
{
}
protected function loop(e:Event):void //响应EnterFrame事件的方法
{
renderer.renderScene(scene, camera, viewPort);
}
protected function resetCameraPosData():void //这是方便实时获取camera的常用属性的方法
{
camPos = new Number3D(camera.x, camera.y, camera.z);
camRot = new Number3D(camera.rotationX, camera.rotationY, camera.rotationZ);
camFov = new Number3D(camera.fov, camera.zoom, camera.focus);
}
protected function updateCameraPos():void ////这是方便实时设置camera的常用属性的方法
{
camera.x = camPos.x;
camera.y = camPos.y;
camera.z = camPos.z;
camera.rotationX = camRot.x;
camera.rotationY = camRot.y;
camera.rotationZ = camRot.z;
camera.fov = camFov.x;
camera.zoom = camFov.y;
camera.focus = camFov.z;
}