1) Explosions now work, though need a new texture and

better particle parameters.
2) Minor work on smoke particle system, not finished.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3573 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2009-06-02 12:06:35 +00:00
parent 2b9d7a0b55
commit 55c7bbe600
10 changed files with 91 additions and 148 deletions

View File

@ -30,53 +30,33 @@
Explosion::Explosion(const Vec3& coord, const int explosion_sound) Explosion::Explosion(const Vec3& coord, const int explosion_sound)
{ {
m_remaining_time = 1.5f;
m_node = irr_driver->addParticleNode(); m_node = irr_driver->addParticleNode();
scene::IParticleEmitter* em = m_node->createBoxEmitter( m_node->setPosition(coord.toIrrVector());
core::aabbox3d<f32>(-7,0,-7,7,1,7), // emitter size Material *m = material_manager->getMaterial("explode.png");
core::vector3df(0.0f,0.06f,0.0f), // initial direction m_node->setMaterialTexture(0, m->getTexture());
80,100, // emit rate m->setMaterialProperties(&(m_node->getMaterial(0)));
video::SColor(0,255,255,255), // darkest color //m_node->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
video::SColor(0,255,255,255), // brightest color
800,2000,0, // min and max age, angle
core::dimension2df(10.f,10.f), // min size
core::dimension2df(20.f,20.f)); // max size
m_node->setEmitter(em); // this grabs the emitter scene::IParticleEmitter* em = m_node->createPointEmitter();
em->drop(); // so we can drop it here without deleting it em->setDirection(core::vector3df(0.0f,0.0006f,0.0f)); // velocity in m/ms(!!)
em->setMinParticlesPerSecond(1);
em->setMaxParticlesPerSecond(5);
em->setMinStartSize(core::dimension2df(0.1f, 0.1f));
em->setMaxStartSize(core::dimension2df(0.5f, 0.5f));
m_node->setEmitter(em); // this grabs the emitter
em->drop(); // so we can drop it here without deleting it
scene::IParticleAffector* paf = m_node->createFadeOutParticleAffector(); scene::IParticleAffector* paf = m_node->createFadeOutParticleAffector();
m_node->addAffector(paf); // same goes for the affector
m_node->addAffector(paf); // same goes for the affector paf->drop();
paf->drop();
//scene::IParticleEmitter *em =
// m_node->createPointEmitter(Vec3(0, 0, 1).toIrrVector(),
// 5, 10 // min and max particles per second
// );
//m_node->setEmitter(em);
//em->drop();
//scene::IParticleAffector *paf = //scene::IParticleAffector *paf =
// m_node->createGravityAffector(Vec3(0, 0, -5).toIrrVector()); // m_node->createGravityAffector(Vec3(0, 0, -5).toIrrVector());
//m_node->addAffector(paf); //m_node->addAffector(paf);
//paf->drop(); //paf->drop();
//paf = m_node->createFadeOutParticleAffector();
//m_node->addAffector(paf);
//paf->drop();
m_node->setPosition(coord.toIrrVector());
m_node->setPosition(core::vector3df(5, 5, 5));
m_node->setScale(core::vector3df(2,2,2));
m_node->setMaterialFlag(video::EMF_LIGHTING, false);
m_node->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
Material *m = material_manager->getMaterial("lava.png");
m_node->setMaterialTexture(0, m->getTexture());
m_node->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);
m_explode_sound = sfx_manager->newSFX( (SFXManager::SFXType)explosion_sound ); m_explode_sound = sfx_manager->newSFX( (SFXManager::SFXType)explosion_sound );
init(coord); init(coord);
} // Explosion } // Explosion
@ -95,35 +75,28 @@ void Explosion::init(const Vec3& coord)
{ {
m_explode_sound->position(coord); m_explode_sound->position(coord);
m_explode_sound->play(); m_explode_sound->play();
} // init
m_has_ended = false;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Explosion::update(float dt) void Explosion::update(float dt)
{ {
#ifndef HAVE_IRRLICHT m_remaining_time -=dt;
//fprintf(stderr, "Explosion: update: ");
if(++m_step >= m_seq->getNumKids()) // Do nothing more if the animation is still playing
if(m_remaining_time>0) return;
// Otherwise check that the sfx has finished, otherwise the
// sfx will get aborted 'in the middle' when this explosion
// object is removed.
if(m_explode_sound->getStatus() == SFXManager::SFX_PLAYING)
{ {
//be sure that the sound is not prematurely stopped m_remaining_time = 0;
if(m_explode_sound->getStatus() != SFXManager::SFX_PLAYING)
{
//fprintf(stderr, "Sound finished. Removing.\n");
stk_scene->remove((ssgTransform*)this);
projectile_manager->FinishedExplosion();
m_has_ended = true;
return;
}
else
{
//fprintf(stderr, "Waiting for sound to finish.\n");
}
} }
else else
{ {
//fprintf(stderr, "Step.\n"); // Sound and animation finished --> remove node
m_seq->selectStep(m_step); irr_driver->removeNode(m_node);
projectile_manager->FinishedExplosion();
return;
} }
#endif
} }

View File

@ -30,7 +30,7 @@ class Explosion
{ {
private: private:
SFXBase* m_explode_sound; SFXBase* m_explode_sound;
bool m_has_ended; float m_remaining_time;
scene::IParticleSystemSceneNode scene::IParticleSystemSceneNode
*m_node; *m_node;
@ -40,7 +40,7 @@ public:
void init (const Vec3& coord); void init (const Vec3& coord);
void update (float delta_t); void update (float delta_t);
int inUse (); int inUse ();
bool hasEnded () { return m_has_ended; } bool hasEnded () { return m_remaining_time<0.0f; }
} ; } ;

View File

@ -19,88 +19,56 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "smoke.hpp" #include "smoke.hpp"
#include "material_manager.hpp" #include "material_manager.hpp"
#include "graphics/irr_driver.hpp"
#include "io/file_manager.hpp"
#include "karts/kart.hpp" #include "karts/kart.hpp"
#include "physics/btKart.hpp"
#include "utils/constants.hpp"
Smoke::Smoke(Kart* kart) Smoke::Smoke(Kart* kart) : m_kart(kart)
: ParticleSystem(200, 0.0f, true, 0.75f), {
m_kart(kart) m_node = irr_driver->addParticleNode();
{ m_node->setParent(m_kart->getNode());
#ifndef HAVE_IRRLICHT m_node->setPosition(core::vector3df(0, 1, -1));
m_node->setMaterialFlag(video::EMF_LIGHTING, false);
#ifdef DEBUG m_node->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
setName("smoke"); //const std::string s=file_manager->getTextureFile("smoke.png");
#endif video::ITexture *tex = material_manager->getMaterial("smoke.png")->getTexture();
bsphere.setCenter(0, 0, 0); m_node->setMaterialTexture(0, tex);
bsphere.setRadius(1000.0f); //m_node->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);
dirtyBSphere(); //m_node->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);
m_smokepuff = new ssgSimpleState ();
#ifndef HAVE_IRRLICHT
m_smokepuff->setTexture(material_manager->getMaterial("smoke.rgb")->getState()->getTexture());
#endif
m_smokepuff -> setTranslucent () ;
m_smokepuff -> enable ( GL_TEXTURE_2D ) ;
m_smokepuff -> setShadeModel ( GL_SMOOTH ) ;
m_smokepuff -> disable ( GL_CULL_FACE ) ;
m_smokepuff -> enable ( GL_BLEND ) ;
m_smokepuff -> disable ( GL_ALPHA_TEST ) ;
m_smokepuff -> enable ( GL_LIGHTING ) ;
m_smokepuff -> setColourMaterial ( GL_EMISSION ) ;
m_smokepuff -> setMaterial ( GL_AMBIENT, 0, 0, 0, 1 ) ;
m_smokepuff -> setMaterial ( GL_DIFFUSE, 0, 0, 0, 1 ) ;
m_smokepuff -> setMaterial ( GL_SPECULAR, 0, 0, 0, 1 ) ;
m_smokepuff -> setShininess ( 0 ) ;
m_smokepuff->ref();
setState(m_smokepuff); m_emitter = m_node->createBoxEmitter(core::aabbox3df(0, 0, 0, 0.3f, 0.3f, 1.3f),
#endif core::vector3df(0, 0, 0),
20, // minParticlesPerSecond,
30 // maxParticlesPerSecond
);
m_node->setParticleSize(core::dimension2df(0.01f, 0.01f));
m_node->setEmitter(m_emitter); // this grabs the emitter
//scene::IParticleAffector *af = m_node->createFadeOutParticleAffector();
//m_node->addAffector(af);
//af->drop();
} // KartParticleSystem } // KartParticleSystem
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Destructor, removes
*/
Smoke::~Smoke() Smoke::~Smoke()
{ {
//ssgDeRefDelete(m_smokepuff);
} // ~Smoke } // ~Smoke
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Smoke::update(float t) void Smoke::update(float t)
{ {
ParticleSystem::update(t); Vec3 dir = m_kart->getTrans().getBasis()*Vec3(0,-.01f,0);
m_emitter->setDirection(dir.toIrrVector());
} // update } // update
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Smoke::particle_create(int, Particle *p) void Smoke::setCreationRate(float f)
{ {
#ifndef HAVE_IRRLICHT f=0;
sgSetVec4(p->m_col, 1, 1, 1, 1 ); /* initially white */ m_emitter->setMaxParticlesPerSecond(int(f));
sgSetVec3(p->m_vel, 0, 0, 0 ); m_emitter->setMaxParticlesPerSecond(int(f));
sgSetVec3(p->m_acc, 0, 0, 2.0f ); /* Gravity */ } // setCreationRate
p->m_size = 0.5f;
p->m_time_to_live = 0.4f;
// Change from left to right wheel and back for each new particle
static int wheel_number = 2;
wheel_number = 5 - wheel_number;
Vec3 xyz=m_kart->getVehicle()->getWheelInfo(wheel_number).m_raycastInfo.m_contactPointWS;
sgCopyVec3 (p->m_pos, xyz.toFloat());
p->m_vel[0] += cos(DEGREE_TO_RAD(rand()%180));
p->m_vel[1] += sin(DEGREE_TO_RAD(rand()%180));
p->m_vel[2] += sin(DEGREE_TO_RAD(rand()%100));
bsphere.setCenter ( xyz.getX(), xyz.getY(), xyz.getZ() ) ;
#endif
} // particle_create
//-----------------------------------------------------------------------------
void Smoke::particle_update(float delta, int,
Particle * particle)
{
#ifndef HAVE_IRRLICHT
particle->m_size -= delta*.2f;
particle->m_col[3] -= delta * 2.0f;
#endif
} // particle_update

View File

@ -17,26 +17,29 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_SMOKE_H #ifndef HEADER_SMOKE_HPP
#define HEADER_SMOKE_H #define HEADER_SMOKE_HPP
#include "particle_system.hpp" #include "irrlicht.h"
using namespace irr;
class Kart; class Kart;
class Smoke : public ParticleSystem class Smoke
{ {
private: private:
/** The kart to which this smoke belongs. */ /** The kart to which this smoke belongs. */
Kart *m_kart; const Kart *m_kart;
/** The texture to use. */ /** Irrlicht's particle system. */
//ssgSimpleState *m_smokepuff; scene::IParticleSystemSceneNode *m_node;
/** The emitter. Access to this is needed to adjust the number of
* particles per second. */
scene::IParticleEmitter *m_emitter;
public: public:
Smoke (Kart* kart); Smoke (Kart* kart);
~Smoke (); ~Smoke ();
virtual void update (float t ); virtual void update (float t);
virtual void particle_create(int index, Particle* p ); void setCreationRate(float f);
virtual void particle_update(float deltaTime, int index, Particle *p );
}; };
#endif #endif

View File

@ -242,7 +242,7 @@ Kart::~Kart()
sfx_manager->deleteSFX(m_skid_sound ); sfx_manager->deleteSFX(m_skid_sound );
sfx_manager->deleteSFX(m_goo_sound ); sfx_manager->deleteSFX(m_goo_sound );
//if(m_smoke_system) ssgDeRefDelete(m_smoke_system); if(m_smoke_system) delete m_smoke_system;
//if(m_nitro) ssgDeRefDelete(m_nitro); //if(m_nitro) ssgDeRefDelete(m_nitro);
m_animated_node->removeChild(m_shadow->getSceneNode()); m_animated_node->removeChild(m_shadow->getSceneNode());

View File

@ -48,7 +48,6 @@ Moveable::~Moveable()
if(m_animated_node) irr_driver->removeNode(m_animated_node); if(m_animated_node) irr_driver->removeNode(m_animated_node);
if(m_mesh) irr_driver->removeMesh(m_mesh); if(m_mesh) irr_driver->removeMesh(m_mesh);
if(m_animated_mesh) irr_driver->removeMesh(m_animated_mesh); if(m_animated_mesh) irr_driver->removeMesh(m_animated_mesh);
// FIXME LEAK: what about model? ssgDeRefDelete(m_model_transform)
} // ~Moveable } // ~Moveable
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -59,7 +59,7 @@ public:
Moveable(); Moveable();
virtual ~Moveable(); virtual ~Moveable();
scene::ISceneNode scene::ISceneNode
*getNode() { return m_node ? m_node : m_animated_node; } *getNode() const { return m_node ? m_node : m_animated_node; }
void setNode(scene::ISceneNode *n); void setNode(scene::ISceneNode *n);
void setAnimatedNode(scene::IAnimatedMeshSceneNode *n); void setAnimatedNode(scene::IAnimatedMeshSceneNode *n);
virtual const btVector3 virtual const btVector3

View File

@ -118,7 +118,7 @@ void Material::install(bool is_full_path)
/** Sets the appropriate flags in an irrlicht SMaterial. /** Sets the appropriate flags in an irrlicht SMaterial.
* \param material The irrlicht SMaterial which gets the flags set. * \param material The irrlicht SMaterial which gets the flags set.
*/ */
void Material::setMaterialProperties(scene::IMeshBuffer *mb) const void Material::setMaterialProperties(video::SMaterial *m) const
{ {
if(m_transparency) if(m_transparency)
// Note: if EMT_TRANSPARENT_ALPHA_CHANNEL is used, you have to use // Note: if EMT_TRANSPARENT_ALPHA_CHANNEL is used, you have to use
@ -126,10 +126,10 @@ void Material::setMaterialProperties(scene::IMeshBuffer *mb) const
// scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); and enable // scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); and enable
// updates of the Z buffer of the material. Since the _REF // updates of the Z buffer of the material. Since the _REF
// approach is faster (and looks better imho), this is used for now. // approach is faster (and looks better imho), this is used for now.
mb->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; m->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
else if(m_sphere_map) else if(m_sphere_map)
mb->getMaterial().MaterialType = video::EMT_SPHERE_MAP; m->MaterialType = video::EMT_SPHERE_MAP;
else if(m_alpha_blending) else if(m_alpha_blending)
mb->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; m->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
// FIXME: more parameters need to be set! // FIXME: more parameters need to be set!
} // setMaterialProperties } // setMaterialProperties

View File

@ -56,7 +56,7 @@ public:
bool is_full_path=false); bool is_full_path=false);
~Material (); ~Material ();
void setMaterialProperties(scene::IMeshBuffer *mb) const; void setMaterialProperties(video::SMaterial *m) const;
/** Returns the ITexture associated with this material. */ /** Returns the ITexture associated with this material. */
video::ITexture *getTexture() const { return m_texture; } video::ITexture *getTexture() const { return m_texture; }
bool isIgnore () const { return m_ignore; } bool isIgnore () const { return m_ignore; }

View File

@ -55,7 +55,7 @@ void MaterialManager::setAllMaterialFlags(video::ITexture* t,
for(int i = (int)m_materials.size()-1; i>=0; i-- ) for(int i = (int)m_materials.size()-1; i>=0; i-- )
{ {
if(m_materials[i]->getTexFname()==image) if(m_materials[i]->getTexFname()==image)
m_materials[i]->setMaterialProperties(mb); m_materials[i]->setMaterialProperties(&(mb->getMaterial()));
} // for i } // for i
} // setAllMaterialFlags } // setAllMaterialFlags