/src/aerys/minko/scene/node/light/PointLight.as

https://bitbucket.org/HopeSky/mars_nd2d · ActionScript · 241 lines · 195 code · 44 blank · 2 comment · 25 complexity · 0a697a58513afe3a007d5ca2b1c03262 MD5 · raw file

  1. package aerys.minko.scene.node.light
  2. {
  3. import aerys.minko.ns.minko_scene;
  4. import aerys.minko.render.resource.texture.CubeTextureResource;
  5. import aerys.minko.render.resource.texture.ITextureResource;
  6. import aerys.minko.render.resource.texture.TextureResource;
  7. import aerys.minko.scene.node.AbstractSceneNode;
  8. import aerys.minko.scene.node.ISceneNode;
  9. import aerys.minko.scene.node.Scene;
  10. import aerys.minko.type.binding.DataBindings;
  11. import aerys.minko.type.enum.ShadowMappingType;
  12. import aerys.minko.type.math.Matrix4x4;
  13. import aerys.minko.type.math.Vector4;
  14. use namespace minko_scene;
  15. public class PointLight extends AbstractLight
  16. {
  17. public static const TYPE : uint = 2;
  18. private static const MAP_NAMES : Vector.<String> = new <String>[
  19. 'shadowMapCube',
  20. 'shadowMapDPFront',
  21. 'shadowMapDPBack'
  22. ];
  23. private static const TMP_VECTOR : Vector4 = new Vector4();
  24. private static const FRUSTUM_POINTS : Vector.<Vector4> = new <Vector4>[
  25. new Vector4(-1, -1, 0, 1),
  26. new Vector4(-1, -1, 1, 1),
  27. new Vector4(-1, +1, 0, 1),
  28. new Vector4(-1, +1, 1, 1),
  29. new Vector4(+1, -1, 0, 1),
  30. new Vector4(+1, -1, 1, 1),
  31. new Vector4(+1, +1, 0, 1),
  32. new Vector4(+1, +1, 1, 1)
  33. ];
  34. private var _worldPosition : Vector4;
  35. private var _projection : Matrix4x4;
  36. private var _shadowMapSize : uint;
  37. public function get diffuse() : Number
  38. {
  39. return getProperty('diffuse') as Number;
  40. }
  41. public function get specular() : Number
  42. {
  43. return getProperty('specular') as Number;
  44. }
  45. public function get shininess() : Number
  46. {
  47. return getProperty('shininess') as Number;
  48. }
  49. public function get attenuationDistance() : Number
  50. {
  51. return getProperty('attenuationDistance') as Number;
  52. }
  53. public function get shadowMapSize() : uint
  54. {
  55. return _shadowMapSize;
  56. }
  57. public function get shadowMapZNear() : Number
  58. {
  59. return getProperty('zNear');
  60. }
  61. public function get shadowMapZFar() : Number
  62. {
  63. return getProperty('zFar');
  64. }
  65. public function set diffuse(v : Number) : void
  66. {
  67. setProperty('diffuse', v);
  68. if (getProperty('diffuseEnabled') != (v != 0))
  69. setProperty('diffuseEnabled', v != 0);
  70. }
  71. public function set specular(v : Number) : void
  72. {
  73. setProperty('specular', v);
  74. if (getProperty('specularEnabled') != (v != 0))
  75. setProperty('specularEnabled', v != 0);
  76. }
  77. public function set shininess(v : Number) : void
  78. {
  79. setProperty('shininess', v);
  80. }
  81. public function set attenuationDistance(v : Number) : void
  82. {
  83. setProperty('attenuationDistance', v);
  84. if (getProperty('attenuationEnabled') != (v != 0))
  85. setProperty('attenuationEnabled', v != 0);
  86. }
  87. public function set shadowMapSize(v : uint) : void
  88. {
  89. _shadowMapSize = v;
  90. this.shadowCastingType = this.shadowCastingType
  91. }
  92. public function set shadowMapZNear(v : Number) : void
  93. {
  94. setProperty('zNear', v);
  95. updateProjectionMatrix();
  96. }
  97. public function set shadowMapZFar(v : Number) : void
  98. {
  99. setProperty('zFar', v);
  100. updateProjectionMatrix();
  101. }
  102. override public function set shadowCastingType(v : uint) : void
  103. {
  104. var shadowMap : ITextureResource;
  105. // start by clearing current shadow maps.
  106. for each (var mapName : String in MAP_NAMES)
  107. {
  108. shadowMap = getProperty(mapName) as ITextureResource;
  109. if (shadowMap !== null)
  110. {
  111. shadowMap.dispose();
  112. removeProperty(mapName);
  113. }
  114. }
  115. switch (v)
  116. {
  117. case ShadowMappingType.NONE:
  118. setProperty('shadowCastingType', ShadowMappingType.NONE);
  119. break;
  120. case ShadowMappingType.DUAL_PARABOLOID:
  121. if (!((_shadowMapSize & (~_shadowMapSize + 1)) == _shadowMapSize
  122. && _shadowMapSize <= 2048))
  123. throw new Error(_shadowMapSize + ' is an invalid size for dual paraboloid shadow maps');
  124. // set textures and shadowmaptype
  125. shadowMap = new TextureResource(_shadowMapSize, _shadowMapSize);
  126. setProperty('shadowMapDPFront', shadowMap);
  127. shadowMap = new TextureResource(_shadowMapSize, _shadowMapSize);
  128. setProperty('shadowMapDPBack', shadowMap);
  129. setProperty('shadowCastingType', ShadowMappingType.DUAL_PARABOLOID);
  130. break;
  131. case ShadowMappingType.CUBE:
  132. if (!((_shadowMapSize & (~_shadowMapSize + 1)) == _shadowMapSize
  133. && _shadowMapSize <= 1024))
  134. throw new Error(_shadowMapSize + ' is an invalid size for cubic shadow maps');
  135. shadowMap = new CubeTextureResource(_shadowMapSize);
  136. setProperty('shadowMapCube', shadowMap);
  137. setProperty('shadowCastingType', ShadowMappingType.CUBE);
  138. break;
  139. default:
  140. throw new ArgumentError('Invalid shadow casting type.');
  141. }
  142. }
  143. public function PointLight(color : uint = 0xFFFFFFFF,
  144. diffuse : Number = .6,
  145. specular : Number = .8,
  146. shininess : Number = 64,
  147. attenuationDistance : Number = 0,
  148. emissionMask : uint = 0x1,
  149. shadowCastingType : uint = 0,
  150. shadowMapSize : uint = 512,
  151. shadowMapZNear : Number = 0.1,
  152. shadowMapZFar : Number = 1000)
  153. {
  154. _worldPosition = new Vector4();
  155. _projection = new Matrix4x4();
  156. _shadowMapSize = shadowMapSize;
  157. super(color, emissionMask, shadowCastingType, TYPE);
  158. this.diffuse = diffuse;
  159. this.specular = specular;
  160. this.shininess = shininess;
  161. this.attenuationDistance = attenuationDistance;
  162. this.shadowMapZNear = shadowMapZNear;
  163. this.shadowMapZFar = shadowMapZFar;
  164. setProperty('worldPosition', _worldPosition);
  165. setProperty('projection', _projection);
  166. if ([ShadowMappingType.NONE,
  167. ShadowMappingType.DUAL_PARABOLOID,
  168. ShadowMappingType.CUBE].indexOf(shadowCastingType) == -1)
  169. throw new Error('Invalid ShadowMappingType.');
  170. }
  171. override protected function transformChangedHandler(transform : Matrix4x4) : void
  172. {
  173. super.transformChangedHandler(transform);
  174. localToWorld.getTranslation(_worldPosition);
  175. }
  176. private function updateProjectionMatrix() : void
  177. {
  178. var zNear : Number = this.shadowMapZNear;
  179. var zFar : Number = this.shadowMapZFar;
  180. var fd : Number = 1. / Math.tan(Math.PI / 4);
  181. var m33 : Number = 1. / (zFar - zNear);
  182. var m43 : Number = -zNear / (zFar - zNear);
  183. _projection.initialize(fd, 0, 0, 0, 0, fd, 0, 0, 0, 0, m33, 1, 0, 0, m43, 0);
  184. }
  185. override minko_scene function cloneNode() : AbstractSceneNode
  186. {
  187. var light : PointLight = new PointLight(
  188. color, diffuse, specular, shininess,
  189. attenuationDistance, emissionMask,
  190. shadowCastingType, shadowMapSize
  191. );
  192. light.name = this.name;
  193. light.transform.copyFrom(this.transform);
  194. return light;
  195. }
  196. }
  197. }