//called by a particle store (particle type) to emit a particle in a different particle store internal void Emit(ParticleSystemEmitData emit, int sourceIndex, float sourceIndexF) { particleStore[emit.typeIndex].Emit(this, emit, sourceIndex, sourceIndexF, timeStep); }
//the logic to emit a single particle public void Emit(ParticleSystem system, ParticleSystemEmitData emit, int sourceIndex, float sourceIndexF, int step) { //need more capacity? if (particleCapacity == particles.Length) Array.Resize(ref this.particles, this.particles.Length * 2); uint index = particleCapacity++; //for profiling maxParticleCapacity = Math.Max(maxParticleCapacity, index); //find the step the particle will be removed on int stepIndex = emit.baseLifeTimeStep; if (emit.varianceTimeStep != 0) stepIndex += system.systemRandom.Next(emit.varianceTimeStep); stepIndex = Math.Max(1, stepIndex); //lifespan in steps int life = stepIndex; //remove step stepIndex = (stepIndex + step) & timeStepMask; //create the particle Particle particle = new Particle(); particle.index = particleCapacityF++; particle.previousParticleIndexForTimeStep = uint.MaxValue; particle.nextParticleIndexForTimeStep = uint.MaxValue; particle.addActionIndex = addActionCount; if (timeSteps[stepIndex].count++ != 0) { //step isn't empty? uint previousFirst = timeSteps[stepIndex].firstParticleIndex; particle.nextParticleIndexForTimeStep = previousFirst; particles[previousFirst].previousParticleIndexForTimeStep = index; } //start of the linked list timeSteps[stepIndex].firstParticleIndex = index; particle.timeStepIndex = (ushort)stepIndex; //store this.particles[index] = particle; //create the addAction AddAction action = new AddAction(); action.index = index; action.lifeSteps = (uint)life; action.indexF = particle.index; action.cloneFromIndex = sourceIndex; action.cloneFromIndexF = sourceIndexF; action.cloneTypeIndex = emit.emitFromTypeIndex; //if sourceIndex is -1, then this is a root level particle, //so it's positin is set by the application. if (sourceIndex == -1) { system.GetSpawnDetails(out action.spawnDetails); } typeEmitDependancy[emit.emitFromTypeIndex + 1] = true; //cannot spawn more than 32k particles in a single frame if (addActionCount != (ushort)short.MaxValue) { addActions[addActionCount] = action; if (++addActionCount == addActions.Length) Array.Resize(ref addActions, addActions.Length * 2); } }
//emit a particle from every particle public void EmitEach(ParticleSystem system, ParticleSystemEmitData emit, int step) { //emits one particle from every particle. //don't want to emit from a particle being emitted... (recursive emit) int cap = (int)particleCapacity; float f = 0; for (int i = 0; i < cap; i++) system.Emit(emit,i,f++); }