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(); } }
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; }
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); }
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); }
// 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.")); } } }
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); } }
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); }
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); } }
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); }