Change particle emitters into track objects so that they can be animated. I think I also fixed a few relatively minor leaks along the way
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11415 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
f766785302
commit
8760f28450
@ -200,7 +200,7 @@ ParticleEmitter::ParticleEmitter(const ParticleKind* type,
|
||||
ParticleEmitter::~ParticleEmitter()
|
||||
{
|
||||
assert(m_magic_number == 0x58781325);
|
||||
assert(m_node != NULL);
|
||||
if (m_node != NULL)
|
||||
irr_driver->removeNode(m_node);
|
||||
m_emitter->drop();
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace irr
|
||||
}
|
||||
using namespace irr;
|
||||
|
||||
#include "utils/leak_check.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
@ -74,6 +75,8 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
LEAK_CHECK()
|
||||
|
||||
ParticleEmitter (const ParticleKind* type,
|
||||
const Vec3 &position,
|
||||
scene::ISceneNode* parent = NULL);
|
||||
@ -95,6 +98,9 @@ public:
|
||||
|
||||
scene::IParticleSystemSceneNode* getNode() { return m_node; }
|
||||
|
||||
/** call this if the node was freed otherwise */
|
||||
void unsetNode() { m_node = NULL; }
|
||||
|
||||
void addHeightMapAffector(Track* t);
|
||||
};
|
||||
#endif
|
||||
|
@ -1334,41 +1334,7 @@ void Track::loadTrackModel(World* parent, bool reverse_track,
|
||||
{
|
||||
if (UserConfigParams::m_graphical_effects)
|
||||
{
|
||||
std::string path;
|
||||
irr::core::vector3df emitter_origin;
|
||||
node->get("kind", &path);
|
||||
node->getXYZ(&emitter_origin);
|
||||
|
||||
int clip_distance = -1;
|
||||
node->get("clip_distance", &clip_distance);
|
||||
|
||||
try
|
||||
{
|
||||
ParticleKind* kind = ParticleKindManager::get()->getParticles( path.c_str() );
|
||||
if (kind == NULL)
|
||||
{
|
||||
throw std::runtime_error(path + " could not be loaded");
|
||||
}
|
||||
ParticleEmitter* emitter = new ParticleEmitter( kind, emitter_origin );
|
||||
|
||||
if (clip_distance > 0)
|
||||
{
|
||||
scene::ISceneManager* sm = irr_driver->getSceneManager();
|
||||
scene::ISceneNode* sroot = sm->getRootSceneNode();
|
||||
LODNode* lod = new LODNode("particles", sroot, sm);
|
||||
lod->add(clip_distance, (scene::ISceneNode*)emitter->getNode(), true);
|
||||
//m_all_emitters.push_back(emitter);
|
||||
m_all_nodes.push_back( lod );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_all_emitters.push_back(emitter);
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
{
|
||||
fprintf(stderr, "[Track] WARNING: Could not load particles '%s'; cause :\n %s", path.c_str(), e.what());
|
||||
}
|
||||
m_track_object_manager->add(*node);
|
||||
}
|
||||
}
|
||||
else if(name=="sky-dome" || name=="sky-box" || name=="sky-color")
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include "audio/sfx_buffer.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/lod_node.hpp"
|
||||
#include "graphics/particle_emitter.hpp"
|
||||
#include "graphics/particle_kind_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "items/item_manager.hpp"
|
||||
@ -30,6 +33,8 @@
|
||||
#include "tracks/track.hpp"
|
||||
|
||||
#include <IMeshSceneNode.h>
|
||||
#include <ISceneManager.h>
|
||||
#include <IParticleSystemSceneNode.h>
|
||||
|
||||
/** A track object: any additional object on the track. This object implements
|
||||
* a graphics-only representation, i.e. there is no physical representation.
|
||||
@ -49,6 +54,8 @@ TrackObject::TrackObject(const XMLNode &xml_node)
|
||||
m_sound = NULL;
|
||||
m_mesh = NULL;
|
||||
m_node = NULL;
|
||||
m_emitter = NULL;
|
||||
m_lod_emitter_node = NULL;
|
||||
|
||||
xml_node.get("xyz", &m_init_xyz );
|
||||
xml_node.get("hpr", &m_init_hpr );
|
||||
@ -72,9 +79,50 @@ TrackObject::TrackObject(const XMLNode &xml_node)
|
||||
bool trigger_when_near = false;
|
||||
float trigger_distance = 1.0f;
|
||||
|
||||
if (xml_node.getName() == "particle-emitter")
|
||||
{
|
||||
std::string path;
|
||||
irr::core::vector3df emitter_origin;
|
||||
xml_node.get("kind", &path);
|
||||
xml_node.getXYZ(&emitter_origin);
|
||||
|
||||
int clip_distance = -1;
|
||||
xml_node.get("clip_distance", &clip_distance);
|
||||
|
||||
try
|
||||
{
|
||||
ParticleKind* kind = ParticleKindManager::get()->getParticles( path.c_str() );
|
||||
if (kind == NULL)
|
||||
{
|
||||
throw std::runtime_error(path + " could not be loaded");
|
||||
}
|
||||
ParticleEmitter* emitter = new ParticleEmitter( kind, emitter_origin );
|
||||
|
||||
if (clip_distance > 0)
|
||||
{
|
||||
scene::ISceneManager* sm = irr_driver->getSceneManager();
|
||||
scene::ISceneNode* sroot = sm->getRootSceneNode();
|
||||
LODNode* lod = new LODNode("particles", sroot, sm);
|
||||
lod->add(clip_distance, (scene::ISceneNode*)emitter->getNode(), true);
|
||||
//m_all_emitters.push_back(emitter);
|
||||
m_node = lod;
|
||||
m_lod_emitter_node = lod;
|
||||
m_emitter = emitter;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_node = emitter->getNode(); // FIXME: this leaks
|
||||
m_emitter = emitter;
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
{
|
||||
fprintf(stderr, "[Track] WARNING: Could not load particles '%s'; cause :\n %s", path.c_str(), e.what());
|
||||
}
|
||||
}
|
||||
// FIXME: at this time sound emitters are just disabled in multiplayer
|
||||
// otherwise the sounds would be constantly heard
|
||||
if (sound.size() > 0 && race_manager->getNumLocalPlayers() < 2)
|
||||
else if (sound.size() > 0 && race_manager->getNumLocalPlayers() < 2)
|
||||
{
|
||||
float rolloff = 0.5;
|
||||
xml_node.get("rolloff", &rolloff );
|
||||
@ -155,7 +203,6 @@ TrackObject::TrackObject(const XMLNode &xml_node)
|
||||
// don't use this scene node
|
||||
if (model_name == "")
|
||||
{
|
||||
m_node = NULL;
|
||||
m_mesh = NULL;
|
||||
|
||||
if (trigger_when_near)
|
||||
@ -321,8 +368,18 @@ TrackObject::TrackObject()
|
||||
*/
|
||||
TrackObject::~TrackObject()
|
||||
{
|
||||
if(m_node)
|
||||
if (m_emitter)
|
||||
{
|
||||
if (m_lod_emitter_node != NULL)
|
||||
{
|
||||
irr_driver->removeNode(m_lod_emitter_node);
|
||||
m_emitter->unsetNode();
|
||||
}
|
||||
delete m_emitter; // this will also delete m_node
|
||||
}
|
||||
else if (m_node)
|
||||
irr_driver->removeNode(m_node);
|
||||
|
||||
if(m_mesh)
|
||||
{
|
||||
irr_driver->dropAllTextures(m_mesh);
|
||||
@ -336,7 +393,6 @@ TrackObject::~TrackObject()
|
||||
delete m_sound->getBuffer();
|
||||
sfx_manager->deleteSFX(m_sound);
|
||||
}
|
||||
|
||||
} // ~TrackObject
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -34,6 +34,7 @@ using namespace irr;
|
||||
|
||||
class XMLNode;
|
||||
class SFXBase;
|
||||
class ParticleEmitter;
|
||||
|
||||
/**
|
||||
* \ingroup tracks
|
||||
@ -68,6 +69,8 @@ private:
|
||||
|
||||
virtual void OnAnimationEnd(scene::IAnimatedMeshSceneNode* node);
|
||||
|
||||
ParticleEmitter* m_emitter;
|
||||
|
||||
protected:
|
||||
/** The irrlicht scene node this object is attached to. */
|
||||
scene::ISceneNode *m_node;
|
||||
@ -98,6 +101,8 @@ protected:
|
||||
|
||||
std::string m_type;
|
||||
|
||||
LODNode* m_lod_emitter_node;
|
||||
|
||||
public:
|
||||
TrackObject(const XMLNode &xml_node);
|
||||
TrackObject();
|
||||
|
@ -56,7 +56,12 @@ void TrackObjectManager::add(const XMLNode &xml_node)
|
||||
|
||||
std::string type;
|
||||
xml_node.get("type", &type);
|
||||
if(type=="movable")
|
||||
|
||||
if (xml_node.getName() == "particle-emitter")
|
||||
{
|
||||
m_all_objects.push_back(new ThreeDAnimation(xml_node));
|
||||
}
|
||||
else if (type=="movable")
|
||||
{
|
||||
if (is_lod)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user