1) Moved zipper and nitro particle code into a common class

KartGFX (to make kart.cpp smaller). Work in progress.
2) Updated VS 9 project file.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10733 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2012-01-27 13:09:51 +00:00
parent ad2a999034
commit 1a49c6bfe5
8 changed files with 296 additions and 97 deletions

View File

@@ -223,6 +223,8 @@ supertuxkart_SOURCES = \
karts/emergency_animation.hpp \
karts/kart.cpp \
karts/kart.hpp \
karts/kart_gfx.cpp \
karts/kart_gfx.hpp \
karts/kart_with_stats.cpp \
karts/kart_with_stats.hpp \
karts/kart_model.cpp \

View File

@@ -229,7 +229,7 @@ void ParticleEmitter::update(float dt)
if (m_emission_decay_rate > 0)
{
m_max_rate = m_min_rate = std::max(0.0f, (m_min_rate - m_emission_decay_rate*dt));
setCreationRate(m_min_rate);
setCreationRateAbsolute(m_min_rate);
}
// There seems to be no way to randomise the velocity for particles,
@@ -247,15 +247,31 @@ void ParticleEmitter::update(float dt)
} // update
//-----------------------------------------------------------------------------
/** Sets the creation rate as a relative fraction between minimum (f=0) and
* maximum (f=1) of the creation rates defined in the particle kind.
* \param fraction Fraction to use.
*/
void ParticleEmitter::setCreationRateRelative(float fraction)
{
assert(fraction >= 0.0f);
assert(fraction <= 1.0f);
const float min_rate = (float)(m_particle_type->getMinRate());
const float max_rate = (float)(m_particle_type->getMaxRate());
setCreationRateAbsolute(min_rate + fraction*(max_rate - min_rate));
} // setCreationRateRelative
void ParticleEmitter::setCreationRate(float f)
//-----------------------------------------------------------------------------
/** Sets the absolute creation rate (in particles per second).
* \param f The creation rate (in particles per second).
*/
void ParticleEmitter::setCreationRateAbsolute(float f)
{
m_emitter->setMinParticlesPerSecond(int(f));
m_emitter->setMaxParticlesPerSecond(int(f));
m_min_rate = f;
m_max_rate = f;
// FIXME: to work around irrlicht bug, when an emitter is paused by setting the rate
// to 0 results in a massive emission when enabling it back. In irrlicht 1.8
// the node has a method called "clearParticles" that should be cleaner than this
@@ -267,7 +283,7 @@ void ParticleEmitter::setCreationRate(float f)
{
m_node->setEmitter(m_emitter);
}
} // setCreationRate
} // setCreationRateAbsolute
//-----------------------------------------------------------------------------

View File

@@ -79,7 +79,8 @@ public:
scene::ISceneNode* parent = NULL);
virtual ~ParticleEmitter();
virtual void update (float dt);
void setCreationRate(float f);
void setCreationRateAbsolute(float fraction);
void setCreationRateRelative(float f);
int getCreationRate();
void setPosition(const Vec3 &pos);

View File

@@ -836,6 +836,10 @@
RelativePath="..\..\karts\kart.cpp"
>
</File>
<File
RelativePath="..\..\karts\kart_gfx.cpp"
>
</File>
<File
RelativePath="..\..\karts\kart_model.cpp"
>
@@ -1208,10 +1212,6 @@
RelativePath="..\..\states_screens\arenas_screen.cpp"
>
</File>
<File
RelativePath="..\..\states_screens\challenges.cpp"
>
</File>
<File
RelativePath="..\..\states_screens\credits.cpp"
>
@@ -1974,6 +1974,10 @@
RelativePath="..\..\karts\kart_control.hpp"
>
</File>
<File
RelativePath="..\..\karts\kart_gfx.hpp"
>
</File>
<File
RelativePath="..\..\karts\kart_model.hpp"
>
@@ -2346,10 +2350,6 @@
RelativePath="..\..\states_screens\arenas_screen.hpp"
>
</File>
<File
RelativePath="..\..\states_screens\challenges.hpp"
>
</File>
<File
RelativePath="..\..\states_screens\credits.hpp"
>

View File

@@ -39,6 +39,7 @@
#include "graphics/shadow.hpp"
#include "graphics/skid_marks.hpp"
#include "graphics/slip_stream.hpp"
#include "karts/kart_gfx.hpp"
#include "modes/world.hpp"
#include "io/file_manager.hpp"
#include "items/item_manager.hpp"
@@ -100,10 +101,6 @@ Kart::Kart (const std::string& ident, Track* track, int position, bool is_first_
m_shadow_enabled = false;
m_shadow = NULL;
m_terrain_particles = NULL;
m_nitro = NULL;
m_nitro_kind = NULL;
m_zipper_fire = NULL;
m_zipper_fire_kind = NULL;
m_collision_particles = NULL;
m_slipstream = NULL;
m_skidmarks = NULL;
@@ -125,7 +122,7 @@ Kart::Kart (const std::string& ident, Track* track, int position, bool is_first_
m_wheel_rotation = 0;
m_kart_model->setKart(this);
// Create SFXBase for each custom sound (TODO: add back when properly done)
/*
for (int n = 0; n < SFXManager::NUM_CUSTOMS; n++)
@@ -186,6 +183,7 @@ Kart::Kart (const std::string& ident, Track* track, int position, bool is_first_
loadData(type, is_first_kart, track, animations);
m_kart_gfx = new KartGFX(this);
reset();
} // Kart
@@ -429,14 +427,11 @@ Kart::~Kart()
sfx_manager->deleteSFX(m_skid_sound );
sfx_manager->deleteSFX(m_goo_sound );
sfx_manager->deleteSFX(m_beep_sound );
delete m_kart_gfx;
if(m_terrain_sound) sfx_manager->deleteSFX(m_terrain_sound);
if(m_previous_terrain_sound) sfx_manager->deleteSFX(m_previous_terrain_sound);
if(m_terrain_particles) delete m_terrain_particles;
if(m_nitro) delete m_nitro;
if(m_nitro_kind) delete m_nitro_kind;
if(m_zipper_fire) delete m_zipper_fire;
if(m_collision_particles) delete m_collision_particles;
if(m_zipper_fire_kind) delete m_zipper_fire_kind;
if(m_slipstream) delete m_slipstream;
if(m_rain) delete m_rain;
if(m_sky_particles_emitter) delete m_sky_particles_emitter;
@@ -545,14 +540,10 @@ void Kart::reset()
m_kart_model->setAnimation(KartModel::AF_DEFAULT);
m_view_blocked_by_plunger = 0.0;
m_attachment->clear();
if (m_nitro)
{
m_nitro->setCreationRate(0.0f);
m_nitro->clearParticles();
}
m_kart_gfx->reset();
m_zipper_fire->setCreationRate(0.0f);
if (m_collision_particles) m_collision_particles->setCreationRate(0.0f);
if (m_collision_particles)
m_collision_particles->setCreationRateAbsolute(0.0f);
m_powerup.reset();
m_race_position = m_initial_position;
@@ -813,7 +804,6 @@ void Kart::update(float dt)
{
if (m_eliminated)
{
printf("a\n");
EmergencyAnimation::update(dt);
return;
}
@@ -924,8 +914,7 @@ void Kart::update(float dt)
}
} // UserConfigParams::m_graphical_effects
if (m_nitro) m_nitro->update(dt);
m_zipper_fire->update(dt);
m_kart_gfx->update(dt);
if (m_collision_particles) m_collision_particles->update(dt);
updatePhysics(dt);
@@ -1056,7 +1045,7 @@ void Kart::update(float dt)
*/
void Kart::showZipperFire()
{
m_zipper_fire->setCreationRate(800.0f);
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_ZIPPER, 800.0f);
}
//-----------------------------------------------------------------------------
@@ -1188,7 +1177,7 @@ void Kart::handleMaterialGFX()
if(!pk)
{
// Disable potentially running particle effects
m_terrain_particles->setCreationRate(0);
m_terrain_particles->setCreationRateAbsolute(0);
return; // no particle effect, return
}
@@ -1206,7 +1195,7 @@ void Kart::handleMaterialGFX()
}
else
{
m_terrain_particles->setCreationRate(0);
m_terrain_particles->setCreationRateAbsolute(0);
return;
}
@@ -1217,7 +1206,7 @@ void Kart::handleMaterialGFX()
// set the position after setParticleType
m_terrain_particles->setPosition(xyz);
m_terrain_particles->setCreationRate(create);
m_terrain_particles->setCreationRateAbsolute(create);
}
return;
@@ -1252,7 +1241,7 @@ void Kart::handleMaterialGFX()
const Material *surface_material;
if(!getSurfaceInfo(from, &xyz, &surface_material))
{
m_terrain_particles->setCreationRate(0);
m_terrain_particles->setCreationRateAbsolute(0);
return;
}
const ParticleKind *pk =
@@ -1279,7 +1268,7 @@ void Kart::handleMaterialGFX()
{
create = 0.0f;
}
m_terrain_particles->setCreationRate(create);
m_terrain_particles->setCreationRateAbsolute(create);
const std::string s = surface_material->getSFXName();
@@ -1413,10 +1402,7 @@ float Kart::handleNitro(float dt)
/** Activates a slipstream effect */
void Kart::setSlipstreamEffect(float f)
{
if (m_zipper_fire)
{
m_zipper_fire->setCreationRate(f);
}
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_ZIPPER, f);
} // setSlipstreamEffect
// -----------------------------------------------------------------------------
@@ -2066,27 +2052,7 @@ void Kart::loadData(RaceManager::KartType type, bool is_first_kart,
}
Vec3 position(0, getKartHeight()*0.35f, -getKartLength()*0.35f);
try
{
m_nitro_kind = new ParticleKind(file_manager->getGfxFile("nitro.xml"));
m_nitro = new ParticleEmitter(m_nitro_kind, position, getNode());
}
catch (std::runtime_error& e)
{
std::cerr << e.what() << std::endl;
}
try
{
m_zipper_fire_kind = new ParticleKind(file_manager->getGfxFile("zipper_fire.xml"));
m_zipper_fire = new ParticleEmitter(m_zipper_fire_kind, position, getNode());
}
catch (std::runtime_error& e)
{
std::cerr << e.what() << std::endl;
}
m_slipstream = new SlipStream(this);
if(m_kart_properties->hasSkidmarks())
@@ -2175,34 +2141,22 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
-m_kart_model->getWheelGraphicsPosition(0).getY() );
center_shift.setY(y);
if (m_nitro)
if (m_controls.m_nitro && isOnGround() && m_collected_energy > 0)
{
// fabs(speed) is important, otherwise the negative number will
// become a huge unsigned number in the particle scene node!
const float min_rate = (float)(m_nitro->getParticlesInfo()->getMinRate());
const float max_rate = (float)(m_nitro->getParticlesInfo()->getMaxRate());
const float rate = fabsf(getSpeed())/m_kart_properties->getMaxSpeed();
assert(rate >= 0.0f); // allow for rounding errors...
//assert(rate <= 2.0f); // max speed is not always respected it seems...
float calculated_rate = m_controls.m_nitro && isOnGround() && m_collected_energy > 0
? (min_rate + rate*(max_rate - min_rate)) : 0;
m_nitro->setCreationRate(calculated_rate);
// the emitter box should spread from last frame's position to the current position
// if we want nitro to be emitted in a smooth, continuous flame and not in blobs
m_nitro->resizeBox(std::max(0.25f, getSpeed()*dt));
float f = fabsf(getSpeed())/m_kart_properties->getMaxSpeed();
// The speed of the kart can be higher (due to powerups) than
// the normal maximum speed of the kart.
if(f>1.0f) f = 1.0f;
m_kart_gfx->setCreationRateRelative(KartGFX::KGFX_NITRO, f);
}
else
m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_NITRO, 0);
m_kart_gfx->resizeBox(KartGFX::KGFX_NITRO, getSpeed(), dt);
m_kart_gfx->resizeBox(KartGFX::KGFX_ZIPPER, getSpeed(), dt);
if (m_zipper_fire)
{
if (m_zipper_fire->getCreationRate() > 0)
{
// the emitter box should spread from last frame's position to the current position
// if we want nitro to be emitted in a smooth, continuous flame and not in blobs
m_zipper_fire->resizeBox(std::max(0.25f, getSpeed()*dt));
}
}
Moveable::updateGraphics(dt, center_shift,
btQuaternion(getVisualSkidOffset(), 0, 0));

View File

@@ -44,6 +44,7 @@ class btUprightConstraint;
class Camera;
class Item;
class KartGFX;
class KartModel;
class ParticleEmitter;
class ParticleKind;
@@ -158,18 +159,9 @@ private:
ParticleEmitter *m_sky_particles_emitter;
/** Graphical effect when using a nitro. */
ParticleEmitter *m_nitro;
/** All particle effects. */
KartGFX *m_kart_gfx;
/** The particle kind for the nitro. */
ParticleKind *m_nitro_kind;
/** Graphical effect when using a zipper. */
ParticleEmitter *m_zipper_fire;
/** The particle kind for the nitro. */
ParticleKind *m_zipper_fire_kind;
/** For collisions */
ParticleEmitter *m_collision_particles;

169
src/karts/kart_gfx.cpp Normal file
View File

@@ -0,0 +1,169 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2012 Joerg Henrichs
//
// 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 "karts/kart_gfx.hpp"
#include "config/user_config.hpp"
#include "io/file_manager.hpp"
#include "graphics/particle_emitter.hpp"
#include "graphics/particle_kind.hpp"
#include "karts/kart.hpp"
#include <iostream>
KartGFX::KartGFX(const Kart *kart)
{
if(!UserConfigParams::m_graphical_effects)
{
for(unsigned int i=0; i<KGFX_COUNT; i++)
{
m_all_emitters.push_back(NULL);
m_all_particle_kinds.push_back(NULL);
}
return;
}
m_kart = kart;
Vec3 position(0, kart->getKartHeight()*0.35f,
-kart->getKartLength()*0.35f);
// Create all effects. Note that they must be created
// in the order of KartGFXType.
addEffect(KGFX_NITRO, "nitro.xml", position);
addEffect(KGFX_ZIPPER, "zipper_fire.xml", position);
addEffect(KGFX_SKID, "nitro.xml", position);
} // KartGFX
// ----------------------------------------------------------------------------
KartGFX::~KartGFX()
{
for(unsigned int i=0; i<KGFX_COUNT; i++)
{
if(m_all_emitters[i])
delete m_all_emitters[i];
if(m_all_particle_kinds[i])
delete m_all_particle_kinds[i];
} // for i < KGFX_COUNT
} // ~KartGFX
// ----------------------------------------------------------------------------
/** Creates a new particle node with the specified particle kind read from
* the given file.
* \param type The KGFX_ type of this type.
* \param file_name The file name of the particle specification.
* \param position Where on the kart the particles should be emitted.
*/
void KartGFX::addEffect(KartGFXType type, const std::string &file_name,
const Vec3 &position)
{
ParticleKind *kind = NULL;
ParticleEmitter *emitter = NULL;
try
{
kind = new ParticleKind(file_manager->getGfxFile(file_name));
emitter = new ParticleEmitter(kind,
position,
m_kart->getNode() );
}
catch (std::runtime_error& e)
{
// If an error happens, mark this emitter as non existant
// by adding a NULL to the list (which is tested for in all
// cases). C++ guarantees that all memory allocated in the
// constructor is properly freed.
std::cerr << e.what() << std::endl;
kind = NULL;
emitter = NULL;
}
assert(m_all_emitters.size()==type);
m_all_emitters.push_back(emitter);
assert(m_all_particle_kinds.size()==type);
m_all_particle_kinds.push_back(kind);
} // addEffect
// ----------------------------------------------------------------------------
void KartGFX::reset()
{
for(unsigned int i=0; i<m_all_emitters.size(); i++)
{
if(m_all_emitters[i])
{
m_all_emitters[i]->setCreationRateAbsolute(0);
m_all_emitters[i]->clearParticles();
}
}
} // reset
// ----------------------------------------------------------------------------
/** Updates all gfx.
* \param dt Time step size.
*/
void KartGFX::update(float dt)
{
if(!UserConfigParams::m_graphical_effects) return;
for(unsigned int i=0; i<m_all_emitters.size(); i++)
{
if(m_all_emitters[i])
m_all_emitters[i]->update(dt);
}
} // update
// ----------------------------------------------------------------------------
/** Sets the creation rate for the specified particle type relative to the
* given minimum and maximum particle rate.
* \param type The particle effect for which to set the
* creation rate.
* \param f The new relative creation rate.
*/
void KartGFX::setCreationRateRelative(KartGFXType type, float f)
{
if(m_all_emitters[type])
m_all_emitters[type]->setCreationRateRelative(f);
} // setCreationRate
// ----------------------------------------------------------------------------
/** Sets the absolute creation rate for the specified particle type.
* \param type The particle effect for which to set the
* creation rate (in particles per seconds).
* \param f The new creation rate.
*/
void KartGFX::setCreationRateAbsolute(KartGFXType type, float f)
{
if(m_all_emitters[type])
m_all_emitters[type]->setCreationRateAbsolute(f);
} // setCreationRate
// ----------------------------------------------------------------------------
/** Resize the area from which the particles are emitted: the emitter box
* should spread from last frame's position to the current position if
* we want the particles to be emitted in a smooth, continuous flame and not
* in blobs.
* \param type The particle effect for which to resize the emitting box.
* \param speed Current speed of the kart.
* \param dt Time step size.
*/
void KartGFX::resizeBox(KartGFXType type, float speed, float dt)
{
if(m_all_emitters[type])
m_all_emitters[type]->resizeBox(std::max(0.25f, speed*dt));
} // resizeBox

65
src/karts/kart_gfx.hpp Normal file
View File

@@ -0,0 +1,65 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2012 Joerg Henrichs
//
// 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_KART_GFX_HPP
#define HEADER_KART_GFX_HPP
/** \defgroup karts
* This class implements all particle effects for a kart. */
#include <vector>
class Kart;
class ParticleEmitter;
class ParticleKind;
class Vec3;
class KartGFX
{
public:
/** All particle effects supported by this object.
* Nitro, zipper, and skidding effects. KGFX_COUNT
* is the number of entries and must therefore be last. */
enum KartGFXType { KGFX_NITRO=0,
KGFX_ZIPPER,
KGFX_SKID,
KGFX_COUNT};
private:
/** Vector of all particle kinds. */
std::vector<ParticleKind*> m_all_particle_kinds;
/** Vector of all particle emitters. */
std::vector<ParticleEmitter*> m_all_emitters;
/** Pointer to the owner of this kart. */
const Kart *m_kart;
void addEffect(KartGFXType type, const std::string &file_name,
const Vec3 &position);
public:
KartGFX(const Kart *kart);
~KartGFX();
void reset();
void update(float dt);
void setCreationRateAbsolute(KartGFXType type, float f);
void setCreationRateRelative(KartGFXType type, float f);
void resizeBox(KartGFXType type, float speed, float dt);
}; // KartWGFX
#endif