1. package
  2. {
  3. import away3d.cameras.Camera3D;
  4. import away3d.containers.View3D;
  5. import away3d.core.math.Number3D;
  6. import away3d.core.render.Renderer;
  7.  
  8. import flash.display.BlendMode;
  9. import flash.events.*;
  10.  
  11. import mx.collections.ArrayCollection;
  12. import mx.core.UIComponent;
  13.  
  14. import org.flintparticles.threeD.away3d.Away3DRenderer;
  15.  
  16. public class EngineManager extends UIComponent
  17. {
  18. public static const version:String = "1.0.0";
  19. protected static const MEASURED_MIN_WIDTH:int = 25;
  20. protected static const MEASURED_MIN_HEIGHT:int = 25;
  21. protected static const MEASURED_WIDTH:int = 100;
  22. protected static const MEASURED_HEIGHT:int = 100;
  23.  
  24. // Away3D view
  25. internal var view:View3D = null;
  26. // Away3D camera
  27. internal var cam:Camera3D = null;
  28. // a collection of the BaseObjects
  29. protected var baseObjects:ArrayCollection = new ArrayCollection();
  30. // a collection where new BaseObjects are placed, to avoid adding items
  31. // to baseObjects while in the baseObjects collection while it is in a loop
  32. protected var newBaseObjects:ArrayCollection = new ArrayCollection();
  33. // a collection where removed BaseObjects are placed, to avoid removing items
  34. // to baseObjects while in the baseObjects collection while it is in a loop
  35. protected var removedBaseObjects:ArrayCollection = new ArrayCollection();
  36. // the last frame time
  37. protected var lastFrame:Date;
  38. // the application manager
  39. internal var applicationManager:ApplicationManager = null;
  40. // the resource manager
  41. protected var myResourceManager:ResourceManager = null;
  42. // true when we have added the Away3D controls
  43. protected var addedToStage:Boolean = false;
  44. // true if some properties have been modifed
  45. protected var propertiesDirty:Boolean = false;
  46.  
  47. // Away3D Flint renderer
  48. internal var renderer:Away3DRenderer = null;
  49.  
  50. public static const ParticleSystems:ArrayCollection = new ArrayCollection(["fountain", "fire"]);
  51. protected static const ParticleSystemsString:String = ConvertArrayCollectionToString(ParticleSystems);
  52.  
  53. protected var particleSystem:String = ParticleSystems[0];
  54.  
  55. [Inspectable(defaultValue=particleSystem,enumeration=particleSystemsString)]
  56. [Bindable]
  57. public function set ParticleSystem(value:String):void
  58. {
  59. particleSystem = value;
  60. propertyChanged();
  61. }
  62.  
  63. public function get ParticleSystem():String
  64. {
  65. return particleSystem;
  66. }
  67.  
  68. internal function get MyResourceManager():ResourceManager
  69. {
  70. return myResourceManager;
  71. }
  72.  
  73. protected function propertyChanged():void
  74. {
  75. propertiesDirty = true;
  76. invalidateProperties();
  77. invalidateDisplayList();
  78. }
  79.  
  80. public static function ConvertArrayCollectionToString(array:ArrayCollection):String
  81. {
  82. var retValue:String = "";
  83. var i:int = 0;
  84. for each (var element:String in array)
  85. {
  86. if (i != 0) retValue += ",";
  87. retValue += element;
  88. ++i;
  89. }
  90.  
  91. return retValue;
  92. }
  93.  
  94. public function EngineManager()
  95. {
  96. super();
  97. }
  98.  
  99. override protected function measure():void
  100. {
  101. super.measure();
  102.  
  103. // set a bunch of predefined sizes
  104. this.measuredMinWidth = MEASURED_MIN_WIDTH;
  105. this.measuredMinHeight = MEASURED_MIN_HEIGHT;
  106. this.measuredHeight = MEASURED_HEIGHT;
  107. this.measuredWidth = MEASURED_WIDTH;
  108. }
  109.  
  110. override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
  111. {
  112. super.updateDisplayList(unscaledWidth, unscaledHeight);
  113.  
  114. if (view != null)
  115. {
  116. // resize the viewport to match the new settings
  117. view.height = this.height;
  118. view.width = this.width;
  119. }
  120. }
  121.  
  122. override protected function commitProperties():void
  123. {
  124. super.commitProperties();
  125.  
  126. if (propertiesDirty)
  127. {
  128. propertiesDirty = false;
  129.  
  130. if (addedToStage)
  131. {
  132. applicationManager.shutdown();
  133. myResourceManager.shutdown();
  134. shutdownAll();
  135. myResourceManager.startupResourceManager();
  136. applicationManager.startupApplicationManager(this);
  137. }
  138. }
  139. }
  140.  
  141. override protected function createChildren():void
  142. {
  143. super.createChildren();
  144.  
  145. addEventListener(Event.ADDED_TO_STAGE, createChildrenEx);
  146. addEventListener(Event.REMOVED_FROM_STAGE, shutdown);
  147. }
  148.  
  149. protected function shutdown(event:Event):void
  150. {
  151. if (applicationManager != null)
  152. applicationManager.shutdown();
  153.  
  154. shutdownAll();
  155.  
  156. this.removeChild(view);
  157.  
  158. applicationManager = null;
  159. addedToStage = false;
  160. view = null;
  161. cam = null;
  162. }
  163.  
  164. protected function createChildrenEx(event:Event):void
  165. {
  166. if (!addedToStage)
  167. {
  168. cam = new Camera3D({x:0, y:0, z:-500, lookat:new Number3D(0, 0, 0)});
  169.  
  170. view = new View3D({x:stage.width/2, y:stage.height/2, camera:cam});
  171. view.renderer = Renderer.BASIC;
  172. addChild(view);
  173. addEventListener(Event.ENTER_FRAME, onEnterFrame);
  174.  
  175. // set the initial frame time
  176. lastFrame = new Date();
  177.  
  178. // initialise the Away3D Flint renderer
  179. renderer = new Away3DRenderer(view.scene );
  180.  
  181. // load any resources
  182. myResourceManager = new ResourceManager(this);
  183. myResourceManager.startupResourceManager();
  184.  
  185. // start the application manager
  186. applicationManager = new ApplicationManager().startupApplicationManager(this);
  187.  
  188. addedToStage = true;
  189. }
  190. }
  191.  
  192. protected function onEnterFrame(event:Event):void
  193. {
  194. // Calculate the time since the last frame
  195. var thisFrame:Date = new Date();
  196. var seconds:Number = (thisFrame.getTime() - lastFrame.getTime())/1000.0;
  197. lastFrame = thisFrame;
  198.  
  199. // sync the baseObjects collection with any BaseObjects created or removed during the
  200. // render loop
  201. removeDeletedBaseObjects();
  202. insertNewBaseObjects();
  203.  
  204. // allow each BaseObject to update itself
  205. for each (var baseObject:BaseObject in baseObjects)
  206. baseObject.enterFrame(seconds);
  207.  
  208. // render the scene
  209. view.render();
  210. }
  211.  
  212. public function addBaseObject(baseObject:BaseObject):void
  213. {
  214. newBaseObjects.addItem(baseObject);
  215. }
  216.  
  217. public function removeBaseObject(baseObject:BaseObject):void
  218. {
  219. removedBaseObjects.addItem(baseObject);
  220. }
  221.  
  222. public function shutdownAll():void
  223. {
  224. // don't dispose objects twice
  225. for each (var baseObject:BaseObject in baseObjects)
  226. {
  227. var found:Boolean = false;
  228. for each (var removedObject:BaseObject in removedBaseObjects)
  229. {
  230. if (removedObject == baseObject)
  231. {
  232. found = true;
  233. break;
  234. }
  235. }
  236.  
  237. if (!found)
  238. baseObject.shutdown();
  239. }
  240. }
  241.  
  242. protected function insertNewBaseObjects():void
  243. {
  244. for each (var baseObject:BaseObject in newBaseObjects)
  245. baseObjects.addItem(baseObject);
  246.  
  247. newBaseObjects.removeAll();
  248. }
  249.  
  250. protected function removeDeletedBaseObjects():void
  251. {
  252. for each (var removedObject:BaseObject in removedBaseObjects)
  253. {
  254. var i:int = 0;
  255. for (i = 0; i < baseObjects.length; ++i)
  256. {
  257. if (baseObjects.getItemAt(i) == removedObject)
  258. {
  259. baseObjects.removeItemAt(i);
  260. break;
  261. }
  262. }
  263.  
  264. }
  265.  
  266. removedBaseObjects.removeAll();
  267. }
  268. }
  269. }
  270.