babylon.coneParticleEmitter.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. module BABYLON {
  2. /**
  3. * Particle emitter emitting particles from the inside of a cone.
  4. * It emits the particles alongside the cone volume from the base to the particle.
  5. * The emission direction might be randomized.
  6. */
  7. export class ConeParticleEmitter implements IParticleEmitterType {
  8. private _radius: number;
  9. private _angle: number;
  10. private _height: number;
  11. /**
  12. * Gets or sets the radius of the emission cone
  13. */
  14. public get radius(): number {
  15. return this._radius;
  16. }
  17. public set radius(value: number) {
  18. this._radius = value;
  19. this._buildHeight();
  20. }
  21. /**
  22. * Gets or sets the angle of the emission cone
  23. */
  24. public get angle(): number {
  25. return this._angle;
  26. }
  27. public set angle(value: number) {
  28. this._angle = value;
  29. this._buildHeight();
  30. }
  31. private _buildHeight() {
  32. if (this._angle !== 0) {
  33. this._height = this._radius / Math.tan(this._angle / 2);
  34. }
  35. else {
  36. this._height = 1;
  37. }
  38. }
  39. /**
  40. * Creates a new instance ConeParticleEmitter
  41. * @param radius the radius of the emission cone (1 by default)
  42. * @param angles the cone base angle (PI by default)
  43. * @param directionRandomizer defines how much to randomize the particle direction [0-1] (default is 0)
  44. */
  45. constructor(radius = 1, angle = Math.PI,
  46. /** defines how much to randomize the particle direction [0-1] (default is 0) */
  47. public directionRandomizer = 0) {
  48. this.angle = angle;
  49. this.radius = radius;
  50. }
  51. /**
  52. * Called by the particle System when the direction is computed for the created particle.
  53. * @param worldMatrix is the world matrix of the particle system
  54. * @param directionToUpdate is the direction vector to update with the result
  55. * @param particle is the particle we are computed the direction for
  56. */
  57. public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
  58. if (this._angle === 0) {
  59. Vector3.TransformNormalFromFloatsToRef(0, 1.0, 0, worldMatrix, directionToUpdate);
  60. }
  61. else {
  62. // measure the direction Vector from the emitter to the particle.
  63. var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
  64. var randX = Scalar.RandomRange(0, this.directionRandomizer);
  65. var randY = Scalar.RandomRange(0, this.directionRandomizer);
  66. var randZ = Scalar.RandomRange(0, this.directionRandomizer);
  67. direction.x += randX;
  68. direction.y += randY;
  69. direction.z += randZ;
  70. direction.normalize();
  71. Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
  72. }
  73. }
  74. /**
  75. * Called by the particle System when the position is computed for the created particle.
  76. * @param worldMatrix is the world matrix of the particle system
  77. * @param positionToUpdate is the position vector to update with the result
  78. * @param particle is the particle we are computed the position for
  79. */
  80. startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
  81. var s = Scalar.RandomRange(0, Math.PI * 2);
  82. var h = Scalar.RandomRange(0, 1);
  83. // Better distribution in a cone at normal angles.
  84. h = 1 - h * h;
  85. var radius = Scalar.RandomRange(0, this._radius);
  86. radius = radius * h;
  87. var randX = radius * Math.sin(s);
  88. var randZ = radius * Math.cos(s);
  89. var randY = h * this._height;
  90. Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
  91. }
  92. /**
  93. * Clones the current emitter and returns a copy of it
  94. * @returns the new emitter
  95. */
  96. public clone(): ConeParticleEmitter {
  97. let newOne = new ConeParticleEmitter(this._radius, this._angle, this.directionRandomizer);
  98. Tools.DeepCopy(this, newOne);
  99. return newOne;
  100. }
  101. /**
  102. * Called by the {BABYLON.GPUParticleSystem} to setup the update shader
  103. * @param effect defines the update shader
  104. */
  105. public applyToShader(effect: Effect): void {
  106. effect.setFloat("radius", this._radius);
  107. effect.setFloat("coneAngle", this._angle);
  108. effect.setFloat("height", this._height);
  109. effect.setFloat("directionRandomizer", this.directionRandomizer);
  110. }
  111. /**
  112. * Returns a string to use to update the GPU particles update shader
  113. * @returns a string containng the defines string
  114. */
  115. public getEffectDefines(): string {
  116. return "#define CONEEMITTER"
  117. }
  118. /**
  119. * Returns the string "ConeEmitter"
  120. * @returns a string containing the class name
  121. */
  122. public getClassName(): string {
  123. return "ConeEmitter";
  124. }
  125. /**
  126. * Serializes the particle system to a JSON object.
  127. * @returns the JSON object
  128. */
  129. public serialize(): any {
  130. var serializationObject: any = {};
  131. serializationObject.type = this.getClassName();
  132. serializationObject.radius = this._radius;
  133. serializationObject.angle = this._angle;
  134. serializationObject.directionRandomizer = this.directionRandomizer;
  135. return serializationObject;
  136. }
  137. /**
  138. * Parse properties from a JSON object
  139. * @param serializationObject defines the JSON object
  140. */
  141. public parse(serializationObject: any): void {
  142. this.radius = serializationObject.radius;
  143. this.angle = serializationObject.angle;
  144. this.directionRandomizer = serializationObject.directionRandomizer;
  145. }
  146. }
  147. }