Bläddra i källkod

adding subParticleSystem

Ibraheem Osama 7 år sedan
förälder
incheckning
4c727458f6

+ 1 - 0
Tools/Gulp/config.json

@@ -267,6 +267,7 @@
             "files": [
                 "../../src/Particles/babylon.particle.js",
                 "../../src/Particles/babylon.particleSystem.js",
+                "../../src/Particles/babylon.subParticleSystem.js",
                 "../../src/Particles/babylon.boxParticleEmitter.js",
                 "../../src/Particles/babylon.coneParticleEmitter.js",
                 "../../src/Particles/babylon.sphereParticleEmitter.js",

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 10088 - 7368
dist/preview release/babylon.d.ts


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 56 - 69
dist/preview release/viewer/babylon.viewer.js


+ 5 - 1
src/Particles/babylon.particle.ts

@@ -14,11 +14,15 @@
         private _currentFrameCounter = 0;
         public cellIndex: number = 0;
 
-        constructor(private particleSystem: ParticleSystem) {
+        constructor(public particleSystem: ParticleSystem, public generation = 0) {
             if (!this.particleSystem.isAnimationSheetEnabled) {
                 return;
             }
 
+            this.setCellInfoFromSystem();
+        }
+
+        public setCellInfoFromSystem(): void {
             this.cellIndex = this.particleSystem.startSpriteCellID;
 
             if (this.particleSystem.spriteCellChangeSpeed == 0) {

+ 115 - 9
src/Particles/babylon.particleSystem.ts

@@ -108,6 +108,7 @@
         private _currentRenderId = -1;
 
         private _alive: boolean;
+
         private _started = false;
         private _stopped = false;
         private _actualFrame = 0;
@@ -128,6 +129,20 @@
         }
         // end of sheet animation
 
+        // sub emitters
+        public subEmitters: ParticleSystem[];
+
+        // TODO need to lazy loaded
+        public createdSubSystems = new Array<SubParticleSystem>();
+        public stockSubSystems = new StringDictionary<Array<SubParticleSystem>>();
+
+        private _isEmitting = false;
+        // to be overriden by subSystems
+        public stoppedEmitting(): void {
+
+        }
+        //end of sub emitter
+
         constructor(public name: string, capacity: number, scene: Scene, customEffect: Nullable<Effect> = null, private _isAnimationSheetEnabled: boolean = false, epsilon: number = 0.01) {
             this.id = name;
             this._capacity = capacity;
@@ -173,6 +188,7 @@
                     if (particle.age >= particle.lifeTime) { // Recycle by swapping with last particle
                         this.recycleParticle(particle);
                         index--;
+                        this.emitFromParticle(particle);
                         continue;
                     }
                     else {
@@ -215,11 +231,15 @@
         }
 
         public recycleParticle(particle: Particle): void {
-            var lastParticle = <Particle>this.particles.pop();
+            ParticleSystem.recycleParticle(this, this, particle);
+        }
+
+        public static recycleParticle(rootSystem: ParticleSystem, currentSystem: ParticleSystem, particle: Particle) {
+            var lastParticle = <Particle>currentSystem.particles.pop();
 
             if (lastParticle !== particle) {
                 lastParticle.copyTo(particle);
-                this._stockParticles.push(lastParticle);
+                rootSystem._stockParticles.push(lastParticle);
             }
         }
 
@@ -245,6 +265,40 @@
             this._stopped = true;
         }
 
+        public stopSubEmitters(): void {
+            if (this.createdSubSystems.length === 0)
+                return;
+
+            this.createdSubSystems.forEach(subSystem => {
+                subSystem.stop();
+            });
+        }
+
+        public static emitFromGeneration(system: ParticleSystem, particle: Particle, generation: number): void {
+            if (!system.subEmitters || system.subEmitters.length === 0 || generation >= system.subEmitters.length) {
+                return;
+            }
+
+            var generationString = generation.toString();
+
+            if (!system.stockSubSystems.contains(generationString) || (system.stockSubSystems.get(generationString) as (Array<SubParticleSystem>)).length === 0) {
+                var subSystem = system.subEmitters[generation].cloneToSubSystem(system.name, particle.position, generation, system);
+                system.createdSubSystems.push(subSystem);
+                subSystem.start();
+            }
+            else {
+                var stockSubSystem = (system.stockSubSystems.get(generationString) as (Array<SubParticleSystem>)).pop() as SubParticleSystem;
+                stockSubSystem.emitter = particle.position;
+                if (system.subEmitters[generation].manualEmitCount != -1)
+                    stockSubSystem.manualEmitCount = system.subEmitters[generation].manualEmitCount;
+            }
+        }
+        // sub emitter
+        public emitFromParticle(particle: Particle): void {
+            ParticleSystem.emitFromGeneration(this, particle, 0);
+        }
+        // end of sub emitter
+
         // animation sheet
 
         public _appendParticleVertex(index: number, particle: Particle, offsetX: number, offsetY: number): void {
@@ -289,10 +343,39 @@
             this._vertexData[offset + 11] = particle.cellIndex;
         }
 
+        public static createParticle(rootSystem: ParticleSystem, currentSystem: ParticleSystem): Particle {
+            let particle: Particle;
+            if (rootSystem._stockParticles.length !== 0) {
+                particle = <Particle>rootSystem._stockParticles.pop();
+                particle.age = 0;
+                particle.cellIndex = currentSystem.startSpriteCellID;
+                if (currentSystem !== particle.particleSystem) {
+                    particle.particleSystem = currentSystem;
+                    particle.setCellInfoFromSystem();
+                }
+            } else {
+                particle = new Particle(currentSystem);
+            }
+            return particle;
+        }
+
+        public createParticle(): Particle {
+            return ParticleSystem.createParticle(this, this);
+        }
+
         private _update(newParticles: number): void {
             // Update current
             this._alive = this.particles.length > 0;
 
+            if (this._alive) {
+                this._isEmitting = true;
+            }
+
+            if (!this._alive && this._isEmitting) {
+                this._isEmitting = false;
+                this.stoppedEmitting();
+            }
+
             this.updateFunction(this.particles);
 
             // Add new ones
@@ -312,13 +395,7 @@
                     break;
                 }
 
-                if (this._stockParticles.length !== 0) {
-                    particle = <Particle>this._stockParticles.pop();
-                    particle.age = 0;
-                    particle.cellIndex = this.startSpriteCellID;
-                } else {
-                    particle = new Particle(this);
-                }
+                particle = this.createParticle();
 
                 this.particles.push(particle);
 
@@ -578,6 +655,12 @@
             // Callback
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
+
+            if (this.subEmitters) {
+                this.subEmitters.forEach(emitter => {
+                    emitter.dispose();
+                });
+            }
         }
 
         public createSphereEmitter(radius = 1): SphereParticleEmitter {
@@ -619,6 +702,29 @@
             return ((random * (max - min)) + min);
         }
 
+        public cloneToSubSystem(name: string, newEmitter: Vector3, generation: number, root: ParticleSystem): SubParticleSystem {
+            var custom: Nullable<Effect> = null;
+            var program: any = null;
+            if (this.customShader != null) {
+                program = this.customShader;
+                var defines: string = (program.shaderOptions.defines.length > 0) ? program.shaderOptions.defines.join("\n") : "";
+                custom = this._scene.getEngine().createEffectForParticles(program.shaderPath.fragmentElement, program.shaderOptions.uniforms, program.shaderOptions.samplers, defines);
+            }
+            var result = new SubParticleSystem(name, this._capacity, this._scene, generation, root, custom);
+            result.customShader = program;
+            Tools.DeepCopy(this, result, ["customShader"]);
+            result.name = name + "Child" + root.count++;
+            result.id = result.name;
+            result.emitter = newEmitter;
+            result.particleEmitterType = this.particleEmitterType;
+            if (this.particleTexture) {
+                result.particleTexture = new Texture(this.particleTexture.url, this._scene);
+            }
+
+            return result;
+        }
+
+        private count = 0;
 
         // Clone
         public clone(name: string, newEmitter: any): ParticleSystem {

+ 1 - 1
src/Particles/babylon.sphereParticleEmitter.ts

@@ -6,7 +6,7 @@ module BABYLON {
 
         startDirectionFunction(emitPower: number, worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
             // measure the direction Vector from the emitter to the particle.
-            var direction = particle.position.subtract(worldMatrix.getTranslation());
+            var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
             Vector3.TransformNormalFromFloatsToRef(direction.x * emitPower, direction.y * emitPower, direction.z * emitPower, worldMatrix, directionToUpdate);
         }
 

+ 31 - 0
src/Particles/babylon.subParticleSystem.ts

@@ -0,0 +1,31 @@
+module BABYLON {
+    export class SubParticleSystem extends ParticleSystem {
+        constructor(name: string, capacity: number, scene: Scene, private _generation: number, private _parentParticleSystem: ParticleSystem, customEffect: Nullable<Effect> = null, _isAnimationSheetEnabled: boolean = false, epsilon: number = 0.01) {
+            super(name, capacity, scene, customEffect, _isAnimationSheetEnabled, epsilon);
+        }
+
+        public stoppedEmitting(): void {
+            var generationString = this._generation.toString();
+            if (this._parentParticleSystem.stockSubSystems.contains(generationString)) {
+                (this._parentParticleSystem.stockSubSystems.get(generationString) as (Array<SubParticleSystem>)).push(this);
+            }
+            else {
+                var subSysArray = new Array<SubParticleSystem>();
+                subSysArray.push(this);
+                this._parentParticleSystem.stockSubSystems.add(generationString, subSysArray);
+            }
+        }
+
+        public emitFromParticle(particle: Particle): void {
+            ParticleSystem.emitFromGeneration(this._parentParticleSystem, particle, this._generation + 1);
+        }
+
+        public recycleParticle(particle: Particle): void {
+            ParticleSystem.recycleParticle(this._parentParticleSystem, this, particle);
+        }
+
+        public createParticle(): Particle {
+            return ParticleSystem.createParticle(this._parentParticleSystem, this);
+        }
+    }
+}