Particles bouncing off objects and terrain
by Norris Bonner · in Torque Game Engine · 02/02/2005 (6:13 pm) · 7 replies
Ive looked everywhere, downloaded a tutorial that I thought had the nFo but it didnt. Does anyone know how to implement this? Im a newb.
Thanks in advance
Thanks in advance
About the author
#2
02/02/2005 (9:03 pm)
That's what debris is for, right?
#3
Of course, implementation is a little more complicated than that...
02/02/2005 (9:41 pm)
A few people have implemented this in the past. You basically cast a ray from each particles starting position to its ending position for each tick, see what it hit, if anything, and reflect about the normal of the hit face (handily provided in the RayInfo structure).Of course, implementation is a little more complicated than that...
#4
I was having the same dilemma until I found some code in game/debris.cc that helped alot. I used this code for specific instances of very large particles bouncing off of InteriorObjectType masks. You can change the subset of masks to suit your needs. This is what I did - haven't tested it completely but I hope that it will put you on the right track:
changes in bold to game/particleEngine.cc:
04/15/2005 (9:38 am)
Hi Norris -I was having the same dilemma until I found some code in game/debris.cc that helped alot. I used this code for specific instances of very large particles bouncing off of InteriorObjectType masks. You can change the subset of masks to suit your needs. This is what I did - haven't tested it completely but I hope that it will put you on the right track:
changes in bold to game/particleEngine.cc:
[b]
bool PEngine::bounce( const Point3F &nextPos, Particle *particle, const U32 t )
{
F32 radius = 2.0; //I adjusted this value (very unscientifically) for my particle
Point3F curPos = particle->pos;
Point3F dir = nextPos - curPos;
if( dir.magnitudeSafe() == 0.0 ) return false;
dir.normalizeSafe();
Point3F extent = nextPos + dir * radius;
F32 totalDist = Point3F( extent - curPos ).magnitudeSafe();
F32 moveDist = Point3F( nextPos - curPos ).magnitudeSafe();
F32 movePercent = (moveDist / totalDist);
RayInfo rayInfo;
U32 collisionMask = InteriorObjectType;
if( gClientContainer.castRay( curPos, extent, collisionMask, &rayInfo ) )
{
Point3F reflection = particle->vel - rayInfo.normal * (mDot( particle->vel, rayInfo.normal ) * 2.0);
particle->vel = reflection;
//got rid of this so bounces will be like billiard reflections
//Point3F tangent = reflection - rayInfo.normal * mDot( reflection, rayInfo.normal );
//particle->vel -= tangent;
Point3F velDir = particle->vel;
velDir.normalizeSafe();
Point3F bouncePos = curPos + dir * rayInfo.t * movePercent;
bouncePos += particle->vel * t;
particle->pos = bouncePos;
return true;
}
return false;
}
[/b]
void PEngine::updateSingleParticle(Particle* particle, ParticleEmitter &emitter, const U32 ms)
{
AssertFatal(particle != NULL, "PEngine::updateSingleParticle: Error, must have a particle to process in this function");
AssertFatal(ms != 0, "PEngine::updateSingleParticle: error, no time to update?");
F32 t = F32(ms) / 1000.0;
Point3F a = particle->acc;
a -= particle->vel * particle->dataBlock->dragCoefficient;
a -= ParticleEngine::windVelocity * particle->dataBlock->windCoefficient;
a += Point3F(0, 0, -9.81) * particle->dataBlock->gravityCoefficient;
particle->vel += a * t;
[b]
if (!bounce(particle->pos + particle->vel*t, particle, t))
particle->pos += particle->vel * t;
//particle->pos += particle->vel * t;[/b]
.......
#5
04/25/2005 (9:32 am)
Ok... so it seems that this bounce process should be extremely CPU intensive. I'm creating minimal particles so maybe that's why my computer is handling it well. So perhaps this function might be better implemented in for a low number of particles (i.e. don't go use it for a waterfall). Just a thought.
#6
05/16/2005 (1:21 am)
For set piece effects (like waterfalls) you could fake it, though. Put another particle emmitter or two at the base of the waterfall, inside the rocks that are getting "hit." Only the techies will notice. :-)
#7
05/16/2005 (2:13 am)
Another good idea is to only bounce off of static stuff, and simply calculate the bounce when you spawn the particle, not every tick.
Associate Anthony Rosenbaum