Added some smoke when skidding is used.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2533 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
6e72015c53
commit
fbdde1aa76
@ -70,16 +70,13 @@ Kart::Kart (const std::string& kart_name, int position,
|
||||
#endif
|
||||
{
|
||||
m_kart_properties = kart_properties_manager->getKart(kart_name);
|
||||
//m_grid_position = position;
|
||||
m_initial_position = position;
|
||||
m_collected_energy = 0;
|
||||
m_eliminated = false;
|
||||
m_finished_race = false;
|
||||
m_finish_time = 0.0f;
|
||||
m_wheelie_angle = 0.0f;
|
||||
m_smokepuff = NULL;
|
||||
m_smoke_system = NULL;
|
||||
m_exhaust_pipe = NULL;
|
||||
m_skidmark_left = NULL;
|
||||
m_skidmark_right = NULL;
|
||||
|
||||
@ -244,8 +241,7 @@ Kart::~Kart()
|
||||
sfx_manager->deleteSFX(m_crash_sound );
|
||||
sfx_manager->deleteSFX(m_skid_sound );
|
||||
|
||||
if(m_smokepuff) delete m_smokepuff;
|
||||
if(m_smoke_system != NULL) delete m_smoke_system;
|
||||
if(m_smoke_system) ssgDeRefDelete(m_smoke_system);
|
||||
|
||||
ssgDeRefDelete(m_shadow);
|
||||
|
||||
@ -930,23 +926,11 @@ void Kart::processSkidMarks()
|
||||
} // processSkidMarks
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <scene.hpp>
|
||||
void Kart::loadData()
|
||||
{
|
||||
float r [ 2 ] = { -10.0f, 100.0f } ;
|
||||
|
||||
m_smokepuff = new ssgSimpleState ();
|
||||
m_smokepuff->setTexture(material_manager->getMaterial("smoke.rgb")->getState()->getTexture());
|
||||
m_smokepuff -> setTranslucent () ;
|
||||
m_smokepuff -> enable ( GL_TEXTURE_2D ) ;
|
||||
m_smokepuff -> setShadeModel ( GL_SMOOTH ) ;
|
||||
m_smokepuff -> enable ( GL_CULL_FACE ) ;
|
||||
m_smokepuff -> enable ( GL_BLEND ) ;
|
||||
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 ) ;
|
||||
|
||||
ssgEntity *obj = m_kart_properties->getKartModel()->getRoot();
|
||||
createPhysics();
|
||||
@ -960,16 +944,11 @@ void Kart::loadData()
|
||||
getModelTransform() -> addKid ( lod ) ;
|
||||
|
||||
// Attach Particle System
|
||||
//JH sgCoord pipe_pos = {{0, 0, .3}, {0, 0, 0}} ;
|
||||
m_smoke_system = new Smoke(this, 50, 100.0f, true, 0.35f, 1000);
|
||||
m_smoke_system -> init(5);
|
||||
//JH m_smoke_system -> setState (getMaterial ("smoke.png")-> getState() );
|
||||
//m_smoke_system -> setState ( m_smokepuff ) ;
|
||||
// m_exhaust_pipe = new ssgTransform (&pipe_pos);
|
||||
// m_exhaust_pipe -> addKid (m_smoke_system) ;
|
||||
// comp_model-> addKid (m_exhaust_pipe) ;
|
||||
|
||||
//
|
||||
m_smoke_system = new Smoke(this);
|
||||
m_smoke_system->ref();
|
||||
scene->add(m_smoke_system);
|
||||
|
||||
m_skidmark_left = new SkidMark(/* angle sign */ -1);
|
||||
m_skidmark_right = new SkidMark(/* angle sign */ 1);
|
||||
|
||||
@ -1018,6 +997,8 @@ void Kart::updateGraphics(const Vec3& off_xyz, const Vec3& off_hpr)
|
||||
center_shift.setZ(X);
|
||||
const float offset_pitch = DEGREE_TO_RAD(m_wheelie_angle);
|
||||
|
||||
if(m_smoke_system)
|
||||
m_smoke_system->setCreationRate((m_skidding-1)*100.0f);
|
||||
|
||||
float speed_ratio = getSpeed()/getMaxSpeed();
|
||||
float offset_heading = getSteerPercent()*0.05f*3.1415926f * speed_ratio * m_skidding*m_skidding;
|
||||
|
@ -71,10 +71,9 @@ protected:
|
||||
private:
|
||||
/** The amount of energy collected bu hitting coins. */
|
||||
float m_collected_energy;
|
||||
ssgSimpleState* m_smokepuff;
|
||||
|
||||
// don't delete the following 2 vars (they're kids in the hirarchy)
|
||||
Smoke *m_smoke_system;
|
||||
ssgTransform* m_exhaust_pipe;
|
||||
|
||||
float m_wheel_rotation;
|
||||
/** For each wheel it stores the suspension length after the karts are at
|
||||
|
@ -22,64 +22,71 @@
|
||||
|
||||
#include "particle_system.hpp"
|
||||
|
||||
ParticleSystem::ParticleSystem ( int num, float _create_rate, int _ttf,
|
||||
float sz, float bsphere_size)
|
||||
: ssgVtxTable ( GL_QUADS,
|
||||
new ssgVertexArray ( num * 4 /*, new sgVec3 [ num * 4 ]*/ ),
|
||||
new ssgNormalArray ( num * 4 /*, new sgVec3 [ num * 4 ]*/ ),
|
||||
new ssgTexCoordArray ( num * 4 /*, new sgVec2 [ num * 4 ]*/ ),
|
||||
new ssgColourArray ( num * 4 /*, new sgVec4 [ num * 4 ]*/ )
|
||||
)
|
||||
#include <algorithm>
|
||||
#include "vec3.hpp"
|
||||
|
||||
ParticleSystem::ParticleSystem ( int num, float create_rate, int ttf, float sz)
|
||||
: ssgVtxTable(GL_QUADS,
|
||||
new ssgVertexArray (num*4, new sgVec3[num*4] ),
|
||||
new ssgNormalArray (num*4, new sgVec3[num*4] ),
|
||||
new ssgTexCoordArray(num*4, new sgVec2[num*4] ),
|
||||
new ssgColourArray (num*4, new sgVec4[num*4] )
|
||||
)
|
||||
{
|
||||
m_turn_to_face = _ttf ;
|
||||
#ifdef DEBUG
|
||||
setName("particle-system");
|
||||
#endif
|
||||
m_turn_to_face = ttf;
|
||||
m_create_error = 0 ;
|
||||
m_create_rate = _create_rate ;
|
||||
m_create_rate = create_rate;
|
||||
m_size = sz;
|
||||
|
||||
m_size = sz ;
|
||||
|
||||
bsphere . setRadius ( bsphere_size ) ;
|
||||
bsphere . setCenter ( 0, 0, 0 ) ;
|
||||
bsphere.setRadius(100); // a better value is computed in update
|
||||
bsphere.setCenter(0, 0, 0);
|
||||
|
||||
m_num_particles = num ;
|
||||
m_num_verts = num * 4 ;
|
||||
|
||||
m_particles = new Particle [ num ] ;
|
||||
m_particles = new Particle[num];
|
||||
|
||||
int i ;
|
||||
|
||||
for ( i = 0 ; i < m_num_verts ; i++ )
|
||||
{
|
||||
sgSetVec3 ( getNormal ( i ), 0, -1, 0 ) ;
|
||||
sgSetVec4 ( getColour ( i ), 1, 1, 1, 1 ) ;
|
||||
sgZeroVec3 ( getVertex ( i ) ) ;
|
||||
}
|
||||
sgSetVec3 (getNormal(i), 0, -1, 0 );
|
||||
sgSetVec4 (getColour(i), 1, 1, 1, 1 );
|
||||
sgZeroVec3(getVertex(i) );
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < m_num_particles ; i++ )
|
||||
{
|
||||
sgSetVec2(getTexCoord(i*4+0), 0, 0 );
|
||||
sgSetVec2(getTexCoord(i*4+1), 1, 0 );
|
||||
sgSetVec2(getTexCoord(i*4+2), 1, 1 );
|
||||
sgSetVec2(getTexCoord(i*4+3), 0, 1 );
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < m_num_particles ; i++ )
|
||||
{
|
||||
sgSetVec2 ( getTexCoord ( i*4+0 ), 0, 0 ) ;
|
||||
sgSetVec2 ( getTexCoord ( i*4+1 ), 1, 0 ) ;
|
||||
sgSetVec2 ( getTexCoord ( i*4+2 ), 1, 1 ) ;
|
||||
sgSetVec2 ( getTexCoord ( i*4+3 ), 0, 1 ) ;
|
||||
}
|
||||
|
||||
m_num_active = 0 ;
|
||||
}
|
||||
m_num_active = 0 ;
|
||||
} // ParticleSystem
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
ParticleSystem::init(int initial_num)
|
||||
void ParticleSystem::init(int initial_num)
|
||||
{
|
||||
for ( int i = 0 ; i < initial_num ; i++ )
|
||||
particle_create(i, & m_particles [ i ] ) ;
|
||||
}
|
||||
} // init
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
ParticleSystem::recalcBSphere()
|
||||
/** Update the bounding sphere for this particle system. This function is only
|
||||
* called during setup, from then on the bounding sphere is always updated
|
||||
* during update(), and so the correct value is always set. So no actual
|
||||
* computation is done here.
|
||||
*/
|
||||
void ParticleSystem::recalcBSphere()
|
||||
{
|
||||
bsphere . setRadius ( 1000.0f ) ;
|
||||
bsphere . setCenter ( 0, 0, 0 ) ;
|
||||
}
|
||||
bsphere.setRadius( 1000.0f );
|
||||
bsphere.setCenter( 0, 0, 0 );
|
||||
} // recalcBSphere
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ParticleSystem::draw_geometry ()
|
||||
@ -144,13 +151,12 @@ void ParticleSystem::draw_geometry ()
|
||||
{
|
||||
glDisable ( GL_CULL_FACE ) ;
|
||||
glDepthMask ( 0 ) ;
|
||||
|
||||
ssgVtxTable::draw_geometry () ;
|
||||
|
||||
glDepthMask ( 1 ) ;
|
||||
glEnable ( GL_CULL_FACE ) ;
|
||||
}
|
||||
}
|
||||
} // draw_geometry
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ParticleSystem::~ParticleSystem ()
|
||||
@ -159,7 +165,7 @@ ParticleSystem::~ParticleSystem ()
|
||||
// the functions are virtual (illegal in destructor)
|
||||
|
||||
delete[] m_particles ;
|
||||
}
|
||||
} // ~ParticleSystem
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ParticleSystem::update ( float t )
|
||||
@ -178,8 +184,10 @@ void ParticleSystem::update ( float t )
|
||||
particle_update( t, i, & m_particles [ i ] ) ;
|
||||
}
|
||||
|
||||
Vec3 xyz_min(10000), xyz_max(-10000);
|
||||
/* Check for death of particles */
|
||||
for ( i = 0 ; i < m_num_particles ; i++ )
|
||||
{
|
||||
if ( m_particles [ i ] . m_time_to_live <= 0.0 )
|
||||
{
|
||||
particle_delete ( i, & m_particles [ i ] ) ;
|
||||
@ -190,13 +198,39 @@ void ParticleSystem::update ( float t )
|
||||
{
|
||||
particle_create( i, & m_particles [ i ] ) ;
|
||||
m_create_error -= 1.0f ;
|
||||
Vec3 p(m_particles[i].m_pos);
|
||||
xyz_min.min(p);
|
||||
xyz_max.max(p);
|
||||
}
|
||||
}
|
||||
else
|
||||
else // m_time_to_live >0
|
||||
{
|
||||
m_num_active++ ;
|
||||
Vec3 p(m_particles[i].m_pos);
|
||||
xyz_min.min(p);
|
||||
xyz_max.max(p);
|
||||
}
|
||||
}
|
||||
} // for i
|
||||
|
||||
// Update the bounding sphere
|
||||
// ==========================
|
||||
// Determine a bounding sphere by taking the medium of min and max as the
|
||||
// center. Then use the longest distance along one axis(!) to get a maxium
|
||||
// boundary box - the radius of a boundary sphere can then be estimated to
|
||||
// be less then sqrt(x*x+y*y+z*z) = sqrt(3*max(x,y,z)^2) = max(xyz)*sqrt(3)
|
||||
// (This avoids more expensive computations for the distance of each
|
||||
// particle: a 2nd loop to determine the distance of each particle to the
|
||||
// center to get the correct maximum distance, which is the radius).
|
||||
Vec3 center = 0.5*(xyz_min+xyz_max);
|
||||
bsphere.setCenter(center.toFloat());
|
||||
float radius = xyz_max.getX() - xyz_min.getX();
|
||||
radius = std::max(radius, xyz_max.getY() - xyz_min.getY());
|
||||
radius = std::max(radius, xyz_max.getZ() - xyz_min.getZ());
|
||||
if(radius<0) radius = 0; // happens if no particles exist.
|
||||
// add the size of the actual quad to the radius on both ends
|
||||
bsphere.setRadius((radius+2*m_size)*1.733f); // 1.733 approx. sqrt(3)
|
||||
bsphere_is_invalid = 0;
|
||||
} // update
|
||||
|
||||
/* EOF */
|
||||
|
||||
|
@ -21,6 +21,10 @@
|
||||
|
||||
#include <plib/ssg.h>
|
||||
|
||||
/** This is basically the ssgaParticle, but this implementation supports
|
||||
* methods to be used to create, update and delete the objects instead
|
||||
* of function pointer as the original plib.
|
||||
*/
|
||||
class Particle
|
||||
{
|
||||
public:
|
||||
@ -56,7 +60,10 @@ public:
|
||||
} ;
|
||||
|
||||
|
||||
class ParticleSystem ;
|
||||
/** This is basically the ssgaParticleSystem, but this implementation supports
|
||||
* methods to be used to create, update and delete the objects instead
|
||||
* of function pointer as the original plib.
|
||||
*/
|
||||
|
||||
class ParticleSystem : public ssgVtxTable
|
||||
{
|
||||
@ -74,7 +81,7 @@ class ParticleSystem : public ssgVtxTable
|
||||
public:
|
||||
|
||||
ParticleSystem ( int num, float _create_rate, int _turn_to_face,
|
||||
float sz, float bsphere_size);
|
||||
float sz);
|
||||
virtual ~ParticleSystem () ;
|
||||
virtual void update ( float t ) ;
|
||||
|
||||
|
102
src/smoke.cpp
102
src/smoke.cpp
@ -20,81 +20,83 @@
|
||||
|
||||
#include "smoke.hpp"
|
||||
#include "constants.hpp"
|
||||
#include "material_manager.hpp"
|
||||
#include "karts/kart.hpp"
|
||||
|
||||
Smoke::Smoke(Kart* kart_,
|
||||
int num, float _create_rate, int _ttf,
|
||||
float sz, float bsphere_size)
|
||||
: ParticleSystem (num, _create_rate, _ttf, sz, bsphere_size),
|
||||
m_kart(kart_)
|
||||
Smoke::Smoke(Kart* kart)
|
||||
: ParticleSystem(200, 0.0f, true, 0.75f),
|
||||
m_kart(kart)
|
||||
{
|
||||
getBSphere () -> setCenter ( 0, 0, 0 ) ;
|
||||
getBSphere () -> setRadius ( 1000.0f ) ;
|
||||
#ifdef DEBUG
|
||||
setName("smoke");
|
||||
#endif
|
||||
bsphere.setCenter(0, 0, 0);
|
||||
bsphere.setRadius(1000.0f);
|
||||
dirtyBSphere();
|
||||
|
||||
m_smokepuff = new ssgSimpleState ();
|
||||
m_smokepuff->setTexture(material_manager->getMaterial("smoke.rgb")->getState()->getTexture());
|
||||
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 -> 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);
|
||||
|
||||
} // KartParticleSystem
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Smoke::update ( float t )
|
||||
Smoke::~Smoke()
|
||||
{
|
||||
#if 0
|
||||
std::cout << "BSphere: r:" << getBSphere()->radius
|
||||
<< " (" << getBSphere()->center[0]
|
||||
<< ", " << getBSphere()->center[1]
|
||||
<< ", " << getBSphere()->center[2]
|
||||
<< ")"
|
||||
<< std::endl;
|
||||
#endif
|
||||
getBSphere () -> setRadius ( 1000.0f ) ;
|
||||
ssgDeRefDelete(m_smokepuff);
|
||||
} // ~Smoke
|
||||
//-----------------------------------------------------------------------------
|
||||
void Smoke::update(float t)
|
||||
{
|
||||
bsphere.setRadius(1000.0f);
|
||||
ParticleSystem::update(t);
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Smoke::particle_create(int, Particle *p)
|
||||
{
|
||||
sgSetVec4 ( p -> m_col, 1, 1, 1, 1 ) ; /* initially white */
|
||||
sgSetVec3 ( p -> m_pos, 0, 0, 0 ) ; /* start off on the ground */
|
||||
sgSetVec3 ( p -> m_vel, 0, 0, 0 ) ;
|
||||
sgSetVec3 ( p -> m_acc, 0, 0, 2.0f ) ; /* Gravity */
|
||||
p -> m_size = .5f;
|
||||
p -> m_time_to_live = 0.5 ; /* Droplets evaporate after 5 seconds */
|
||||
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.8f;
|
||||
|
||||
const Vec3& hpr = m_kart->getHPR();
|
||||
const Vec3& xyz = m_kart->getXYZ();
|
||||
const btVector3 VEL = m_kart->getVelocity();
|
||||
|
||||
const float X_DIRECTION = cos (hpr.getHeading() - M_PI*0.5f); // Point at the rear
|
||||
const float Y_DIRECTION = sin (hpr.getHeading() - M_PI*0.5f); // Point at the rear
|
||||
// The origin of the smoke depends on the turn direction: either rear
|
||||
// left or rear right wheel - use the outer one.
|
||||
int wheel_number = m_kart->getSteerPercent()>0 ? 2 : 3;
|
||||
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));
|
||||
|
||||
p->m_pos[0] += X_DIRECTION * 0.7f;
|
||||
p->m_pos[1] += Y_DIRECTION * 0.7f;
|
||||
|
||||
const float ABS_VEL = sqrt((VEL.getX() * VEL.getX()) + (VEL.getY() * VEL.getY()));
|
||||
|
||||
p->m_vel[0] = X_DIRECTION * -ABS_VEL/2;
|
||||
p->m_vel[1] = Y_DIRECTION * -ABS_VEL/2;
|
||||
|
||||
p->m_vel[0] += sgCos ((float)(rand()%180));
|
||||
p->m_vel[1] += sgSin ((float)(rand()%180));
|
||||
p->m_vel[2] += sgSin ((float)(rand()%100));
|
||||
|
||||
getBSphere()->setCenter ( xyz.getX(), xyz.getY(), xyz.getZ() ) ;
|
||||
bsphere.setCenter ( xyz.getX(), xyz.getY(), xyz.getZ() ) ;
|
||||
} // particle_create
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Smoke::particle_update (float delta, int,
|
||||
Particle * particle)
|
||||
void Smoke::particle_update(float delta, int,
|
||||
Particle * particle)
|
||||
{
|
||||
particle->m_size += delta*2.0f;
|
||||
particle->m_size -= delta*.2f;
|
||||
particle->m_col[3] -= delta * 2.0f;
|
||||
|
||||
particle->m_pos[0] += particle->m_vel[0] * delta;
|
||||
particle->m_pos[1] += particle->m_vel[1] * delta;
|
||||
particle->m_pos[2] += particle->m_vel[2] * delta;
|
||||
} // particle_update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void Smoke::particle_delete (int , Particle* )
|
||||
{} // particle_delete
|
||||
{
|
||||
} // particle_delete
|
||||
|
||||
|
@ -29,11 +29,13 @@ class Kart;
|
||||
class Smoke : public ParticleSystem
|
||||
{
|
||||
private:
|
||||
Kart* m_kart;
|
||||
|
||||
/** The kart to which this smoke belongs. */
|
||||
Kart *m_kart;
|
||||
/** The texture to use. */
|
||||
ssgSimpleState *m_smokepuff;
|
||||
public:
|
||||
Smoke(Kart* kart, int num, float _create_rate,
|
||||
int _turn_to_face, float sz, float bsphere_size);
|
||||
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 );
|
||||
|
Loading…
x
Reference in New Issue
Block a user