PageRenderTime 445ms CodeModel.GetById 181ms app.highlight 11ms RepoModel.GetById 250ms app.codeStats 1ms

/src/away3d/lights/DirectionalLight.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 165 lines | 113 code | 20 blank | 32 comment | 10 complexity | 3a50f45a2882e024c0a5014c12426065 MD5 | raw file
  1package away3d.lights
  2{
  3	import away3d.*;
  4	import away3d.bounds.*;
  5	import away3d.cameras.*;
  6	import away3d.core.base.*;
  7	import away3d.core.math.*;
  8	import away3d.core.partition.*;
  9	import away3d.lights.shadowmaps.*;
 10	
 11	import flash.geom.*;
 12	
 13	use namespace arcane;
 14	
 15	/**
 16	 * DirectionalLight represents an idealized light "at infinity", to be used for distant light sources such as the sun.
 17	 * In any position in the scene, the light raytracing will always be parallel.
 18	 * Although the position of the light does not impact its effect, it can be used along with lookAt to intuitively
 19	 * create day cycles by orbiting the position around a center point and using lookAt at that position.
 20	 */
 21	public class DirectionalLight extends LightBase
 22	{
 23		private var _direction:Vector3D;
 24		private var _tmpLookAt:Vector3D;
 25		private var _sceneDirection:Vector3D;
 26		private var _projAABBPoints:Vector.<Number>;
 27		
 28		/**
 29		 * Creates a new DirectionalLight object.
 30		 * @param xDir The x-component of the light's directional vector.
 31		 * @param yDir The y-component of the light's directional vector.
 32		 * @param zDir The z-component of the light's directional vector.
 33		 */
 34		public function DirectionalLight(xDir:Number = 0, yDir:Number = -1, zDir:Number = 1)
 35		{
 36			super();
 37			direction = new Vector3D(xDir, yDir, zDir);
 38			_sceneDirection = new Vector3D();
 39		}
 40		
 41		override protected function createEntityPartitionNode():EntityNode
 42		{
 43			return new DirectionalLightNode(this);
 44		}
 45		
 46		/**
 47		 * The direction of the light in scene coordinates.
 48		 */
 49		public function get sceneDirection():Vector3D
 50		{
 51			if (_sceneTransformDirty)
 52				updateSceneTransform();
 53			return _sceneDirection;
 54		}
 55		
 56		/**
 57		 * The direction of the light.
 58		 */
 59		public function get direction():Vector3D
 60		{
 61			return _direction;
 62		}
 63		
 64		public function set direction(value:Vector3D):void
 65		{
 66			_direction = value;
 67			//lookAt(new Vector3D(x + _direction.x, y + _direction.y, z + _direction.z));
 68			if (!_tmpLookAt)
 69				_tmpLookAt = new Vector3D();
 70			_tmpLookAt.x = x + _direction.x;
 71			_tmpLookAt.y = y + _direction.y;
 72			_tmpLookAt.z = z + _direction.z;
 73			
 74			lookAt(_tmpLookAt);
 75		}
 76		
 77		/**
 78		 * @inheritDoc
 79		 */
 80		override protected function getDefaultBoundingVolume():BoundingVolumeBase
 81		{
 82			// directional lights are to be considered global, hence always in view
 83			return new NullBounds();
 84		}
 85		
 86		/**
 87		 * @inheritDoc
 88		 */
 89		override protected function updateBounds():void
 90		{
 91		}
 92		
 93		/**
 94		 * @inheritDoc
 95		 */
 96		override protected function updateSceneTransform():void
 97		{
 98			super.updateSceneTransform();
 99			sceneTransform.copyColumnTo(2, _sceneDirection);
100			_sceneDirection.normalize();
101		}
102		
103		override protected function createShadowMapper():ShadowMapperBase
104		{
105			return new DirectionalShadowMapper();
106		}
107		
108		/**
109		 * @inheritDoc
110		 */
111		override arcane function getObjectProjectionMatrix(renderable:IRenderable, camera:Camera3D, target:Matrix3D = null):Matrix3D
112		{
113			var raw:Vector.<Number> = Matrix3DUtils.RAW_DATA_CONTAINER;
114			var bounds:BoundingVolumeBase = renderable.sourceEntity.bounds;
115			var m:Matrix3D = new Matrix3D();
116			
117			m.copyFrom(renderable.getRenderSceneTransform(camera));
118			m.append(inverseSceneTransform);
119			
120			if (!_projAABBPoints)
121				_projAABBPoints = new Vector.<Number>();
122			m.transformVectors(bounds.aabbPoints, _projAABBPoints);
123			
124			var xMin:Number = Number.POSITIVE_INFINITY, xMax:Number = Number.NEGATIVE_INFINITY;
125			var yMin:Number = Number.POSITIVE_INFINITY, yMax:Number = Number.NEGATIVE_INFINITY;
126			var zMin:Number = Number.POSITIVE_INFINITY, zMax:Number = Number.NEGATIVE_INFINITY;
127			var d:Number;
128			for (var i:int = 0; i < 24; ) {
129				d = _projAABBPoints[i++];
130				if (d < xMin)
131					xMin = d;
132				if (d > xMax)
133					xMax = d;
134				d = _projAABBPoints[i++];
135				if (d < yMin)
136					yMin = d;
137				if (d > yMax)
138					yMax = d;
139				d = _projAABBPoints[i++];
140				if (d < zMin)
141					zMin = d;
142				if (d > zMax)
143					zMax = d;
144			}
145			
146			var invXRange:Number = 1/(xMax - xMin);
147			var invYRange:Number = 1/(yMax - yMin);
148			var invZRange:Number = 1/(zMax - zMin);
149			raw[0] = 2*invXRange;
150			raw[5] = 2*invYRange;
151			raw[10] = invZRange;
152			raw[12] = -(xMax + xMin)*invXRange;
153			raw[13] = -(yMax + yMin)*invYRange;
154			raw[14] = -zMin*invZRange;
155			raw[1] = raw[2] = raw[3] = raw[4] = raw[6] = raw[7] = raw[8] = raw[9] = raw[11] = 0;
156			raw[15] = 1;
157			
158			target ||= new Matrix3D();
159			target.copyRawDataFrom(raw);
160			target.prepend(m);
161			
162			return target;
163		}
164	}
165}