PageRenderTime 14ms CodeModel.GetById 1ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/src/away3d/containers/Scene3D.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 179 lines | 92 code | 23 blank | 64 comment | 3 complexity | 094c58435e10e77580e4a2d40e587dbc MD5 | raw file
  1package away3d.containers
  2{
  3	import away3d.arcane;
  4	import away3d.core.partition.NodeBase;
  5	import away3d.core.partition.Partition3D;
  6	import away3d.core.traverse.PartitionTraverser;
  7	import away3d.entities.Entity;
  8	import away3d.events.Scene3DEvent;
  9	
 10	import flash.events.EventDispatcher;
 11	
 12	use namespace arcane;
 13	
 14	/**
 15	 * The Scene3D class represents an independent 3D scene in which 3D objects can be created and manipulated.
 16	 * Multiple Scene3D instances can be created in the same SWF file.
 17	 *
 18	 * Scene management happens through the scene graph, which is exposed using addChild and removeChild methods.
 19	 * Internally, the Scene3D object also manages any space partition objects that have been assigned to objects in
 20	 * the scene graph, of which there is at least 1.
 21	 */
 22	public class Scene3D extends EventDispatcher
 23	{
 24		arcane var _sceneGraphRoot:ObjectContainer3D;
 25		private var _partitions:Vector.<Partition3D>;
 26		
 27		/**
 28		 * Creates a new Scene3D object.
 29		 */
 30		public function Scene3D()
 31		{
 32			_partitions = new Vector.<Partition3D>();
 33			_sceneGraphRoot = new ObjectContainer3D();
 34			_sceneGraphRoot.scene = this;
 35			_sceneGraphRoot._isRoot = true;
 36			_sceneGraphRoot.partition = new Partition3D(new NodeBase());
 37		}
 38		
 39		/**
 40		 * Sends a PartitionTraverser object down the scene partitions
 41		 * @param traverser The traverser which will pass through the partitions.
 42		 *
 43		 * @see away3d.core.traverse.PartitionTraverser
 44		 * @see away3d.core.traverse.EntityCollector
 45		 */
 46		public function traversePartitions(traverser:PartitionTraverser):void
 47		{
 48			var i:uint;
 49			var len:uint = _partitions.length;
 50			
 51			traverser.scene = this;
 52			
 53			while (i < len)
 54				_partitions[i++].traverse(traverser);
 55		}
 56		
 57		/**
 58		 * The root partition to be used by the Scene3D.
 59		 */
 60		public function get partition():Partition3D
 61		{
 62			return _sceneGraphRoot.partition;
 63		}
 64		
 65		public function set partition(value:Partition3D):void
 66		{
 67			_sceneGraphRoot.partition = value;
 68			
 69			dispatchEvent(new Scene3DEvent(Scene3DEvent.PARTITION_CHANGED, _sceneGraphRoot));
 70		}
 71		
 72		public function contains(child:ObjectContainer3D):Boolean
 73		{
 74			return _sceneGraphRoot.contains(child);
 75		}
 76		
 77		/**
 78		 * Adds a child to the scene's root.
 79		 * @param child The child to be added to the scene
 80		 * @return A reference to the added child.
 81		 */
 82		public function addChild(child:ObjectContainer3D):ObjectContainer3D
 83		{
 84			return _sceneGraphRoot.addChild(child);
 85		}
 86		
 87		/**
 88		 * Removes a child from the scene's root.
 89		 * @param child The child to be removed from the scene.
 90		 */
 91		public function removeChild(child:ObjectContainer3D):void
 92		{
 93			_sceneGraphRoot.removeChild(child);
 94		}
 95		
 96		/**
 97		 * Removes a child from the scene's root.
 98		 * @param index Index of child to be removed from the scene.
 99		 */
100		public function removeChildAt(index:uint):void
101		{
102			_sceneGraphRoot.removeChildAt(index);
103		}
104		
105		/**
106		 * Retrieves the child with the given index
107		 * @param index The index for the child to be retrieved.
108		 * @return The child with the given index
109		 */
110		public function getChildAt(index:uint):ObjectContainer3D
111		{
112			return _sceneGraphRoot.getChildAt(index);
113		}
114		
115		/**
116		 * The amount of children directly contained by the scene.
117		 */
118		public function get numChildren():uint
119		{
120			return _sceneGraphRoot.numChildren;
121		}
122		
123		/**
124		 * When an entity is added to the scene, or to one of its children, add it to the partition tree.
125		 * @private
126		 */
127		arcane function registerEntity(entity:Entity):void
128		{
129			var partition:Partition3D = entity.implicitPartition;
130			addPartitionUnique(partition);
131			
132			partition.markForUpdate(entity);
133		}
134		
135		/**
136		 * When an entity is removed from the scene, or from one of its children, remove it from its former partition tree.
137		 * @private
138		 */
139		arcane function unregisterEntity(entity:Entity):void
140		{
141			entity.implicitPartition.removeEntity(entity);
142		}
143		
144		/**
145		 * When an entity has moved or changed size, update its position in its partition tree.
146		 */
147		arcane function invalidateEntityBounds(entity:Entity):void
148		{
149			entity.implicitPartition.markForUpdate(entity);
150		}
151		
152		/**
153		 * When a partition is assigned to an object somewhere in the scene graph, add the partition to the list if it isn't in there yet
154		 */
155		arcane function registerPartition(entity:Entity):void
156		{
157			addPartitionUnique(entity.implicitPartition);
158		}
159		
160		/**
161		 * When a partition is removed from an object somewhere in the scene graph, remove the partition from the list
162		 */
163		arcane function unregisterPartition(entity:Entity):void
164		{
165			// todo: wait... is this even correct?
166			// shouldn't we check the number of children in implicitPartition and remove partition if 0?
167			entity.implicitPartition.removeEntity(entity);
168		}
169		
170		/**
171		 * Add a partition if it's not in the list
172		 */
173		protected function addPartitionUnique(partition:Partition3D):void
174		{
175			if (_partitions.indexOf(partition) == -1)
176				_partitions.push(partition);
177		}
178	}
179}