// step the simulation void ParticleSystem::step(float deltaTime) { assert(m_bInitialized); m_params.time = m_time; setParameters(&m_params); m_pos.map(); m_vel.map(); // integrate particles integrateSystem(m_pos.getDevicePtr(), m_pos.getDeviceWritePtr(), m_vel.getDevicePtr(), m_vel.getDeviceWritePtr(), deltaTime, m_numParticles); m_pos.unmap(); m_vel.unmap(); m_pos.swap(); m_vel.swap(); m_time += deltaTime; }
void System::update( float dt ) { computeGravitation(); integrateSystem( dt ); Vector3f r, v; for( size_t i = 0; i < _nBodies; ++i ){ // printf("start of for\n"); // printf("X: pos = %g, vel = %g \n", _body[i].position().x(), _body[i].velocity().x()); r = _body[i].position(); v = _body[i].velocity(); _body[i].oldPosition() = r; _body[i].oldVelocity() = v; // printf("X old: pos = %g, vel = %g \n", _body[i].oldPosition().x(), _body[i].oldVelocity().x()); // printf("Y old: pos = %g \n", _body[i].oldPosition().y()); // printf("Z old: pos = %g \n", _body[i].oldPosition().z()); // printf("end of for\n"); } integrateSystem( dt ); average(); }
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); }
// 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); } }
//Step the simulation void ParticleSystem::update(float deltaTime){ assert(m_bInitialized); setParameters(&m_params); setParametersHost(&m_params); //Download positions from VBO memHandle_t pos; if (!m_bQATest) { glBindBufferARB(GL_ARRAY_BUFFER, m_posVbo); pos = (memHandle_t)glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE); copyArrayToDevice(m_dPos, pos, 0, m_numParticles * 4 * sizeof(float)); } integrateSystem( m_dPos, m_dVel, deltaTime, m_numParticles ); calcHash( m_dHash, m_dIndex, m_dPos, m_numParticles ); bitonicSort(NULL, m_dHash, m_dIndex, m_dHash, m_dIndex, 1, m_numParticles, 0); //Find start and end of each cell and //Reorder particle data for better cache coherency findCellBoundsAndReorder( m_dCellStart, m_dCellEnd, m_dReorderedPos, m_dReorderedVel, m_dHash, m_dIndex, m_dPos, m_dVel, m_numParticles, m_numGridCells ); collide( m_dVel, m_dReorderedPos, m_dReorderedVel, m_dIndex, m_dCellStart, m_dCellEnd, m_numParticles, m_numGridCells ); //Update buffers if (!m_bQATest) { copyArrayFromDevice(pos,m_dPos, 0, m_numParticles * 4 * sizeof(float)); glUnmapBufferARB(GL_ARRAY_BUFFER); } }
// step the simulation void ParticleSystem::update(quint8 *deviceGridMapOfWayPointPressure) { //qDebug() << __PRETTY_FUNCTION__; //if(mParametersSimulation->gridParticleSystem.worldMax.x == 0.0f) return; // why this? if(!mIsInitialized) slotInitialize(); QTime startTime = QTime::currentTime(); startTime.start(); // Get a pointer to the particle positions in the device by mapping GPU mem into CPU mem float *deviceParticlePositions = (float*)CudaHelper::mapGLBufferObject(&mCudaVboResourceParticlePositions); //qDebug() << __PRETTY_FUNCTION__ << "0: getting pointer finished at" << startTime.elapsed(); // Update constants copyParametersToGpu(mParametersSimulation); //qDebug() << __PRETTY_FUNCTION__ << "1: setting parameters finished at" << startTime.elapsed(); // Get a pointer to the "__constant__ ParametersParticleSystem parametersParticleSystem" on the device ParametersParticleSystem* paramsParticleSystem; getDeviceAddressOfParametersParticleSystem(¶msParticleSystem); // Integrate integrateSystem( deviceParticlePositions, // in/out: The particle positions, unsorted mDeviceParticleVel, // in/out: The particle velocities, unsorted deviceGridMapOfWayPointPressure, // output: A grid mapping the 3d-space to waypoint pressure. Cells with high values (255) should be visited for information gain. mDeviceParticleCollisionPositions, // input: The particle's last collision position (or 0 if it didn't collide yet) paramsParticleSystem, // input: The particle system's parameters mParametersSimulation->particleCount); // showInformationGain(); //qDebug() << __PRETTY_FUNCTION__ << "2: integrating system finished at" << startTime.elapsed(); // Now that particles have been moved, they might be contained in different grid cells. So recompute the // mapping gridCell => particleIndex. This will allow fast neighbor searching in the grid during collision phase. computeMappingFromPointToGridCell( mDeviceParticleMapGridCell, // output: The key - part of the particle gridcell->index map, unsorted mDeviceParticleMapIndex, // output: The value-part of the particle gridcell->index map, unsorted deviceParticlePositions, // input: The particle positions after integration, unsorted and possibly colliding with other particles ¶msParticleSystem->gridParticleSystem, mParametersSimulation->particleCount); // input: The number of particles, one thread per particle //qDebug() << __PRETTY_FUNCTION__ << "3: computing particle spatial hash table finished at" << startTime.elapsed(); // Sort the mapping gridCell => particleId on gridCell sortGridOccupancyMap(mDeviceParticleMapGridCell, mDeviceParticleMapIndex, mParametersSimulation->particleCount); //qDebug() << __PRETTY_FUNCTION__ << "4: sorting particle spatial hash table finished at" << startTime.elapsed(); // Reorder particle arrays into sorted order and find start and end of each cell. The ordering of the particles is useful // only for the particle/particle-collisions. The collision code writes the post-collision velocities back into the // original, unsorted particle velocity array, where is will be used again in the next iteration's integrateSystem(). sortParticlePosAndVelAccordingToGridCellAndFillCellStartAndEndArrays( mDeviceParticleCellStart, // output: At which index in mDeviceMapParticleIndex does cell X start? mDeviceParticleCellEnd, // output: At which index in mDeviceMapParticleIndex does cell X end? mDeviceParticleSortedPos, // output: The particle positions, sorted by gridcell mDeviceParticleSortedVel, // output: The particle velocities, sorted by gridcell mDeviceParticleMapGridCell, // input: The key - part of the particle gridcell->index map, unsorted mDeviceParticleMapIndex, // input: The value-part of the particle gridcell->index map, unsorted deviceParticlePositions, // input: The particle-positions, unsorted mDeviceParticleVel, // input: The particle-velocities, unsorted mParametersSimulation->particleCount, // input: The number of particles mParametersSimulation->gridParticleSystem.getCellCount() // input: Number of grid cells ); //qDebug() << __PRETTY_FUNCTION__ << "5: computing particle navigation tables and sorting particles finished at" << startTime.elapsed(); // Same for colliders if(mUpdateMappingFromColliderToGridCell) { float *deviceColliderPositions = (float*)CudaHelper::mapGLBufferObject(&mCudaVboResourceColliderPositions); computeMappingFromPointToGridCell( mDeviceColliderMapGridCell, // output: The key - part of the collider gridcell->index map, unsorted mDeviceColliderMapIndex, // output: The value-part of the collider gridcell->index map, unsorted deviceColliderPositions, // input: The collider positions (no integration), unsorted and possibly colliding with particles ¶msParticleSystem->gridParticleSystem, mPointCloudColliders->getRenderInfo()->at(0)->size // input: The number of colliders, one thread per particle ); //qDebug() << __PRETTY_FUNCTION__ << "6: computing collider spatial hash table finished at" << startTime.elapsed(); sortGridOccupancyMap(mDeviceColliderMapGridCell, mDeviceColliderMapIndex, mPointCloudColliders->getRenderInfo()->at(0)->size); //qDebug() << __PRETTY_FUNCTION__ << "7: sorting collider spatial hash table finished at" << startTime.elapsed(); sortParticlePosAndVelAccordingToGridCellAndFillCellStartAndEndArrays( mDeviceColliderCellStart, // output: At which index in mDeviceMapColliderIndex does cell X start? mDeviceColliderCellEnd, // output: At which index in mDeviceMapColliderIndex does cell X end? mDeviceColliderSortedPos, // output: The collider positions, sorted by gridcell 0, // output: The collider velocities, sorted by gridcell / they have no vel, so pass 0 mDeviceColliderMapGridCell, // input: The key - part of the collider gridcell->index map, unsorted mDeviceColliderMapIndex, // input: The value-part of the collider gridcell->index map, unsorted deviceColliderPositions, // input: The particle-positions, unsorted 0, // input: The particle-velocities, unsorted / they have no vel, so pass 0 mPointCloudColliders->getRenderInfo()->at(0)->size, // input: The number of colliders mParametersSimulation->gridParticleSystem.cells.x * mParametersSimulation->gridParticleSystem.cells.y * mParametersSimulation->gridParticleSystem.cells.z // input: Number of grid cells ); cudaGraphicsUnmapResources(1, &mCudaVboResourceColliderPositions, 0); mUpdateMappingFromColliderToGridCell = false; } //qDebug() << __PRETTY_FUNCTION__ << "8: computing collider navigation tables and sorting particles finished at" << startTime.elapsed(); // process collisions between particles collideParticlesWithParticlesAndColliders( mDeviceParticleVel, // output: The particle velocities deviceParticlePositions, // output: The w-component is changed whenever a particle has hit a collider. Used just for visualization. mDeviceParticleCollisionPositions, // output: Every particle's position of last collision, or 0.0/0.0/0.0 if none occurred. mDeviceParticleSortedPos, // input: The particle positions, sorted by gridcell mDeviceParticleSortedVel, // input: The particle velocities, sorted by gridcell mDeviceParticleMapIndex, // input: The value-part of the particle gridcell->index map, sorted by gridcell mDeviceParticleCellStart, // input: At which index in mDeviceMapParticleIndex does cell X start? mDeviceParticleCellEnd, // input: At which index in mDeviceMapParticleIndex does cell X end? mDeviceColliderSortedPos, // input: The collider positions, sorted by gridcell mDeviceColliderMapIndex, // input: The value-part of the collider gridcell->index map, sorted by gridcell mDeviceColliderCellStart, // input: At which index in mDeviceMapColliderIndex does cell X start? mDeviceColliderCellEnd, // input: At which index in mDeviceMapColliderIndex does cell X end? mParametersSimulation->particleCount, // input: How many particles to collide against other particles (one thread per particle) mParametersSimulation->gridParticleSystem.cells.x * mParametersSimulation->gridParticleSystem.cells.y * mParametersSimulation->gridParticleSystem.cells.z // input: Number of grid cells ); //showCollisionPositions(); //qDebug() << __PRETTY_FUNCTION__ << "9: colliding particles finished at" << startTime.elapsed(); // Unmap at end here to avoid unnecessary graphics/CUDA context switch. // Once unmapped, the resource may not be accessed by CUDA until they // are mapped again. This function provides the synchronization guarantee // that any CUDA work issued before ::cudaGraphicsUnmapResources() // will complete before any subsequently issued graphics work begins. cudaGraphicsUnmapResources(1, &mCudaVboResourceParticlePositions, 0); size_t memTotal, memFree; cudaMemGetInfo(&memFree, &memTotal); //qDebug() << __PRETTY_FUNCTION__ << "finished," << startTime.elapsed() << "ms, fps:" << 1000.0f/startTime.elapsed() << "free mem:" << memFree / 1048576; }
void System::update( float dt ) { computeGravitation(); integrateSystem( dt ); }
void CudaSystem::integrate() { integrateSystem(m_dPos[0], m_dPos[1],m_dVel[0], m_dVel[1], FExt->m_F, m_dMass, dt, 0, particles.size()); }
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); } }