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();
}
}
}