New XML-based particle system. May need a few tweaks
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7255 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
a3df5843aa
commit
ec3c1f76a0
26
data/nitro.xml
Normal file
26
data/nitro.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0"?>
|
||||
<particles emitter="box">
|
||||
|
||||
<spreading value="0.002" />
|
||||
<material file="nitro-particle.png" />
|
||||
|
||||
<!-- Amount of particles emitted per second -->
|
||||
<rate min="5"
|
||||
max="10" />
|
||||
|
||||
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
|
||||
<lifetime min="1000"
|
||||
max="2000" />
|
||||
|
||||
<!-- Size of the particles -->
|
||||
<size min="0.22"
|
||||
max="0.5" />
|
||||
|
||||
<!-- Doesn't seem to work -->
|
||||
<color min="255 255 255"
|
||||
max="255 255 255" />
|
||||
|
||||
<!-- How much time in milliseconds before the particle is fully faded out -->
|
||||
<fadeout time="1500" />
|
||||
|
||||
</particles>
|
26
data/smoke.xml
Normal file
26
data/smoke.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0"?>
|
||||
<particles emitter="box">
|
||||
|
||||
<spreading value="0.003" />
|
||||
<material file="smoke.png" />
|
||||
|
||||
<!-- Amount of particles emitted per second -->
|
||||
<rate min="5"
|
||||
max="10" />
|
||||
|
||||
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
|
||||
<lifetime min="1000"
|
||||
max="2000" />
|
||||
|
||||
<!-- Size of the particles -->
|
||||
<size min="0.2"
|
||||
max="0.66" />
|
||||
|
||||
<!-- Doesn't seem to work -->
|
||||
<color min="255 255 255"
|
||||
max="255 255 255" />
|
||||
|
||||
<!-- How much time in milliseconds before the particle is fully faded out -->
|
||||
<fadeout time="1500" />
|
||||
|
||||
</particles>
|
@ -73,6 +73,8 @@ supertuxkart_SOURCES = \
|
||||
graphics/moving_texture.hpp \
|
||||
graphics/particle_emitter.cpp \
|
||||
graphics/particle_emitter.hpp \
|
||||
graphics/particle_kind.cpp \
|
||||
graphics/particle_kind.hpp \
|
||||
graphics/shadow.cpp \
|
||||
graphics/shadow.hpp \
|
||||
graphics/skid_marks.cpp \
|
||||
|
@ -21,18 +21,26 @@
|
||||
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/particle_kind.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
|
||||
ParticleEmitter::ParticleEmitter(float particleSize, core::vector3df position, Material* material,
|
||||
int minParticlesPerSecond, int maxParticlesPerSecond,
|
||||
video::SColor minStartColor, video::SColor maxStartColor,
|
||||
int lifeTimeMin, int lifeTimeMax, int maxAngle, int fadeOutTime,
|
||||
float directionMultiplier, float minSize, float maxSize, scene::ISceneNode* parent)
|
||||
ParticleEmitter::ParticleEmitter(ParticleKind* type, core::vector3df position,
|
||||
scene::ISceneNode* parent)
|
||||
{
|
||||
m_direction_multiplier = directionMultiplier;
|
||||
m_node = irr_driver->addParticleNode();
|
||||
m_particle_type = type;
|
||||
|
||||
Material* material = type->getMaterial();
|
||||
const float minSize = type->getMinSize();
|
||||
const float maxSize = type->getMaxSize();
|
||||
const int lifeTimeMin = type->getMinLifetime();
|
||||
const int lifeTimeMax = type->getMaxLifetime();
|
||||
|
||||
assert(material->getTexture() != NULL);
|
||||
assert(maxSize >= minSize);
|
||||
assert(lifeTimeMax >= lifeTimeMin);
|
||||
|
||||
#ifdef DEBUG
|
||||
std::string debug_name = std::string("particles(") + material->getTexture()->getName().getPath().c_str() + ")";
|
||||
@ -53,20 +61,22 @@ ParticleEmitter::ParticleEmitter(float particleSize, core::vector3df position, M
|
||||
m_node->setMaterialTexture(0, material->getTexture());
|
||||
|
||||
// FIXME: does the maxAngle param work at all??
|
||||
|
||||
m_emitter = m_node->createPointEmitter(core::vector3df(0.0f, 0.3f, 0.0f), // velocity in m/ms
|
||||
minParticlesPerSecond, maxParticlesPerSecond,
|
||||
minStartColor, maxStartColor,
|
||||
// FIXME: the min and max color params don't appear to work
|
||||
m_emitter = m_node->createPointEmitter(core::vector3df(0.0f, 0.0f, 0.0f), // velocity in m/ms
|
||||
type->getMinRate(), type->getMaxRate(),
|
||||
type->getMinColor(), type->getMaxColor(),
|
||||
lifeTimeMin, lifeTimeMax,
|
||||
maxAngle
|
||||
0 /* angle */
|
||||
);
|
||||
m_emitter->setMinStartSize(core::dimension2df(minSize, minSize));
|
||||
m_emitter->setMaxStartSize(core::dimension2df(maxSize, maxSize));
|
||||
m_node->setEmitter(m_emitter); // this grabs the emitter
|
||||
m_emitter->drop(); // so we can drop our references
|
||||
|
||||
// FIXME: fade-out color doesn't seem to quite work
|
||||
scene::IParticleFadeOutAffector *af = m_node->createFadeOutParticleAffector(video::SColor(0, 255, 0, 0), fadeOutTime);
|
||||
// FIXME: this is ridiculous, the fadeout time should be equal to the lifetime, except that the
|
||||
// lifetime is random...
|
||||
scene::IParticleFadeOutAffector *af = m_node->createFadeOutParticleAffector(video::SColor(0, 0, 0, 0),
|
||||
type->getFadeoutTime());
|
||||
m_node->addAffector(af);
|
||||
af->drop();
|
||||
|
||||
@ -86,12 +96,14 @@ void ParticleEmitter::update()
|
||||
// No particles to emit, no need to change the speed
|
||||
if (m_emitter->getMinParticlesPerSecond() == 0) return;
|
||||
|
||||
const float spreading = m_particle_type->getSpreadFactor();
|
||||
|
||||
// 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 dir(cos(DEGREE_TO_RAD*(rand()%180))*m_direction_multiplier,
|
||||
sin(DEGREE_TO_RAD*(rand()%100))*m_direction_multiplier,
|
||||
sin(DEGREE_TO_RAD*(rand()%180))*m_direction_multiplier);
|
||||
Vec3 dir(cos(DEGREE_TO_RAD*(rand()%180))*spreading,
|
||||
sin(DEGREE_TO_RAD*(rand()%100))*spreading,
|
||||
sin(DEGREE_TO_RAD*(rand()%180))*spreading);
|
||||
|
||||
m_emitter->setDirection(dir.toIrrVector());
|
||||
} // update
|
||||
|
@ -26,6 +26,7 @@
|
||||
using namespace irr;
|
||||
|
||||
class Material;
|
||||
class ParticleKind;
|
||||
|
||||
/**
|
||||
* \brief manages smoke particle effects
|
||||
@ -41,18 +42,12 @@ private:
|
||||
/** The emitters. Access to these is needed to adjust the number of
|
||||
* particles per second. */
|
||||
scene::IParticleEmitter *m_emitter;
|
||||
|
||||
/** Size of the particles. */
|
||||
float m_particle_size;
|
||||
|
||||
float m_direction_multiplier;
|
||||
|
||||
ParticleKind *m_particle_type;
|
||||
|
||||
public:
|
||||
ParticleEmitter (float particleSize, core::vector3df position, Material* material,
|
||||
int minParticlesPerSeconds, int maxParticlesPerSecond,
|
||||
video::SColor minStartColor, video::SColor maxStartColor,
|
||||
int lifeTimeMin, int lifeTimeMax, int maxAngle, int fadeOutTime,
|
||||
float directionMultiplier, float minSize, float maxSize,
|
||||
|
||||
ParticleEmitter (ParticleKind* type, core::vector3df position,
|
||||
scene::ISceneNode* parent = NULL);
|
||||
virtual ~ParticleEmitter();
|
||||
virtual void update ();
|
||||
|
154
src/graphics/particle_kind.cpp
Normal file
154
src/graphics/particle_kind.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
// $Id$
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs, Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "graphics/particle_kind.hpp"
|
||||
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
ParticleKind::ParticleKind(const std::string file) : m_min_start_color(255,255,255,255), m_max_start_color(255,255,255,255)
|
||||
{
|
||||
// ---- Initial values to prevent readin uninitialized values
|
||||
m_max_size = 0.5;
|
||||
m_min_size = 0.5;
|
||||
m_spread_factor = 0.001;
|
||||
m_shape = EMITTER_POINT;
|
||||
m_material = NULL;
|
||||
m_min_rate = 10;
|
||||
m_max_rate = 10;
|
||||
m_lifetime_min = 400;
|
||||
m_lifetime_max = 400;
|
||||
m_fadeout_time = 400;
|
||||
|
||||
|
||||
// ----- Read XML file
|
||||
|
||||
//std::cout << "==== READING " << file << " ====\n";
|
||||
|
||||
XMLNode* xml = file_manager->createXMLTree(file);
|
||||
|
||||
if (xml == NULL)
|
||||
{
|
||||
throw std::runtime_error("[ParticleKind] Cannot find file " + file);
|
||||
}
|
||||
|
||||
if (xml->getName() != "particles")
|
||||
{
|
||||
delete xml;
|
||||
throw std::runtime_error("[ParticleKind] No <particles> main node in smoke.xml");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
std::string emitterShape = "point";
|
||||
xml->get("emitter", &emitterShape);
|
||||
|
||||
if (emitterShape == "point")
|
||||
{
|
||||
m_shape = EMITTER_POINT;
|
||||
}
|
||||
else if (emitterShape == "box")
|
||||
{
|
||||
m_shape = EMITTER_BOX;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "[ParticleKind] <particles> main node has unknown value for attribute 'emitter'\n";
|
||||
m_shape = EMITTER_POINT;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const XMLNode* spreading = xml->getNode("spreading");
|
||||
spreading->get("value", &m_spread_factor);
|
||||
|
||||
//std::cout << "m_spread_factor = " << m_spread_factor << "\n";
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const XMLNode* material = xml->getNode("material");
|
||||
std::string materialFile;
|
||||
material->get("file", &materialFile);
|
||||
|
||||
if (materialFile.size() == 0)
|
||||
{
|
||||
delete xml;
|
||||
throw std::runtime_error("[ParticleKind] <material> tag has invalid 'file' attribute");
|
||||
}
|
||||
|
||||
m_material = material_manager->getMaterial(materialFile);
|
||||
if (m_material->getTexture() == NULL)
|
||||
{
|
||||
throw std::runtime_error("[ParticleKind] Cannot locate file " + materialFile);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const XMLNode* rate = xml->getNode("rate");
|
||||
rate->get("min", &m_min_rate);
|
||||
rate->get("max", &m_max_rate);
|
||||
|
||||
//std::cout << "m_min_rate = " << m_min_rate << "\n";
|
||||
//std::cout << "m_max_rate = " << m_max_rate << "\n";
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const XMLNode* lifetime = xml->getNode("lifetime");
|
||||
lifetime->get("min", &m_lifetime_min);
|
||||
lifetime->get("max", &m_lifetime_max);
|
||||
|
||||
//std::cout << "m_lifetime_min = " << m_lifetime_min << "\n";
|
||||
//std::cout << "m_lifetime_max = " << m_lifetime_max << "\n";
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const XMLNode* size = xml->getNode("size");
|
||||
//size->get("default", &m_particle_size);
|
||||
size->get("min", &m_min_size);
|
||||
size->get("max", &m_max_size);
|
||||
|
||||
//std::cout << "m_particle_size = " << m_particle_size << "\n";
|
||||
//std::cout << "m_min_size = " << m_min_size << "\n";
|
||||
//std::cout << "m_max_size = " << m_max_size << "\n";
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const XMLNode* color = xml->getNode("color");
|
||||
video::SColor minColor;
|
||||
video::SColor maxColor;
|
||||
color->get("min", &m_min_start_color);
|
||||
color->get("max", &m_max_start_color);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const XMLNode* fadeout = xml->getNode("fadeout");
|
||||
fadeout->get("time", &m_fadeout_time);
|
||||
|
||||
//std::cout << "m_fadeout_time = " << m_fadeout_time << "\n";
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
delete xml;
|
||||
}
|
99
src/graphics/particle_kind.hpp
Normal file
99
src/graphics/particle_kind.hpp
Normal file
@ -0,0 +1,99 @@
|
||||
// $Id$
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs, Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// 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_PARTICLE_KIND_HPP
|
||||
#define HEADER_PARTICLE_KIND_HPP
|
||||
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
#include <string>
|
||||
#include "irrlicht.h"
|
||||
using namespace irr;
|
||||
|
||||
class Material;
|
||||
|
||||
enum EmitterShape
|
||||
{
|
||||
EMITTER_POINT,
|
||||
EMITTER_BOX
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief type of particles
|
||||
* \ingroup graphics
|
||||
*/
|
||||
class ParticleKind : public NoCopy
|
||||
{
|
||||
private:
|
||||
|
||||
/** Size of the particles. */
|
||||
//float m_particle_size;
|
||||
float m_max_size;
|
||||
float m_min_size;
|
||||
|
||||
float m_spread_factor;
|
||||
|
||||
EmitterShape m_shape;
|
||||
|
||||
Material* m_material;
|
||||
|
||||
/** Minimal emission rate in particles per second */
|
||||
int m_min_rate;
|
||||
|
||||
/** Maximal emission rate in particles per second */
|
||||
int m_max_rate;
|
||||
|
||||
int m_lifetime_min;
|
||||
int m_lifetime_max;
|
||||
|
||||
int m_fadeout_time;
|
||||
|
||||
video::SColor m_min_start_color;
|
||||
video::SColor m_max_start_color;
|
||||
|
||||
public:
|
||||
|
||||
ParticleKind(const std::string file);
|
||||
virtual ~ParticleKind() {}
|
||||
|
||||
|
||||
//float getParticleSize() const { return m_particle_size; }
|
||||
float getMaxSize () const { return m_max_size; }
|
||||
float getMinSize () const { return m_min_size; }
|
||||
|
||||
int getMinRate () const { return m_min_rate; }
|
||||
int getMaxRate () const { return m_max_rate; }
|
||||
|
||||
float getSpreadFactor() const { return m_spread_factor; }
|
||||
|
||||
EmitterShape getShape () const { return m_shape; }
|
||||
|
||||
Material* getMaterial () const { return m_material; }
|
||||
|
||||
int getMaxLifetime () const { return m_lifetime_max; }
|
||||
int getMinLifetime () const { return m_lifetime_min; }
|
||||
|
||||
int getFadeoutTime () const { return m_fadeout_time; }
|
||||
|
||||
video::SColor getMinColor() const { return m_min_start_color; }
|
||||
video::SColor getMaxColor() const { return m_max_start_color; }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
953C304E12BEF384005BB4CD /* tutorial_data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 953C304C12BEF384005BB4CD /* tutorial_data.cpp */; };
|
||||
953F8B2111F7C13C00205E66 /* scalable_font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 953F8B1F11F7C13C00205E66 /* scalable_font.cpp */; };
|
||||
9542FC7712D3BDB000C00366 /* particle_emitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9542FC7512D3BDB000C00366 /* particle_emitter.cpp */; };
|
||||
9542FD4C12D3E0D700C00366 /* particle_kind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9542FD4A12D3E0D700C00366 /* particle_kind.cpp */; };
|
||||
95453ACA11808B8700A155B9 /* emergency_animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95453AC811808B8700A155B9 /* emergency_animation.cpp */; };
|
||||
9545ABCA11E3E38300D3C37A /* progress_bar_widget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9545ABC811E3E38300D3C37A /* progress_bar_widget.cpp */; };
|
||||
954E486A11B19C4100B1DF63 /* fribidi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 954E486911B19C4100B1DF63 /* fribidi.framework */; };
|
||||
@ -439,6 +440,8 @@
|
||||
9540E2570FD5F8FD002985B8 /* no_copy.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = no_copy.hpp; path = ../../utils/no_copy.hpp; sourceTree = SOURCE_ROOT; };
|
||||
9542FC7512D3BDB000C00366 /* particle_emitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = particle_emitter.cpp; path = ../../graphics/particle_emitter.cpp; sourceTree = SOURCE_ROOT; };
|
||||
9542FC7612D3BDB000C00366 /* particle_emitter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = particle_emitter.hpp; path = ../../graphics/particle_emitter.hpp; sourceTree = SOURCE_ROOT; };
|
||||
9542FD4A12D3E0D700C00366 /* particle_kind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = particle_kind.cpp; path = ../../graphics/particle_kind.cpp; sourceTree = SOURCE_ROOT; };
|
||||
9542FD4B12D3E0D700C00366 /* particle_kind.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = particle_kind.hpp; path = ../../graphics/particle_kind.hpp; sourceTree = SOURCE_ROOT; };
|
||||
95453AC811808B8700A155B9 /* emergency_animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = emergency_animation.cpp; path = ../../karts/emergency_animation.cpp; sourceTree = SOURCE_ROOT; };
|
||||
95453AC911808B8700A155B9 /* emergency_animation.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = emergency_animation.hpp; path = ../../karts/emergency_animation.hpp; sourceTree = SOURCE_ROOT; };
|
||||
9545ABC811E3E38300D3C37A /* progress_bar_widget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = progress_bar_widget.cpp; path = ../../guiengine/widgets/progress_bar_widget.cpp; sourceTree = SOURCE_ROOT; };
|
||||
@ -1251,6 +1254,8 @@
|
||||
952A153A103F66D600B1895D /* moving_texture.hpp */,
|
||||
9542FC7512D3BDB000C00366 /* particle_emitter.cpp */,
|
||||
9542FC7612D3BDB000C00366 /* particle_emitter.hpp */,
|
||||
9542FD4A12D3E0D700C00366 /* particle_kind.cpp */,
|
||||
9542FD4B12D3E0D700C00366 /* particle_kind.hpp */,
|
||||
952A153D103F66D600B1895D /* shadow.cpp */,
|
||||
952A153E103F66D600B1895D /* shadow.hpp */,
|
||||
952A153F103F66D600B1895D /* skid_marks.cpp */,
|
||||
@ -2726,6 +2731,7 @@
|
||||
951B50AE12C9698B004F6993 /* xml_writer.cpp in Sources */,
|
||||
9538A56012CD094200CE3220 /* addon.cpp in Sources */,
|
||||
9542FC7712D3BDB000C00366 /* particle_emitter.cpp in Sources */,
|
||||
9542FD4C12D3E0D700C00366 /* particle_kind.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -255,6 +255,8 @@ int XMLNode::get(const std::string &attribute, int *value) const
|
||||
{
|
||||
std::string s;
|
||||
if(!get(attribute, &s)) return 0;
|
||||
// FIXME: don't use "atoi", if the number in the attribute is not an int we want an error message,
|
||||
// not silently return 0... easy to get bitten by this
|
||||
*value = atoi(s.c_str());
|
||||
return 1;
|
||||
} // get(int)
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/particle_emitter.hpp"
|
||||
#include "graphics/particle_kind.hpp"
|
||||
#include "graphics/shadow.hpp"
|
||||
#include "graphics/skid_marks.hpp"
|
||||
#include "graphics/slip_stream.hpp"
|
||||
@ -55,8 +56,6 @@
|
||||
# pragma warning(disable:4355)
|
||||
#endif
|
||||
|
||||
const float SMOKE_PARTICLE_SIZE = 0.33f;
|
||||
|
||||
/** The kart constructor.
|
||||
* \param ident The identifier for the kart model to use.
|
||||
* \param position The position (or rank) for this kart (between 1 and
|
||||
@ -86,6 +85,7 @@ Kart::Kart (const std::string& ident, int position,
|
||||
m_race_position = position;
|
||||
m_collected_energy = 0;
|
||||
m_finished_race = false;
|
||||
m_wheel_toggle = 1;
|
||||
m_finish_time = 0.0f;
|
||||
m_shadow_enabled = false;
|
||||
m_shadow = NULL;
|
||||
@ -1442,25 +1442,29 @@ void Kart::loadData()
|
||||
// Attach Particle System
|
||||
if (UserConfigParams::m_graphical_effects)
|
||||
{
|
||||
core::vector3df position(-getKartWidth()*0.35f, SMOKE_PARTICLE_SIZE*0.25f, -getKartLength()*0.5f);
|
||||
m_smoke_system = new ParticleEmitter(SMOKE_PARTICLE_SIZE, position, material_manager->getMaterial("smoke.png"),
|
||||
5 /* min particles */, 10 /* max particles */,
|
||||
video::SColor(255,0,0,0) /* min color */,
|
||||
video::SColor(255,255,255,255) /* max color */,
|
||||
300 /* lifeTimeMin */, 500 /* lifeTimeMax */, 20 /* max angle */,
|
||||
500 /* fade-out time */, 0.003f, SMOKE_PARTICLE_SIZE/1.5f, SMOKE_PARTICLE_SIZE*1.5f);
|
||||
try
|
||||
{
|
||||
core::vector3df position(-getKartWidth()*0.35f, 0.06, -getKartLength()*0.5f);
|
||||
m_smoke_system = new ParticleEmitter(new ParticleKind(file_manager->getDataFile("smoke.xml")), position);
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
m_water_splash_system = new WaterSplash(this);
|
||||
|
||||
const float particle_size = 0.25f;
|
||||
core::vector3df position(0, particle_size*0.25f, -getKartLength()*0.5f);
|
||||
m_nitro = new ParticleEmitter(particle_size, position, material_manager->getMaterial("nitro-particle.png"),
|
||||
5 /* min particles */, 10 /* max particles */,
|
||||
video::SColor(255,0,0,0) /* min color */,
|
||||
video::SColor(255,255,255,255) /* max color */,
|
||||
150 /* lifeTimeMin */, 250 /* lifeTimeMax */, 40 /* max angle */,
|
||||
2500 /* fade-out time */, 0.003f, particle_size/1.5f, particle_size*2.0f,
|
||||
getNode());
|
||||
|
||||
try
|
||||
{
|
||||
m_nitro = new ParticleEmitter(new ParticleKind(file_manager->getDataFile("nitro.xml")), position, getNode());
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
|
||||
m_slipstream = new SlipStream(this);
|
||||
|
||||
@ -1551,16 +1555,15 @@ void Kart::updateGraphics(const Vec3& offset_xyz,
|
||||
f=250.0f;
|
||||
m_smoke_system->setCreationRate((m_skidding-1)*f);
|
||||
|
||||
static int left = 1;
|
||||
left = 1 - left;
|
||||
const btWheelInfo &wi = getVehicle()->getWheelInfo(2 + left);
|
||||
m_wheel_toggle = 1 - m_wheel_toggle;
|
||||
const btWheelInfo &wi = getVehicle()->getWheelInfo(2 + m_wheel_toggle);
|
||||
Vec3 c = wi.m_raycastInfo.m_contactPointWS;
|
||||
|
||||
// FIXME: instead of constantly moving the emitter around, just make it a child of the kart node
|
||||
// FIXME: the X position is not yet always accurate.
|
||||
m_smoke_system->setPosition(core::vector3df(c.getX() + SMOKE_PARTICLE_SIZE*0.25f * (left ? +1 : -1),
|
||||
m_smoke_system->setPosition(core::vector3df(c.getX() + 0.06f * (m_wheel_toggle ? +1 : -1),
|
||||
c.getY(),
|
||||
c.getZ() + SMOKE_PARTICLE_SIZE*0.25f));
|
||||
c.getZ() + 0.06f));
|
||||
|
||||
}
|
||||
if(m_water_splash_system)
|
||||
|
@ -106,6 +106,9 @@ private:
|
||||
* determine startup boost. */
|
||||
bool m_has_started;
|
||||
|
||||
/** For skidding smoke */
|
||||
int m_wheel_toggle;
|
||||
|
||||
float m_max_gear_rpm; /**<Maximum engine rpm's for the current gear*/
|
||||
float m_bounce_back_time; /**<A short time after a collision acceleration
|
||||
* is disabled to allow the karts to bounce back*/
|
||||
|
Loading…
Reference in New Issue
Block a user