babylon.coneParticleEmitter.ts 6.2 KB

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