예제 #1
0
	void Group::sortParticles()
	{
		computeDistances();

		if (sortingEnabled)
			sortParticles(0,pool.getNbActive() - 1);
	}
void ParticleSystem::drawParticles() 
{
    gravity = Vector(0.0, gravity_y, 0.0);
    main_direction = Vector(particle_direction[X], 
                            particle_direction[Y], 
                            particle_direction[Z]);
    int current_time = glutGet(GLUT_ELAPSED_TIME);
    elapsed = (current_time - last_time) * 0.001f;
    last_time = current_time;

    getCameraMatrices();

    if (max_particles != m_max_particles) {
        max_particles = m_max_particles;
        particles.resize(max_particles);

        if (system_type != POINTS) {
            delete [] position_size_data;
            delete [] color_data;
            delete [] age_data;
            position_size_data = new GLfloat[max_particles * 4];
            color_data = new GLubyte[max_particles * 4];
            age_data = new GLfloat[max_particles];
        }
    }

    computeParticles();

    if (system_type != POINTS) {
        sortParticles();
        bindShaders();
    }
}
예제 #3
0
void PoiseuilleFlowSystem::update(){
	assert(IsInitialized);

	float *dPos;

	if (IsOpenGL) 
		dPos = (float *) mapGLBufferObject(&cuda_posvbo_resource);
	else 
		dPos = (float *) cudaPosVBO;    		
	
	calculatePoiseuilleHash(dHash, dIndex, dPos, numParticles);

	sortParticles(dHash, dIndex, numParticles);

	reorderPoiseuilleData(
		dCellStart,
		dCellEnd,
		dSortedPos,		
		dSortedVel,
		dHash,
		dIndex,
		dPos,		
		dVelLeapFrog,
		numParticles,
		numGridCells);
	
	calculatePoiseuilleDensity(		
		dMeasures,
		dSortedPos,	
		dSortedVel,
		dIndex,
		dCellStart,
		dCellEnd,
		numParticles,
		numGridCells);

	calculatePoiseuilleAcceleration(
		dAcceleration,
		dMeasures,		
		dSortedPos,			
		dSortedVel,
		dIndex,
		dCellStart,
		dCellEnd,
		numParticles,
		numGridCells);    

	integratePoiseuilleSystem(
		dPos,
		dVel,	
		dVelLeapFrog,
		dAcceleration,
		numParticles);
	
	if (IsOpenGL) {
		unmapGLBufferObject(cuda_posvbo_resource);
	}
	elapsedTime+= params.deltaTime;
}
예제 #4
0
	void Group::sortParticles(int start,int end)
	{
		if (start < end)
		{
			int i = start - 1;
			int j = end + 1;
			float pivot = particleData[(start + end) >> 1].sqrDist;
			while (true)
			{
				do ++i;
				while (particleData[i].sqrDist > pivot);
				do --j;	
				while (particleData[j].sqrDist < pivot);
				if (i < j)
					swapParticles(pool[i],pool[j]);
				else break;
			}

			sortParticles(start,j);
			sortParticles(j + 1,end);
		}
예제 #5
0
void Particles::Update()
{
	assert(initFlag);
	float *dPos;
	dPos = (float *)mapGLBufferObject(&m_cuda_posvbo_resource);

	setParameters(&mparams);
	integrateSystem(dPos, velGpu, mparams.timeStep, numParticles);
	calcHash(gridParticleHash, gridParticleIndex,dPos,numParticles);
	sortParticles(gridParticleHash,gridParticleIndex,numParticles);
	reorderDataAndFindCellStart(cellStart,cellEnd,sortedPos,sortedVel,gridParticleHash,gridParticleIndex,dPos,velGpu,numParticles,mparams.wholeNumCells);
	simFluid(velGpu, sortedPos, sortedVel, gridParticleIndex, cellStart, cellEnd, numParticles, solidPosGpu, solidVelGpu, buoyancyGpu, buoyancyAngGpu);
	unmapGLBufferObject(m_cuda_posvbo_resource);
}
예제 #6
0
// depth sort the particles
void
ParticleSystem::depthSort()
{
    if (!m_doDepthSort)
    {
        return;
    }

    m_pos.map();
    m_indices.map();

    // calculate depth
    calcDepth(m_pos.getDevicePtr(), m_sortKeys.getDevicePtr(), m_indices.getDevicePtr(), m_sortVector, m_numParticles);

    // radix sort
    sortParticles(m_sortKeys.getDevicePtr(), m_indices.getDevicePtr(), m_numParticles);

    m_pos.unmap();
    m_indices.unmap();
}
void ParticleSystemCore::drawPrimitives (DrawEnv *pEnv)
{
    //If I have a Drawer tell it to draw the particles
    if(getDrawer() != NULL && getSystem() != NULL)
    {
		
		checkAndInitializeSort();
		sortParticles(pEnv);

		getDrawer()->draw(pEnv, getSystem(), *getMFSort());
    }
    else
    {
        if(getDrawer() == NULL)
        {
            FWARNING(("ParticleSystemCore::draw: ParticleSystemDrawer is Null."));
        }
        if(getSystem() == NULL)
        {
            FWARNING(("ParticleSystemCore::draw: ParticleSystem is Null."));
        }
    }
}
예제 #8
0
void SPHSystem::computeDensity() {
    sortParticles();
    
    vector<float>& rho = density;
    
    memset(&(rho[0]), 0, sizeof(float)*rho.size());
    
    for (int i = 0; i < n; ++i) {
        rho[i] += mass * kern.poly6(0);
        
        for(int nidx=0;nidx<nid[i].size();nidx++) {
            const Grid::cell_t& ncell = pgrid.getcell(nid[i][nidx]);
            
            for (int j : ncell) {
                if (i >= j) {
                    continue;
                }
                Vec dp = p[i] - p[j];
                
                float r = glm::length(dp);
                float rho_ij = mass * kern.poly6(r);
                rho[i] += rho_ij;
                rho[j] += rho_ij;
            }
        }
    }
    
    // update pressure
//    const float B = params.k;
//    const float gamma = 7.0;
//    const float invRHO0 = 1.0 / params.rho0;
    for (int i=0; i<n; ++i) {
        pressure[i] = params.k * (rho[i] - params.rho0);
//        pressure[i] = B * (powf(rho[i] * invRHO0, gamma) - 1);
        invrho[i] = 1.0 / rho[i];
    }
}
void ParticleManager::doSpatialHash(float4 * pos, uint numParticles)
{
	calcHash(m_dGridParticleHash, m_dGridParticleIndex, (float*)pos, numParticles);
	sortParticles(m_dGridParticleHash, m_dGridParticleIndex, numParticles);
	FindCellStart(m_dCellStart, m_dCellEnd, m_dGridParticleHash, m_dGridParticleIndex, numParticles, m_params->numCells);
}
// step the simulation
void
ParticleSystem::update(float deltaTime)
{
    assert(m_bInitialized);

    float *dPos;

    if (m_bUseOpenGL)
    {
        dPos = (float *) mapGLBufferObject(&m_cuda_posvbo_resource);
    }
    else
    {
        dPos = (float *) m_cudaPosVBO;
    }

    // update constants
    setParameters(&m_params);

    // integrate
    integrateSystem(
        dPos,
        m_dVel,
        deltaTime,
        m_numParticles);

    // calculate grid hash
    calcHash(
        m_dGridParticleHash,
        m_dGridParticleIndex,
        dPos,
        m_numParticles);

    // sort particles based on hash
    sortParticles(m_dGridParticleHash, m_dGridParticleIndex, m_numParticles);

    // reorder particle arrays into sorted order and
    // find start and end of each cell
    reorderDataAndFindCellStart(
        m_dCellStart,
        m_dCellEnd,
        m_dSortedPos,
        m_dSortedVel,
        m_dGridParticleHash,
        m_dGridParticleIndex,
        dPos,
        m_dVel,
        m_numParticles,
        m_numGridCells);

    // process collisions
    collide(
        m_dVel,
        m_dSortedPos,
        m_dSortedVel,
        m_dGridParticleIndex,
        m_dCellStart,
        m_dCellEnd,
        m_numParticles,
        m_numGridCells);

    // note: do unmap at end here to avoid unnecessary graphics/CUDA context switch
    if (m_bUseOpenGL)
    {
        unmapGLBufferObject(m_cuda_posvbo_resource);
    }
}
예제 #11
0
	bool Group::update(float deltaTime)
	{
		unsigned int nbManualBorn = nbBufferedParticles;
		unsigned int nbAutoBorn = 0;

		bool hasActiveEmitters = false;	

		// Updates emitters
		activeEmitters.clear();
		std::vector<Emitter*>::const_iterator endIt = emitters.end();
		for (std::vector<Emitter*>::const_iterator it = emitters.begin(); it != endIt; ++it)
		{
			if ((*it)->isActive())
			{
				int nb = (*it)->updateNumber(deltaTime);
				if (nb > 0)
				{
					EmitterData data = {*it,nb};
					activeEmitters.push_back(data);
					nbAutoBorn += nb;
				}
			}

			hasActiveEmitters |= !((*it)->isSleeping());
		}
		std::vector<EmitterData>::iterator emitterIt = activeEmitters.begin();

		unsigned int nbBorn = nbAutoBorn + nbManualBorn;

		// Inits bounding box
		if (boundingBoxEnabled)
		{
			const float maxFloat = std::numeric_limits<float>::max();
			AABBMin.set(maxFloat,maxFloat,maxFloat);
			AABBMax.set(-maxFloat,-maxFloat,-maxFloat);
		}

		// Prepare modifiers for processing
		activeModifiers.clear();
		for (std::vector<Modifier*>::iterator it = modifiers.begin(); it != modifiers.end(); ++it)
		{
			(*it)->beginProcess(*this);
			if ((*it)->isActive())
				activeModifiers.push_back(*it);
		}

		// Updates particles
		for (size_t i = 0; i < pool.getNbActive(); ++i)
		{
			if ((pool[i].update(deltaTime))||((fupdate != NULL)&&((*fupdate)(pool[i],deltaTime))))
			{
				if (fdeath != NULL)
					(*fdeath)(pool[i]);

				if (nbBorn > 0)
				{
					pool[i].init();
					launchParticle(pool[i],emitterIt,nbManualBorn);
					--nbBorn;
				}
				else
				{
					particleData[i].sqrDist = 0.0f;
					pool.makeInactive(i);
					--i;
				}
			}
			else
			{
				if (boundingBoxEnabled)
					updateAABB(pool[i]);

				if (distanceComputationEnabled)
					pool[i].computeSqrDist();
			}
		}

		// Terminates modifiers processing
		for (std::vector<Modifier*>::iterator it = modifiers.begin(); it != modifiers.end(); ++it)
			(*it)->endProcess(*this);

		// Emits new particles if some left
		for (int i = nbBorn; i > 0; --i)
			pushParticle(emitterIt,nbManualBorn);

		// Sorts particles if enabled
		if ((sortingEnabled)&&(pool.getNbActive() > 1))
			sortParticles(0,pool.getNbActive() - 1);

		if ((!boundingBoxEnabled)||(pool.getNbActive() == 0))
		{
			AABBMin.set(0.0f,0.0f,0.0f);
			AABBMax.set(0.0f,0.0f,0.0f);
		}

		return (hasActiveEmitters)||(pool.getNbActive() > 0);
	}
예제 #12
0
void FluidSystem::update(float deltaTime) //整个particle或流体的update
{
    assert(m_bInitialized);

    float *dPos;
    if (m_bUseOpenGL)
    {
		m_dPos = (float *)mapGLBufferObject(&m_cuda_posvbo_resource);
		m_dVel = (float *)mapGLBufferObject(&m_cuda_velvbo_resource);

    }
    else
    {
		m_dPos = (float *)m_cudaPosVBO;
		m_dVel = (float *)m_cudaVelVBO;
    }
/////////////////////////////////////////////////////calculate time
	cudaEvent_t start, stop;
	cudaEventCreate(&start);
	cudaEventCreate(&stop);
	// Start record
	cudaEventRecord(start, 0);
///////////////////////////////////////////////////////////////////////

    setParameters(&m_params);

    integrateSystem(
		m_dPos,
        m_dVel,
		m_dDen,
		m_dPre,
        deltaTime,
        m_numParticles,
		buoyancyForce);

	//calculateBuoyancy();

	cudaEvent_t start1, stop1;
	cudaEventCreate(&start1);
	cudaEventCreate(&stop1);
	// Start record
	cudaEventRecord(start1, 0);

    calcHash(
        m_dGridParticleHash,
        m_dGridParticleIndex,
		m_dPos,
        m_numParticles);

    sortParticles(m_dGridParticleHash, m_dGridParticleIndex, m_numParticles);

    reorderDataAndFindCellStart(
        m_dCellStart,
        m_dCellEnd,
        m_dSortedPos,
        m_dSortedVel,
        m_dGridParticleHash,
        m_dGridParticleIndex,
		m_dPos,
        m_dVel,
        m_numParticles,
        m_numGridCells,
		m_dSortedDen,
		m_dSortedPre,
		m_dDen,   //old density
		m_dPre,//old pressure
		m_dSortedColorf,
		m_dColorf);

	cudaEventRecord(stop1, 0);
	cudaEventSynchronize(stop1);
	float elapsedTime1;
	cudaEventElapsedTime(&elapsedTime1, start1, stop1); // that's our time!

	std::cout <<"neighbour " <<elapsedTime1 << endl;

	// Clean up:
	cudaEventDestroy(start1);
	cudaEventDestroy(stop1);

	/*colorfield(
		m_dSortedPos,
		m_dGridParticleIndex,
		m_dCellStart,
		m_dCellEnd,
		m_numParticles,
		m_numGridCells,
		m_dColorf,
		m_dSortedColorf);*/
	//
	copyArrayFromDevice(m_hDen, m_dDen, 0, sizeof(float) * m_numParticles);


	/*glBindBufferARB(GL_ARRAY_BUFFER, m_colorVBO);
	float *data = (float *)glMapBufferARB(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
	float *ptr = data;

	for (uint i = 0; i<m_numParticles; i++)
	{
		float t = i / (float)m_numParticles;
		if (  m_hDen[i]<2.5f){
			colorRamp(1, 1, 1, ptr);
			ptr += 3;
			*ptr++ = 0.1f;
		}
		else
		{
			colorRamp(0, 1, 1, ptr);
			ptr += 3;
			*ptr++ = 0.1f;
		}

	}

	glUnmapBufferARB(GL_ARRAY_BUFFER);*/


	cudaEvent_t start2, stop2;
	cudaEventCreate(&start2);
	cudaEventCreate(&stop2);
	// Start record
	cudaEventRecord(start2, 0);

	calculateDensity(m_dSortedPos,
		m_dGridParticleIndex,
		m_dCellStart,
		m_dCellEnd,
		m_numParticles,
		m_dDen);

    collide(
        m_dVel, //new velocity
        m_dSortedPos,
        m_dSortedVel,
        m_dGridParticleIndex,
        m_dCellStart,
        m_dCellEnd,
        m_numParticles,
        m_numGridCells,
		m_dDen, //new density
		m_dPre, //new pressure
		m_dSortedDen,
		m_dSortedPre,
		m_dPos,
		buoyancyForce);

	cudaEventRecord(stop2, 0);
	cudaEventSynchronize(stop2);
	float elapsedTime2;
	cudaEventElapsedTime(&elapsedTime2, start2, stop2); // that's our time!

	std::cout << "renew " << elapsedTime2 << endl;

	// Clean up:
	cudaEventDestroy(start2);
	cudaEventDestroy(stop2);
	////////////////////////////////////////////////////////////stop calculate time
	cudaEventRecord(stop, 0);
	cudaEventSynchronize(stop);
	float elapsedTime;
	cudaEventElapsedTime(&elapsedTime, start, stop); // that's our time!

	std::cout << "whole " << elapsedTime << endl;

	// Clean up:
	cudaEventDestroy(start);
	cudaEventDestroy(stop);
	//////////////////////////////////////////////////////////

    if (m_bUseOpenGL)
    {
        unmapGLBufferObject(m_cuda_posvbo_resource);
		unmapGLBufferObject(m_cuda_velvbo_resource);
    }
}
예제 #13
0
bool Group::update(float deltaTimeInSeconds)
{
	uint32 nbManualBorn = NumOfBufferedParticles;
	uint32 nbAutoBorn = 0;

	bool hasActiveEmitters = false;

	// Updates emitters
	activeEmitters.clear();

	Emitter** endIt = emitters.end();
	for( Emitter** it = emitters.begin(); it < endIt; ++it )
	{
		if( (*it)->isActive() )
		{
			uint32 nb = (*it)->updateNumber(deltaTimeInSeconds);
			if( nb > 0 )
			{
				EmitterData data = {*it, nb};
				activeEmitters.add(data);
				nbAutoBorn += nb;
			}
		}

		hasActiveEmitters |= !((*it)->isSleeping());
	}

	EmitterData* emitterIt = activeEmitters.begin();

	uint32 nbBorn = nbAutoBorn + nbManualBorn;

	// Inits bounding box
	if(boundingBoxEnabled)
	{
		boundingBoxAABB.vcMin.Set(0, 0, 0);
		boundingBoxAABB.vcMax.Set(0, 0, 0);
		boundingBoxAABB.vcCenter.Set(0, 0, 0);
	}

	// Prepare modifiers for processing
	activeModifiers.clear();
	for( Modifier** it = modifiers.begin(); it < modifiers.end(); ++it )
	{
		(*it)->beginProcess(*this);
		if( (*it)->isActive() )
			activeModifiers.add(*it);
	}

	// Updates particles
	for( uint32 i = 0; i < pool.getSizeOfActive(); ++i )
	{
		if( pool[i].update(deltaTimeInSeconds) || ((fupdate != NULL) && ((*fupdate)(pool[i], deltaTimeInSeconds))) )
		{
			if( fdeath != NULL )
				(*fdeath)(pool[i]);

			if( nbBorn > 0 )
			{
				pool[i].init();
				launchParticle(pool[i], emitterIt, nbManualBorn);
				--nbBorn;
			}
			else
			{
				particleData[i].sqrDist = 0.0f;
				pool.makeInactive(i);
				--i;
			}
		}
		else
		{
			if( boundingBoxEnabled )
				updateAABB(pool[i]);

			if( distanceComputationEnabled )
				pool[i].computeSqrDist();
		}
	}

	// Terminates modifiers processing
	for( Modifier** it = modifiers.begin(); it < modifiers.end(); ++it )
		(*it)->endProcess(*this);

	// Emits new particles if some left
	for( uint32 i = nbBorn; i > 0; --i )
		pushParticle(emitterIt, nbManualBorn);

	// Sorts particles if enabled
	if( sortingEnabled && (pool.getSizeOfActive() > 1) )
		sortParticles(0, pool.getSizeOfActive() - 1);

	if( !boundingBoxEnabled || (pool.getSizeOfActive() == 0) )
	{
		boundingBoxAABB.vcMin.Set(0, 0, 0);
		boundingBoxAABB.vcMax.Set(0, 0, 0);
		boundingBoxAABB.vcCenter.Set(0, 0, 0);
	}

	return hasActiveEmitters || (pool.getSizeOfActive() > 0);
}