PageRenderTime 47ms CodeModel.GetById 10ms app.highlight 18ms RepoModel.GetById 16ms app.codeStats 0ms

/src/away3d/core/traverse/EntityCollector.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 314 lines | 220 code | 34 blank | 60 comment | 11 complexity | 50eb334a3c81dd9e8aa8bddacbcfdee0 MD5 | raw file
  1package away3d.core.traverse
  2{
  3	import away3d.arcane;
  4	import away3d.cameras.Camera3D;
  5	import away3d.core.base.IRenderable;
  6	import away3d.core.data.EntityListItem;
  7	import away3d.core.data.EntityListItemPool;
  8	import away3d.core.data.RenderableListItem;
  9	import away3d.core.data.RenderableListItemPool;
 10	import away3d.core.math.Matrix3DUtils;
 11	import away3d.core.math.Matrix3DUtils;
 12	import away3d.core.math.Plane3D;
 13	import away3d.core.partition.NodeBase;
 14	import away3d.entities.Entity;
 15	import away3d.lights.DirectionalLight;
 16	import away3d.lights.LightBase;
 17	import away3d.lights.LightProbe;
 18	import away3d.lights.PointLight;
 19	import away3d.materials.MaterialBase;
 20	
 21	import flash.geom.Vector3D;
 22	
 23	use namespace arcane;
 24	
 25	/**
 26	 * The EntityCollector class is a traverser for scene partitions that collects all scene graph entities that are
 27	 * considered potientially visible.
 28	 *
 29	 * @see away3d.partition.Partition3D
 30	 * @see away3d.partition.Entity
 31	 */
 32	public class EntityCollector extends PartitionTraverser
 33	{
 34		protected var _skyBox:IRenderable;
 35		protected var _opaqueRenderableHead:RenderableListItem;
 36		protected var _blendedRenderableHead:RenderableListItem;
 37		private var _entityHead:EntityListItem;
 38		protected var _renderableListItemPool:RenderableListItemPool;
 39		protected var _entityListItemPool:EntityListItemPool;
 40		protected var _lights:Vector.<LightBase>;
 41		private var _directionalLights:Vector.<DirectionalLight>;
 42		private var _pointLights:Vector.<PointLight>;
 43		private var _lightProbes:Vector.<LightProbe>;
 44		protected var _numEntities:uint;
 45		protected var _numLights:uint;
 46		protected var _numTriangles:uint;
 47		protected var _numMouseEnableds:uint;
 48		protected var _camera:Camera3D;
 49		private var _numDirectionalLights:uint;
 50		private var _numPointLights:uint;
 51		private var _numLightProbes:uint;
 52		protected var _cameraForward:Vector3D;
 53		private var _customCullPlanes:Vector.<Plane3D>;
 54		private var _cullPlanes:Vector.<Plane3D>;
 55		private var _numCullPlanes:uint;
 56		
 57		/**
 58		 * Creates a new EntityCollector object.
 59		 */
 60		public function EntityCollector()
 61		{
 62			init();
 63		}
 64		
 65		private function init():void
 66		{
 67			_lights = new Vector.<LightBase>();
 68			_directionalLights = new Vector.<DirectionalLight>();
 69			_pointLights = new Vector.<PointLight>();
 70			_lightProbes = new Vector.<LightProbe>();
 71			_renderableListItemPool = new RenderableListItemPool();
 72			_entityListItemPool = new EntityListItemPool();
 73		}
 74		
 75		/**
 76		 * The camera that provides the visible frustum.
 77		 */
 78		public function get camera():Camera3D
 79		{
 80			return _camera;
 81		}
 82		
 83		public function set camera(value:Camera3D):void
 84		{
 85			_camera = value;
 86			_entryPoint = _camera.scenePosition;
 87			_cameraForward = Matrix3DUtils.getForward(_camera.transform, _cameraForward);
 88			_cullPlanes = _camera.frustumPlanes;
 89		}
 90		
 91		public function get cullPlanes():Vector.<Plane3D>
 92		{
 93			return _customCullPlanes;
 94		}
 95		
 96		public function set cullPlanes(value:Vector.<Plane3D>):void
 97		{
 98			_customCullPlanes = value;
 99		}
100		
101		/**
102		 * The amount of IRenderable objects that are mouse-enabled.
103		 */
104		public function get numMouseEnableds():uint
105		{
106			return _numMouseEnableds;
107		}
108		
109		/**
110		 * The sky box object if encountered.
111		 */
112		public function get skyBox():IRenderable
113		{
114			return _skyBox;
115		}
116		
117		/**
118		 * The list of opaque IRenderable objects that are considered potentially visible.
119		 * @param value
120		 */
121		public function get opaqueRenderableHead():RenderableListItem
122		{
123			return _opaqueRenderableHead;
124		}
125		
126		public function set opaqueRenderableHead(value:RenderableListItem):void
127		{
128			_opaqueRenderableHead = value;
129		}
130		
131		/**
132		 * The list of IRenderable objects that require blending and are considered potentially visible.
133		 * @param value
134		 */
135		public function get blendedRenderableHead():RenderableListItem
136		{
137			return _blendedRenderableHead;
138		}
139		
140		public function set blendedRenderableHead(value:RenderableListItem):void
141		{
142			_blendedRenderableHead = value;
143		}
144		
145		public function get entityHead():EntityListItem
146		{
147			return _entityHead;
148		}
149		
150		/**
151		 * The lights of which the affecting area intersects the camera's frustum.
152		 */
153		public function get lights():Vector.<LightBase>
154		{
155			return _lights;
156		}
157		
158		public function get directionalLights():Vector.<DirectionalLight>
159		{
160			return _directionalLights;
161		}
162		
163		public function get pointLights():Vector.<PointLight>
164		{
165			return _pointLights;
166		}
167		
168		public function get lightProbes():Vector.<LightProbe>
169		{
170			return _lightProbes;
171		}
172		
173		/**
174		 * Clears all objects in the entity collector.
175		 */
176		public function clear():void
177		{
178			if (_camera) {
179				_entryPoint = _camera.scenePosition;
180				_cameraForward = Matrix3DUtils.getForward(_camera.transform, _cameraForward);
181			}
182			_cullPlanes = _customCullPlanes? _customCullPlanes : (_camera? _camera.frustumPlanes : null);
183			_numCullPlanes = _cullPlanes? _cullPlanes.length : 0;
184			_numTriangles = _numMouseEnableds = 0;
185			_blendedRenderableHead = null;
186			_opaqueRenderableHead = null;
187			_entityHead = null;
188			_renderableListItemPool.freeAll();
189			_entityListItemPool.freeAll();
190			_skyBox = null;
191			if (_numLights > 0)
192				_lights.length = _numLights = 0;
193			if (_numDirectionalLights > 0)
194				_directionalLights.length = _numDirectionalLights = 0;
195			if (_numPointLights > 0)
196				_pointLights.length = _numPointLights = 0;
197			if (_numLightProbes > 0)
198				_lightProbes.length = _numLightProbes = 0;
199		}
200		
201		/**
202		 * Returns true if the current node is at least partly in the frustum. If so, the partition node knows to pass on the traverser to its children.
203		 *
204		 * @param node The Partition3DNode object to frustum-test.
205		 */
206		override public function enterNode(node:NodeBase):Boolean
207		{
208			var enter:Boolean = _collectionMark != node._collectionMark && node.isInFrustum(_cullPlanes, _numCullPlanes);
209			node._collectionMark = _collectionMark;
210			return enter;
211		}
212		
213		/**
214		 * Adds a skybox to the potentially visible objects.
215		 * @param renderable The skybox to add.
216		 */
217		override public function applySkyBox(renderable:IRenderable):void
218		{
219			_skyBox = renderable;
220		}
221		
222		/**
223		 * Adds an IRenderable object to the potentially visible objects.
224		 * @param renderable The IRenderable object to add.
225		 */
226		override public function applyRenderable(renderable:IRenderable):void
227		{
228			var material:MaterialBase;
229			var entity:Entity = renderable.sourceEntity;
230			if (renderable.mouseEnabled)
231				++_numMouseEnableds;
232			_numTriangles += renderable.numTriangles;
233			
234			material = renderable.material;
235			if (material) {
236				var item:RenderableListItem = _renderableListItemPool.getItem();
237				item.renderable = renderable;
238				item.materialId = material._uniqueId;
239				item.renderOrderId = material._renderOrderId;
240				item.cascaded = false;
241				var entityScenePos:Vector3D = entity.scenePosition;
242				var dx:Number = _entryPoint.x - entityScenePos.x;
243				var dy:Number = _entryPoint.y - entityScenePos.y;
244				var dz:Number = _entryPoint.z - entityScenePos.z;
245				// project onto camera's z-axis
246				item.zIndex = dx*_cameraForward.x + dy*_cameraForward.y + dz*_cameraForward.z + entity.zOffset;
247				item.renderSceneTransform = renderable.getRenderSceneTransform(_camera);
248				if (material.requiresBlending) {
249					item.next = _blendedRenderableHead;
250					_blendedRenderableHead = item;
251				} else {
252					item.next = _opaqueRenderableHead;
253					_opaqueRenderableHead = item;
254				}
255			}
256		}
257		
258		/**
259		 * @inheritDoc
260		 */
261		override public function applyEntity(entity:Entity):void
262		{
263			++_numEntities;
264			
265			var item:EntityListItem = _entityListItemPool.getItem();
266			item.entity = entity;
267			
268			item.next = _entityHead;
269			_entityHead = item;
270		}
271		
272		/**
273		 * Adds a light to the potentially visible objects.
274		 * @param light The light to add.
275		 */
276		override public function applyUnknownLight(light:LightBase):void
277		{
278			_lights[_numLights++] = light;
279		}
280		
281		override public function applyDirectionalLight(light:DirectionalLight):void
282		{
283			_lights[_numLights++] = light;
284			_directionalLights[_numDirectionalLights++] = light;
285		}
286		
287		override public function applyPointLight(light:PointLight):void
288		{
289			_lights[_numLights++] = light;
290			_pointLights[_numPointLights++] = light;
291		}
292		
293		override public function applyLightProbe(light:LightProbe):void
294		{
295			_lights[_numLights++] = light;
296			_lightProbes[_numLightProbes++] = light;
297		}
298		
299		/**
300		 * The total number of triangles collected, and which will be pushed to the render engine.
301		 */
302		public function get numTriangles():uint
303		{
304			return _numTriangles;
305		}
306		
307		/**
308		 * Cleans up any data at the end of a frame.
309		 */
310		public function cleanUp():void
311		{
312		}
313	}
314}