particleSystemSet.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import { Nullable } from "../types";
  2. import { Color3 } from '../Maths/math.color';
  3. import { TransformNode } from "../Meshes/transformNode";
  4. import { AbstractMesh } from "../Meshes/abstractMesh";
  5. import { SphereBuilder } from "../Meshes/Builders/sphereBuilder";
  6. import { IParticleSystem } from "./IParticleSystem";
  7. import { GPUParticleSystem } from "./gpuParticleSystem";
  8. import { EngineStore } from "../Engines/engineStore";
  9. import { ParticleSystem } from "../Particles/particleSystem";
  10. import { Scene, IDisposable } from "../scene";
  11. import { StandardMaterial } from "../Materials/standardMaterial";
  12. /** Internal class used to store shapes for emitters */
  13. class ParticleSystemSetEmitterCreationOptions {
  14. public kind: string;
  15. public options: any;
  16. public renderingGroupId: number;
  17. }
  18. /**
  19. * Represents a set of particle systems working together to create a specific effect
  20. */
  21. export class ParticleSystemSet implements IDisposable {
  22. /**
  23. * Gets or sets base Assets URL
  24. */
  25. public static BaseAssetsUrl = "https://assets.babylonjs.com/particles";
  26. private _emitterCreationOptions: ParticleSystemSetEmitterCreationOptions;
  27. private _emitterNode: Nullable<TransformNode>;
  28. /**
  29. * Gets the particle system list
  30. */
  31. public systems = new Array<IParticleSystem>();
  32. /**
  33. * Gets the emitter node used with this set
  34. */
  35. public get emitterNode(): Nullable<TransformNode> {
  36. return this._emitterNode;
  37. }
  38. /**
  39. * Creates a new emitter mesh as a sphere
  40. * @param options defines the options used to create the sphere
  41. * @param renderingGroupId defines the renderingGroupId to use for the sphere
  42. * @param scene defines the hosting scene
  43. */
  44. public setEmitterAsSphere(options: { diameter: number, segments: number, color: Color3 }, renderingGroupId: number, scene: Scene) {
  45. if (this._emitterNode) {
  46. this._emitterNode.dispose();
  47. }
  48. this._emitterCreationOptions = {
  49. kind: "Sphere",
  50. options: options,
  51. renderingGroupId: renderingGroupId
  52. };
  53. let emitterMesh = SphereBuilder.CreateSphere("emitterSphere", { diameter: options.diameter, segments: options.segments }, scene);
  54. emitterMesh.renderingGroupId = renderingGroupId;
  55. var material = new StandardMaterial("emitterSphereMaterial", scene);
  56. material.emissiveColor = options.color;
  57. emitterMesh.material = material;
  58. for (var system of this.systems) {
  59. system.emitter = emitterMesh;
  60. }
  61. this._emitterNode = emitterMesh;
  62. }
  63. /**
  64. * Starts all particle systems of the set
  65. * @param emitter defines an optional mesh to use as emitter for the particle systems
  66. */
  67. public start(emitter?: AbstractMesh): void {
  68. for (var system of this.systems) {
  69. if (emitter) {
  70. system.emitter = emitter;
  71. }
  72. system.start();
  73. }
  74. }
  75. /**
  76. * Release all associated resources
  77. */
  78. public dispose(): void {
  79. for (var system of this.systems) {
  80. system.dispose();
  81. }
  82. this.systems = [];
  83. if (this._emitterNode) {
  84. this._emitterNode.dispose();
  85. this._emitterNode = null;
  86. }
  87. }
  88. /**
  89. * Serialize the set into a JSON compatible object
  90. * @param serializeTexture defines if the texture must be serialized as well
  91. * @returns a JSON compatible representation of the set
  92. */
  93. public serialize(serializeTexture = false): any {
  94. var result: any = {};
  95. result.systems = [];
  96. for (var system of this.systems) {
  97. result.systems.push(system.serialize(serializeTexture));
  98. }
  99. if (this._emitterNode) {
  100. result.emitter = this._emitterCreationOptions;
  101. }
  102. return result;
  103. }
  104. /**
  105. * Parse a new ParticleSystemSet from a serialized source
  106. * @param data defines a JSON compatible representation of the set
  107. * @param scene defines the hosting scene
  108. * @param gpu defines if we want GPU particles or CPU particles
  109. * @returns a new ParticleSystemSet
  110. */
  111. public static Parse(data: any, scene: Scene, gpu = false): ParticleSystemSet {
  112. var result = new ParticleSystemSet();
  113. var rootUrl = this.BaseAssetsUrl + "/textures/";
  114. scene = scene || EngineStore.LastCreatedScene;
  115. for (var system of data.systems) {
  116. result.systems.push(gpu ? GPUParticleSystem.Parse(system, scene, rootUrl, true) : ParticleSystem.Parse(system, scene, rootUrl, true));
  117. }
  118. if (data.emitter) {
  119. let options = data.emitter.options;
  120. switch (data.emitter.kind) {
  121. case "Sphere":
  122. result.setEmitterAsSphere({
  123. diameter: options.diameter,
  124. segments: options.segments,
  125. color: Color3.FromArray(options.color)
  126. }, data.emitter.renderingGroupId, scene);
  127. break;
  128. }
  129. }
  130. return result;
  131. }
  132. }