Convert explosion from hardcoded particle system to our current XML system
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@12964 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
33
data/gfx/explosion.xml
Normal file
33
data/gfx/explosion.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0"?>
|
||||
<particles emitter="sphere" radius="0.3">
|
||||
|
||||
<spreading angle="180" />
|
||||
|
||||
<velocity x="0.000"
|
||||
y="0.0035"
|
||||
z="0.000" />
|
||||
|
||||
<material file="explode.png" />
|
||||
|
||||
<!-- Amount of particles emitted per second -->
|
||||
<rate min="500"
|
||||
max="800" />
|
||||
|
||||
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
|
||||
<lifetime min="1000"
|
||||
max="1200" />
|
||||
|
||||
<!-- Size of the particles -->
|
||||
<size min="0.65"
|
||||
max="0.95"
|
||||
x-increase-factor="0.6"
|
||||
y-increase-factor="0.6"
|
||||
/>
|
||||
|
||||
<color min="255 255 255"
|
||||
max="255 255 255" />
|
||||
|
||||
<!-- How much time in milliseconds before the particle is fully faded out -->
|
||||
<fadeout time="800" />
|
||||
|
||||
</particles>
|
||||
@@ -23,6 +23,8 @@
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/particle_emitter.hpp"
|
||||
#include "graphics/particle_kind_manager.hpp"
|
||||
#include "items/projectile_manager.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
@@ -37,39 +39,10 @@ Explosion::Explosion(const Vec3& coord, const char* explosion_sound)
|
||||
{
|
||||
// short emision time, explosion, not constant flame
|
||||
m_remaining_time = burst_time;
|
||||
m_node = irr_driver->addParticleNode();
|
||||
m_node->grab();
|
||||
#ifdef DEBUG
|
||||
m_node->setName("explosion");
|
||||
#endif
|
||||
m_node->setPosition(coord.toIrrVector());
|
||||
Material* m = material_manager->getMaterial("explode.png");
|
||||
m_node->setMaterialTexture(0, m->getTexture());
|
||||
m->setMaterialProperties(&(m_node->getMaterial(0)), NULL);
|
||||
m_node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
|
||||
|
||||
scene::IParticleEmitter* em =
|
||||
m_node->createSphereEmitter(core::vector3df(0.0f,0.0f,0.0f), 0.5f,
|
||||
/* velocity in m/ms */core::vector3df(0.0f,0.005f,0.0f),
|
||||
600, 900, // min max particles per sec
|
||||
video::SColor(0, 0, 0, 0), // min colour
|
||||
video::SColor(0, 0, 0, 0), // max colour
|
||||
(int)((burst_time + explosion_time)
|
||||
*1000.0f), // min life ms
|
||||
(int)((burst_time + explosion_time)
|
||||
*1000.0f), // max max life ms
|
||||
90, // max angle
|
||||
// min and max start size
|
||||
core::dimension2df(0.3f, 0.3f),
|
||||
core::dimension2df(0.75f, 0.75f)
|
||||
);
|
||||
m_node->setEmitter(em); // this grabs the emitter
|
||||
em->drop(); // so we can drop it here without deleting it
|
||||
|
||||
scene::IParticleAffector* scale_affector =
|
||||
m_node->createScaleParticleAffector(core::dimension2df(3.0f, 3.0f));
|
||||
m_node->addAffector(scale_affector); // same goes for the affector
|
||||
scale_affector->drop();
|
||||
|
||||
ParticleKindManager* pkm = ParticleKindManager::get();
|
||||
ParticleKind* particles = pkm->getParticles("explosion.xml");
|
||||
m_emitter = new ParticleEmitter(particles, coord, NULL);
|
||||
} // Explosion
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -77,12 +50,9 @@ Explosion::Explosion(const Vec3& coord, const char* explosion_sound)
|
||||
*/
|
||||
Explosion::~Explosion()
|
||||
{
|
||||
if(m_node)
|
||||
if(m_emitter)
|
||||
{
|
||||
m_node->drop();
|
||||
// Remove from scene node by removing from parent.
|
||||
irr_driver->removeNode(m_node);
|
||||
m_node = NULL;
|
||||
delete m_emitter;
|
||||
}
|
||||
} // ~Explosion
|
||||
|
||||
@@ -101,19 +71,20 @@ bool Explosion::updateAndDelete(float dt)
|
||||
|
||||
if (m_remaining_time < 0.0f && m_remaining_time >= -explosion_time)
|
||||
{
|
||||
|
||||
scene::ISceneNode* node = m_emitter->getNode();
|
||||
|
||||
const int intensity = (int)(255-(m_remaining_time/-explosion_time)*255);
|
||||
m_node->getMaterial(0).AmbientColor.setGreen(intensity);
|
||||
m_node->getMaterial(0).DiffuseColor.setGreen(intensity);
|
||||
m_node->getMaterial(0).EmissiveColor.setGreen(intensity);
|
||||
node->getMaterial(0).AmbientColor.setGreen(intensity);
|
||||
node->getMaterial(0).DiffuseColor.setGreen(intensity);
|
||||
node->getMaterial(0).EmissiveColor.setGreen(intensity);
|
||||
|
||||
m_node->getMaterial(0).AmbientColor.setBlue(intensity);
|
||||
m_node->getMaterial(0).DiffuseColor.setBlue(intensity);
|
||||
m_node->getMaterial(0).EmissiveColor.setBlue(intensity);
|
||||
node->getMaterial(0).AmbientColor.setBlue(intensity);
|
||||
node->getMaterial(0).DiffuseColor.setBlue(intensity);
|
||||
node->getMaterial(0).EmissiveColor.setBlue(intensity);
|
||||
|
||||
m_node->getMaterial(0).AmbientColor.setRed(intensity);
|
||||
m_node->getMaterial(0).DiffuseColor.setRed(intensity);
|
||||
m_node->getMaterial(0).EmissiveColor.setRed(intensity);
|
||||
node->getMaterial(0).AmbientColor.setRed(intensity);
|
||||
node->getMaterial(0).DiffuseColor.setRed(intensity);
|
||||
node->getMaterial(0).EmissiveColor.setRed(intensity);
|
||||
|
||||
}
|
||||
|
||||
@@ -127,8 +98,8 @@ bool Explosion::updateAndDelete(float dt)
|
||||
if (m_remaining_time > -explosion_time)
|
||||
{
|
||||
// Stop the emitter and wait a little while for all particles to have time to fade out
|
||||
m_node->getEmitter()->setMinParticlesPerSecond(0);
|
||||
m_node->getEmitter()->setMaxParticlesPerSecond(0);
|
||||
m_emitter->getNode()->getEmitter()->setMinParticlesPerSecond(0);
|
||||
m_emitter->getNode()->getEmitter()->setMaxParticlesPerSecond(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -30,6 +30,7 @@ using namespace irr;
|
||||
|
||||
class Vec3;
|
||||
class SFXBase;
|
||||
class ParticleEmitter;
|
||||
|
||||
const float explosion_time = 1.5f;
|
||||
|
||||
@@ -39,8 +40,8 @@ const float explosion_time = 1.5f;
|
||||
class Explosion : public HitSFX
|
||||
{
|
||||
private:
|
||||
float m_remaining_time;
|
||||
scene::IParticleSystemSceneNode *m_node;
|
||||
float m_remaining_time;
|
||||
ParticleEmitter* m_emitter;
|
||||
|
||||
public:
|
||||
Explosion(const Vec3& coord, const char* explosion_sound);
|
||||
|
||||
@@ -381,14 +381,16 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
||||
m_node->setMaterialTexture(0, irr_driver->getTexture((file_manager->getDataDir() + "gui/main_help.png").c_str()));
|
||||
}
|
||||
|
||||
// velocity in m/ms
|
||||
core::vector3df velocity(m_particle_type->getVelocityX(),
|
||||
m_particle_type->getVelocityY(),
|
||||
m_particle_type->getVelocityZ());
|
||||
|
||||
switch (type->getShape())
|
||||
{
|
||||
case EMITTER_POINT:
|
||||
{
|
||||
m_emitter = m_node->createPointEmitter(core::vector3df(m_particle_type->getVelocityX(),
|
||||
m_particle_type->getVelocityY(),
|
||||
m_particle_type->getVelocityZ()), // velocity in m/ms
|
||||
m_emitter = m_node->createPointEmitter(velocity,
|
||||
type->getMinRate(), type->getMaxRate(),
|
||||
type->getMinColor(), type->getMaxColor(),
|
||||
lifeTimeMin, lifeTimeMax,
|
||||
@@ -404,13 +406,11 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
||||
|
||||
m_emitter = m_node->createBoxEmitter(core::aabbox3df(-box_size_x, -box_size_y, -0.6f,
|
||||
box_size_x, box_size_y, -0.6f - type->getBoxSizeZ()),
|
||||
core::vector3df(m_particle_type->getVelocityX(),
|
||||
m_particle_type->getVelocityY(),
|
||||
m_particle_type->getVelocityZ()), // velocity in m/ms
|
||||
velocity,
|
||||
type->getMinRate(), type->getMaxRate(),
|
||||
type->getMinColor(), type->getMaxColor(),
|
||||
lifeTimeMin, lifeTimeMax,
|
||||
m_particle_type->getAngleSpread() /* angle */
|
||||
m_particle_type->getAngleSpread()
|
||||
);
|
||||
|
||||
#if VISUALIZE_BOX_EMITTER
|
||||
@@ -435,6 +435,18 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case EMITTER_SPHERE:
|
||||
{
|
||||
m_emitter = m_node->createSphereEmitter(core::vector3df(0.0f,0.0f,0.0f) /* center */,
|
||||
m_particle_type->getSphereRadius(),
|
||||
velocity,
|
||||
type->getMinRate(), type->getMaxRate(),
|
||||
type->getMinColor(), type->getMaxColor(),
|
||||
lifeTimeMin, lifeTimeMax,
|
||||
m_particle_type->getAngleSpread()
|
||||
);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fprintf(stderr, "[ParticleEmitter] Unknown shape\n");
|
||||
@@ -476,6 +488,16 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
||||
m_node->addAffector(faa);
|
||||
faa->drop();
|
||||
}
|
||||
|
||||
if (type->hasScaleAffector())
|
||||
{
|
||||
core::dimension2df factor = core::dimension2df(type->getScaleAffectorFactorX(),
|
||||
type->getScaleAffectorFactorY());
|
||||
scene::IParticleAffector* scale_affector =
|
||||
m_node->createScaleParticleAffector(factor);
|
||||
m_node->addAffector(scale_affector);
|
||||
scale_affector->drop();
|
||||
}
|
||||
}
|
||||
} // setParticleType
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ ParticleKind::ParticleKind(const std::string file) : m_min_start_color(255,255,2
|
||||
m_box_x = 0.5f;
|
||||
m_box_y = 0.5f;
|
||||
m_box_z = 0.5f;
|
||||
m_sphere_radius = 0.5f;
|
||||
m_angle_spread = 45;
|
||||
m_velocity_x = 0.001f;
|
||||
m_velocity_y = 0.001f;
|
||||
@@ -51,6 +52,9 @@ ParticleKind::ParticleKind(const std::string file) : m_min_start_color(255,255,2
|
||||
m_fade_away_end = -1.0f;
|
||||
m_force_lost_to_gravity_time = 1000;
|
||||
m_emission_decay_rate = 0;
|
||||
m_has_scale_affector = NULL;
|
||||
m_scale_affector_factor_x = 0.0f;
|
||||
m_scale_affector_factor_y = 0.0f;
|
||||
|
||||
|
||||
// ----- Read XML file
|
||||
@@ -87,6 +91,12 @@ ParticleKind::ParticleKind(const std::string file) : m_min_start_color(255,255,2
|
||||
xml->get("box_y", &m_box_y);
|
||||
xml->get("box_z", &m_box_z);
|
||||
}
|
||||
else if (emitterShape == "sphere")
|
||||
{
|
||||
m_shape = EMITTER_SPHERE;
|
||||
|
||||
xml->get("radius", &m_sphere_radius);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "[ParticleKind] <particles> main node has unknown value for attribute 'emitter'\n");
|
||||
@@ -154,6 +164,10 @@ ParticleKind::ParticleKind(const std::string file) : m_min_start_color(255,255,2
|
||||
size->get("min", &m_min_size);
|
||||
size->get("max", &m_max_size);
|
||||
}
|
||||
|
||||
bool has_x = size->get("x-increase-factor", &m_scale_affector_factor_x);
|
||||
bool has_y = size->get("y-increase-factor", &m_scale_affector_factor_y);
|
||||
m_has_scale_affector = (has_x || has_y);
|
||||
|
||||
//std::cout << "m_particle_size = " << m_particle_size << "\n";
|
||||
//std::cout << "m_min_size = " << m_min_size << "\n";
|
||||
|
||||
@@ -30,6 +30,7 @@ class Material;
|
||||
enum EmitterShape
|
||||
{
|
||||
EMITTER_POINT,
|
||||
EMITTER_SPHERE,
|
||||
EMITTER_BOX
|
||||
};
|
||||
|
||||
@@ -77,6 +78,9 @@ private:
|
||||
/** For box emitters only */
|
||||
float m_box_x, m_box_y, m_box_z;
|
||||
|
||||
/** For sphere emitters only */
|
||||
float m_sphere_radius;
|
||||
|
||||
/** Distance from camera at which particles start fading out, or negative if disabled */
|
||||
float m_fade_away_start, m_fade_away_end;
|
||||
|
||||
@@ -86,6 +90,10 @@ private:
|
||||
|
||||
std::string m_material_file;
|
||||
|
||||
bool m_has_scale_affector;
|
||||
float m_scale_affector_factor_x;
|
||||
float m_scale_affector_factor_y;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@@ -119,6 +127,8 @@ public:
|
||||
float getBoxSizeY () const { return m_box_y; }
|
||||
float getBoxSizeZ () const { return m_box_z; }
|
||||
|
||||
float getSphereRadius() const { return m_sphere_radius; }
|
||||
|
||||
int getAngleSpread () const { return m_angle_spread; }
|
||||
|
||||
float getVelocityX () const { return m_velocity_x; }
|
||||
@@ -138,6 +148,11 @@ public:
|
||||
|
||||
int getEmissionDecayRate() const { return m_emission_decay_rate; }
|
||||
|
||||
|
||||
bool hasScaleAffector() const { return m_has_scale_affector; }
|
||||
float getScaleAffectorFactorX() const { return m_scale_affector_factor_x; }
|
||||
float getScaleAffectorFactorY() const { return m_scale_affector_factor_y; };
|
||||
|
||||
std::string getName() const { return m_name; }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user