Particle Collision

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
daniel.retief
Posts: 5
Joined: Thu Sep 07, 2006 9:22 am

Particle Collision

Post by daniel.retief »

Hello,

I was wondering if someone could help me with my little challenge. I need to create a software program using C# that simulates water fountains. I decided to use Irrlicht on recommendation from a friend, who stated that Irrlicht has a great particle system. I was wondering if it was possible to use collision detection on the particles, so that the particles will collide with any other meshes that I have loaded into the scene, for example, a fountain pool, or a wall.

Any help would be much appreciated.

Thanks
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

I'm not 100% sure, but I guess that this would need a new triangle selector implementation, just as for terrains and octtrees. The reason is that the particle system manages the particles internally, such that the usual collisions do not work. While this should be possible already with basic programming skills (you're basically comparing vertex distances) I cannot assess the overall amount of work required with Irrlicht's particle implementation.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

It seems like you could write your own particle affector that could do collisions. Here is a simple one that does collisions with a plane. You could extend this to use a triangle selector and the scene collision manager. I would not expect performance to be great, but it might work.

Code: Select all

class CCollisionParticleAffector : public IParticleAffector
{
public:
   //!
   CCollisionParticleAffector(const core::plane3df& plane)
      : Plane(plane)
   {
   }

   //! Affects an array of particles.
   virtual void affect(u32 now, SParticle* particlearray, u32 count)
   {
      u32 p;
      for (p = 0; p < count; ++p)
      {
         SParticle& particle = particlearray[p];

         f32 distanceToPlane = Plane.getDistanceTo(particle.pos);
         if (distanceToPlane < 0.f)
         {
            // move the particle above the plane
            particle.pos -= (Plane.Normal * distanceToPlane);

            // clear the part of the velocity that is into the plane
            particle.vector -= ((f32)particle.vector.getLength()) * Plane.Normal;
         }
      }
   }

   //!
   virtual E_PARTICLE_AFFECTOR_TYPE getType()
   {
      return EPAT_NONE;
   }

private:
   core::plane3df Plane;
};

   // code used to test it...
   IParticleSystemSceneNode* particles = smgr->addParticleSystemSceneNode(false);
   particles->setMaterialFlag(video::EMF_LIGHTING, false);
   particles->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
   particles->setMaterialTexture(0, driver->getTexture("../../media/particlewhite.bmp"));


   IParticleEmitter* emitter = particles->createBoxEmitter();
      particles->setEmitter(emitter);
   emitter->drop();

   IParticleAffector* affector;

   affector = particles->createGravityAffector(core::vector3df(.02f, -0.03f, 0.f));
      particles->addAffector(affector);
   affector->drop();

   affector = new CCollisionParticleAffector(core::plane3df(0, -10, 0, 0, 1, 0));
      particles->addAffector(affector);
   affector->drop();
Post Reply