hemisphericParticleEmitter.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { Tools } from "Tools";
  2. import { Vector3, Matrix, Scalar } from "Math";
  3. import { Effect } from "Materials";
  4. import { IParticleEmitterType, Particle } from "Particles";
  5. /**
  6. * Particle emitter emitting particles from the inside of a hemisphere.
  7. * It emits the particles alongside the hemisphere radius. The emission direction might be randomized.
  8. */
  9. export class HemisphericParticleEmitter implements IParticleEmitterType {
  10. /**
  11. * Creates a new instance HemisphericParticleEmitter
  12. * @param radius the radius of the emission hemisphere (1 by default)
  13. * @param radiusRange the range of the emission hemisphere [0-1] 0 Surface only, 1 Entire Radius (1 by default)
  14. * @param directionRandomizer defines how much to randomize the particle direction [0-1]
  15. */
  16. constructor(
  17. /**
  18. * The radius of the emission hemisphere.
  19. */
  20. public radius = 1,
  21. /**
  22. * The range of emission [0-1] 0 Surface only, 1 Entire Radius.
  23. */
  24. public radiusRange = 1,
  25. /**
  26. * How much to randomize the particle direction [0-1].
  27. */
  28. public directionRandomizer = 0) {
  29. }
  30. /**
  31. * Called by the particle System when the direction is computed for the created particle.
  32. * @param worldMatrix is the world matrix of the particle system
  33. * @param directionToUpdate is the direction vector to update with the result
  34. * @param particle is the particle we are computed the direction for
  35. */
  36. public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
  37. var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
  38. var randX = Scalar.RandomRange(0, this.directionRandomizer);
  39. var randY = Scalar.RandomRange(0, this.directionRandomizer);
  40. var randZ = Scalar.RandomRange(0, this.directionRandomizer);
  41. direction.x += randX;
  42. direction.y += randY;
  43. direction.z += randZ;
  44. direction.normalize();
  45. Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
  46. }
  47. /**
  48. * Called by the particle System when the position is computed for the created particle.
  49. * @param worldMatrix is the world matrix of the particle system
  50. * @param positionToUpdate is the position vector to update with the result
  51. * @param particle is the particle we are computed the position for
  52. */
  53. public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
  54. var randRadius = this.radius - Scalar.RandomRange(0, this.radius * this.radiusRange);
  55. var v = Scalar.RandomRange(0, 1.0);
  56. var phi = Scalar.RandomRange(0, 2 * Math.PI);
  57. var theta = Math.acos(2 * v - 1);
  58. var randX = randRadius * Math.cos(phi) * Math.sin(theta);
  59. var randY = randRadius * Math.cos(theta);
  60. var randZ = randRadius * Math.sin(phi) * Math.sin(theta);
  61. Vector3.TransformCoordinatesFromFloatsToRef(randX, Math.abs(randY), randZ, worldMatrix, positionToUpdate);
  62. }
  63. /**
  64. * Clones the current emitter and returns a copy of it
  65. * @returns the new emitter
  66. */
  67. public clone(): HemisphericParticleEmitter {
  68. let newOne = new HemisphericParticleEmitter(this.radius, this.directionRandomizer);
  69. Tools.DeepCopy(this, newOne);
  70. return newOne;
  71. }
  72. /**
  73. * Called by the GPUParticleSystem to setup the update shader
  74. * @param effect defines the update shader
  75. */
  76. public applyToShader(effect: Effect): void {
  77. effect.setFloat("radius", this.radius);
  78. effect.setFloat("radiusRange", this.radiusRange);
  79. effect.setFloat("directionRandomizer", this.directionRandomizer);
  80. }
  81. /**
  82. * Returns a string to use to update the GPU particles update shader
  83. * @returns a string containng the defines string
  84. */
  85. public getEffectDefines(): string {
  86. return "#define HEMISPHERICEMITTER";
  87. }
  88. /**
  89. * Returns the string "HemisphericParticleEmitter"
  90. * @returns a string containing the class name
  91. */
  92. public getClassName(): string {
  93. return "HemisphericParticleEmitter";
  94. }
  95. /**
  96. * Serializes the particle system to a JSON object.
  97. * @returns the JSON object
  98. */
  99. public serialize(): any {
  100. var serializationObject: any = {};
  101. serializationObject.type = this.getClassName();
  102. serializationObject.radius = this.radius;
  103. serializationObject.radiusRange = this.radiusRange;
  104. serializationObject.directionRandomizer = this.directionRandomizer;
  105. return serializationObject;
  106. }
  107. /**
  108. * Parse properties from a JSON object
  109. * @param serializationObject defines the JSON object
  110. */
  111. public parse(serializationObject: any): void {
  112. this.radius = serializationObject.radius;
  113. this.radiusRange = serializationObject.radiusRange;
  114. this.directionRandomizer = serializationObject.directionRandomizer;
  115. }
  116. }