First version of skid marks (though the skid marks are not yet
transparent, nor do they fade). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3616 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
8130ab34af
commit
7bb91862ff
@ -19,27 +19,25 @@
|
|||||||
|
|
||||||
#include "graphics/skid_marks.hpp"
|
#include "graphics/skid_marks.hpp"
|
||||||
|
|
||||||
#include "graphics/scene.hpp"
|
#include "graphics/irr_driver.hpp"
|
||||||
#include "karts/kart.hpp"
|
#include "karts/kart.hpp"
|
||||||
#include "physics/btKart.hpp"
|
#include "physics/btKart.hpp"
|
||||||
#include "utils/coord.hpp"
|
#include "utils/coord.hpp"
|
||||||
|
|
||||||
float SkidMarks::m_avoid_z_fighting = 0.0f;
|
float SkidMarks::m_avoid_z_fighting = 0.0f;
|
||||||
const float SkidMarks::m_start_alpha = 0.5f;
|
const int SkidMarks::m_start_alpha = 128;
|
||||||
|
|
||||||
/** Initialises empty skid marks. */
|
/** Initialises empty skid marks. */
|
||||||
SkidMarks::SkidMarks(const Kart& kart, float width) : m_kart(kart)
|
SkidMarks::SkidMarks(const Kart& kart, float width) : m_kart(kart)
|
||||||
{
|
{
|
||||||
#ifndef HAVE_IRRLICHT
|
m_width = width;
|
||||||
m_width = width;
|
m_material = new video::SMaterial();
|
||||||
m_skid_state = new ssgSimpleState();
|
m_material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
|
||||||
m_skid_state->ref();
|
m_material->AmbientColor = video::SColor(255, 0, 0, 0);
|
||||||
m_skid_state->enable(GL_BLEND);
|
m_material->DiffuseColor = video::SColor(255, 0, 0, 0);
|
||||||
m_skid_state->setMaterial(GL_SPECULAR, 0.0f, 0.0f, 0.0f, 1.0f);
|
m_material->Shininess = 0;
|
||||||
m_skid_state->setShininess(0.0f);
|
m_skid_marking = false;
|
||||||
m_skid_marking = false;
|
m_current = -1;
|
||||||
m_current = -1;
|
|
||||||
#endif
|
|
||||||
} // SkidMark
|
} // SkidMark
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -47,7 +45,7 @@ SkidMarks::SkidMarks(const Kart& kart, float width) : m_kart(kart)
|
|||||||
SkidMarks::~SkidMarks()
|
SkidMarks::~SkidMarks()
|
||||||
{
|
{
|
||||||
reset(); // remove all skid marks
|
reset(); // remove all skid marks
|
||||||
//ssgDeRefDelete(m_skid_state);
|
delete m_material;
|
||||||
} // ~SkidMarks
|
} // ~SkidMarks
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -55,10 +53,12 @@ SkidMarks::~SkidMarks()
|
|||||||
*/
|
*/
|
||||||
void SkidMarks::reset()
|
void SkidMarks::reset()
|
||||||
{
|
{
|
||||||
for(unsigned int i=0; i<m_left.size(); i++)
|
for(unsigned int i=0; i<m_nodes.size(); i++)
|
||||||
{
|
{
|
||||||
//stk_scene->remove(m_left[i]);
|
irr_driver->removeNode(m_nodes[i]);
|
||||||
//stk_scene->remove(m_right[i]);
|
irr_driver->removeMesh(m_meshes[i]);
|
||||||
|
delete m_left[i];
|
||||||
|
delete m_right[i];
|
||||||
}
|
}
|
||||||
m_left.clear();
|
m_left.clear();
|
||||||
m_right.clear();
|
m_right.clear();
|
||||||
@ -73,9 +73,8 @@ void SkidMarks::reset()
|
|||||||
*/
|
*/
|
||||||
void SkidMarks::update(float dt)
|
void SkidMarks::update(float dt)
|
||||||
{
|
{
|
||||||
#ifndef HAVE_IRRLICHT
|
float f = dt/stk_config->m_skid_fadeout_time*m_start_alpha;
|
||||||
float f = dt/stk_config->m_skid_fadeout_time;
|
for(unsigned int i=0; i<m_left.size(); i++)
|
||||||
for(int i=0; i<m_current; i++)
|
|
||||||
{
|
{
|
||||||
m_left[i]->fade(f);
|
m_left[i]->fade(f);
|
||||||
m_right[i]->fade(f);
|
m_right[i]->fade(f);
|
||||||
@ -104,8 +103,10 @@ void SkidMarks::update(float dt)
|
|||||||
delta.length2()<0.0001)
|
delta.length2()<0.0001)
|
||||||
{
|
{
|
||||||
m_skid_marking = false;
|
m_skid_marking = false;
|
||||||
m_left[m_current]->makeDList();
|
// The vertices and indices will not change anymore (till these
|
||||||
m_right[m_current]->makeDList();
|
// skid mark quads are deleted)
|
||||||
|
m_left[m_current]->setHardwareMappingHint(scene::EHM_STATIC);
|
||||||
|
m_right[m_current]->setHardwareMappingHint(scene::EHM_STATIC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,12 +120,19 @@ void SkidMarks::update(float dt)
|
|||||||
raycast_left.m_contactPointWS + delta);
|
raycast_left.m_contactPointWS + delta);
|
||||||
m_right[m_current]->add(raycast_right.m_contactPointWS-delta,
|
m_right[m_current]->add(raycast_right.m_contactPointWS-delta,
|
||||||
raycast_right.m_contactPointWS);
|
raycast_right.m_contactPointWS);
|
||||||
|
// Adjust the boundary box of the mesh to include the
|
||||||
|
// adjusted aabb of its buffers.
|
||||||
|
core::aabbox3df aabb=m_meshes[m_current]->getBoundingBox();
|
||||||
|
aabb.addInternalBox(m_left[m_current]->getAABB());
|
||||||
|
aabb.addInternalBox(m_right[m_current]->getAABB());
|
||||||
|
m_meshes[m_current]->setBoundingBox(aabb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently no skid marking
|
// Currently no skid marking
|
||||||
// -------------------------
|
// -------------------------
|
||||||
if((!m_kart.getControls().m_drift) || (fabsf(m_kart.getControls().m_steer) < 0.001f)) return; // no skidmarking
|
if((!m_kart.getControls().m_drift) ||
|
||||||
|
(fabsf(m_kart.getControls().m_steer) < 0.001f)) return; // no skidmarking
|
||||||
|
|
||||||
// not turning enough, don't draw skidmarks if kart is going straight ahead
|
// not turning enough, don't draw skidmarks if kart is going straight ahead
|
||||||
// this is even stricter for Ai karts, since they tend to use LOTS of skidding
|
// this is even stricter for Ai karts, since they tend to use LOTS of skidding
|
||||||
@ -154,116 +162,123 @@ void SkidMarks::update(float dt)
|
|||||||
|
|
||||||
SkidMarkQuads *smq_left = new SkidMarkQuads(raycast_left.m_contactPointWS,
|
SkidMarkQuads *smq_left = new SkidMarkQuads(raycast_left.m_contactPointWS,
|
||||||
raycast_left.m_contactPointWS + delta,
|
raycast_left.m_contactPointWS + delta,
|
||||||
m_skid_state, m_avoid_z_fighting);
|
m_material, m_avoid_z_fighting);
|
||||||
stk_scene->add(smq_left);
|
scene::SMesh *new_mesh = new scene::SMesh();
|
||||||
|
new_mesh->addMeshBuffer(smq_left);
|
||||||
|
|
||||||
m_avoid_z_fighting += 0.001f;
|
m_avoid_z_fighting += 0.001f;
|
||||||
if(m_avoid_z_fighting>0.01f) m_avoid_z_fighting = 0.0f;
|
if(m_avoid_z_fighting>0.01f) m_avoid_z_fighting = 0.0f;
|
||||||
SkidMarkQuads *smq_right = new SkidMarkQuads(raycast_right.m_contactPointWS
|
SkidMarkQuads *smq_right = new SkidMarkQuads(raycast_right.m_contactPointWS
|
||||||
- delta,
|
- delta,
|
||||||
raycast_right.m_contactPointWS,
|
raycast_right.m_contactPointWS,
|
||||||
m_skid_state,
|
m_material,
|
||||||
m_avoid_z_fighting);
|
m_avoid_z_fighting);
|
||||||
stk_scene->add(smq_right);
|
new_mesh->addMeshBuffer(smq_right);
|
||||||
|
scene::ISceneNode *new_node = irr_driver->addMesh(new_mesh);
|
||||||
|
|
||||||
m_current++;
|
m_current++;
|
||||||
if(m_current>=stk_config->m_max_skidmarks)
|
if(m_current>=stk_config->m_max_skidmarks)
|
||||||
m_current = 0;
|
m_current = 0;
|
||||||
if(m_current>=(int)m_left.size())
|
if(m_current>=(int)m_left.size())
|
||||||
{
|
{
|
||||||
m_left. push_back(smq_left );
|
m_left. push_back (smq_left );
|
||||||
m_right.push_back(smq_right);
|
m_right.push_back (smq_right);
|
||||||
|
m_meshes.push_back(new_mesh);
|
||||||
|
m_nodes.push_back (new_node);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stk_scene->remove(m_left [m_current]);
|
irr_driver->removeNode(m_nodes[m_current]);
|
||||||
stk_scene->remove(m_right[m_current]);
|
// Not necessary to delete m_nodes: removeNode
|
||||||
m_left [m_current] = smq_left;
|
// deletes the node since its refcount reaches zero.
|
||||||
m_right[m_current] = smq_right;
|
delete m_meshes[m_current];
|
||||||
|
delete m_left [m_current];
|
||||||
|
delete m_right [m_current];
|
||||||
|
|
||||||
|
m_left [m_current] = smq_left;
|
||||||
|
m_right [m_current] = smq_right;
|
||||||
|
m_meshes[m_current] = new_mesh;
|
||||||
|
m_nodes [m_current] = new_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
m_skid_marking = true;
|
m_skid_marking = true;
|
||||||
#endif
|
// More triangles are added each frame, so for now leave it
|
||||||
|
// to stream.
|
||||||
|
m_left[m_current]->setHardwareMappingHint(scene::EHM_STREAM);
|
||||||
|
m_right[m_current]->setHardwareMappingHint(scene::EHM_STREAM);
|
||||||
} // update
|
} // update
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
#ifndef HAVE_IRRLICHT
|
|
||||||
SkidMarks::SkidMarkQuads::SkidMarkQuads(const Vec3 &left, const Vec3 &right,
|
SkidMarks::SkidMarkQuads::SkidMarkQuads(const Vec3 &left, const Vec3 &right,
|
||||||
ssgSimpleState *state, float z_offset)
|
video::SMaterial *material,
|
||||||
: ssgVtxTable(GL_QUAD_STRIP,
|
float z_offset)
|
||||||
new ssgVertexArray,
|
: scene::SMeshBuffer()
|
||||||
new ssgNormalArray,
|
|
||||||
new ssgTexCoordArray,
|
|
||||||
new ssgColourArray )
|
|
||||||
{
|
{
|
||||||
m_z_offset = z_offset;
|
m_z_offset = z_offset;
|
||||||
m_fade_out = 0.0f;
|
m_fade_out = 0.0f;
|
||||||
// If only one colours and/or normal is specified, it is used for
|
|
||||||
// all fertices in the table.
|
m_material = material;
|
||||||
sgVec4 colour;
|
Material = *material;
|
||||||
sgSetVec4(colour, 0.00f, 0.00f, 0.00f, SkidMarks::m_start_alpha);
|
m_aabb = core::aabbox3df(left.toIrrVector());
|
||||||
colours->add(colour);
|
|
||||||
sgVec3 normal;
|
|
||||||
sgSetVec3(normal, 0, 0, 1);
|
|
||||||
normals->add(normal);
|
|
||||||
|
|
||||||
setState(state);
|
|
||||||
m_aabb_min = Vec3(10000);
|
|
||||||
m_aabb_max = Vec3(-10000);
|
|
||||||
add(left, right);
|
add(left, right);
|
||||||
|
|
||||||
} // SkidMarkQuads
|
} // SkidMarkQuads
|
||||||
#endif
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
void SkidMarks::SkidMarkQuads::add(const Vec3 &left, const Vec3 &right)
|
||||||
|
{
|
||||||
|
// The skid marks must be raised slightly higher, otherwise it blends
|
||||||
|
// too much with the track.
|
||||||
|
int n = Vertices.size();
|
||||||
|
|
||||||
|
video::S3DVertex v;
|
||||||
|
v.Color = m_material->DiffuseColor;
|
||||||
|
v.Color.setAlpha(m_start_alpha);
|
||||||
|
v.Pos = left.toIrrVector();
|
||||||
|
v.Pos.Y += m_z_offset;
|
||||||
|
v.Normal = core::vector3df(0, 1, 0);
|
||||||
|
Vertices.push_back(v);
|
||||||
|
v.Pos = right.toIrrVector();
|
||||||
|
v.Pos.Y += m_z_offset;
|
||||||
|
Vertices.push_back(v);
|
||||||
|
// Out of the box Irrlicht only supports triangle meshes and not
|
||||||
|
// triangle strips. Since this is a strip it would be more efficient
|
||||||
|
// to use a special triangle strip scene node.
|
||||||
|
if(n>=2)
|
||||||
|
{
|
||||||
|
Indices.push_back(n-2);
|
||||||
|
Indices.push_back(n );
|
||||||
|
Indices.push_back(n-1);
|
||||||
|
Indices.push_back(n-1);
|
||||||
|
Indices.push_back(n );
|
||||||
|
Indices.push_back(n+1);
|
||||||
|
}
|
||||||
|
// Adjust the axis-aligned boundary boxes.
|
||||||
|
m_aabb.addInternalPoint(left.toIrrVector() );
|
||||||
|
m_aabb.addInternalPoint(right.toIrrVector());
|
||||||
|
setBoundingBox(m_aabb);
|
||||||
|
|
||||||
|
setDirty();
|
||||||
|
} // add
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
/** Fades the current skid marks.
|
/** Fades the current skid marks.
|
||||||
* \param f fade factor.
|
* \param f fade factor.
|
||||||
*/
|
*/
|
||||||
void SkidMarks::SkidMarkQuads::fade(float f)
|
void SkidMarks::SkidMarkQuads::fade(float f)
|
||||||
{
|
{
|
||||||
#ifndef HAVE_IRRLICHT
|
m_fade_out += f*255;
|
||||||
m_fade_out += f;
|
if(m_fade_out>0.1f*255)
|
||||||
// Only actually change the alpha value every 0.1. Otherwise we can't use
|
|
||||||
// display lists, which makes skid marks too slow
|
|
||||||
if(m_fade_out>0.1f)
|
|
||||||
{
|
{
|
||||||
//float *c=colours->get(0);
|
video::SColor &c=Material.DiffuseColor;
|
||||||
c[3] -= m_fade_out;
|
int a=c.getAlpha();
|
||||||
if(c[3]<0.0f) c[3]=0.0f;
|
a -= a<m_fade_out ? a : m_fade_out;
|
||||||
//makeDList();
|
c.setAlpha(a);
|
||||||
|
for(unsigned int i=0; i<Vertices.size(); i++)
|
||||||
|
{
|
||||||
|
Vertices[i].Color.setAlpha(a);
|
||||||
|
}
|
||||||
m_fade_out = 0.0f;
|
m_fade_out = 0.0f;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} // fade
|
} // fade
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void SkidMarks::SkidMarkQuads::recalcBSphere()
|
|
||||||
{
|
|
||||||
#ifndef HAVE_IRRLICHT
|
|
||||||
Vec3 diff = m_aabb_max - m_aabb_min;
|
|
||||||
bsphere.setRadius(diff.length()*0.5f);
|
|
||||||
Vec3 center = (m_aabb_min + m_aabb_max)*0.5f;
|
|
||||||
bsphere.setCenter(center.toFloat());
|
|
||||||
#endif
|
|
||||||
} // recalcBSphere
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void SkidMarks::SkidMarkQuads::add(const Vec3 &left, const Vec3 &right)
|
|
||||||
{
|
|
||||||
#ifndef HAVE_IRRLICHT
|
|
||||||
// The skid marks must be raised slightly higher, otherwise it blends
|
|
||||||
// too much with the track.
|
|
||||||
sgVec3 l;
|
|
||||||
sgCopyVec3(l, left.toFloat());
|
|
||||||
l[2]+=0.01f+m_z_offset;
|
|
||||||
sgVec3 r;
|
|
||||||
sgCopyVec3(r, right.toFloat());
|
|
||||||
r[2]+=0.01f;
|
|
||||||
vertices->add(l);
|
|
||||||
vertices->add(r);
|
|
||||||
// Adjust the axis-aligned boundary boxes.
|
|
||||||
m_aabb_min.min(left);m_aabb_min.min(right);
|
|
||||||
m_aabb_max.max(left);m_aabb_max.max(right);
|
|
||||||
|
|
||||||
dirtyBSphere();
|
|
||||||
#endif
|
|
||||||
} // add
|
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "irrlicht.h"
|
||||||
|
using namespace irr;
|
||||||
|
|
||||||
#include "utils/vec3.hpp"
|
#include "utils/vec3.hpp"
|
||||||
|
|
||||||
class Coord;
|
class Coord;
|
||||||
@ -31,19 +34,21 @@ class Kart;
|
|||||||
class SkidMarks
|
class SkidMarks
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/** Reference to the kart to which these skidmarks belong. */
|
/** Reference to the kart to which these skidmarks belong. */
|
||||||
const Kart &m_kart;
|
const Kart &m_kart;
|
||||||
/** True if the kart was skidding in the previous frame. */
|
/** True if the kart was skidding in the previous frame. */
|
||||||
bool m_skid_marking;
|
bool m_skid_marking;
|
||||||
/** Reduce effect of Z-fighting. */
|
/** Reduce effect of Z-fighting. */
|
||||||
float m_width;
|
float m_width;
|
||||||
/** Index of current (last added) skid mark quad. */
|
/** Index of current (last added) skid mark quad. */
|
||||||
int m_current;
|
int m_current;
|
||||||
|
/** Initial alpha value. */
|
||||||
|
static const int m_start_alpha;
|
||||||
|
|
||||||
/** Initial alpha value. */
|
/** Material to use for the skid marks. */
|
||||||
static const float m_start_alpha;
|
video::SMaterial *m_material;
|
||||||
|
|
||||||
class SkidMarkQuads //: public ssgVtxTable
|
class SkidMarkQuads : public scene::SMeshBuffer
|
||||||
{
|
{
|
||||||
/** Used to move skid marks at the same location slightly on
|
/** Used to move skid marks at the same location slightly on
|
||||||
* top of each other to avoid a 'wobbling' effect when sometines
|
* top of each other to avoid a 'wobbling' effect when sometines
|
||||||
@ -54,23 +59,31 @@ private:
|
|||||||
float m_fade_out;
|
float m_fade_out;
|
||||||
/** For culling, we need the overall radius of the skid marks. We
|
/** For culling, we need the overall radius of the skid marks. We
|
||||||
* approximate this by maintaining an axis-aligned boundary box. */
|
* approximate this by maintaining an axis-aligned boundary box. */
|
||||||
Vec3 m_aabb_min, m_aabb_max;
|
core::aabbox3df m_aabb;
|
||||||
|
/** Material to use for the skid marks. */
|
||||||
|
video::SMaterial *m_material;
|
||||||
public:
|
public:
|
||||||
#ifndef HAVE_IRRLICHT
|
|
||||||
SkidMarkQuads (const Vec3 &left, const Vec3 &right,
|
SkidMarkQuads (const Vec3 &left, const Vec3 &right,
|
||||||
ssgSimpleState *state, float z_offset);
|
video::SMaterial *material, float z_offset);
|
||||||
#endif
|
|
||||||
void recalcBSphere();
|
|
||||||
void add (const Vec3 &left,
|
void add (const Vec3 &left,
|
||||||
const Vec3 &right);
|
const Vec3 &right);
|
||||||
void fade (float f);
|
void fade (float f);
|
||||||
|
/** Returns the aabb of this skid mark quads. */
|
||||||
|
const core::aabbox3df &getAABB() { return m_aabb; }
|
||||||
}; // SkidMarkQuads
|
}; // SkidMarkQuads
|
||||||
|
|
||||||
/** Two skidmark objects for the left and right wheel. */
|
/** Two skidmark objects for the left and right wheel. */
|
||||||
std::vector <SkidMarkQuads *> m_left, m_right;
|
std::vector<SkidMarkQuads *> m_left, m_right;
|
||||||
/** The state for colour etc. */
|
|
||||||
//ssgSimpleState *m_skid_state;
|
/** The meshes - each mesh containing two mesh buffers (left/right). */
|
||||||
static float m_avoid_z_fighting;
|
std::vector<scene::IMesh *> m_meshes;
|
||||||
|
|
||||||
|
/** The nodes where each left/right pair is attached to. */
|
||||||
|
std::vector<scene::ISceneNode *> m_nodes;
|
||||||
|
|
||||||
|
/** Shared static so that consecutive skidmarks are at a slightly
|
||||||
|
* different height. */
|
||||||
|
static float m_avoid_z_fighting;
|
||||||
public:
|
public:
|
||||||
SkidMarks(const Kart& kart, float width=0.2f);
|
SkidMarks(const Kart& kart, float width=0.2f);
|
||||||
~SkidMarks();
|
~SkidMarks();
|
||||||
|
Loading…
Reference in New Issue
Block a user