Simplified smoke system (to use only one particle system instead of two),

and improved the origin of the smoke to be the actual position of the
wheels (though this is sometimes still not 'correct' enough atm).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3602 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2009-06-10 13:04:30 +00:00
parent ba7c983d18
commit c0ab52bfb3
2 changed files with 41 additions and 55 deletions

View File

@@ -24,56 +24,38 @@
#include "graphics/irr_driver.hpp"
#include "io/file_manager.hpp"
#include "karts/kart.hpp"
#include "physics/btKart.hpp"
#include "utils/constants.hpp"
Smoke::Smoke(Kart* kart) : m_kart(kart)
Smoke::Smoke(Kart* kart) : m_kart(kart), m_particle_size(0.33f)
{
const float particle_size = 0.33f;
// Left wheel
m_node_l = irr_driver->addParticleNode();
m_node_l->setParent(m_kart->getNode());
m_node_l->setPosition(core::vector3df(-m_kart->getKartWidth()*0.35f, particle_size*0.25f, -m_kart->getKartLength()*0.5f)); // Should use (behind) wheel pos
Material *ml= material_manager->getMaterial("smoke.png");
ml->setMaterialProperties(&(m_node_l->getMaterial(0)));
m_node_l->setMaterialTexture(0, ml->getTexture());
m_node = irr_driver->addParticleNode();
// Note: the smoke system is NOT child of the kart, since bullet
// gives the position of the wheels on the ground in world coordinates.
// So it's easier not to move the particle system with the kart, and set
// the position directly from the wheel coordinates.
m_node->setPosition(core::vector3df(-m_kart->getKartWidth()*0.35f,
m_particle_size*0.25f,
-m_kart->getKartLength()*0.5f));
Material *m= material_manager->getMaterial("smoke.png");
m->setMaterialProperties(&(m_node->getMaterial(0)));
m_node->setMaterialTexture(0, m->getTexture());
m_emitter_l = m_node_l->createPointEmitter(core::vector3df(0, 0, 0), // velocity in m/ms
m_emitter = m_node->createPointEmitter(core::vector3df(0, 0, 0), // velocity in m/ms
5, 10,
video::SColor(255,0,0,0),
video::SColor(255,255,255,255),
300, 500,
20 // max angle
);
m_emitter_l->setMinStartSize(core::dimension2df(particle_size/1.5f, particle_size/1.5f));
m_emitter_l->setMaxStartSize(core::dimension2df(particle_size*1.5f, particle_size*1.5f));
m_node_l->setEmitter(m_emitter_l); // this grabs the emitter
m_emitter->setMinStartSize(core::dimension2df(m_particle_size/1.5f, m_particle_size/1.5f));
m_emitter->setMaxStartSize(core::dimension2df(m_particle_size*1.5f, m_particle_size*1.5f));
m_node->setEmitter(m_emitter); // this grabs the emitter
scene::IParticleFadeOutAffector *afl = m_node_l->createFadeOutParticleAffector(video::SColor(0, 255, 0, 0), 500);
m_node_l->addAffector(afl);
afl->drop();
scene::IParticleFadeOutAffector *af = m_node->createFadeOutParticleAffector(video::SColor(0, 255, 0, 0), 500);
m_node->addAffector(af);
af->drop();
// Right wheel
m_node_r = irr_driver->addParticleNode();
m_node_r->setParent(m_kart->getNode());
m_node_r->setPosition(core::vector3df(m_kart->getKartWidth()*0.35f, particle_size*0.25f, -m_kart->getKartLength()*0.5f)); // Should use (behind) wheel pos
Material *mr= material_manager->getMaterial("smoke.png");
mr->setMaterialProperties(&(m_node_r->getMaterial(0)));
m_node_r->setMaterialTexture(0, mr->getTexture());
m_emitter_r = m_node_r->createPointEmitter(core::vector3df(0, 0, 0), // velocity in m/ms
5, 10,
video::SColor(255,0,0,0),
video::SColor(255,255,255,255),
300, 500,
20 // max angle
);
m_emitter_r->setMinStartSize(core::dimension2df(particle_size/1.5f, particle_size/1.5f));
m_emitter_r->setMaxStartSize(core::dimension2df(particle_size*1.5f, particle_size*1.5f));
m_node_r->setEmitter(m_emitter_r); // this grabs the emitter
scene::IParticleFadeOutAffector *afr = m_node_r->createFadeOutParticleAffector(video::SColor(255, 255, 0, 0), 500);
m_node_r->addAffector(afr);
afr->drop();
} // KartParticleSystem
//-----------------------------------------------------------------------------
@@ -81,33 +63,37 @@ Smoke::Smoke(Kart* kart) : m_kart(kart)
*/
Smoke::~Smoke()
{
irr_driver->removeNode(m_node_l);
irr_driver->removeNode(m_node_r);
irr_driver->removeNode(m_node);
} // ~Smoke
//-----------------------------------------------------------------------------
void Smoke::update(float t)
{
// No particles to emit, no need to change the speed
if(m_emitter_l->getMinParticlesPerSecond()==0)
if(m_emitter->getMinParticlesPerSecond()==0)
return;
static int left=1;
left = 1-left;
const btWheelInfo &wi = m_kart->getVehicle()->getWheelInfo(left ? 3 : 2);
Vec3 c=wi.m_raycastInfo.m_contactPointWS;
// FIXME: the X position is not yet always accurate.
m_node->setPosition(core::vector3df(c.getX()+ m_particle_size*0.25f * (left?+1:-1),
c.getZ()+m_particle_size*0.25f,
c.getY()));
// There seems to be no way to randomise the velocity for particles,
// so we have to do this manually, by changing the default velocity.
// Irrlicht expects velocity (called 'direction') in m/ms!!
Vec3 dirl(cos(DEGREE_TO_RAD(rand()%180))*0.002f,
Vec3 dir(cos(DEGREE_TO_RAD(rand()%180))*0.002f,
sin(DEGREE_TO_RAD(rand()%180))*0.002f,
sin(DEGREE_TO_RAD(rand()%100))*0.002f);
m_emitter_l->setDirection(dirl.toIrrVector());
Vec3 dirr(cos(DEGREE_TO_RAD(rand()%180))*0.002f,
sin(DEGREE_TO_RAD(rand()%180))*0.002f,
sin(DEGREE_TO_RAD(rand()%100))*0.002f);
m_emitter_r->setDirection(dirr.toIrrVector());
m_emitter->setDirection(dir.toIrrVector());
} // update
//-----------------------------------------------------------------------------
void Smoke::setCreationRate(float f)
{
m_emitter_l->setMinParticlesPerSecond(int(f));
m_emitter_l->setMaxParticlesPerSecond(int(f));
m_emitter_r->setMinParticlesPerSecond(int(f));
m_emitter_r->setMaxParticlesPerSecond(int(f));
m_emitter->setMinParticlesPerSecond(int(f));
m_emitter->setMaxParticlesPerSecond(int(f));
} // setCreationRate

View File

@@ -31,12 +31,12 @@ private:
/** The kart to which this smoke belongs. */
const Kart *m_kart;
/** Irrlicht's particle systems. */
scene::IParticleSystemSceneNode *m_node_l; /* left wheel */
scene::IParticleSystemSceneNode *m_node_r; /* right wheel */
scene::IParticleSystemSceneNode *m_node; /* left wheel */
/** The emitters. Access to these is needed to adjust the number of
* particles per second. */
scene::IParticleEmitter *m_emitter_l;
scene::IParticleEmitter *m_emitter_r;
scene::IParticleEmitter *m_emitter;
/** Size of the particles. */
const float m_particle_size;
public:
Smoke (Kart* kart);
virtual ~Smoke ();