Example #1
0
void ParticleEmitterRate::stepInternal(ParticleData& particles, PxReal dt, const PxVec3& externalAcceleration, PxReal maxParticleVelocity)
{
	PX_ASSERT(mNumX > 0 && mNumY > 0);
	PxU32 numEmittedParticles = 0;

	//figure out how many particle have to be emitted with the given rate.
	mParticlesToEmit += mRate*dt;
	PxU32 numEmit = (PxU32)(mParticlesToEmit);
	if(numEmit == 0)
		return;
	
	PxU32 numLayers = (PxU32)(numEmit / (mNumX * mNumY)) + 1;
	PxReal layerDistance = dt * mVelocity / numLayers;

	PxU32 sparseMax = 0;

	//either shuffle or draw without repeat (approximation)
	bool denseEmission = (PxU32(PARTICLE_EMITTER_SPARSE_FACTOR*numEmit) > mNumSites);
	if(denseEmission)
	{
		initDenseSites();
	}
	else
	{
		sparseMax = PARTICLE_EMITTER_SPARSE_FACTOR*numEmit;
		mSites.resize(sparseMax);
	}

	// generate particles
	PxU32 l = 0;
	while(numEmit > 0)
	{
		PxVec3 layerVec = mAxisZ * (layerDistance * (PxReal)l);
		l++;

		if(denseEmission)
			shuffleDenseSites();
		else
			initSparseSiteHash(numEmit, sparseMax);

		for (PxU32 i = 0; i < mNumSites && numEmit > 0; i++)
		{
			PxU32 emissionSite;
			if (denseEmission)
				emissionSite = mSites[i];
			else
				emissionSite = pickSparseEmissionSite(sparseMax);

			PxU32 x = emissionSite / mNumY;
			PxU32 y = emissionSite % mNumY;

			PxReal offset = 0.0f;
			if (y%2) offset = mSpacingX * 0.5f;
				
			if (isOutsideShape(x,y,offset)) 
				continue;

			//position noise
			PxVec3 posNoise;
			posNoise.x = randInRange(-mRandomPos.x, mRandomPos.x);
			posNoise.y = randInRange(-mRandomPos.y, mRandomPos.y);	
			posNoise.z = randInRange(-mRandomPos.z, mRandomPos.z);	

			PxVec3 emissionPoint = mBasePos + layerVec + 
				mAxisX*(posNoise.x+offset+mSpacingX*x) + mAxisY*(posNoise.y+mSpacingY*y) + mAxisZ*posNoise.z;

			PxVec3 particleVelocity;
			computeSiteVelocity(particleVelocity, emissionPoint);

			bool isSpawned = spawnParticle(particles, numEmittedParticles, particles.maxParticles - particles.numParticles, emissionPoint, particleVelocity);
			if(isSpawned)
			{
				numEmit--;
				mParticlesToEmit -= 1.0f;
			}
			else
				return;
		}
	}
}
void ParticleEmitterPressure::stepInternal(ParticleData& particles, PxReal dt, const PxVec3& externalAcceleration, PxReal maxParticleVelocity)
{
	PX_ASSERT(mNumX > 0 && mNumY > 0);
	
	mSimulationAcceleration = externalAcceleration;
	mSimulationMaxVelocity = maxParticleVelocity;
	
	PxU32 numEmittedParticles = 0;

	PxU32 maxParticlesPerStep = (PxU32)physx::shdfnd::floor(mMaxRate*dt);
	PxU32 maxParticles = PxMin(particles.maxParticles - particles.numParticles, maxParticlesPerStep);

	PxU32 siteNr = 0;	
	for(PxU32 y = 0; y != mNumY; y++)
	{
		PxReal offset = 0.0f;
		if (y%2) offset = mSpacingX * 0.5f;

		for(PxU32 x = 0; x != mNumX; x++)
		{
			if (isOutsideShape(x,y,offset))
				continue;

			SiteData& siteData = mSites[siteNr];

			//position noise
			PxVec3 posNoise;
			posNoise.x = randInRange(-mRandomPos.x, mRandomPos.x);
			posNoise.y = randInRange(-mRandomPos.y, mRandomPos.y);
			
			//special code for Z noise 
			if (!siteData.predecessor) 
				siteData.noiseZ = randInRange(-mRandomPos.z, mRandomPos.z);
			else
			{
				PxReal noiseZOffset = PxMin(mMaxZNoiseOffset, mRandomPos.z);
				siteData.noiseZ += randInRange(-noiseZOffset, noiseZOffset);
				siteData.noiseZ = PxClamp(siteData.noiseZ, mRandomPos.z, -mRandomPos.z);
			}

			posNoise.z = siteData.noiseZ;

			//set position
			PxVec3 sitePos = mBasePos + mAxisX*(offset+mSpacingX*x) + mAxisY*(mSpacingY*y) + mAxisZ*siteData.noiseZ;
			PxVec3 particlePos = sitePos + mAxisX*posNoise.x + mAxisY*posNoise.y;

			PxVec3 siteVel;
			computeSiteVelocity(siteVel, particlePos);

			if (siteData.predecessor)
			{
				predictPredecessorPos(siteData, dt);
			}
			else			{
				bool isSpawned = spawnParticle(particles, numEmittedParticles, maxParticles, particlePos, siteVel);
				if(isSpawned)
				{
					updatePredecessor(siteData, particlePos, siteVel);
				}
				else
				{
					siteData.predecessor = false;
					return;
				}
			}
			
			bool allSpawned = stepEmissionSite(siteData, particles, numEmittedParticles, maxParticles, sitePos, siteVel, dt);
			if(!allSpawned)
				return;

			siteNr++;
		}
	}
}