package { import flash.events.Event; import mx.collections.ArrayCollection; import mx.core.Application; import mx.core.UIComponent; import org.papervision3d.cameras.Camera3D; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; import fr.seraf.wow.primitive.WSphere; import fr.seraf.wow.core.WOWEngine; import fr.seraf.wow.core.data.WVector; public class EngineManager extends UIComponent { // Papervision viewport public var viewport:Viewport3D = null; // Papervision rendering engine public var renderer:BasicRenderEngine = null; // Papervision scene public var defaultScene:Scene3D = null; // Papervision camera public var defaultCamera:Camera3D = null; // a collection of the BaseObjects protected var baseObjects:ArrayCollection = new ArrayCollection(); // a collection where new BaseObjects are placed, to avoid adding items // to baseObjects while in the baseObjects collection while it is in a loop protected var newBaseObjects:ArrayCollection = new ArrayCollection(); // a collection where removed BaseObjects are placed, to avoid removing items // to baseObjects while in the baseObjects collection while it is in a loop protected var removedBaseObjects:ArrayCollection = new ArrayCollection(); // the last frame time protected var lastFrame:Date; // the WOW physics engine public var wow:WOWEngine; public function EngineManager() { super(); } public function startup():void { // initialize the Papervision 3D engine components viewport = new Viewport3D(Application.application.height, Application.application.width, true); addChild(viewport); renderer = new BasicRenderEngine(); defaultScene = new Scene3D(); defaultCamera = new Camera3D(); addEventListener(Event.ENTER_FRAME, onEnterFrame); // set the initial frame time lastFrame = new Date(); wow = new WOWEngine(); wow.addMasslessForce(new WVector(0,10,0)); } protected function onEnterFrame(event:Event):void { // Calculate the time since the last frame var thisFrame:Date = new Date(); var seconds:Number = (thisFrame.getTime() - lastFrame.getTime())/1000.0; lastFrame = thisFrame; // sync the baseObjects collection with any BaseObjects created or removed during the // render loop removeDeletedBaseObjects(); insertNewBaseObjects(); wow.step(); // allow each BaseObject to update itself for each (var baseObject:BaseObject in baseObjects) baseObject.enterFrame(seconds); // render the scene renderer.renderScene(defaultScene, defaultCamera, viewport); } public function addBaseObject(baseObject:BaseObject):void { newBaseObjects.addItem(baseObject); } public function removeBaseObject(baseObject:BaseObject):void { removedBaseObjects.addItem(baseObject); } protected function shutdownAll():void { // don't dispose objects twice for each (var baseObject:BaseObject in baseObjects) { var found:Boolean = false; for each (var removedObject:BaseObject in removedBaseObjects) { if (removedObject == baseObject) { found = true; break; } } if (!found) baseObject.shutdown(); } } protected function insertNewBaseObjects():void { for each (var baseObject:BaseObject in newBaseObjects) baseObjects.addItem(baseObject); newBaseObjects.removeAll(); } protected function removeDeletedBaseObjects():void { for each (var removedObject:BaseObject in removedBaseObjects) { var i:int = 0; for (i = 0; i < baseObjects.length; ++i) { if (baseObjects.getItemAt(i) == removedObject) { baseObjects.removeItemAt(i); break; } } } removedBaseObjects.removeAll(); } } }