PageRenderTime 29ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/HopeSky/mars_nd2d
ActionScript | 160 lines | 124 code | 29 blank | 7 comment | 7 complexity | 305c41cf593e1a688f17fa155713393e MD5 | raw file
  1. package aerys.minko.scene.node.light
  2. {
  3. import aerys.minko.ns.minko_lighting;
  4. import aerys.minko.render.material.phong.PhongProperties;
  5. import aerys.minko.scene.node.AbstractSceneNode;
  6. import aerys.minko.scene.node.ISceneNode;
  7. import aerys.minko.scene.node.Scene;
  8. import aerys.minko.type.binding.DataBindings;
  9. import aerys.minko.type.binding.DataProvider;
  10. import aerys.minko.scene.node.data.LightDataProvider;
  11. use namespace minko_lighting;
  12. public class AbstractLight extends AbstractSceneNode
  13. {
  14. private static const TYPE_STRINGS : Vector.<String> =
  15. new <String>['AmbientLight', 'DirectionalLight', 'PointLight', 'SpotLight'];
  16. private var _dataProvider : DataProvider;
  17. private var _lightId : int;
  18. public function get color() : uint
  19. {
  20. return getProperty('color') as uint;
  21. }
  22. public function get emissionMask() : uint
  23. {
  24. return getProperty('emissionMask') as uint;
  25. }
  26. public function get shadowCastingType() : uint
  27. {
  28. return getProperty('shadowCastingType') as uint;
  29. }
  30. public function set color(v : uint) : void
  31. {
  32. setProperty('color', v);
  33. }
  34. public function set emissionMask(v : uint) : void
  35. {
  36. setProperty('emissionMask', v);
  37. }
  38. public function set shadowCastingType(v : uint) : void
  39. {
  40. throw new Error('Must be overriden');
  41. }
  42. private function set lightId(v : int) : void
  43. {
  44. var numProperties : uint = 0;
  45. var propertyNames : Vector.<String> = new Vector.<String>();
  46. var propertyValues : Vector.<Object> = new Vector.<Object>();
  47. for (var propertyName : String in _dataProvider.dataDescriptor)
  48. {
  49. propertyNames.push(PhongProperties.getPropertyFor(propertyName));
  50. propertyValues.push(_dataProvider.getProperty(propertyName));
  51. ++numProperties;
  52. }
  53. _dataProvider.removeAllProperties();
  54. _lightId = v;
  55. for (var propertyId : uint = 0; propertyId < numProperties; ++propertyId)
  56. _dataProvider.setProperty(
  57. PhongProperties.getNameFor(v, propertyNames[propertyId]),
  58. propertyValues[propertyId]
  59. );
  60. }
  61. public function AbstractLight(color : uint,
  62. emissionMask : uint,
  63. shadowCastingType : uint,
  64. type : uint)
  65. {
  66. _dataProvider = new LightDataProvider();
  67. _lightId = -1;
  68. this.color = color;
  69. this.emissionMask = emissionMask;
  70. this.shadowCastingType = shadowCastingType;
  71. setProperty('type', type);
  72. setProperty('localToWorld', localToWorld);
  73. setProperty('worldToLocal', worldToLocal);
  74. }
  75. protected final function getProperty(name : String) : *
  76. {
  77. var propertyName : String = PhongProperties.getNameFor(_lightId, name);
  78. return _dataProvider.getProperty(propertyName);
  79. }
  80. protected final function setProperty(name : String, value : Object) : void
  81. {
  82. var propertyName : String = PhongProperties.getNameFor(_lightId, name);
  83. _dataProvider.setProperty(propertyName, value);
  84. }
  85. protected final function removeProperty(name : String) : void
  86. {
  87. if (_dataProvider.getProperty(name) !== null)
  88. _dataProvider.removeProperty(name);
  89. }
  90. override protected function addedToSceneHandler(child : ISceneNode, scene : Scene):void
  91. {
  92. // this happens AFTER being added to scene
  93. super.addedToSceneHandler(child, scene);
  94. sortLights(scene);
  95. }
  96. override protected function removedFromSceneHandler(child : ISceneNode, scene : Scene):void
  97. {
  98. // This happens AFTER being removed from scene.
  99. super.removedFromSceneHandler(child, scene);
  100. sortLights(scene);
  101. }
  102. private static function sortLights(scene : Scene) : void
  103. {
  104. var sceneBindings : DataBindings = scene.bindings;
  105. var lights : Vector.<ISceneNode> = scene.getDescendantsByType(AbstractLight);
  106. var numLights : uint = lights.length;
  107. var lightId : uint;
  108. // remove all lights from scene bindings.
  109. var numProviders : uint = sceneBindings.numProviders;
  110. for (var providerId : int = numProviders - 1; providerId >= 0; --providerId)
  111. {
  112. var provider : DataProvider = sceneBindings.getProviderAt(providerId) as DataProvider;
  113. if (provider is LightDataProvider)
  114. sceneBindings.removeProvider(provider);
  115. }
  116. // sorting allow to limit the number of shaders that will be generated
  117. // if (add|remov)ing many lights all the time (add order won't matter anymore).
  118. lights.sort(compare);
  119. // update all descriptors.
  120. for (lightId = 0; lightId < numLights; ++lightId)
  121. AbstractLight(lights[lightId]).lightId = lightId;
  122. // put back all lights into scene bindings.
  123. for (lightId = 0; lightId < numLights; ++lightId)
  124. sceneBindings.addProvider(AbstractLight(lights[lightId])._dataProvider);
  125. }
  126. private static function compare(light1 : AbstractLight, light2 : AbstractLight) : int
  127. {
  128. return Object(light1).constructor.TYPE - Object(light2).constructor.TYPE;
  129. }
  130. }
  131. }