void ParticleFilterLocalizer::resample() { ParticleList resampledParticles; int particleCount = (int)particles.size(); int index = Math::randomInt(0, particleCount - 1); float beta = 0.0f; float maxProbability = 1.0f; for (int i = 0; i < particleCount; i++) { beta += Math::randomFloat() * 2.0f * maxProbability; while (beta > particles[index]->probability) { beta -= particles[index]->probability; index = (index + 1) % particleCount; } resampledParticles.push_back(new Particle( particles[index]->x, particles[index]->y, particles[index]->orientation, particles[index]->probability )); } for (ParticleList::const_iterator it = particles.begin(); it != particles.end(); it++) { delete *it; } particles.clear(); particles = resampledParticles; }
void MDcalculation::calculateMeanDisplacement(){ //Resetting for(int t = 0; t < 3; t++){ rMeanSquared[t] = 0; } ParticleList* list; for(int i = 1; i < Nx + 1; i++){ for(int j = 1; j < Ny + 1; j++){ for(int k = 1; k < Nz + 1; k++){ list = cells[i][j][k]; for(Particle* p = list->getFirst(); list->hasNext(); p = list->getNext()){ for(int d = 0; d < 3; d++){ rMeanSquared[p->type] += p->rReal[d]*p->rReal[d]; } } } } } MPI_Reduce(rMeanSquared, rMeanSquaredSum, 3, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); if(rank == 0){ for(int t = 0; t < 3; t++){ if(NparticlesType[t] == 0){ rMeanSquaredSum[t] = 0; }else{ rMeanSquaredSum[t] = rMeanSquaredSum[t]/NparticlesType[t]; } } } }
void AdvanceTime(ParticleList& list, float dt, float timeStep) { Time += dt; for (size_t i = 0; i < list.size(); ++i) { Point3 p(list[i].Px, list[i].Py, list[i].Pz); Vector3 v = ComputeCurl(p); Point3 midx = p + 0.5f * timeStep * v; p += timeStep * ComputeCurl(midx); list[i].Px = p.getX(); list[i].Py = p.getY(); list[i].Pz = p.getZ(); list[i].Vx = v.getX(); list[i].Vy = v.getY(); list[i].Vz = v.getZ(); } for (ParticleList::iterator i = list.begin(); i != list.end();) { if (i->Py > PlumeCeiling) { i = list.erase(i); } else { ++i; } } noise.set_time(0.5f*NoiseGain[0]/NoiseLengthScale[0]*Time); if (!ShowStreamlines || Time < 0.1f) SeedParticles(list, dt); }
void add_particles_mpi(ParticleList &particles, CellMatrix &cells) { ParticleList::iterator iter = particles.begin(); while(iter != particles.end()) { particle_t tmp = (*iter); Point p = get_cell_index(tmp); cells[p.y][p.x].push_back(&(*iter)); ++iter; } }
void RenderingEngine::DrawTouchTrail(){ long length = _touchTrails->size(); if(length == 0) return; if(length > _touchTrailArraysLength){ if(_touchTrailArrays != NULL){ delete _touchTrailArrays; } length *= 2; _touchTrailArrays = CreateParticlePointArrays(length*2); _touchTrailArraysLength = length; } glUniform1f(_uniforms.PointSize, _factory->particleWidth); DrawParticles(_touchTrails, _touchTrails->size(), _touchTrailArrays); }
ParticleList * ReadParticleListFromFile(char * file) { ParticleList * ReadParticleList = 0; PLNode * CurrentNode = 0; char character; int pid, itotal; double E, px, py, pz, weight; itotal = 0; ReadParticleList = new ParticleList; CurrentNode = ReadParticleList->GetHeadNode(); cout << "Reading particle list from file: " << file << endl; cout << endl; ifstream fin(file); while (fin.get(character)) { fin >> pid; fin >> E; fin >> px; fin >> py; fin >> pz; fin >> weight; Particle * pParticle = new Particle; pParticle->Set4mom(E,px,py,pz); pParticle->SetID(pid); pParticle->SetWeight(weight); pParticle->SetDecaysum(0.0); pParticle->SetGeneration(1); if ( E>0.0 ) { itotal++; if ( fmod((double)itotal,10000.0)==0.0 ) cout << itotal << " particles read from file" << endl; ReadParticleList->InsertAfter(CurrentNode, pParticle); CurrentNode = CurrentNode->GetNextNode(); } E = 0.0; } fin.close(); cout << endl; return ReadParticleList; }
void beforeResort(ParticleList &pl, OutBuffer& out) { if (pl.size() == 1) { beforeResortCalled = true; int res = 42; out.write(res); } }
void ParticleRender::drawParticles(const ParticleList &particles) { ci::gl::ScopedTextureBind stb(mTexture); // Prevent writing to the depth buffer, which will block out // pixels that are supposed to be transparent. ci::gl::ScopedDepthWrite sdw(false); ci::gl::ScopedBlendAlpha sba; ci::gl::color(1.0f, 1.0f, 1.0f, 1.0f); size_t k = 0, size = particles.size(); while (size >= BUFFER_SIZE) { drawParticles(k, k + BUFFER_SIZE, particles); k += BUFFER_SIZE; size -= BUFFER_SIZE; } drawParticles(k, particles.size(), particles); }
void afterResort(ParticleList &pl, InBuffer& inbuf) { if (pl.size() == 1) { afterResortCalled = true; int res; inbuf.read(res); BOOST_CHECK_EQUAL(res, 42); } }
void MDcalculation::thermostat(double dt, double T0, double tau, double T){ double gamma = sqrt(1 + dt/tau*(T0/T - 1)); //Scaling velocities ParticleList* list; for(int i = 1; i <= Nx; i++){ for(int j = 1; j <= Ny; j++){ for(int k = 1; k <= Nz; k++){ list = cells[i][j][k]; for(Particle* p = list->getFirst(); list->hasNext(); p = list->getNext()){ for(int d = 0; d < 3; d++){ p->v[d] = p->v[d]*gamma; } } } } } }
void MDcalculation::calculateForces(bool monitoring){ V = 0; ParticleList* list; //Calculating weights, finding 2BF and 3BF particle lists findNeighbours(); // return; //Calculating 2BF and 3BF for(int i = 0; i < Nx + 2; i++){ for(int j = 0; j < Ny + 2; j++){ for(int k = 0; k < Nz + 2; k++){ list = cells[i][j][k]; if(i != 0 && i != Nx + 1 && j != 0 && j != Ny + 1 && k != 0 && k != Nz + 1){ //Internal 3BF calculation for(Particle* p = list->getFirst(); list->hasNext(); p = list->getNext()){ V += potential->force2(p); V += potential->force3(p); } }else{ //3BF for boundary with internal for(Particle* p = list->getFirst(); list->hasNext(); p = list->getNext()){ V += potential->boundaryForce3(p); } } } } } }
void FixedSingleList::afterRecvParticles(ParticleList &pl, InBuffer& buf) { longint size = pl.size(); std::vector< longint > received(size); buf.read(received); for (std::vector< longint >::iterator it=received.begin(); it!=received.end(); it++) { globalSingles.insert(*it); } LOG4ESPP_INFO(theLogger, "received fixed single list after receive particles"); }
void ParticleRender::drawParticles(size_t start, size_t end, const ParticleList &particles) { if (start >= particles.size()) return; if (end > particles.size()) end = particles.size(); // update our instance positions; map our instance data VBO, write new positions, unmap glm::vec4 *data = (glm::vec4*)mInstanceDataVbo->mapReplace(); for (size_t k=start; k<end; ++k) { const Particle& p(particles[k]); data->x = p.mPosition.x; data->y = p.mPosition.y; data->z = p.mPosition.z; data->w = p.mAlpha; *data++; } mInstanceDataVbo->unmap(); // and draw mBatch->drawInstanced(end-start); }
void Cell::removeLostParticles(ParticleList &lost) { for (ParticleList::iterator it = particles.begin(); it != particles.end();) { const Particle &particle = *it; if (!isInside(particle)) { // particle moved outside of cell lost.push_back(particle); // add to lost it = particles.erase(it); // erase particle } else it++; } }
void FixedSingleList::beforeSendParticles(ParticleList& pl, OutBuffer& buf) { std::vector< longint > toSend(pl.size()); // loop over the particle list for (ParticleList::Iterator pit(pl); pit.isValid(); ++pit) { longint pid = pit->id(); toSend.push_back(pid); globalSingles.erase(pid); LOG4ESPP_DEBUG(theLogger, "erase and send particle with pid from FixedSingleList" << pid); } // send the list buf.write(toSend); LOG4ESPP_INFO(theLogger, "prepared fixed single list before send particles"); }
static void SeedParticles(ParticleList& list, float dt) { static float time = 0; time += dt; unsigned int num_new = (unsigned int) (time * ParticlesPerSecond); if (num_new == 0) return; time = 0; list.reserve(list.size() + num_new); for (unsigned int i = 0; i < num_new; ++i) { float theta = randhashf(Seed++, 0, M_PI * 2); float r = randhashf(Seed++, 0, SeedRadius); float y = randhashf(Seed++, 0, InitialBand); Particle p; p.Px = r*std::cos(theta); p.Py = PlumeBase + y; p.Pz = r*std::sin(theta) + 0.125f; // Nudge the emitter towards the viewer p.ToB = Time; list.push_back(p); } }
// apply force from actors to reactors void Bin::apply_forces(ParticleList& reactors, ParticleList& actors) { for( ParticleIterator reactor = reactors.begin(); reactor != reactors.end(); reactor++ ) { if ((*reactor)->tag < 0) continue; for (ParticleIterator actor = actors.begin(); actor != actors.end(); actor++ ){ if ( *reactor == *actor) continue; double dx = (*actor)->x - (*reactor)->x; double dy = (*actor)->y - (*reactor)->y; double r2 = dx * dx + dy * dy; if( r2 > cutoff * cutoff ) continue; r2 = fmax( r2, min_r*min_r ); double r = sqrt( r2 ); // very simple short-range repulsive force double coef = ( 1 - cutoff / r ) / r2 / mass; (*reactor)->ax += coef * dx; (*reactor)->ay += coef * dy; } } }
void MDcalculation::calculateKineticEnergy(){ K = 0; double Ksum; double v2; ParticleList* list; for(int i = 1; i < Nx + 1; i++){ for(int j = 1; j < Ny + 1; j++){ for(int k = 1; k < Nz + 1; k++){ list = cells[i][j][k]; for(Particle* p = list->getFirst(); list->hasNext(); p = list->getNext()){ if(container->mark[p->id]){ continue; } v2 = p->v[0]*p->v[0] + p->v[1]*p->v[1] + p->v[2]*p->v[2]; K += potential->m[p->type]*v2; } } } } K = 0.5*K; MPI_Allreduce(&K, &Ksum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); K = Ksum; }
void VarianceDiffusionStrategy<StateType>::diffuse(const ParticleList &_src, ParticleList &_dest) { if(_src.size() == 0) return; if(_dest.size() != _src.size()) _dest = _src; const unsigned numDofs = _src[0].state.size(); unsigned index = 0; StateType noise = _dest[0].state; if(mVariance.size() != noise.size()) { TRACE("------------- variance has wrong size. (should not be possible) ---------- ABORTING"); return; } if(mVarianceFactor.size() != noise.size()) { TRACE("----------resizing variance factors. (should not happen) -------------- "); mVarianceFactor.resize(noise.size(), 1); } // iterate over all source particles for(ParticleListConstIterator it = _src.begin(); it != _src.end(); it++) { // for every dof for(unsigned i=0; i < numDofs; i++) { noise[i] = this->mNormDistGenerator() * mVariance[i] * mVarianceFactor[i]; } _dest[index].state = noise; _dest[index].state += _src[index].state; index++; } }
void MDcalculation::interchangeParticles(int dim){ MPI_Status status; MPI_Request req0, req1; int* stats; int* statsIn; double* data; double* dataIn; int nStats, nData; int nStatsIn, nDataIn; //Senders and recievers int right = neighbour[2*dim]; int left = neighbour[2*dim + 1]; //Export arrays ParticleList* rightExport = exportList[2*dim]; ParticleList* leftExport = exportList[2*dim + 1]; //Communicating to right rightExport->makeArrays(&stats, &data, &nStats, &nData); rightExport->deleteParticles(); shiftCoordinatesOut(data, nData, dim); //Send data to right MPI_Isend(data, nData, MPI_DOUBLE, right, 0, MPI_COMM_WORLD, &req0); //Recieve data from left MPI_Probe(left, 0, MPI_COMM_WORLD, &status); MPI_Get_count(&status, MPI_DOUBLE, &nDataIn); dataIn = new double[nDataIn]; MPI_Irecv(dataIn, nDataIn, MPI_DOUBLE, left, 0, MPI_COMM_WORLD, &req1); MPI_Wait(&req0, &status); MPI_Wait(&req1, &status); //Send stats to right MPI_Isend(stats, nStats, MPI_INT, right, 1, MPI_COMM_WORLD, &req0); //Recieve stats from left MPI_Probe(left, 1, MPI_COMM_WORLD, &status); MPI_Get_count(&status, MPI_INT, &nStatsIn); statsIn = new int[nStatsIn]; MPI_Irecv(statsIn, nStatsIn, MPI_INT, left, 1, MPI_COMM_WORLD, &req1); MPI_Wait(&req0, &status); MPI_Wait(&req1, &status); addParticles(statsIn, dataIn, nStatsIn, nDataIn); delete[] stats; delete[] data; delete[] statsIn; delete[] dataIn; //Communicating to left leftExport->makeArrays(&stats, &data, &nStats, &nData); leftExport->deleteParticles(); //Send data to left MPI_Isend(data, nData, MPI_DOUBLE, left, 0, MPI_COMM_WORLD, &req0); //Recieve data from right MPI_Probe(right, 0, MPI_COMM_WORLD, &status); MPI_Get_count(&status, MPI_DOUBLE, &nDataIn); dataIn = new double[nDataIn]; MPI_Irecv(dataIn, nDataIn, MPI_DOUBLE, right, 0, MPI_COMM_WORLD, &req1); MPI_Wait(&req0, &status); MPI_Wait(&req1, &status); //Send stats to left MPI_Isend(stats, nStats, MPI_INT, left, 1, MPI_COMM_WORLD, &req0); //Recieve stats from right MPI_Probe(right, 1, MPI_COMM_WORLD, &status); MPI_Get_count(&status, MPI_INT, &nStatsIn); statsIn = new int[nStatsIn]; MPI_Irecv(statsIn, nStatsIn, MPI_INT, right, 1, MPI_COMM_WORLD, &req1); MPI_Wait(&req0, &status); MPI_Wait(&req1, &status); shiftCoordinatesIn(dataIn, nDataIn, dim); addParticles(statsIn, dataIn, nStatsIn, nDataIn); delete[] stats; delete[] data; delete[] statsIn; delete[] dataIn; }
int main( int argc, char **argv ) { // // process command line parameters // if( find_option( argc, argv, "-h" ) >= 0 ) { printf( "Options:\n" ); printf( "-h to see this help\n" ); printf( "-n <int> to set the number of particles\n" ); printf( "-o <filename> to specify the output file name\n" ); return 0; } int n = read_int( argc, argv, "-n", 1000 ); char *savename = read_string( argc, argv, "-o", NULL ); // // set up MPI // int n_proc, rank; set_size(n); int num_cells = get_num_cells(); MPI_Init( &argc, &argv ); MPI_Comm_size( MPI_COMM_WORLD, &n_proc ); MPI_Comm_rank( MPI_COMM_WORLD, &rank ); // // allocate generic resources // // FILE *fsave = savename && rank == 0 ? fopen( savename, "w" ) : NULL; FILE *fsave = savename ? fopen( savename, "w" ) : NULL; particle_t *particles = (particle_t*) malloc( n * sizeof(particle_t) ); MPI_Datatype PARTICLE; MPI_Type_contiguous( 6, MPI_DOUBLE, &PARTICLE ); MPI_Type_commit( &PARTICLE ); ParticleList reference_particles; // the particles needed to compute correct forces on my_particles. ParticleList my_particles; // the particles that this process is responsible for updating. CellMatrix cells(num_cells); // dummy particle particle_t dummy; dummy.x = -1; dummy.y = -1; // // set up the data partitioning across processors // int *partition_offsets = (int*) malloc( (n_proc+1) * sizeof(int) ); int *partition_sizes = (int*) malloc( n_proc * sizeof(int) ); // // allocate storage for local partition // int rows_per_thread = (num_cells + n_proc - 1) / n_proc; int top_row = min( rank * rows_per_thread, num_cells); // the top row that the process is responsible for. int bottom_row = min( (rank+1) * rows_per_thread, num_cells); // the bottow row that this process needs but is not responsible for int my_amount; // // initialize and distribute the particles (that's fine to leave it unoptimized) // ParticleList all_particles; all_particles.clear(); init_cell_matrix(cells); if( rank == 0 ) { all_particles.clear(); init_particles( n, particles ); update_cells(particles, cells, n); for(int rankId = 0; rankId < n_proc; rankId++) { partition_offsets[rankId] = all_particles.size(); int first_row = min( rankId * rows_per_thread, num_cells); int last_row = min( (rankId+1) * rows_per_thread, num_cells); ParticleList tmp; tmp.clear(); get_particles_from_rows(first_row, last_row, &tmp, cells); all_particles.insert(all_particles.end(), tmp.begin(), tmp.end()); partition_sizes[rankId] = tmp.size(); } partition_offsets[n_proc] = n; } // broadcast all offsets and sizes so we can scatter later. MPI_Bcast(partition_offsets, n_proc+1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(partition_sizes, n_proc, MPI_INT, 0, MPI_COMM_WORLD); // get my_amount from the partition sizes array and rezise the my_particles vector. my_amount = partition_sizes[rank]; my_particles.resize(my_amount); MPI_Scatterv( &all_particles.front(), partition_sizes, partition_offsets, PARTICLE, &my_particles.front(), my_amount, PARTICLE, 0, MPI_COMM_WORLD ); clear_cells(top_row-1, bottom_row+1, cells); add_particles_mpi(my_particles, cells); // // simulate a number of time steps // double simulation_time = read_timer( ); for( int step = 0; step < NSTEPS; step++ ) { // // save current step if necessary (slightly different semantics than in other codes) // if( fsave && (step%SAVEFREQ) == 0 ) { if(rank == 0) // root saves to file. First it recieves particles from other processes then write to file { int num_waiting = n - my_particles.size(); int i; int count = num_waiting; // put root particles in particles array for(i = 0; i < my_particles.size(); i++) { particles[i] = my_particles[i]; } particle_t other; // recieve particles from other processes. while(num_waiting > 0) { MPI_Status stat; MPI_Recv(&other, 1, PARTICLE, MPI_ANY_SOURCE, SAVE, MPI_COMM_WORLD, &stat); particles[i] = other; i++; num_waiting--; } save( fsave, n, particles ); } else // all other processes will send their particles to root(0) { for(int i = 0; i < my_particles.size(); i++) { MPI_Request req; MPI_Isend(&my_particles[i], 1 , PARTICLE, 0, SAVE, MPI_COMM_WORLD, &req ); } } } // // compute all forces // ParticleList::iterator iter = my_particles.begin(); while(iter != my_particles.end()) { particle_t *curr_particle = &(*iter); curr_particle->ax = 0; curr_particle->ay = 0; apply_force(curr_particle, cells); ++iter; } reference_particles.clear(); ParticleList out_of_bounds; out_of_bounds.clear(); ParticleList bounds; bounds.clear(); iter = my_particles.begin(); /* Iterate through all my particles and send all particles that are not our responsibility any longer to other processes. Send first and last row particles as references to other processes aswell. */ while(iter != my_particles.end()) { move(*iter); Point p = get_cell_index(*iter); if(p.y < top_row || p.y >= bottom_row) // check if out of bounds { particle_t tmp = (*iter); int index = out_of_bounds.size(); out_of_bounds.push_back(tmp); iter = my_particles.erase(iter); // send to process above or below int target = (p.y < top_row)? rank-1 : rank+1; MPI_Request request; MPI_Isend(&out_of_bounds[index], 1, PARTICLE, target, NEW, MPI_COMM_WORLD, &request ); // non blocking send continue; } else if(p.y == top_row && top_row > 0) // send our top row particles to the process above except if we are root { particle_t tmp = (*iter); int index = bounds.size(); bounds.push_back(tmp); MPI_Request request; MPI_Isend(&bounds[index], 1, PARTICLE, rank-1, BOUND, MPI_COMM_WORLD, &request ); // non blocking send } else if(p.y == bottom_row-1 && rank < n_proc-1) // send our top row particles to the process below except if we are last { particle_t tmp = (*iter); int index = bounds.size(); bounds.push_back(tmp); MPI_Request request; MPI_Isend(&bounds[index], 1, PARTICLE, rank+1, BOUND, MPI_COMM_WORLD, &request ); // non blocking send } ++iter; } MPI_Request req; // send message to process below and above that we are done sending particles. if(top_row > 0) MPI_Isend(&dummy, 1, PARTICLE, rank - 1, DONE, MPI_COMM_WORLD, &req); if(bottom_row < num_cells) MPI_Isend(&dummy, 1, PARTICLE, rank + 1, DONE, MPI_COMM_WORLD, &req); // get ready to recieve new particles from other processes. int isDone = 2; if(top_row == 0) isDone--; // we are root, should only recieve from process below. if(bottom_row == num_cells) isDone--; // we are last process, we should only recieve from process above. particle_t new_particle; while(isDone > 0) { MPI_Status status; MPI_Recv(&new_particle, 1, PARTICLE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); // check what sort of particle was recieved. if(status.MPI_TAG == DONE) { isDone--; continue; } else if(status.MPI_TAG == NEW) { my_particles.push_back(new_particle); } else if(status.MPI_TAG == BOUND) { reference_particles.push_back(new_particle); } } MPI_Barrier(MPI_COMM_WORLD); // wait in order to synchronize with same frame. // update our cells with my particles and the reference particles. clear_cells(top_row-1, bottom_row+1, cells); add_particles_mpi(my_particles, cells); add_particles_mpi(reference_particles, cells); } simulation_time = read_timer( ) - simulation_time; if( rank == 0 ) printf( "n = %d, n_procs = %d, simulation time = %g s\n", n, n_proc, simulation_time ); // // release resources // free( partition_offsets ); free( partition_sizes ); free( particles ); if( fsave ) fclose( fsave ); MPI_Finalize( ); return 0; }
void ParticleEmitter::spawn(float delta, const AnimationTime& at, ParticleList& ps, const Matrix& m) { if (!mVisibility.getFrame(at.current)) { return; } //换算成秒 float timeFactor = delta / 1000.0f; mCurrentEmission += mEmitRate.getFrame(at) * timeFactor; while(mCurrentEmission >= 1.0f) { if (ps.size() >= mLimitNumber /*|| !ps.empty()*/) { return; } Particle p; p.mEmitter = this; float speed; float width; float length; float height; float latitude; float variation; p.mVertices[0].texture_.x = 0; p.mVertices[0].texture_.y = 0; p.mVertices[1].texture_.x = 0; p.mVertices[1].texture_.y = 1; p.mVertices[2].texture_.x = 1; p.mVertices[2].texture_.y = 1; p.mVertices[3].texture_.x = 1; p.mVertices[3].texture_.y = 0; p.mStopMove = false; p.mColorStart = mColorStart; p.mColorMiddle = mColorMiddle; p.mColorEnd = mColorEnd; p.mAlpha = mAlpha; speed = mSpeedKFs.getFrame(at); width = mWidth.getFrame(at); length = mLength.getFrame(at); height = mHeigth.getFrame(at); latitude = mLatitude.getFrame(at); variation = mVariationKFs.getFrame(at); speed *= (1.0f + randomReal(0.0f, variation)); p.mPosition = Vector3(randomReal(-width,width), randomReal(-height,height), randomReal(-length,length)); p.mPosition = m.applyVector(p.mPosition); p.mOriginalPosition = p.mPosition; p.mNodeOriginalPosition = m.applyToOrigin(); Matrix mtxX; { Quaternion q; q.fromAngleAxis(randomReal(0,latitude * TwoPI / 360.f), Vector3::AxisX); mtxX.make(Vector3::Zero, Vector3::One, q); } Matrix mtxY; { Quaternion q; q.fromAngleAxis(randomReal(0,TwoPI), Vector3::AxisY); mtxY.make(Vector3::Zero, Vector3::One, q); } Matrix rot; rot.multiply(mtxX, mtxY); p.mVelocity = rot.applyVector(Vector3(0,1,0)); p.mVelocity.normalise(); p.mVelocity = m.applyVectorNormal(p.mVelocity); p.mVelocity *= speed; p.mAge = 0.0f; if(mLifeSpan < mLifeVar) p.mLife = mLifeSpan; else p.mLife= randomReal(mLifeSpan - mLifeVar, mLifeSpan + mLifeVar); p.mGravity = mGravity.getFrame(at); p.mExplosiveForce = mExplosiveForce.getFrame(at); //每个粒子的缩放比例都可能不同 p.mScale.x = randomReal(mScale.x - mScaleVar.x, mScale.x + mScaleVar.x); if(mFixedSize) { p.mScale.y = p.mScale.z = p.mScale.x; } else { p.mScale.y = randomReal(mScale.y - mScaleVar.y, mScale.y + mScaleVar.y); p.mScale.z = randomReal(mScale.z - mScaleVar.z, mScale.z + mScaleVar.z); } //粒子旋转的角度 p.mAngle = randomReal(mInitAngleBegin, mInitAngleEnd); p.mRotateSpeed = randomReal(mRotateSpeed - mRotateSpeedVar, mRotateSpeed + mRotateSpeedVar) * timeFactor * 15.0f; if(mHead) { p.mHeadFramesNum = ((mHeadLifeSpan.y - mHeadLifeSpan.x + 1.0f) * mHeadLifeSpan.z); p.mHeadDecalFramesNum = ((mHeadDecay.y - mHeadDecay.x + 1.0f) * mHeadDecay.z); } else { p.mHeadFramesNum = 0; p.mHeadDecalFramesNum = 0; } if(mTail) { p.mTailFramesNum = ((mTailLifeSpan.y - mTailLifeSpan.x + 1.0f) * mTailLifeSpan.z); p.mTailDecalFramesNum = ((mTailDecay.y - mTailDecay.x + 1.0f) * mTailDecay.z); } else { p.mTailFramesNum = 0; p.mTailDecalFramesNum = 0; } if(mWander) { p.mWanderRadius = mWanderRadius; p.mWanderSpeed = mWanderSpeed; p.mWander = true; p.mWanderS = 0.0f; Matrix m1,m2; for(int i = 0;i < 4;i++) { { Quaternion q; q.fromAngleAxis(randomReal(0,TwoPI), Vector3::AxisX); m1.make(Vector3::Zero, Vector3::One, q); } { Quaternion q; q.fromAngleAxis(randomReal(0,TwoPI), Vector3::AxisY); m2.make(Vector3::Zero, Vector3::One, q); } Matrix mt; mt.multiply(m1, m2); p.mWanderCatmullRom[i] = mWanderRadius * (mt.applyVector(Vector3::AxisZ)); } } // ps.push_back(p); // mCurrentEmission -= 1.0f; } }
/* recieve and rebuild global tuple information */ void FixedTupleListAdress::afterRecvParticles (ParticleList &pl, InBuffer& buf) { //std::cout << "afterRecvParticles\n"; /* std::vector<longint> received, pids; int n; longint pidK; GlobalTuples::iterator it = globalTuples.begin(); // receive the tuple list buf.read(received); int size = received.size(); int i = 0; while (i < size) { // unpack the list pidK = received[i++]; //std::cout << "receive pidK "<< pidK << "\n"; n = received[i++]; //std::cout << "receive n "<< n << "\n"; for (; n > 0; --n) { LOG4ESPP_DEBUG(theLogger, "received vector for pid " << pidK); storage->addAdrATParticleFTPL(received[i]); // add AT particle to storage pids.push_back(received[i++]); } // add pids vector to global tuples it = globalTuples.insert(it, std::make_pair(pidK, pids)); pids.clear(); } if (i != size) { LOG4ESPP_ERROR(theLogger, "recv particles might have read garbage\n"); } LOG4ESPP_INFO(theLogger, "received fixed particle list after receive particles"); */ std::vector<longint> pids; int size, i, n; longint pidK; GlobalTuples::iterator it = globalTuples.begin(); size = pl.size(); for (i = 0; i < size; ++i) { //std::cout << "i: " << i << "\n"; // receive the tuple list //std::cout << "receive pidK: "; buf.read(pidK); //std::cout << pidK << " at "; /* // testing Particle* vp = storage->lookupRealParticle(pidK); Real3D vpp = vp->position(); // see where VP is folded Real3D vpp_old = vpp; Real3D vpp_new = vpp; Real3D moved; int dir; Int3D image(0,0,0); for (dir = 0; dir < 3; ++dir) { storage->getSystem()->bc->foldCoordinate(vpp_new, image, dir); if (vpp_new[dir] != vpp_old[dir]) { moved[dir] = vpp_old[dir] - vpp_new[dir]; break; // do not continue looping } } */ //std::cout << "receive n: "; buf.read(n); //std::cout << n << "\n"; //std::cout << storage->getRank() << ": add AT particles "; for (; n > 0; --n) { LOG4ESPP_DEBUG(theLogger, "received vector for pid " << pidK); /*storage->addAdrATParticleFTPL(received[i]); // add AT particle to storage pids.push_back(received[i++]); Particle *p = storage->addAdrATParticleFTPL();*/ Particle p; //std::cout << " read *p : "; buf.read(p); //std::cout << " AT particle " << p.id() << " at " << p.position() << " "; //p.position()[dir] = p.position()[dir] - moved[dir]; //std::cout << "--> moved to " << p.position() << "\n"; storage->addAdrATParticleFTPL(p); //std::cout << p.getId() << " at " << p.position() << "\n"; pids.push_back(p.id()); } //std::cout << "\n"; // add pids vector to global tuples it = globalTuples.insert(it, std::make_pair(pidK, pids)); pids.clear(); } }