/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

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