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