//LC: added for local (re)localization
void MapModel::distributeLocally(Particles& particles, double roll, double pitch, double yaw,
                                    double x, double y, double z,
                                    UniformGeneratorT& rngUniform, double dist_linear, double dist_angular){        //maxHeight added by LC
  double sizeX,sizeY,sizeZ, minX, minY, minZ;
  //LC: get total map size
  m_map->getMetricSize(sizeX,sizeY,sizeZ);
  //LC: get minimum values of map bounding box
  m_map->getMetricMin(minX, minY, minZ);

  double weight = 1.0 / particles.size();
  Particles::iterator it = particles.begin();
  while (true){
    if (it == particles.end())
      break;

    // obtain a pose hypothesis:
    double x_new = x + dist_linear * ((rngUniform() - 0.5) * 2);
    double y_new = y + dist_linear * ((rngUniform() - 0.5) * 2);
    double z_new = z + dist_linear * ((rngUniform() - 0.5) * 2);

    double roll_new = roll;// + dist_angular * ((rngUniform() - 0.5) * 2);
    double pitch_new = pitch;// + dist_angular * ((rngUniform() - 0.5) * 2);
    double yaw_new = yaw + dist_angular * ((rngUniform() - 0.5) * 2);

    if(it == particles.begin()) {
        // obtain a pose hypothesis:
        x_new = x;
        y_new = y;
        z_new = z;

        roll_new = roll;
        pitch_new = pitch;
        yaw_new = yaw;
    }

    //set new pose
    it->pose.getOrigin().setX(x_new);
    it->pose.getOrigin().setY(y_new);
    it->pose.getOrigin().setZ(z_new);

    //set orientation
    it->pose.setRotation(tf::createQuaternionFromRPY(roll_new, pitch_new, yaw_new));

    it->weight = weight;
    it++;

  }

}
SecondaryStructureResidue setup_coarse_secondary_structure_residue(
    const Particles &ssr_ps, Model *mdl,
    bool winner_takes_all_per_res) {
  Floats scores;
  scores.push_back(0.0);
  scores.push_back(0.0);
  scores.push_back(0.0);
  int count = 0;
  for (Particles::const_iterator p = ssr_ps.begin(); p != ssr_ps.end();
       ++p) {
    IMP_USAGE_CHECK(SecondaryStructureResidue::get_is_setup(*p),
                    "all particles must be SecondaryStructureResidues");
    SecondaryStructureResidue ssr(*p);
    Floats tmp_scores;
    tmp_scores.push_back(ssr.get_prob_helix());
    tmp_scores.push_back(ssr.get_prob_strand());
    tmp_scores.push_back(ssr.get_prob_coil());
    int max_i = 0;
    Float max = 0.0;
    for (int i = 0; i < 3; i++) {
      if (tmp_scores[i] > max) {
        max = tmp_scores[i];
        max_i = i;
      }
      if (!winner_takes_all_per_res) scores[i] += tmp_scores[i];
    }
    if (winner_takes_all_per_res) scores[max_i] += 1.0;
    count++;
  }
  IMP_NEW(Particle, coarse_p, (mdl));
  SecondaryStructureResidue ssres = SecondaryStructureResidue::setup_particle(
      coarse_p, scores[0] / count, scores[1] / count, scores[2] / count);
  return ssres;
}
Пример #3
0
void
System::
init_particles(
    Particles<Particle_T> & particles,
    size_t in,
    size_t out,
    int mass)
{
  auto it(particles.begin());
  auto end(particles.end());

  for (size_t i = 0; it != end && i < in; ++it, ++i)
  {
    Point p = random_insphere(0, cell_.radius);

    it->x = cell_.x + p.x;
    it->y = cell_.y + p.y;
    it->z = cell_.z + p.z;
    it->mass = mass;

    cell_.put_inside(*it);
  }

  for (size_t i = 0; it != end && i < out; ++it, ++i)
  {
    Point p = random_insphere(cell_.radius, outer_limit_.radius);

    it->x = cell_.x + p.x;
    it->y = cell_.y + p.y;
    it->z = cell_.z + p.z;
    it->mass = mass;

    cell_.put_outside(*it);
  }
}
Пример #4
0
	void _remove(Particle *p)
	{
		Particles::iterator pos = std::find(particles.begin(), particles.end(), p);
		if(pos != particles.end())
		{
			particles.erase(pos);
		}
	}
Пример #5
0
	void projectPositions()
	{
		for(Particles::iterator iter = particles.begin();
			iter != particles.end();
			++iter)
		{
			Particle *p = *iter;
			p->p = p->x + p->v * PHYSICS_DT;
		}
	}
Пример #6
0
	void ClearAllParticles(){ 
		for (ParticlesIterator pIter = g_particles.begin(); pIter != g_particles.end(); ++pIter ) {
			Particle* p = *(pIter);
			if (p) {
				delete p;
				p = NULL;
			}
		}
		g_particles.clear();
	}
Пример #7
0
	void removeFlagged()
	{
		for(Particles::iterator iter = removeList.begin();
			iter != removeList.end();
			++iter)
		{
			Particle *p = *iter;
			_remove(p);
		}
		removeList.clear();
	}
Пример #8
0
	void unprojectVelocities()
	{
		for(Particles::iterator iter = particles.begin();
			iter != particles.end();
			++iter)
		{
			Particle *p = *iter;
			p->v = (p->p - p->x)/PHYSICS_DT;
			p->x = p->p;
		}
	}
Пример #9
0
	void applyVoxelGridConstraint(VoxelGrid *g)
	{
		for(Particles::iterator iter = particles.begin();
			iter != particles.end();
			++iter)
		{
			Particle *p = *iter;
			glm::ivec3 v;
			if(p->type == PARTICLE_PROJECTILE && g->applyConstraint(p,v))
			{
				g->set(v, 0);
				remove(p);
			}
		}
	}
Пример #10
0
void ProblemSpecificBoundaryConditions::operator() (Particles<N>& particles)
{
    using namespace config;

    const real Lx1 = 1.0/Lx;
    const real Lz1 = 1.0/Lz;

    Particle *p = particles.begin ();

    for (uint dummy = 0; dummy < N; ++dummy)
    {
        p->x -= floor ((p->x - x0)*Lx1)*Lx;
        p->z -= floor ((p->z - z0)*Lz1)*Lz;

        ++p;
    }
}
Пример #11
0
void KMLProxy::initialize(Model *m,const Particles &ps,
    const FloatKeys &atts,unsigned int num_centers){
  for(Particles::const_iterator it = ps.begin(); it != ps.end();it++)
  {ps_.push_back(*it);}
  for(FloatKeys::const_iterator it = atts.begin();
      it != atts.end();it++)
  {atts_.push_back(*it);}
  m_ = m;
  kcenters_=num_centers;
  dim_=atts.size();
  centroids_ = Particles();
  data_ = new KMData(dim_,ps_.size());
  for(unsigned int i=0;i<ps_.size(); i++) {
    for(unsigned int j=0;j<atts.size();j++){
      (*(*data_)[i])[j]=ps_[i]->get_value(atts[j]);
    }
  }
  is_init_=true;
}
void MapModel::initGlobal(Particles& particles, double z, double roll, double pitch,
                          const Vector6d& initNoise,
                          UniformGeneratorT& rngUniform, NormalGeneratorT& rngNormal, double maxHeight, double minHeight){        //maxHeight added by LC
  double sizeX,sizeY,sizeZ, minX, minY, minZ;
  //LC: get total map size
  m_map->getMetricSize(sizeX,sizeY,sizeZ);
  //LC: get minimum values of map bounding box
  m_map->getMetricMin(minX, minY, minZ);

  double weight = 1.0 / particles.size();
  Particles::iterator it = particles.begin();
  while (true){
    if (it == particles.end())
      break;
    // obtain a pose hypothesis:
    double x = minX + sizeX * rngUniform();
    double y = minY + sizeY * rngUniform();
    std::vector<double> z_list;
    getHeightlist(x, y, minHeight, maxHeight,z_list);

    //LC: create a pose with random yaw orientation at (x,y) for every entry in the height list
    for (unsigned zIdx = 0; zIdx < z_list.size(); zIdx++){
      if (it == particles.end())
        break;

      // not needed => we already know that z contains valid poses
      // distance map: used distance from obstacles:
      //std::abs(node->getLogOdds()) < 0.1){
      //			if (!isOccupied(octomap::point3d(x, y, z[zIdx]))){

      it->pose.getOrigin().setX(x);
      it->pose.getOrigin().setY(y);
      // TODO: sample z, roll, pitch
      it->pose.getOrigin().setZ(z_list.at(zIdx) + z + rngNormal() * initNoise(2));
      //LC: create yaw orientation from -PI to +PI
      double yaw = rngUniform() * 2 * M_PI  -M_PI;
      it->pose.setRotation(tf::createQuaternionFromRPY(roll, pitch, yaw));
      it->weight = weight;
      it++;
    }
  }

}
Пример #13
0
void MapModel::initGlobal(Particles& particles,
                          const Vector6d& initPose, const Vector6d& initNoise,
                          UniformGeneratorT& rngUniform, NormalGeneratorT& rngNormal){
  double sizeX,sizeY,sizeZ, minX, minY, minZ;
  m_map->getMetricSize(sizeX,sizeY,sizeZ);
  m_map->getMetricMin(minX, minY, minZ);

  double weight = 1.0 / particles.size();
  Particles::iterator it = particles.begin();
  while (true){
    if (it == particles.end())
      break;
    // obtain a pose hypothesis:
    double x = minX + sizeX * rngUniform();
    double y = minY + sizeY * rngUniform();
    std::vector<double> z;
    getHeightlist(x, y, 0.6,z);

    for (unsigned zIdx = 0; zIdx < z.size(); zIdx++){
      if (it == particles.end())
        break;

      // not needed => we already know that z contains valid poses
      // distance map: used distance from obstacles:
      //std::abs(node->getLogOdds()) < 0.1){
      //			if (!isOccupied(octomap::point3d(x, y, z[zIdx]))){

      it->pose.getOrigin().setX(x);
      it->pose.getOrigin().setY(y);
      // TODO: sample z, roll, pitch around odom pose!
      it->pose.getOrigin().setZ(z.at(zIdx) + initPose(2) + rngNormal() * initNoise(2));
      double yaw = rngUniform() * 2 * M_PI  -M_PI;
      it->pose.setRotation(tf::createQuaternionFromYaw(yaw));
      it->weight = weight;
      it++;
    }
  }

}
Пример #14
0
Particles CHARMMParameters::create_dihedrals(Particles bonds) const
{
  IMP_OBJECT_LOG;
  Particles ps;
  BondMap particle_bonds;
  make_bond_map(bonds, particle_bonds);

  // Iterate over all bonds
  for (Particles::const_iterator bit1 = bonds.begin();
       bit1 != bonds.end(); ++bit1) {
    IMP::atom::Bond bd = IMP::atom::Bond(*bit1);
    Particle *p2 = bd.get_bonded(0).get_particle();
    Particle *p3 = bd.get_bonded(1).get_particle();

    // Extend along each bond from p2 and p3 to get candidate
    // p1-p2-p3-p4 dihedrals
    for (base::Vector<IMP::atom::Bond>::const_iterator bit2
         = particle_bonds[p2].begin();
         bit2 != particle_bonds[p2].end(); ++bit2) {
      Particle *p1 = get_other_end_of_bond(p2, *bit2);

      if (p1 != p3) {
        for (base::Vector<IMP::atom::Bond>::const_iterator bit3
             = particle_bonds[p3].begin();
             bit3 != particle_bonds[p3].end(); ++bit3) {
          Particle *p4 = get_other_end_of_bond(p3, *bit3);

          // Avoid generating dihedrals for three-membered rings
          if (p1 != p4 && p2 != p4) {
            internal::add_dihedral_to_list(this, p1, p2, p3, p4, ps);
          }
        }
      }
    }
  }
  return ps;
}
Пример #15
0
Particles CHARMMParameters::create_angles(Particles bonds) const
{
  IMP_OBJECT_LOG;
  Particles ps;
  BondMap particle_bonds;
  make_bond_map(bonds, particle_bonds);

  // Iterate over all bonds
  for (Particles::const_iterator bit1 = bonds.begin();
       bit1 != bonds.end(); ++bit1) {
    IMP::atom::Bond bd = IMP::atom::Bond(*bit1);
    Particle *p2 = bd.get_bonded(0).get_particle();
    Particle *p3 = bd.get_bonded(1).get_particle();

    // Extend along each adjoining p2 bond to get candidate p1-p2-p3 angles
    for (base::Vector<IMP::atom::Bond>::const_iterator bit2
         = particle_bonds[p2].begin();
         bit2 != particle_bonds[p2].end(); ++bit2) {
      Particle *p1 = get_other_end_of_bond(p2, *bit2);
      // Avoid making angles where p1 == p3, and avoid double-counting
      if (p3 > p1) {
        add_angle(p1, p2, p3, ps);
      }
    }
    // Do the same for p2-p3-p4 angles
    for (base::Vector<IMP::atom::Bond>::const_iterator bit2
         = particle_bonds[p3].begin();
         bit2 != particle_bonds[p3].end(); ++bit2) {
      Particle *p4 = get_other_end_of_bond(p3, *bit2);
      if (p4 < p2) {
        add_angle(p2, p3, p4, ps);
      }
    }
  }
  return ps;
}
Пример #16
0
/** @brief get the centers as intensity centroids of local maxima neighbourhood
  *
  * Local maxima are taken as the bright pixels of centersMap
  */
Particles Tracker::getSubPixel(bool autoThreshold)
{
    //boost::progress_timer ptimer;
	//get the positions of the bright centers from flatten centersMap
	if(!quiet) cout<<"get positions ... ";
	list<size_t> flat_positions;
	bool* b = centersMap.origin();
	for(size_t i=0; i<centersMap.num_elements(); ++i)
		if(*b++)
			flat_positions.push_back(i);

	//sort by increasing pixel intensity
	if(!quiet) cout<<flat_positions.size()<<" potential centers ... ";
	flat_positions.sort(compIntensities(data));

	//Find the best intensity threshold
	if(autoThreshold)
	{
	    //construct the centers intensity histogram
	    const long double minhist = *(data+flat_positions.front()),
            maxhist = *(data+flat_positions.back());
        const long double scale = 100.0/(maxhist-minhist);
	    vector<size_t> hist(100, 0);
	    for(list<size_t>::const_iterator c = flat_positions.begin(); c!= flat_positions.end(); ++c)
	    {
	    	size_t l = (*(data + (*c)) - minhist) * scale;
	    	if(l<hist.size())
	    		hist[l]++;
	    }


        //find the population global maximum
        vector<size_t>::iterator peak = max_element(hist.begin(), hist.end());
        if(!quiet) cout<<"peak ="<<distance(hist.begin(), peak)<<" ... ";

        //find the last non-null bin before the peak, and at the same time the bin with the minimum population between it and the peak
        vector<size_t>::iterator non_z = lower_bound(hist.begin(), peak, 1);
        vector<size_t>::iterator lowest = min_element(non_z, peak);
        //cout<<"non_z="<<distance(hist.begin(),non_z)<<"\tlowest="<<distance(hist.begin(),lowest)<<endl;
        while((*lowest)==0)
        {
            non_z = lowest;
            lowest = min_element(lowest, peak);
            //cout<<"non_z="<<distance(hist.begin(),non_z)<<"\tlowest="<<distance(hist.begin(),lowest)<<endl;
        }

        //lowest gives the position of the valley of the histogram, ie the best threshold
        if(!quiet) cout<<"best threshold = "<<distance(hist.begin(), lowest)/scale + minhist<<" ("<<distance(hist.begin(), lowest)<<"%) ... ";
        //We remove all centers that have lower intensity than the best threshold
        list<size_t>::iterator i = flat_positions.begin();
        advance(i, accumulate(hist.begin(), lowest, (size_t)0));
        flat_positions.erase(flat_positions.begin(), i);
        if(!quiet) cout<<flat_positions.size()<<" centers after auto thresholding ... ";
	}

	//centroid binning
	if(!quiet) cout<<"centroid ... ";
	list< valarray<double> > positions;
	boost::array<size_t,3> shape;
	copy(centersMap.shape(), centersMap.shape()+3, shape.begin());
    transform(
		flat_positions.rbegin(), flat_positions.rend(),
		back_inserter(positions),
		centroid(boost::multi_array_ref<float,3>(data,shape))
		);
    //removing marked centers
    positions.remove_if(markedPositionRemover<valarray<double> >());
    if(!quiet) cout<<positions.size()<<" are real local maxima ... ";

    Particles centers;
	for(size_t d=0;d<3;++d)
	{
        centers.bb.edges[d].first  = 0;
		centers.bb.edges[d].second = centersMap.shape()[d];
	}
	//centers.reserve(positions.size());
	copy(positions.begin(), positions.end(), back_inserter(centers));

	if(fortran_order)
	{
		//If the image was filled in row major ordering of the dimensions, the coordinates are given as z,y,x by the tracker.
		//Here we convert to the human-readable x,y,z coordinates
		for_each(centers.begin(), centers.end(), revert<valarray<double> >());
		//don't forget the bounding box
		swap(centers.bb.edges[0].second, centers.bb.edges[2].second);
	}
    if(!quiet) cout << "done!" << endl;
    if(view)
    {
        markCenters();
        display("Centers");
    }
	return centers;
}
Пример #17
0
void MapModel::verifyPoses(Particles& particles){
  double minX, minY, minZ, maxX, maxY, maxZ;
  m_map->getMetricMin(minX, minY, minZ);
  m_map->getMetricMax(maxX, maxY, maxZ);

  // find min. particle weight:
  double minWeight = std::numeric_limits<double>::max();
  for (Particles::iterator it = particles.begin(); it != particles.end(); ++it) {
    if (it->weight < minWeight)
      minWeight = it->weight;

  }

  minWeight -= 200;

  unsigned numWall = 0;
  unsigned numOut = 0;
  unsigned numMotion = 0;


  // TODO possible speedup: cluster particles by grid voxels first?
  // iterate over samples, multi-threaded:
#pragma omp parallel for
  for (unsigned i = 0; i < particles.size(); ++i){

    octomap::point3d position(particles[i].pose.getOrigin().getX(),
                              particles[i].pose.getOrigin().getY(), particles[i].pose.getOrigin().getZ());

    // see if outside of map bounds:
    if (position(0) < minX || position(0) > maxX
        ||	position(1) < minY || position(1) > maxY
        ||	position(2) < minZ || position(2) > maxZ)
    {
      particles[i].weight = minWeight;
#pragma omp atomic
      numOut++;
    } else {

      // see if occupied cell:
      if (this->isOccupied(position)){
        particles[i].weight = minWeight;
#pragma omp atomic
        numWall++;
      } else {
        // see if current pose is a valid walking pose:
        // TODO: need to check height over floor!
        if (m_motionRangeZ >= 0.0 &&
            std::abs(particles[i].pose.getOrigin().getZ() - m_motionMeanZ) > m_motionRangeZ)
        {
          particles[i].weight = minWeight;
#pragma omp atomic
          numMotion++;
        } else if (m_motionRangePitch >= 0.0 || m_motionRangeRoll >= 0.0){

          double yaw, pitch, roll;
          particles[i].pose.getBasis().getRPY(roll, pitch, yaw);

          if ((m_motionRangePitch >= 0.0 && std::abs(pitch) > m_motionRangePitch)
              || (m_motionRangeRoll >= 0.0 && std::abs(roll) > m_motionRangeRoll))
          {
            particles[i].weight = minWeight;
#pragma omp atomic
            numMotion++;
          }
        }
      }
    }
  } // end loop over particles

  if (numWall > 0 || numOut > 0 || numMotion > 0){
    ROS_INFO("Particle weights minimized: %d out of map, %d in obstacles, %d out of motion range", numOut, numWall, numMotion);
  }

  if (numOut + numWall >= particles.size()){
    ROS_WARN("All particles are out of the valid map area or in obstacles!");
  }

}
Пример #18
0
ParticleIndexesAdaptor::ParticleIndexesAdaptor(const Particles &ps)
    : tmp_(new ParticleIndexes(ps.size())), val_(tmp_.get()) {
  *tmp_ = get_indexes(ParticlesTemp(ps.begin(), ps.end()));
}
Пример #19
0
IMPCNMULTIFIT_BEGIN_NAMESPACE

Floats get_rmsd_for_models(const std::string param_filename,
                           const std::string trans_filename,
                           const std::string ref_filename, int start_model,
                           int end_model) {
  std::string protein_filename, surface_filename;
  int cn_symm_deg;

  std::cout << "============= parameters ============" << std::endl;
  std::cout << "params filename : " << param_filename << std::endl;
  std::cout << "trans filename : " << trans_filename << std::endl;
  std::cout << "ref filename : " << ref_filename << std::endl;
  std::cout << "start index to rmsd : " << start_model << std::endl;
  std::cout << "end index to rmsd : " << end_model << std::endl;
  std::cout << "=====================================" << std::endl;

  internal::Parameters params(param_filename.c_str());
  protein_filename = params.get_unit_pdb_fn();
  cn_symm_deg = params.get_cn_symm();

  IMP_NEW(Model, mdl, ());
  atom::Hierarchy asmb_ref;
  atom::Hierarchies mhs;
  // read the monomer
  core::XYZs model_xyzs;
  for (int i = 0; i < cn_symm_deg; i++) {
    atom::Hierarchy h =
        atom::read_pdb(protein_filename, mdl, new atom::CAlphaPDBSelector());
    atom::Chain c = atom::get_chain(
        atom::Residue(atom::get_residue(atom::Atom(core::get_leaves(h)[0]))));
    c.set_id(std::string(1, char(65 + i)));
    atom::add_radii(h);
    atom::create_rigid_body(h);
    mhs.push_back(h);
    Particles leaves = core::get_leaves(h);
    for (Particles::iterator it = leaves.begin(); it != leaves.end();
         it++) {
      model_xyzs.push_back(core::XYZ(*it));
    }
  }
  // read the transformations
  multifit::FittingSolutionRecords recs =
      multifit::read_fitting_solutions(trans_filename.c_str());
  // read the reference structure
  asmb_ref = atom::read_pdb(ref_filename, mdl, new atom::CAlphaPDBSelector());
  atom::Hierarchies ref_chains =
      atom::Hierarchies(atom::get_by_type(asmb_ref, atom::CHAIN_TYPE));
  std::cout << "number of records:" << recs.size() << std::endl;
  Floats rmsd;
  std::ofstream out;
  out.open("rmsd.output");
  if (end_model < 0 || end_model >= static_cast<int>(recs.size())) {
    end_model = recs.size() - 1;
  }

  for (int i = start_model; i >= 0 && i <= end_model; ++i) {
    algebra::Transformation3D t1 = recs[i].get_dock_transformation();
    algebra::Transformation3D t2 = recs[i].get_fit_transformation();
    algebra::Transformation3D t2_inv = t1.get_inverse();
    transform_cn_assembly(mhs, t1);
    for (unsigned int j = 0; j < model_xyzs.size(); j++) {
      model_xyzs[j]
          .set_coordinates(t2.get_transformed(model_xyzs[j].get_coordinates()));
    }
    std::cout << mhs.size() << "," << ref_chains.size() << std::endl;
    Float cn_rmsd = get_cn_rmsd(mhs, ref_chains);
    out << " trans:" << i << " rmsd: " << cn_rmsd
        << " cc: " << 1. - recs[i].get_fitting_score() << std::endl;
    rmsd.push_back(cn_rmsd);
    for (unsigned int j = 0; j < model_xyzs.size(); j++) {
      model_xyzs[j].set_coordinates(
          t2_inv.get_transformed(model_xyzs[j].get_coordinates()));
    }
    /*      std::stringstream ss;
    ss<<"asmb_"<<i<<".pdb";
    atom::write_pdb(mhs,ss.str());*/
    transform_cn_assembly(mhs, t1.get_inverse());
  }

  out.close();
  return rmsd;
}
Пример #20
0
	Particle& GetOrigin(){
		return *(*m_particles.begin() );
	}
Пример #21
0
bool
Particle::update()
{
    if (!mMap) return false;

    if (mLifetimeLeft == 0)
    {
        mAlive = false;
    }

    if (mAlive)
    {
        //calculate particle movement
        if (mMomentum != 1.0f)
        {
            mVelocity *= mMomentum;
        }

        if (mTarget && mAcceleration != 0.0f)
        {
            Vector dist = mPos - mTarget->getPosition();
            dist.x *= SIN45;
            float invHypotenuse;

            switch (Particle::fastPhysics)
            {
                case 1:
                    invHypotenuse = fastInvSqrt(
                        dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
                    break;
                case 2:
                    invHypotenuse = 2.0f /
                        fabs(dist.x) + fabs(dist.y) + fabs(dist.z);
                    break;
                default:
                    invHypotenuse = 1.0f / sqrt(
                        dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
                    break;
            }

            if (invHypotenuse)
            {
                if (mInvDieDistance > 0.0f && invHypotenuse > mInvDieDistance)
                {
                    mAlive = false;
                }
                float accFactor = invHypotenuse * mAcceleration;
                mVelocity -= dist * accFactor;
            }
        }

        if (mRandomnes > 0)
        {
            mVelocity.x += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f;
            mVelocity.y += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f;
            mVelocity.z += (rand()%mRandomnes - rand()%mRandomnes) / 1000.0f;
        }

        mVelocity.z -= mGravity;

        // Update position
        mPos.x += mVelocity.x;
        mPos.y += mVelocity.y * SIN45;
        mPos.z += mVelocity.z * SIN45;

        // Update other stuff
        if (mLifetimeLeft > 0)
        {
            mLifetimeLeft--;
        }
        mLifetimePast++;

        if (mPos.z > PARTICLE_SKY || mPos.z < 0.0f)
        {
            if (mBounce > 0.0f)
            {
                mPos.z *= -mBounce;
                mVelocity *= mBounce;
                mVelocity.z = -mVelocity.z;
            }
            else {
                mAlive = false;
            }
        }

        // Update child emitters
        if (mLifetimePast%Particle::emitterSkip == 0)
        {
            for (   EmitterIterator e = mChildEmitters.begin();
                    e != mChildEmitters.end();
                    e++
                )
            {
                Particles newParticles = (*e)->createParticles();
                for (   ParticleIterator p = newParticles.begin();
                        p != newParticles.end();
                        p++
                    )
                {
                    (*p)->moveBy(mPos.x, mPos.y, mPos.z);
                    mChildParticles.push_back (*p);
                }
            }
        }
    }

    // Update child particles
    for (ParticleIterator p = mChildParticles.begin();
         p != mChildParticles.end();)
    {
        if ((*p)->update())
        {
            p++;
        } else {
            delete (*p);
            p = mChildParticles.erase(p);
        }
    }

    if (!mAlive && mChildParticles.empty() && mAutoDelete)
    {
        return false;
    }

    return true;
}
Пример #22
0
bool Particle::update()
{
    if (!mMap)
        return false;

    if (mLifetimeLeft == 0 && mAlive == ALIVE)
        mAlive = DEAD_TIMEOUT;

    Vector oldPos = mPos;

    if (mAlive == ALIVE)
    {
        //calculate particle movement
        if (mMomentum != 1.0f)
        {
            mVelocity *= mMomentum;
        }

        if (mTarget && mAcceleration != 0.0f)
        {
            Vector dist = mPos - mTarget->getPosition();
            dist.x *= SIN45;
            float invHypotenuse;

            switch (Particle::fastPhysics)
            {
                case 1:
                    invHypotenuse = fastInvSqrt(
                        dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
                    break;
                case 2:
                    invHypotenuse = 2.0f /
                        fabs(dist.x) + fabs(dist.y) + fabs(dist.z);
                    break;
                default:
                    invHypotenuse = 1.0f / sqrt(
                        dist.x * dist.x + dist.y * dist.y + dist.z * dist.z);
                    break;
            }

            if (invHypotenuse)
            {
                if (mInvDieDistance > 0.0f && invHypotenuse > mInvDieDistance)
                {
                    mAlive = DEAD_IMPACT;
                }
                float accFactor = invHypotenuse * mAcceleration;
                mVelocity -= dist * accFactor;
            }
        }

        if (mRandomness > 0)
        {
            mVelocity.x += (rand()%mRandomness - rand()%mRandomness) / 1000.0f;
            mVelocity.y += (rand()%mRandomness - rand()%mRandomness) / 1000.0f;
            mVelocity.z += (rand()%mRandomness - rand()%mRandomness) / 1000.0f;
        }

        mVelocity.z -= mGravity;

        // Update position
        mPos.x += mVelocity.x;
        mPos.y += mVelocity.y * SIN45;
        mPos.z += mVelocity.z * SIN45;

        // Update other stuff
        if (mLifetimeLeft > 0)
        {
            mLifetimeLeft--;
        }
        mLifetimePast++;

        if (mPos.z < 0.0f)
        {
            if (mBounce > 0.0f)
            {
                mPos.z *= -mBounce;
                mVelocity *= mBounce;
                mVelocity.z = -mVelocity.z;
            }
            else
            {
                mAlive = DEAD_FLOOR;
            }
        }
        else if (mPos.z > PARTICLE_SKY)
        {
                mAlive = DEAD_SKY;
        }

        // Update child emitters
        if ((mLifetimePast-1)%Particle::emitterSkip == 0)
        {
            for (EmitterIterator e = mChildEmitters.begin();
                 e != mChildEmitters.end(); e++)
            {
                Particles newParticles = (*e)->createParticles(mLifetimePast);
                for (ParticleIterator p = newParticles.begin();
                     p != newParticles.end(); p++)
                {
                    (*p)->moveBy(mPos);
                    mChildParticles.push_back (*p);
                }
            }
        }
    }

    // create death effect when the particle died
    if (mAlive != ALIVE && mAlive != DEAD_LONG_AGO)
    {
        if ((mAlive & mDeathEffectConditions) > 0x00  && !mDeathEffect.empty())
        {
            Particle* deathEffect = particleEngine->addEffect(mDeathEffect, 0, 0);
            deathEffect->moveBy(mPos);
        }
        mAlive = DEAD_LONG_AGO;
    }

    Vector change = mPos - oldPos;

    // Update child particles

    for (ParticleIterator p = mChildParticles.begin();
         p != mChildParticles.end();)
    {
        //move particle with its parent if desired
        if ((*p)->doesFollow())
        {
            (*p)->moveBy(change);
        }
        //update particle
        if ((*p)->update())
        {
            p++;
        }
        else
        {
            delete (*p);
            p = mChildParticles.erase(p);
        }
    }
    if (mAlive != ALIVE && mChildParticles.empty() && mAutoDelete)
    {
        return false;
    }

    return true;
}