Example #1
0
  /*! \brief Free streams two particles up to the current time.
   * 
   * This is here incase an optimisation or overload is performed later.
   *
   * This synchronises the delayed states of the two particle.
   * \param p1 A Particle to syncronise.
   * \param p2 A Particle to syncronise.
   */
  inline void updateParticlePair(const Particle& p1, const Particle& p2) const
  {
    //This is slow but sure, other stuff like reverse streaming, and
    //partial streaming are faster but work only for some collision
    //detections, not compression

    updateParticle(p1);
    updateParticle(p2);
  }
Example #2
0
ParticleEventData
DynNewtonian::runAndersenWallCollision(Particle& part, const Vector & vNorm, const double& sqrtT, const double) const
{
    updateParticle(part);

    if (hasOrientationData())
        M_throw() << "Need to implement thermostating of the rotational degrees"
                  " of freedom";

    //This gives a completely new random unit vector with a properly
    //distributed Normal component. See Granular Simulation Book
    ParticleEventData tmpDat(part, *Sim->species[part], WALL);

    double mass = Sim->species[tmpDat.getSpeciesID()]->getMass(part.getID());

    for (size_t iDim = 0; iDim < NDIM; iDim++)
        part.getVelocity()[iDim] = Sim->normal_sampler() * sqrtT / std::sqrt(mass);

    part.getVelocity()
    //This first line adds a component in the direction of the normal
    += vNorm * (sqrtT * sqrt(-2.0*log(1.0-Sim->uniform_sampler()) / mass)
                //This removes the original normal component
                -(part.getVelocity() | vNorm));

    tmpDat.setDeltaKE(0.5 * mass * (part.getVelocity().nrm2() - tmpDat.getOldVel().nrm2()));

    return tmpDat;
}
Example #3
0
ParticleEventData
DynNewtonian::randomGaussianEvent(Particle& part, const double& sqrtT,
                                  const size_t dimensions) const
{
#ifdef DYNAMO_DEBUG
    if (dimensions > NDIM)
        M_throw() << "Number of dimensions passed larger than NDIM!";
#endif

    //See http://mathworld.wolfram.com/SpherePointPicking.html

    if (hasOrientationData())
        M_throw() << "Need to implement thermostating of the rotational degrees"
                  " of freedom";

    //Ensure the particle is free streamed first
    updateParticle(part);

    //Collect the precoll data
    ParticleEventData tmpDat(part, *Sim->species[part], GAUSSIAN);

    double mass = Sim->species[tmpDat.getSpeciesID()]->getMass(part.getID());
    double factor = sqrtT / std::sqrt(mass);

    //Assign the new velocities
    for (size_t iDim = 0; iDim < dimensions; iDim++)
        part.getVelocity()[iDim] = Sim->normal_sampler() * factor;

    tmpDat.setDeltaKE(0.5 * mass * (part.getVelocity().nrm2() - tmpDat.getOldVel().nrm2()));

    return tmpDat;
}
Example #4
0
  ParticleEventData 
  DynCompression::runAndersenWallCollision(Particle& part, const Vector & vNorm, const double& sqrtT, const double d) const
  {  
    updateParticle(part);

    if (hasOrientationData())
      M_throw() << "Need to implement thermostating of the rotational degrees"
	" of freedom";

    //This gives a completely new random unit vector with a properly
    //distributed Normal component. See Granular Simulation Book
    ParticleEventData tmpDat(part, *Sim->species[part], WALL);
 
    double mass = Sim->species[tmpDat.getSpeciesID()]->getMass(part.getID());

    std::normal_distribution<> normal_dist;
    std::uniform_real_distribution<> uniform_dist;

    for (size_t iDim = 0; iDim < NDIM; iDim++)
      part.getVelocity()[iDim] = normal_dist(Sim->ranGenerator) * sqrtT / std::sqrt(mass);
  
    part.getVelocity()
      //This first line adds a component in the direction of the normal
      += vNorm * (sqrtT * sqrt(-2.0*log(1.0 - uniform_dist(Sim->ranGenerator)) / mass)
		  //This removes the original normal component
		  -(part.getVelocity() | vNorm)
		  //This adds on the velocity of the wall
		  + d * growthRate)
      ;

    return tmpDat; 
  }
Example #5
0
  NEventData 
  DynGravity::enforceParabola(Particle& part) const
  {
    updateParticle(part);

    const Species& species = *Sim->species(part);
    NEventData retval(ParticleEventData(part, species, VIRTUAL));

    Vector pos(part.getPosition()), vel(part.getVelocity());
    Sim->BCs->applyBC(pos, vel);

    //Find the dimension that is closest to 
    size_t dim = NDIM;
    double time = std::numeric_limits<float>::infinity();
    for (size_t iDim(0); iDim < NDIM; ++iDim)
      if (g[iDim] != 0)
	{
	  double tmpTime = std::abs(- vel[iDim] / g[iDim]);
	  if ((std::abs(tmpTime) < time)) 
	    {
	      time = tmpTime;
	      dim = iDim;
	    }
	}

#ifdef DYNAMO_DEBUG
    if (dim >= NDIM) M_throw() << "Could not find a dimension to enforce the parabola in!";
#endif

    part.getVelocity()[dim] = 0;
    return retval;
  }
Example #6
0
/// \fn ParticleSystem::doUpdate (float delta)
/// \brief Fires the particle update script for every particle. After that the system
/// checks if there are still enough particles alive. If not, new particles are initialized
/// and put in the active list.
void ParticleSystem::update(float delta)
{
   static const float step = 1.0f / 60.0f;

	updatetime += delta;
   if ( updatetime >= step )
   {
		for ( int index = 0; index < active; )
      {
         Particle& particle = mParticles[index];
         updateParticle(particle, delta, index);			
		}

      updatetime = 0.0f;
	}

   emittime += delta;
   while ( emittime > mEmitRate && active < maxActive )
   {
      // fetch a particle from the free list
      Particle& particle = mParticles[active++];
      initParticle(particle);

      emittime -= mEmitRate;
   }
}
Example #7
0
void
DynGravity::enforceParabola(Particle& part) const
{
    updateParticle(part);
    Vector pos(part.getPosition()), vel(part.getVelocity());
    Sim->BCs->applyBC(pos, vel);

    //Find the dimension that is closest to
    size_t dim = NDIM;
    double time = HUGE_VAL;
    for (size_t iDim(0); iDim < NDIM; ++iDim)
        if (g[iDim] != 0)
        {
            double tmpTime = std::abs(- vel[iDim] / g[iDim]);
            if ((std::abs(tmpTime) < time))
            {
                time = tmpTime;
                dim = iDim;
            }
        }

#ifdef DYNAMO_DEBUG
    if (dim >= NDIM) M_throw() << "Could not find a dimension to enforce the parabola in!";
#endif

    part.getVelocity()[dim] = 0;
}
Example #8
0
void ParticleComponent::update(sf::Time dt)
{
	if (mEmitting)
	{
		emitParticles(computeParticleCount(dt));
	}

	mNeedsVertexUpdate = true;

	for (std::size_t i = 0; i < mParticles.size();)
	{
		updateParticle(mParticles[i], dt); // lifetime, move, rotate

		if (mParticles[i].passedLifetime < mParticles[i].totalLifetime)
		{
			for (std::size_t j = 0; j < mAffectors.size(); ++j)
			{
				if (mAffectors[j])
				{
					mAffectors[j](mParticles[i], dt);
				}
			}
			++i;
		}
		else
		{
			mParticles.erase(mParticles.begin() + i);
		}
	}
}
Example #9
0
void Emitter::update(){
    particle *curr = e->particleList;
    while(curr){
        particle *toUpdate = curr;
        curr = curr->next;
        updateParticle(toUpdate);
    }
}
Example #10
0
 ParticleEventData 
 DynCompression::runPlaneEvent(Particle& part, const Vector& vNorm, const double e, const double diameter) const
 {
   updateParticle(part);
   ParticleEventData retVal(part, *Sim->species[part], WALL);
   Vector vij = part.getVelocity() - vNorm * diameter * growthRate;
   part.getVelocity() -= (1+e) * (vNorm | vij) * vNorm;
   return retVal; 
 }
void ParticleManager::update(float dt)
{
	BBGE_PROF(ParticleManager_update);
	numActive = 0;
	for (int i = 0; i < particles.size(); i++)
	{
		if (particles[i].active)
		{
			updateParticle(&particles[i], dt);
		}
	}
}
Example #12
0
ParticleEventData
DynNewtonian::runPlaneEvent(Particle& part, const Vector& vNorm, const double e, const double diameter) const
{
    updateParticle(part);

    ParticleEventData retVal(part, *Sim->species[part], WALL);

    part.getVelocity() -= (1+e) * (vNorm | part.getVelocity()) * vNorm;

    retVal.setDeltaKE(0.5 * Sim->species[retVal.getSpeciesID()]->getMass(part.getID())
                      * (part.getVelocity().nrm2() - retVal.getOldVel().nrm2()));
    return retVal;
}
Example #13
0
void Emitter::update(){
    pthread_mutex_lock(&mutex);
    if(!displaying) return;
    if(playFromFile){
        updateFromFile();
        pthread_mutex_unlock(&mutex);
        return;
    }
    particle *curr = e->particleList;
    while(curr){
        particle *toUpdate = curr;
        curr = curr->next;
        updateParticle(toUpdate);
    }
    pthread_mutex_unlock(&mutex);
}
Example #14
0
void updateParticles(PARTICLE * ps, PARTICLE * tmp) {
  int i, j;
  VECTOR accel;
  VECTOR summAccel;
  memcpy(tmp, ps, sizeof(PARTICLE) * PARTICLE_NUMBER);
  for(i = 0; i != PARTICLE_NUMBER; i++) {
    vectorInit(&summAccel, 0, 0);
    for(j = 0; j != PARTICLE_NUMBER; j++) {
      if (i == j) continue;
	    calcInteraction(ps + i, ps + j, &accel);
      vectorAdd(&summAccel, &accel);
    }
    updateParticle(ps + i, tmp + i, &summAccel);
  }
  memcpy(ps, tmp, sizeof(PARTICLE) * PARTICLE_NUMBER);
}
Example #15
0
    BOOST_FOREACH(const size_t& ID, range2)
    {
        updateParticle(Sim->particles[ID]);

        double mass = Sim->species[Sim->particles[ID]]->getMass(ID);
        structmass2 += mass;

        Vector pos(Sim->particles[ID].getPosition()),
               vel(Sim->particles[ID].getVelocity());

        Sim->BCs->applyBC(pos, vel);

        COMVel2 += vel * mass;

        COMPos2 += pos * mass;
    }
//////////////////////////////////////////////////////////////////////////
// updateParticles
void ScnParticleSystemComponent::updateParticles( BcReal Tick )
{
	// TODO: Iterate over every "affector" at a time, rather than by particle.
	// - See "updateParticle".

	// Not optimal, but clear code is clear. (For now...)
	for( BcU32 Idx = 0; Idx < NoofParticles_; ++Idx )
	{
		ScnParticle& Particle = pParticleBuffer_[ Idx ];

		if( Particle.Alive_ )
		{
			updateParticle( Particle, Tick );
		}
	}
}
Example #17
0
  ParticleEventData 
  DynGravity::runPlaneEvent(Particle &part, const Vector& vNorm, const double e, const double diameter) const
  {
    updateParticle(part);

    double e_val = e;
    if (std::fabs(part.getVelocity() | vNorm) < elasticV) e_val = 1;

    //Now the tc model;
    if (_tc > 0)
      {
	if ((Sim->systemTime - _tcList[part.getID()] < _tc))
	  e_val = 1;
      
	_tcList[part.getID()] = Sim->systemTime;
      }

    return DynNewtonian::runPlaneEvent(part, vNorm, e_val, diameter);
  }
//////////////////////////////////////////////////////////////////////////
// updateParticles
void ScnParticleSystemComponent::updateParticles( BcF32 Tick )
{
	// Wait for upload to have completed.
	UploadFence_.wait();

	// TODO: Iterate over every "affector" at a time, rather than by particle.
	// - See "updateParticle".

	MaAABB FullAABB( MaVec3d( 0.0f, 0.0f, 0.0f ), MaVec3d( 0.0f, 0.0f, 0.0f ) );

	// Not optimal, but clear code is clear. (For now...)
	for( BcU32 Idx = 0; Idx < NoofParticles_; ++Idx )
	{
		ScnParticle& Particle = pParticleBuffer_[ Idx ];

		if( Particle.Alive_ )
		{
			// Update particle.
			updateParticle( Particle, Tick );

			// Expand AABB by particle's max bounds.
			const BcF32 MaxHalfSize = BcMax( Particle.Scale_.x(), Particle.Scale_.y() ) * 0.5f;
			FullAABB.expandBy( Particle.Position_ - MaVec3d( MaxHalfSize, MaxHalfSize, MaxHalfSize ) );
			FullAABB.expandBy( Particle.Position_ + MaVec3d( MaxHalfSize, MaxHalfSize, MaxHalfSize ) );
		}
	}

	// Transform AABB.
	if( IsLocalSpace_ )
	{
		const MaMat4d& WorldTransform = getParentEntity()->getWorldMatrix();
		AABB_ = FullAABB.transform( WorldTransform );
	}
	else
	{
		AABB_ = FullAABB;
	}

	UpdateFence_.decrement();
}
Example #19
0
NEventData
DynNewtonian::multibdyCollision(const IDRange& range1, const IDRange& range2, const double&, const EEventType& eType) const
{
    Vector COMVel1(0,0,0), COMVel2(0,0,0), COMPos1(0,0,0), COMPos2(0,0,0);

    double structmass1(0), structmass2(0);

    BOOST_FOREACH(const size_t& ID, range1)
    {
        updateParticle(Sim->particles[ID]);

        double mass = Sim->species[Sim->particles[ID]]->getMass(ID);
        structmass1 += mass;

        Vector pos(Sim->particles[ID].getPosition()),
               vel(Sim->particles[ID].getVelocity());

        Sim->BCs->applyBC(pos, vel);

        COMVel1 += vel * mass;

        COMPos1 += pos * mass;
    }
Example #20
0
bool updateEmitter(tEmitter *emitter, tVector forces, float dt)
{
	int loop,emits;
	tParticle *particle, *next;
	if (emitter != NULL)
	{
		emitter->forces=forces;
		if (emitter->particle != NULL)
		{
			particle = emitter->particle;
			while (particle)
			{
				next = particle->next;
				updateParticle(particle,emitter,dt);
				particle = next;
			}
		}
		emits=emitter->emitsPerFrame+(int)((float)emitter->emitVar*CORE_FRand(0,1));
		for (loop = 0; loop < emits; loop++)
			addParticle(emitter);
		return TRUE;
	}
	return FALSE;
}
Example #21
0
void ParticleSystem::simulate(float deltaTime) {
    
    _timer += deltaTime;
    
    // update emitters
    for (int emitterIndex = 0; emitterIndex < _numEmitters; emitterIndex++) {
        assert(emitterIndex <= MAX_EMITTERS);
        
        if (_emitter[emitterIndex].active) {
            updateEmitter(emitterIndex, deltaTime);        
        }
    }
    
    // update particles
    for (int p = 0; p < MAX_PARTICLES; p++) {
        if (_particle[p].alive) {        
            if (_particle[p].age > _emitter[_particle[p].emitterIndex].particleLifespan) {            
                killParticle(p);
            } else {
                updateParticle(p, deltaTime);
            }
        }
    }
}
//adds a new particle to the particles array
void ParticleSystem::addParticle(ParticleData* _particle) 
{
	if(lastParticle < this->particleLimit-1)
	{
		particles[++lastParticle]=_particle->particle;
		particlesPositions[lastParticle]=_particle->position;
		particlesVelocities[lastParticle]=_particle->velocity;
		//Add vertex data
		updateParticle(&particlesPositions[lastParticle],&vertexData[lastParticle*12],camera->getViewMatrix(),_particle->particle->size);
		//Add color data
		for(int i=0;i<4;i++)
		{
			colorData[lastParticle*12+i*3]=_particle->color.x;
			colorData[lastParticle*12+i*3+1]=_particle->color.y;
			colorData[lastParticle*12+i*3+2]=_particle->color.z;
		}
	}
	else
	{
		//delete the particle so not to lose memory
		delete _particle->particle;
		//fprintf(stderr,"[ERROR] No more new particles can be added. The system can only handle %d particles.\n",particleLimit);
	}
}