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