Browse Source

Initial hemisphericEmitter for particles

David Catuhe 7 years ago
parent
commit
d85a4c8c60

+ 1 - 0
Tools/Gulp/config.json

@@ -294,6 +294,7 @@
                 "../../src/Particles/EmitterTypes/babylon.boxParticleEmitter.js",
                 "../../src/Particles/EmitterTypes/babylon.coneParticleEmitter.js",
                 "../../src/Particles/EmitterTypes/babylon.sphereParticleEmitter.js",
+                "../../src/Particles/EmitterTypes/babylon.hemisphericParticleEmitter.js",
                 "../../src/Particles/EmitterTypes/babylon.pointParticleEmitter.js",
                 "../../src/Particles/babylon.particleSystemComponent.js"
             ],

+ 126 - 0
src/Particles/EmitterTypes/babylon.hemisphericParticleEmitter.ts

@@ -0,0 +1,126 @@
+module BABYLON {
+    /**
+     * Particle emitter emitting particles from the inside of a hemisphere.
+     * It emits the particles alongside the hemisphere radius. The emission direction might be randomized.
+     */
+    export class HemisphericParticleEmitter implements IParticleEmitterType {
+         /**
+         * Creates a new instance HemisphericParticleEmitter
+         * @param radius the radius of the emission hemisphere (1 by default)
+         * @param radiusRange the range of the emission hemisphere [0-1] 0 Surface only, 1 Entire Radius (1 by default) 
+         * @param directionRandomizer defines how much to randomize the particle direction [0-1]
+         */
+        constructor(
+            /**
+             * The radius of the emission hemisphere.
+             */
+            public radius = 1,
+            /**
+             * The range of emission [0-1] 0 Surface only, 1 Entire Radius.
+             */
+            public radiusRange = 1,
+            /**
+             * How much to randomize the particle direction [0-1].
+             */
+            public directionRandomizer = 0) {
+        }
+
+        /**
+         * Called by the particle System when the direction is computed for the created particle.
+         * @param worldMatrix is the world matrix of the particle system
+         * @param directionToUpdate is the direction vector to update with the result
+         * @param particle is the particle we are computed the direction for
+         */
+        public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+            var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
+            var randX = Scalar.RandomRange(0, this.directionRandomizer);
+            var randY = Scalar.RandomRange(0, this.directionRandomizer);
+            var randZ = Scalar.RandomRange(0, this.directionRandomizer);
+            direction.x += randX;
+            direction.y += randY;
+            direction.z += randZ;
+            direction.normalize();
+
+            Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
+        }
+
+        /**
+         * Called by the particle System when the position is computed for the created particle.
+         * @param worldMatrix is the world matrix of the particle system
+         * @param positionToUpdate is the position vector to update with the result
+         * @param particle is the particle we are computed the position for
+         */
+        public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
+            var randRadius = this.radius - Scalar.RandomRange(0, this.radius * this.radiusRange);
+            var v = Scalar.RandomRange(0, 1.0); 
+            var phi = Scalar.RandomRange(0, Math.PI);
+            var theta = Math.acos(2 * v - 1);
+            var randX = randRadius * Math.cos(phi) * Math.sin(theta);
+            var randY = randRadius * Math.cos(theta);
+            var randZ = randRadius * Math.sin(phi) * Math.sin(theta);
+            Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
+        }
+
+        /**
+         * Clones the current emitter and returns a copy of it
+         * @returns the new emitter
+         */
+        public clone(): HemisphericParticleEmitter {
+            let newOne = new HemisphericParticleEmitter(this.radius, this.directionRandomizer);
+
+            Tools.DeepCopy(this, newOne);
+
+            return newOne;
+        }    
+        
+        /**
+         * Called by the {BABYLON.GPUParticleSystem} to setup the update shader
+         * @param effect defines the update shader
+         */        
+        public applyToShader(effect: Effect): void {
+            effect.setFloat("radius", this.radius);
+            effect.setFloat("radiusRange", this.radiusRange);
+            effect.setFloat("directionRandomizer", this.directionRandomizer);
+        }    
+        
+        /**
+         * Returns a string to use to update the GPU particles update shader
+         * @returns a string containng the defines string
+         */
+        public getEffectDefines(): string {
+            return "#define HEMISPHERICEMITTER"
+        }   
+        
+        /**
+         * Returns the string "HemisphericParticleEmitter"
+         * @returns a string containing the class name
+         */
+        public getClassName(): string {
+            return "HemisphericParticleEmitter";
+        }         
+        
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */        
+        public serialize(): any {
+            var serializationObject: any = {};
+            serializationObject.type = this.getClassName();
+            serializationObject.radius = this.radius;
+            serializationObject.radiusRange = this.radiusRange;
+            serializationObject.directionRandomizer = this.directionRandomizer;
+
+            return serializationObject;
+        }    
+        
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        public parse(serializationObject: any): void {
+            this.radius = serializationObject.radius;
+            this.radiusRange = serializationObject.radiusRange;
+            this.directionRandomizer = serializationObject.directionRandomizer;
+        }          
+    }
+}

+ 12 - 0
src/Particles/babylon.particleSystem.ts

@@ -1599,6 +1599,18 @@
         }
 
         /**
+         * Creates a Hemisphere Emitter for the particle system (emits along the hemisphere radius)
+         * @param radius The radius of the hemisphere to emit from
+         * @param radiusRange The range of the hemisphere to emit from [0-1] 0 Surface Only, 1 Entire Radius
+         * @returns the emitter
+         */
+        public createHemisphericEmitter(radius = 1, radiusRange = 1): HemisphericParticleEmitter {
+            var particleEmitter = new HemisphericParticleEmitter(radius, radiusRange);
+            this.particleEmitterType = particleEmitter;
+            return particleEmitter;
+        }
+
+        /**
          * Creates a Sphere Emitter for the particle system (emits along the sphere radius)
          * @param radius The radius of the sphere to emit from
          * @param radiusRange The range of the sphere to emit from [0-1] 0 Surface Only, 1 Entire Radius