diff --git a/src/explosion.cpp b/src/explosion.cpp index 688b7dbf5..358ad053f 100644 --- a/src/explosion.cpp +++ b/src/explosion.cpp @@ -30,53 +30,33 @@ Explosion::Explosion(const Vec3& coord, const int explosion_sound) { + m_remaining_time = 1.5f; m_node = irr_driver->addParticleNode(); - scene::IParticleEmitter* em = m_node->createBoxEmitter( - core::aabbox3d(-7,0,-7,7,1,7), // emitter size - core::vector3df(0.0f,0.06f,0.0f), // initial direction - 80,100, // emit rate - video::SColor(0,255,255,255), // darkest color - 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->setPosition(coord.toIrrVector()); + Material *m = material_manager->getMaterial("explode.png"); + m_node->setMaterialTexture(0, m->getTexture()); + m->setMaterialProperties(&(m_node->getMaterial(0))); + //m_node->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); - m_node->setEmitter(em); // this grabs the emitter - em->drop(); // so we can drop it here without deleting it + scene::IParticleEmitter* em = m_node->createPointEmitter(); + 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(); - - m_node->addAffector(paf); // same goes for the affector - 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 = m_node->createFadeOutParticleAffector(); + m_node->addAffector(paf); // same goes for the affector + paf->drop(); //scene::IParticleAffector *paf = // m_node->createGravityAffector(Vec3(0, 0, -5).toIrrVector()); //m_node->addAffector(paf); //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 ); init(coord); } // Explosion @@ -95,35 +75,28 @@ void Explosion::init(const Vec3& coord) { m_explode_sound->position(coord); m_explode_sound->play(); - - m_has_ended = false; -} +} // init //----------------------------------------------------------------------------- void Explosion::update(float dt) { -#ifndef HAVE_IRRLICHT - //fprintf(stderr, "Explosion: update: "); - if(++m_step >= m_seq->getNumKids()) + m_remaining_time -=dt; + + // 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 - 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"); - } + m_remaining_time = 0; } else { - //fprintf(stderr, "Step.\n"); - m_seq->selectStep(m_step); + // Sound and animation finished --> remove node + irr_driver->removeNode(m_node); + projectile_manager->FinishedExplosion(); + return; } -#endif } diff --git a/src/explosion.hpp b/src/explosion.hpp index 26db7e963..f9ab5e1e9 100644 --- a/src/explosion.hpp +++ b/src/explosion.hpp @@ -30,7 +30,7 @@ class Explosion { private: SFXBase* m_explode_sound; - bool m_has_ended; + float m_remaining_time; scene::IParticleSystemSceneNode *m_node; @@ -40,7 +40,7 @@ public: void init (const Vec3& coord); void update (float delta_t); int inUse (); - bool hasEnded () { return m_has_ended; } + bool hasEnded () { return m_remaining_time<0.0f; } } ; diff --git a/src/graphics/smoke.cpp b/src/graphics/smoke.cpp index 9a4e7a24c..838780277 100644 --- a/src/graphics/smoke.cpp +++ b/src/graphics/smoke.cpp @@ -19,88 +19,56 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "smoke.hpp" + #include "material_manager.hpp" +#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) - : ParticleSystem(200, 0.0f, true, 0.75f), - m_kart(kart) -{ -#ifndef HAVE_IRRLICHT - -#ifdef DEBUG - setName("smoke"); -#endif - bsphere.setCenter(0, 0, 0); - bsphere.setRadius(1000.0f); - dirtyBSphere(); +Smoke::Smoke(Kart* kart) : m_kart(kart) +{ + m_node = irr_driver->addParticleNode(); + m_node->setParent(m_kart->getNode()); + m_node->setPosition(core::vector3df(0, 1, -1)); + m_node->setMaterialFlag(video::EMF_LIGHTING, false); + m_node->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); + //const std::string s=file_manager->getTextureFile("smoke.png"); + video::ITexture *tex = material_manager->getMaterial("smoke.png")->getTexture(); + m_node->setMaterialTexture(0, tex); + //m_node->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA); + //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); -#endif + m_emitter = m_node->createBoxEmitter(core::aabbox3df(0, 0, 0, 0.3f, 0.3f, 1.3f), + 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 //----------------------------------------------------------------------------- +/** Destructor, removes + */ Smoke::~Smoke() { - //ssgDeRefDelete(m_smokepuff); } // ~Smoke + //----------------------------------------------------------------------------- void Smoke::update(float t) { - ParticleSystem::update(t); + Vec3 dir = m_kart->getTrans().getBasis()*Vec3(0,-.01f,0); + m_emitter->setDirection(dir.toIrrVector()); } // update - //----------------------------------------------------------------------------- -void Smoke::particle_create(int, Particle *p) +void Smoke::setCreationRate(float f) { -#ifndef HAVE_IRRLICHT - sgSetVec4(p->m_col, 1, 1, 1, 1 ); /* initially white */ - sgSetVec3(p->m_vel, 0, 0, 0 ); - sgSetVec3(p->m_acc, 0, 0, 2.0f ); /* Gravity */ - 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 - + f=0; + m_emitter->setMaxParticlesPerSecond(int(f)); + m_emitter->setMaxParticlesPerSecond(int(f)); +} // setCreationRate diff --git a/src/graphics/smoke.hpp b/src/graphics/smoke.hpp index cb1c7330b..24689c82d 100644 --- a/src/graphics/smoke.hpp +++ b/src/graphics/smoke.hpp @@ -17,26 +17,29 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HEADER_SMOKE_H -#define HEADER_SMOKE_H +#ifndef HEADER_SMOKE_HPP +#define HEADER_SMOKE_HPP -#include "particle_system.hpp" +#include "irrlicht.h" +using namespace irr; class Kart; -class Smoke : public ParticleSystem +class Smoke { private: /** The kart to which this smoke belongs. */ - Kart *m_kart; - /** The texture to use. */ - //ssgSimpleState *m_smokepuff; + const Kart *m_kart; + /** Irrlicht's particle system. */ + scene::IParticleSystemSceneNode *m_node; + /** The emitter. Access to this is needed to adjust the number of + * particles per second. */ + scene::IParticleEmitter *m_emitter; public: Smoke (Kart* kart); ~Smoke (); - virtual void update (float t ); - virtual void particle_create(int index, Particle* p ); - virtual void particle_update(float deltaTime, int index, Particle *p ); + virtual void update (float t); + void setCreationRate(float f); }; #endif diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index a84a6d989..6af077767 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -242,7 +242,7 @@ Kart::~Kart() sfx_manager->deleteSFX(m_skid_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); m_animated_node->removeChild(m_shadow->getSceneNode()); diff --git a/src/karts/moveable.cpp b/src/karts/moveable.cpp index 18b07aea2..1d3dc31e8 100644 --- a/src/karts/moveable.cpp +++ b/src/karts/moveable.cpp @@ -48,7 +48,6 @@ Moveable::~Moveable() if(m_animated_node) irr_driver->removeNode(m_animated_node); if(m_mesh) irr_driver->removeMesh(m_mesh); if(m_animated_mesh) irr_driver->removeMesh(m_animated_mesh); - // FIXME LEAK: what about model? ssgDeRefDelete(m_model_transform) } // ~Moveable //----------------------------------------------------------------------------- diff --git a/src/karts/moveable.hpp b/src/karts/moveable.hpp index bcff4af90..5b4f271d6 100644 --- a/src/karts/moveable.hpp +++ b/src/karts/moveable.hpp @@ -59,7 +59,7 @@ public: Moveable(); virtual ~Moveable(); 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 setAnimatedNode(scene::IAnimatedMeshSceneNode *n); virtual const btVector3 diff --git a/src/material.cpp b/src/material.cpp index 3296e3d09..c259ee305 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -118,7 +118,7 @@ void Material::install(bool is_full_path) /** Sets the appropriate flags in an irrlicht SMaterial. * \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) // 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 // updates of the Z buffer of the material. Since the _REF // 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) - mb->getMaterial().MaterialType = video::EMT_SPHERE_MAP; + m->MaterialType = video::EMT_SPHERE_MAP; 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! } // setMaterialProperties diff --git a/src/material.hpp b/src/material.hpp index 456bcb7d2..7713ec6dd 100644 --- a/src/material.hpp +++ b/src/material.hpp @@ -56,7 +56,7 @@ public: bool is_full_path=false); ~Material (); - void setMaterialProperties(scene::IMeshBuffer *mb) const; + void setMaterialProperties(video::SMaterial *m) const; /** Returns the ITexture associated with this material. */ video::ITexture *getTexture() const { return m_texture; } bool isIgnore () const { return m_ignore; } diff --git a/src/material_manager.cpp b/src/material_manager.cpp index 7d03049f2..4ec3d2125 100644 --- a/src/material_manager.cpp +++ b/src/material_manager.cpp @@ -55,7 +55,7 @@ void MaterialManager::setAllMaterialFlags(video::ITexture* t, for(int i = (int)m_materials.size()-1; i>=0; i-- ) { if(m_materials[i]->getTexFname()==image) - m_materials[i]->setMaterialProperties(mb); + m_materials[i]->setMaterialProperties(&(mb->getMaterial())); } // for i } // setAllMaterialFlags