//simple routine to render our particles
void ParticleFluidEmitter::renderParticles()
{
	// lock SDK buffers of *PxParticleSystem* ps for reading
	PxParticleFluidReadData * fd = m_pf->lockParticleFluidReadData();
	// access particle data from PxParticleReadData
	float minX =1000,maxX = -1000,minZ = 1000,maxZ = -1000,minY = 1000,maxY = -1000;
	if (fd)
	{
		PxStrideIterator<const PxParticleFlags> flagsIt(fd->flagsBuffer);
		PxStrideIterator<const PxVec3> positionIt(fd->positionBuffer);
		PxStrideIterator<const PxF32> densityIt(fd->densityBuffer);
		for (unsigned i = 0; i < fd->validParticleRange; ++i, ++flagsIt, ++positionIt,++densityIt)
		{
			if (*flagsIt & PxParticleFlag::eVALID)
			{
				//density tells us how many neighbours a particle has.  
				//If it has a density of 0 it has no neighbours, 1 is maximum neighbouts
				//we can use this to decide if the particle is seperate or part of a larger body of fluid
				glm::vec3 pos(positionIt->x,positionIt->y,positionIt->z);
				
				Gizmos::addAABBFilled(pos, m_size, m_colour, nullptr, false);
			}
		}
		// return ownership of the buffers back to the SDK
		fd->unlock();
	}
}
//simple routine to render our particles
void ParticleEmitter::RenderParticles()
{
	// lock SDK buffers of *PxParticleSystem* ps for reading
	PxParticleReadData* rd = m_ps->lockParticleReadData();
	// access particle data from PxParticleReadData
	if (rd)
	{
		PxStrideIterator<const PxParticleFlags> flagsIt(rd->flagsBuffer);
		PxStrideIterator<const PxVec3> positionIt(rd->positionBuffer);

		for (unsigned int i = 0; i < rd->validParticleRange; ++i, ++flagsIt, ++positionIt)
		{
				if (*flagsIt & PxParticleFlag::eVALID)
				{
						//convert physx vector to a glm vec3
						glm::vec3 pos(positionIt->x,positionIt->y,positionIt->z);
						//use a gizmo box to visualize particle.  This would be much better done using a facing quad preferably done using the geometry shader
						
						m_model->SetLocalTransform(glm::translate(pos) * glm::scale(glm::vec3(0.1f)));
						m_model->Render();
				}
		}
		// return ownership of the buffers back to the SDK
		rd->unlock();
	}
}
//simple routine to render our particles
void ParticleFluidEmitter::renderParticles()
{
	// lock SDK buffers of *PxParticleSystem* ps for reading
	PxParticleFluidReadData * fd = m_pf->lockParticleFluidReadData();
	// access particle data from PxParticleReadData
	float minX =1000,maxX = -1000,minZ = 1000,maxZ = -1000,minY = 1000,maxY = -1000;
	if (fd)
	{
		PxStrideIterator<const PxParticleFlags> flagsIt(fd->flagsBuffer);
		PxStrideIterator<const PxVec3> positionIt(fd->positionBuffer);
		PxStrideIterator<const PxF32> densityIt(fd->densityBuffer);
		for (unsigned i = 0; i < fd->validParticleRange; ++i, ++flagsIt, ++positionIt,++densityIt)
		{
			if (*flagsIt & PxParticleFlag::eVALID)
			{
				//density tells us how many neighbours a particle has.  
				//If it has a density of 0 it has no neighbours, 1 is maximum neighbouts
				//we can use this to decide if the particle is seperate or part of a larger body of fluid
				glm::vec3 pos(positionIt->x,positionIt->y,positionIt->z);

				//glm::vec4 colournoise = glm::vec4(((float)(rand() % 100)) / 100, ((float)(rand() % 100)) / 100, ((float)(rand() % 100)) / 100, 1);
				glm::vec4 colour = glm::vec4(0.196f, 0.518f, 0.749f, 1.0f);
				//colour.a = 1;

				Gizmos::addAABBFilled(pos, glm::vec3(.12, .12, .12), colour);
				//Gizmos::addDisk(pos, 0.1f, 6, glm::vec4(1, 0, 1, 1));
			}
		}
		// return ownership of the buffers back to the SDK
		fd->unlock();
	}
}
//updateParticle
void ParticleFluidEmitter::update(float delta)
{
	//tick the emitter
	m_time += delta;
	m_respawnTime+= delta;
	int numberSpawn = 0;
	//if respawn time is greater than our release delay then we spawn at least one particle so work out how many to spawn
	if(m_respawnTime>m_releaseDelay)
	{
		numberSpawn = (int)(m_respawnTime/m_releaseDelay);
		m_respawnTime -= (numberSpawn * m_releaseDelay);
	}
	// spawn the required number of particles 
	for(int count = 0;count < numberSpawn;count++)
	{
		//get the next free particle
		int particleIndex = getNextFreeParticle();
		if(particleIndex >=0)
		{
			//if we got a particle ID then spawn it
			addPhysXParticle(particleIndex);
		}
	}
	//check to see if we need to release particles because they are either too old or have hit the particle sink
	//lock the particle buffer so we can work on it and get a pointer to read data
	PxParticleReadData* rd = m_pf->lockParticleReadData();
	// access particle data from PxParticleReadData was OK
	if (rd)
	{
		vector<PxU32> particlesToRemove; //we need to build a list of particles to remove so we can do it all in one go
		PxStrideIterator<const PxParticleFlags> flagsIt(rd->flagsBuffer);
		PxStrideIterator<const PxVec3> positionIt(rd->positionBuffer);

		for (unsigned i = 0; i < rd->validParticleRange; ++i, ++flagsIt, ++positionIt)
		{
			if (*flagsIt & PxParticleFlag::eVALID)
				{
					//if particle is either too old or has hit the sink then mark it for removal.  We can't remove it here because we buffer is locked
					if (*flagsIt & PxParticleFlag::eCOLLISION_WITH_DRAIN)
					{
						//mark our local copy of the particle free
						releaseParticle(i);
						//add to our list of particles to remove
						particlesToRemove.push_back(i);
					}
				}
		}
		// return ownership of the buffers back to the SDK
		rd->unlock();
		//if we have particles to release then pass the particles to remove to PhysX so it can release them
		if(particlesToRemove.size()>0)
		{
			//create a buffer of particle indicies which we are going to remove
			PxStrideIterator<const PxU32> indexBuffer(&particlesToRemove[0]);
			//free particles from the physics system
			m_pf->releaseParticles(particlesToRemove.size(), indexBuffer);
		}
	}
}
Пример #5
0
void ParticleEmitter::Draw(RenderingEngine& _renderer) {
	// Lock SDK buffers of *PxParticleSystem* ps for reading
	PxParticleFluidReadData * fd = particleFluid->lockParticleFluidReadData();
	// Access particle data from PxParticleReadData
	float minX = 1000, maxX = -1000, minZ = 1000, maxZ = -1000, minY = 1000, maxY = -1000;
	if (fd) {
		PxStrideIterator<const PxParticleFlags> flagsIt(fd->flagsBuffer);
		PxStrideIterator<const PxVec3> positionIt(fd->positionBuffer);
		PxStrideIterator<const PxF32> densityIt(fd->densityBuffer);
		for (unsigned i = 0; i < fd->validParticleRange; ++i, ++flagsIt, ++positionIt, ++densityIt) {
			if (*flagsIt & PxParticleFlag::eVALID) {
				// Density tells us how many neighbours a particle has.  
				// If it has a density of 0 it has no neighbours, 1 is maximum neighbours
				// We can use this to decide if the particle is seperate or part of a larger body of fluid
				vec3 position(positionIt->x, positionIt->y, positionIt->z);
				Gizmos::AddSphere(position, restParticleDistance * 0.5f, 4, 4, vec4(1, 0, 1, 1));
			}
		}
		// return ownership of the buffers back to the SDK
		fd->unlock();
	}
	Gizmos::AddTransform(this->transform->worldMatrix);
}
//simple routine to render our particles
void ParticleEmitter::renderParticles()
{
	// lock SDK buffers of *PxParticleSystem* ps for reading
	PxParticleReadData* rd = m_ps->lockParticleReadData();
	// access particle data from PxParticleReadData
	if (rd)
	{
		PxStrideIterator<const PxParticleFlags> flagsIt(rd->flagsBuffer);
		PxStrideIterator<const PxVec3> positionIt(rd->positionBuffer);

		for (unsigned i = 0; i < rd->validParticleRange; ++i, ++flagsIt, ++positionIt)
		{
				if (*flagsIt & PxParticleFlag::eVALID)
				{
						//convert physx vector to a glm vec3
						glm::vec3 pos(positionIt->x,positionIt->y,positionIt->z);
						//use a gizmo box to visualize particle.  This would be much better done using a facing quad preferably done using the geometry shader
						Gizmos::addAABBFilled(pos,glm::vec3(.1,.1,.1),glm::vec4(1,0,1,1));
				}
		}
		// return ownership of the buffers back to the SDK
		rd->unlock();
	}
}
Пример #7
0
void DownGroup::updateVisuals()
{
    ParticleGroup::updateVisuals();

    PxParticleReadData * readData = m_particleSystem->lockParticleReadData();
    assert(readData);

    m_particleDrawable->updateParticles(readData);

    // Get drained Particles
    std::vector<uint32_t> particlesToDelete;
    PxStrideIterator<const PxParticleFlags> flagsIt(readData->flagsBuffer);
    PxStrideIterator<const PxVec3> positionIt = readData->positionBuffer;


    TerrainInteraction terrain("water");
    std::vector<unsigned int> lavaToSteam;
    glowutils::AxisAlignedBoundingBox steamBbox;
    std::vector<glm::vec3> steamPositions;

    const TerrainSettings & terrainSettings = terrain.terrain().settings;

    for (unsigned i = 0; i < readData->validParticleRange; ++i, ++flagsIt, ++positionIt) {
        // check range
        if (!(*flagsIt & PxParticleFlag::eVALID)) {
            continue;
        }

        if (positionIt->y > terrainSettings.maxHeight * 0.75f) {
            particlesToDelete.push_back(i);
            continue;
        }

        if (*flagsIt & PxParticleFlag::eCOLLISION_WITH_STATIC) {
            if (positionIt->y < m_particleSize + 0.1)   // collision with water plane
            {
                if (m_elementName == "lava")
                {
                    lavaToSteam.push_back(i);
                    steamBbox.extend(reinterpret_cast<const glm::vec3&>(*positionIt));
                    steamPositions.push_back(reinterpret_cast<const glm::vec3&>(*positionIt));
                    continue;
                } else {
                    particlesToDelete.push_back(i);
                    continue;
                }
            }
            if (terrain.topmostElementAt(positionIt->x, positionIt->z) == m_elementName)
            {
                particlesToDelete.push_back(i);
            }
        }
    }

    assert(m_numParticles == readData->nbValidParticles);
    readData->unlock();

    if (!particlesToDelete.empty())
        releaseParticles(particlesToDelete);

    if (!lavaToSteam.empty())
    {
        DownGroup * steamGroup = ParticleGroupTycoon::instance().getNearestGroup("steam", steamBbox.center());
        steamGroup->createParticles(steamPositions);
        releaseParticles(lavaToSteam);
    }
}