/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
- package away3d.lights
- {
- import away3d.*;
- import away3d.bounds.*;
- import away3d.cameras.*;
- import away3d.core.base.*;
- import away3d.core.math.*;
- import away3d.core.partition.*;
- import away3d.lights.shadowmaps.*;
-
- import flash.geom.*;
-
- use namespace arcane;
-
- /**
- * DirectionalLight represents an idealized light "at infinity", to be used for distant light sources such as the sun.
- * In any position in the scene, the light raytracing will always be parallel.
- * Although the position of the light does not impact its effect, it can be used along with lookAt to intuitively
- * create day cycles by orbiting the position around a center point and using lookAt at that position.
- */
- public class DirectionalLight extends LightBase
- {
- private var _direction:Vector3D;
- private var _tmpLookAt:Vector3D;
- private var _sceneDirection:Vector3D;
- private var _projAABBPoints:Vector.<Number>;
-
- /**
- * Creates a new DirectionalLight object.
- * @param xDir The x-component of the light's directional vector.
- * @param yDir The y-component of the light's directional vector.
- * @param zDir The z-component of the light's directional vector.
- */
- public function DirectionalLight(xDir:Number = 0, yDir:Number = -1, zDir:Number = 1)
- {
- super();
- direction = new Vector3D(xDir, yDir, zDir);
- _sceneDirection = new Vector3D();
- }
-
- override protected function createEntityPartitionNode():EntityNode
- {
- return new DirectionalLightNode(this);
- }
-
- /**
- * The direction of the light in scene coordinates.
- */
- public function get sceneDirection():Vector3D
- {
- if (_sceneTransformDirty)
- updateSceneTransform();
- return _sceneDirection;
- }
-
- /**
- * The direction of the light.
- */
- public function get direction():Vector3D
- {
- return _direction;
- }
-
- public function set direction(value:Vector3D):void
- {
- _direction = value;
- //lookAt(new Vector3D(x + _direction.x, y + _direction.y, z + _direction.z));
- if (!_tmpLookAt)
- _tmpLookAt = new Vector3D();
- _tmpLookAt.x = x + _direction.x;
- _tmpLookAt.y = y + _direction.y;
- _tmpLookAt.z = z + _direction.z;
-
- lookAt(_tmpLookAt);
- }
-
- /**
- * @inheritDoc
- */
- override protected function getDefaultBoundingVolume():BoundingVolumeBase
- {
- // directional lights are to be considered global, hence always in view
- return new NullBounds();
- }
-
- /**
- * @inheritDoc
- */
- override protected function updateBounds():void
- {
- }
-
- /**
- * @inheritDoc
- */
- override protected function updateSceneTransform():void
- {
- super.updateSceneTransform();
- sceneTransform.copyColumnTo(2, _sceneDirection);
- _sceneDirection.normalize();
- }
-
- override protected function createShadowMapper():ShadowMapperBase
- {
- return new DirectionalShadowMapper();
- }
-
- /**
- * @inheritDoc
- */
- override arcane function getObjectProjectionMatrix(renderable:IRenderable, camera:Camera3D, target:Matrix3D = null):Matrix3D
- {
- var raw:Vector.<Number> = Matrix3DUtils.RAW_DATA_CONTAINER;
- var bounds:BoundingVolumeBase = renderable.sourceEntity.bounds;
- var m:Matrix3D = new Matrix3D();
-
- m.copyFrom(renderable.getRenderSceneTransform(camera));
- m.append(inverseSceneTransform);
-
- if (!_projAABBPoints)
- _projAABBPoints = new Vector.<Number>();
- m.transformVectors(bounds.aabbPoints, _projAABBPoints);
-
- var xMin:Number = Number.POSITIVE_INFINITY, xMax:Number = Number.NEGATIVE_INFINITY;
- var yMin:Number = Number.POSITIVE_INFINITY, yMax:Number = Number.NEGATIVE_INFINITY;
- var zMin:Number = Number.POSITIVE_INFINITY, zMax:Number = Number.NEGATIVE_INFINITY;
- var d:Number;
- for (var i:int = 0; i < 24; ) {
- d = _projAABBPoints[i++];
- if (d < xMin)
- xMin = d;
- if (d > xMax)
- xMax = d;
- d = _projAABBPoints[i++];
- if (d < yMin)
- yMin = d;
- if (d > yMax)
- yMax = d;
- d = _projAABBPoints[i++];
- if (d < zMin)
- zMin = d;
- if (d > zMax)
- zMax = d;
- }
-
- var invXRange:Number = 1/(xMax - xMin);
- var invYRange:Number = 1/(yMax - yMin);
- var invZRange:Number = 1/(zMax - zMin);
- raw[0] = 2*invXRange;
- raw[5] = 2*invYRange;
- raw[10] = invZRange;
- raw[12] = -(xMax + xMin)*invXRange;
- raw[13] = -(yMax + yMin)*invYRange;
- raw[14] = -zMin*invZRange;
- raw[1] = raw[2] = raw[3] = raw[4] = raw[6] = raw[7] = raw[8] = raw[9] = raw[11] = 0;
- raw[15] = 1;
-
- target ||= new Matrix3D();
- target.copyRawDataFrom(raw);
- target.prepend(m);
-
- return target;
- }
- }
- }