babylon.light.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. module BABYLON {
  2. export interface IShadowLight {
  3. id: string;
  4. position: Vector3;
  5. transformedPosition: Vector3;
  6. name: string;
  7. shadowMinZ: number;
  8. shadowMaxZ: number;
  9. computeTransformedPosition(): boolean;
  10. getScene(): Scene;
  11. customProjectionMatrixBuilder: (viewMatrix: Matrix, renderList: Array<AbstractMesh>, result: Matrix) => void;
  12. setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void;
  13. needRefreshPerFrame(): boolean;
  14. needCube(): boolean;
  15. getShadowDirection(faceIndex?: number): Vector3;
  16. _shadowGenerator: IShadowGenerator;
  17. }
  18. export class Light extends Node {
  19. //lightmapMode Consts
  20. private static _LIGHTMAP_DEFAULT = 0;
  21. private static _LIGHTMAP_SPECULAR = 1;
  22. private static _LIGHTMAP_SHADOWSONLY = 2;
  23. /**
  24. * If every light affecting the material is in this lightmapMode,
  25. * material.lightmapTexture adds or multiplies
  26. * (depends on material.useLightmapAsShadowmap)
  27. * after every other light calculations.
  28. */
  29. public static get LIGHTMAP_DEFAULT(): number {
  30. return Light._LIGHTMAP_DEFAULT;
  31. }
  32. /**
  33. * material.lightmapTexture as only diffuse lighting from this light
  34. * adds pnly specular lighting from this light
  35. * adds dynamic shadows
  36. */
  37. public static get LIGHTMAP_SPECULAR(): number {
  38. return Light._LIGHTMAP_SPECULAR;
  39. }
  40. /**
  41. * material.lightmapTexture as only lighting
  42. * no light calculation from this light
  43. * only adds dynamic shadows from this light
  44. */
  45. public static get LIGHTMAP_SHADOWSONLY(): number {
  46. return Light._LIGHTMAP_SHADOWSONLY;
  47. }
  48. @serializeAsColor3()
  49. public diffuse = new Color3(1.0, 1.0, 1.0);
  50. @serializeAsColor3()
  51. public specular = new Color3(1.0, 1.0, 1.0);
  52. @serialize()
  53. public intensity = 1.0;
  54. @serialize()
  55. public range = Number.MAX_VALUE;
  56. @serialize()
  57. public includeOnlyWithLayerMask = 0;
  58. public includedOnlyMeshes = new Array<AbstractMesh>();
  59. public excludedMeshes = new Array<AbstractMesh>();
  60. @serialize()
  61. public excludeWithLayerMask = 0;
  62. @serialize()
  63. public lightmapMode = 0;
  64. // PBR Properties.
  65. @serialize()
  66. public radius = 0.00001;
  67. public _shadowGenerator: IShadowGenerator;
  68. private _parentedWorldMatrix: Matrix;
  69. public _excludedMeshesIds = new Array<string>();
  70. public _includedOnlyMeshesIds = new Array<string>();
  71. /**
  72. * Creates a Light object in the scene.
  73. * Documentation : http://doc.babylonjs.com/tutorials/lights
  74. */
  75. constructor(name: string, scene: Scene) {
  76. super(name, scene);
  77. this.getScene().addLight(this);
  78. }
  79. /**
  80. * Returns the string "Light".
  81. */
  82. public getClassName(): string {
  83. return "Light";
  84. }
  85. /**
  86. * @param {boolean} fullDetails - support for multiple levels of logging within scene loading
  87. */
  88. public toString(fullDetails? : boolean) : string {
  89. var ret = "Name: " + this.name;
  90. ret += ", type: " + (["Point", "Directional", "Spot", "Hemispheric"])[this.getTypeID()];
  91. if (this.animations){
  92. for (var i = 0; i < this.animations.length; i++){
  93. ret += ", animation[0]: " + this.animations[i].toString(fullDetails);
  94. }
  95. }
  96. if (fullDetails){
  97. }
  98. return ret;
  99. }
  100. /**
  101. * Returns the Light associated shadow generator.
  102. */
  103. public getShadowGenerator(): IShadowGenerator {
  104. return this._shadowGenerator;
  105. }
  106. /**
  107. * Returns a Vector3, the absolute light position in the World.
  108. */
  109. public getAbsolutePosition(): Vector3 {
  110. return Vector3.Zero();
  111. }
  112. public transferToEffect(effect: Effect, uniformName0?: string, uniformName1?: string): void {
  113. }
  114. public _getWorldMatrix(): Matrix {
  115. return Matrix.Identity();
  116. }
  117. /**
  118. * Boolean : True if the light will affect the passed mesh.
  119. */
  120. public canAffectMesh(mesh: AbstractMesh): boolean {
  121. if (!mesh) {
  122. return true;
  123. }
  124. if (this.includedOnlyMeshes.length > 0 && this.includedOnlyMeshes.indexOf(mesh) === -1) {
  125. return false;
  126. }
  127. if (this.excludedMeshes.length > 0 && this.excludedMeshes.indexOf(mesh) !== -1) {
  128. return false;
  129. }
  130. if (this.includeOnlyWithLayerMask !== 0 && (this.includeOnlyWithLayerMask & mesh.layerMask) === 0) {
  131. return false;
  132. }
  133. if (this.excludeWithLayerMask !== 0 && this.excludeWithLayerMask & mesh.layerMask) {
  134. return false;
  135. }
  136. return true;
  137. }
  138. /**
  139. * Returns the light World matrix.
  140. */
  141. public getWorldMatrix(): Matrix {
  142. this._currentRenderId = this.getScene().getRenderId();
  143. var worldMatrix = this._getWorldMatrix();
  144. if (this.parent && this.parent.getWorldMatrix) {
  145. if (!this._parentedWorldMatrix) {
  146. this._parentedWorldMatrix = Matrix.Identity();
  147. }
  148. worldMatrix.multiplyToRef(this.parent.getWorldMatrix(), this._parentedWorldMatrix);
  149. this._markSyncedWithParent();
  150. return this._parentedWorldMatrix;
  151. }
  152. return worldMatrix;
  153. }
  154. /**
  155. * Disposes the light.
  156. */
  157. public dispose(): void {
  158. if (this._shadowGenerator) {
  159. this._shadowGenerator.dispose();
  160. this._shadowGenerator = null;
  161. }
  162. // Animations
  163. this.getScene().stopAnimation(this);
  164. // Remove from scene
  165. this.getScene().removeLight(this);
  166. super.dispose();
  167. }
  168. /**
  169. * Returns the light type ID (integer).
  170. */
  171. public getTypeID(): number {
  172. return 0;
  173. }
  174. /**
  175. * Returns a new Light object, named "name", from the current one.
  176. */
  177. public clone(name: string): Light {
  178. return SerializationHelper.Clone(Light.GetConstructorFromName(this.getTypeID(), name, this.getScene()), this);
  179. }
  180. /**
  181. * Serializes the current light into a Serialization object.
  182. * Returns the serialized object.
  183. */
  184. public serialize(): any {
  185. var serializationObject = SerializationHelper.Serialize(this);
  186. // Type
  187. serializationObject.type = this.getTypeID();
  188. // Parent
  189. if (this.parent) {
  190. serializationObject.parentId = this.parent.id;
  191. }
  192. // Inclusion / exclusions
  193. if (this.excludedMeshes.length > 0) {
  194. serializationObject.excludedMeshesIds = [];
  195. this.excludedMeshes.forEach((mesh: AbstractMesh) => {
  196. serializationObject.excludedMeshesIds.push(mesh.id);
  197. });
  198. }
  199. if (this.includedOnlyMeshes.length > 0) {
  200. serializationObject.includedOnlyMeshesIds = [];
  201. this.includedOnlyMeshes.forEach((mesh: AbstractMesh) => {
  202. serializationObject.includedOnlyMeshesIds.push(mesh.id);
  203. });
  204. }
  205. // Animations
  206. Animation.AppendSerializedAnimations(this, serializationObject);
  207. serializationObject.ranges = this.serializeAnimationRanges();
  208. return serializationObject;
  209. }
  210. /**
  211. * Creates a new typed light from the passed type (integer) : point light = 0, directional light = 1, spot light = 2, hemispheric light = 3.
  212. * This new light is named "name" and added to the passed scene.
  213. */
  214. static GetConstructorFromName(type: number, name: string, scene: Scene): () => Light {
  215. switch (type) {
  216. case 0:
  217. return () => new PointLight(name, Vector3.Zero(), scene);
  218. case 1:
  219. return () => new DirectionalLight(name, Vector3.Zero(), scene);
  220. case 2:
  221. return () => new SpotLight(name, Vector3.Zero(), Vector3.Zero(), 0, 0, scene);
  222. case 3:
  223. return () => new HemisphericLight(name, Vector3.Zero(), scene);
  224. }
  225. }
  226. /**
  227. * Parses the passed "parsedLight" and returns a new instanced Light from this parsing.
  228. */
  229. public static Parse(parsedLight: any, scene: Scene): Light {
  230. var light = SerializationHelper.Parse(Light.GetConstructorFromName(parsedLight.type, parsedLight.name, scene), parsedLight, scene);
  231. // Inclusion / exclusions
  232. if (parsedLight.excludedMeshesIds) {
  233. light._excludedMeshesIds = parsedLight.excludedMeshesIds;
  234. }
  235. if (parsedLight.includedOnlyMeshesIds) {
  236. light._includedOnlyMeshesIds = parsedLight.includedOnlyMeshesIds;
  237. }
  238. // Parent
  239. if (parsedLight.parentId) {
  240. light._waitingParentId = parsedLight.parentId;
  241. }
  242. // Animations
  243. if (parsedLight.animations) {
  244. for (var animationIndex = 0; animationIndex < parsedLight.animations.length; animationIndex++) {
  245. var parsedAnimation = parsedLight.animations[animationIndex];
  246. light.animations.push(Animation.Parse(parsedAnimation));
  247. }
  248. Node.ParseAnimationRanges(light, parsedLight, scene);
  249. }
  250. if (parsedLight.autoAnimate) {
  251. scene.beginAnimation(light, parsedLight.autoAnimateFrom, parsedLight.autoAnimateTo, parsedLight.autoAnimateLoop, parsedLight.autoAnimateSpeed || 1.0);
  252. }
  253. return light;
  254. }
  255. }
  256. }