Added a test version for slipsteam support. Note that besides

tweaking parameter (and potentially the implementation) there is
currently no graphical indication that you are slipstreaming,
or using a speed boost due to slipstreaming.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3847 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2009-08-13 04:58:37 +00:00
parent 2b5a273b95
commit 83e19ff817
9 changed files with 158 additions and 26 deletions

View File

@ -96,6 +96,12 @@
(time-till-max-skid 0.4 ) ;; Time till maximum skidding is reached. (time-till-max-skid 0.4 ) ;; Time till maximum skidding is reached.
(skid-visual 0.16) ;; Additional graphical rotation of kart. (skid-visual 0.16) ;; Additional graphical rotation of kart.
(slipstream-length 5 ) ;; How far behind a kart slipstream works
(slipstream-time 5 ) ;; How many seconds of sstream give
;; maximum benefit
(slipstream-add-power 3 ) ;; Additional power due to sstreaming.
;; 1 = +100%
;; Bullet physics attributes ;; Bullet physics attributes
(brake-factor 11.0 ) (brake-factor 11.0 )
;; Defines the smallest turn radius at lowest speed (4.64 m at ;; Defines the smallest turn radius at lowest speed (4.64 m at

View File

@ -71,6 +71,7 @@ Kart::Kart (const std::string& kart_name, int position,
m_eliminated = false; m_eliminated = false;
m_finished_race = false; m_finished_race = false;
m_finish_time = 0.0f; m_finish_time = 0.0f;
m_slipstream_time = 0.0f;
m_shadow_enabled = false; m_shadow_enabled = false;
m_shadow = NULL; m_shadow = NULL;
m_smoke_system = NULL; m_smoke_system = NULL;
@ -111,6 +112,15 @@ Kart::Kart (const std::string& kart_name, int position,
} }
loadData(); loadData();
float l = m_kart_properties->getSlipstreamLength();
Vec3 p0(-getKartWidth()*0.5f, -getKartLength()*0.5f, 0);
Vec3 p1(-getKartWidth()*0.5f, -getKartLength()*0.5f-l, 0);
Vec3 p2( getKartWidth()*0.5f, -getKartLength()*0.5f-l, 0);
Vec3 p3( getKartWidth()*0.5f, -getKartLength()*0.5f, 0);
m_slipstream_original_area = new Quad(p0, p1, p2, p3);
m_slipstream_area = new Quad(p0, p1, p2, p3);
reset(); reset();
} // Kart } // Kart
@ -261,6 +271,8 @@ Kart::~Kart()
{ {
delete m_kart_chassis.getChildShape(i); delete m_kart_chassis.getChildShape(i);
} }
delete m_slipstream_original_area;
delete m_slipstream_area;
} // ~Kart } // ~Kart
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -561,6 +573,7 @@ void Kart::update(float dt)
m_water_splash_system->update(dt); m_water_splash_system->update(dt);
m_nitro->update(dt); m_nitro->update(dt);
} // UserConfigParams::m_graphical_effects } // UserConfigParams::m_graphical_effects
updatePhysics(dt); updatePhysics(dt);
Moveable::update(dt); Moveable::update(dt);
@ -723,6 +736,65 @@ float Kart::handleNitro(float dt)
} // handleNitro } // handleNitro
//-----------------------------------------------------------------------------
/** This function manages slipstreaming. It adds up the time a kart was
* slipstreaming, and returns the potential power boost due to coming
* out of slipstream.
*/
float Kart::handleSlipstream(float dt)
{
m_slipstream_original_area->transform(getTrans(), m_slipstream_area);
// Note: there is a slight inconsistency here: Karts are updated one
// after another. So if the position of this kart is compared with the
// slipstream area of a kart already updated, it will use the new
// slipstream area of that kart, but for karts not yet updated the
// old position will be used. The differences should not be noticable,
// and simplifies the update process (which would otherwise have to be
// done in two stages).
unsigned int n = race_manager->getNumKarts();
bool is_sstreaming = false;
for(unsigned int i=0; i<n; i++)
{
Kart *kart = race_manager->getKart(i);
// Don't test for slipstream with itself.
if(kart==this) continue;
// Quick test: the kart must be not more than
// slipstream length+kart_length() away from the other kart
Vec3 delta = getXYZ() - kart->getXYZ();
float l = kart->m_kart_properties->getSlipstreamLength() + kart->getKartLength()*0.5f;
if(delta.length2_2d() > l*l) continue;
if(kart->m_slipstream_area->pointInQuad(getXYZ()))
{
is_sstreaming = true;
break;
}
}
float add_power = 0;
if(m_slipstream_time >0 && !is_sstreaming)
{
// Kart is using slipstream advantage
add_power = getMaxPower() * m_kart_properties->getSlipstreamAddPower();
m_slipstream_time = std::max(m_slipstream_time - dt, 0.0f);
printf("Add power %f, t=%f for '%s'\n", m_slipstream_time, add_power, getIdent().c_str());
}
else if(is_sstreaming)
{
// Kart is collecting sliptstream advantage
m_slipstream_time = std::min(m_slipstream_time + dt,
m_kart_properties->getSlipstreamTime());
}
return add_power;
} // handleSlipstream
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/** This function is called when the race starts. Up to then all brakes are /** This function is called when the race starts. Up to then all brakes are
braking (to avoid the kart from rolling downhill), but they need to be set braking (to avoid the kart from rolling downhill), but they need to be set
@ -766,8 +838,10 @@ void Kart::beep()
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void Kart::updatePhysics (float dt) void Kart::updatePhysics (float dt)
{ {
m_bounce_back_time-=dt; m_bounce_back_time-=dt;
float engine_power = getActualWheelForce() + handleNitro(dt); float engine_power = getActualWheelForce() + handleNitro(dt)
+ handleSlipstream(dt);
if(m_attachment.getType()==ATTACH_PARACHUTE) engine_power*=0.2f; if(m_attachment.getType()==ATTACH_PARACHUTE) engine_power*=0.2f;
if(m_controls.m_accel) // accelerating if(m_controls.m_accel) // accelerating

View File

@ -41,6 +41,7 @@ class SFXBase;
class btUprightConstraint; class btUprightConstraint;
class btKart; class btKart;
class btRaycastVehicle::btVehicleTuning; class btRaycastVehicle::btVehicleTuning;
class Quad;
class Kart : public TerrainInfo, public Moveable class Kart : public TerrainInfo, public Moveable
{ {
@ -49,14 +50,14 @@ private:
unsigned int m_world_kart_id; // index of kart in world unsigned int m_world_kart_id; // index of kart in world
float m_skidding; ///< Accumulated skidding factor. float m_skidding; ///< Accumulated skidding factor.
protected:
Attachment m_attachment;
Powerup m_powerup;
int m_race_position; // current race position (1-numKarts)
int m_initial_position; // initial position of kart int m_initial_position; // initial position of kart
int m_race_position; // current race position (1-numKarts)
KartControl m_controls; // The position of the karts controls protected: // Used by the AI atm
KartControl m_controls; // The kart controls (e.g. steering, fire, ...)
Powerup m_powerup;
float m_zipper_time_left; /**<Zipper time left. */
Attachment m_attachment;
private:
float m_max_speed; // maximum speed of the kart, computed from float m_max_speed; // maximum speed of the kart, computed from
/** Depending on terrain a certain reduction to the maximum speed applies. /** Depending on terrain a certain reduction to the maximum speed applies.
* This reduction is accumulated in m_max_speed_reduction. */ * This reduction is accumulated in m_max_speed_reduction. */
@ -64,11 +65,11 @@ protected:
float m_power_reduction; float m_power_reduction;
float m_max_gear_rpm; /**<Maximum engine rpm's for the current gear*/ float m_max_gear_rpm; /**<Maximum engine rpm's for the current gear*/
float m_max_speed_reverse_ratio; float m_max_speed_reverse_ratio;
float m_zipper_time_left; /**<Zipper time left. */
float m_bounce_back_time; /**<A short time after a collision acceleration float m_bounce_back_time; /**<A short time after a collision acceleration
* is disabled to allow the karts to bounce back*/ * is disabled to allow the karts to bounce back*/
// physics parameters, storing it saves time // Bullet physics parameters
// -------------------------
btRaycastVehicle::btVehicleTuning btRaycastVehicle::btVehicleTuning
*m_tuning; *m_tuning;
btCompoundShape m_kart_chassis; btCompoundShape m_kart_chassis;
@ -76,10 +77,13 @@ protected:
btKart *m_vehicle; btKart *m_vehicle;
btUprightConstraint *m_uprightConstraint; btUprightConstraint *m_uprightConstraint;
private:
/** The amount of energy collected by hitting coins. */ /** The amount of energy collected by hitting coins. */
float m_collected_energy; float m_collected_energy;
Shadow *m_shadow; /**<The shadow of the kart. */
// Graphical effects
// -----------------
/** The shadow of a kart. */
Shadow *m_shadow;
/** If a kart is flying, the shadow is disabled (since it is /** If a kart is flying, the shadow is disabled (since it is
* stuck to the kart, i.e. the shadow would be flying, too). */ * stuck to the kart, i.e. the shadow would be flying, too). */
bool m_shadow_enabled; bool m_shadow_enabled;
@ -88,9 +92,8 @@ private:
/** Water splash when driving in water. */ /** Water splash when driving in water. */
WaterSplash *m_water_splash_system; WaterSplash *m_water_splash_system;
/** Fire when using a nitro. */ /** Graphical effect when using a nitro. */
Nitro *m_nitro; Nitro *m_nitro;
float m_wheel_rotation; float m_wheel_rotation;
/** For each wheel it stores the suspension length after the karts are at /** For each wheel it stores the suspension length after the karts are at
* the start position, i.e. the suspension will be somewhat compressed. * the start position, i.e. the suspension will be somewhat compressed.
@ -101,6 +104,17 @@ private:
/** The skidmarks object for this kart. */ /** The skidmarks object for this kart. */
SkidMarks *m_skidmarks; SkidMarks *m_skidmarks;
// Variables for slipstreaming
// ---------------------------
/** The quad inside which another kart is considered to be slipstreaming.
* This value is current area, i.e. takes the kart position into account. */
Quad *m_slipstream_area;
/** This is slipstream area if the kart is at 0,0,0 without rotation. From
* this value m_slipstream_area is computed by applying the kart transform. */
Quad *m_slipstream_original_area;
/** The time a kart was in slipstream. */
float m_slipstream_time;
float m_finish_time; float m_finish_time;
bool m_finished_race; bool m_finished_race;
@ -119,6 +133,9 @@ private:
SFXBase *m_goo_sound; SFXBase *m_goo_sound;
float m_time_last_crash; float m_time_last_crash;
float handleSlipstream(float dt);
void updatePhysics(float dt);
protected: protected:
float m_rescue_pitch, m_rescue_roll; float m_rescue_pitch, m_rescue_roll;
const KartProperties *m_kart_properties; const KartProperties *m_kart_properties;
@ -179,14 +196,12 @@ public:
bool hasFinishedRace () const { return m_finished_race; } bool hasFinishedRace () const { return m_finished_race; }
void endRescue (); void endRescue ();
void getClosestKart (float *cdist, int *closest); void getClosestKart (float *cdist, int *closest);
void updatePhysics (float dt);
bool hasViewBlockedByPlunger() const bool hasViewBlockedByPlunger() const
{ return m_view_blocked_by_plunger > 0; } { return m_view_blocked_by_plunger > 0; }
void blockViewWithPlunger() { m_view_blocked_by_plunger = 10; } void blockViewWithPlunger() { m_view_blocked_by_plunger = 10; }
/** /** Returns a bullet transform object located at the kart's position
returns a bullet transform object located at the kart's position
and oriented in the direction the kart is going. Can be useful and oriented in the direction the kart is going. Can be useful
e.g. to calculate the starting point and direction of projectiles e.g. to calculate the starting point and direction of projectiles
*/ */

View File

@ -65,6 +65,7 @@ KartProperties::KartProperties() : m_icon_material(0)
m_rubber_band_duration = m_time_till_max_skid = m_rubber_band_duration = m_time_till_max_skid =
m_skid_decrease = m_skid_increase = m_skid_visual = m_skid_max = m_skid_decrease = m_skid_increase = m_skid_visual = m_skid_max =
m_camera_max_accel = m_camera_max_brake = m_camera_max_accel = m_camera_max_brake =
m_slipstream_length = m_slipstream_time = m_slipstream_add_power =
m_camera_distance = UNDEFINED; m_camera_distance = UNDEFINED;
m_gravity_center_shift = Vec3(UNDEFINED); m_gravity_center_shift = Vec3(UNDEFINED);
m_has_skidmarks = true; m_has_skidmarks = true;
@ -260,6 +261,9 @@ void KartProperties::getAllData(const lisp::Lisp* lisp)
lisp->get("has-skidmarks", m_has_skidmarks ); lisp->get("has-skidmarks", m_has_skidmarks );
lisp->get("skid-max", m_skid_max ); lisp->get("skid-max", m_skid_max );
lisp->get("skid-visual", m_skid_visual ); lisp->get("skid-visual", m_skid_visual );
lisp->get("slipstream-length", m_slipstream_length );
lisp->get("slipstream-time", m_slipstream_time );
lisp->get("slipstream-add-power", m_slipstream_add_power );
lisp->getVector("groups", m_groups ); lisp->getVector("groups", m_groups );
@ -348,6 +352,9 @@ void KartProperties::checkAllSet(const std::string &filename)
CHECK_NEG(m_skid_increase, "skid-increase" ); CHECK_NEG(m_skid_increase, "skid-increase" );
CHECK_NEG(m_skid_max, "skid-max" ); CHECK_NEG(m_skid_max, "skid-max" );
CHECK_NEG(m_skid_visual, "skid-visual" ); CHECK_NEG(m_skid_visual, "skid-visual" );
CHECK_NEG(m_slipstream_length, "slipstream-length" );
CHECK_NEG(m_slipstream_time, "slipstream-time" );
CHECK_NEG(m_slipstream_add_power, "slipstream-add-power" );
CHECK_NEG(m_camera_max_accel, "camera-max-accel" ); CHECK_NEG(m_camera_max_accel, "camera-max-accel" );
CHECK_NEG(m_camera_max_brake, "camera-max-brake" ); CHECK_NEG(m_camera_max_brake, "camera-max-brake" );

View File

@ -126,6 +126,11 @@ private:
float m_skid_visual; /**< Additional rotation of 3d model float m_skid_visual; /**< Additional rotation of 3d model
* when skidding. */ * when skidding. */
float m_slipstream_length; /**< How far behind a kart slipstreaming
* is effective. */
float m_slipstream_time; /**< Time after which sstream has maxium
* benefit. */
float m_slipstream_add_power; /**< Additional power due to sstreaming. */
float m_skid_max; /**< Maximal increase of steering when float m_skid_max; /**< Maximal increase of steering when
* skidding. */ * skidding. */
float m_skid_increase; /**< Skidding is multiplied by this when float m_skid_increase; /**< Skidding is multiplied by this when
@ -217,6 +222,12 @@ public:
float getRubberBandDuration () const {return m_rubber_band_duration; } float getRubberBandDuration () const {return m_rubber_band_duration; }
/** Returns additional rotation of 3d model when skidding. */ /** Returns additional rotation of 3d model when skidding. */
float getSkidVisual () const {return m_skid_visual; } float getSkidVisual () const {return m_skid_visual; }
/** Returns how far behind a kart slipstreaming works. */
float getSlipstreamLength () const {return m_slipstream_length; }
/** Returns time after which slipstream has maximum effect. */
float getSlipstreamTime () const {return m_slipstream_time; }
/** Returns additional power due to slipstreaming. */
float getSlipstreamAddPower () const {return m_slipstream_add_power; }
/** Returns the maximum factor by which the steering angle can be increased. */ /** Returns the maximum factor by which the steering angle can be increased. */
float getMaxSkid () const {return m_skid_max; } float getMaxSkid () const {return m_skid_max; }
/** Returns the factor by which m_skidding is multiplied when the kart is /** Returns the factor by which m_skidding is multiplied when the kart is

View File

@ -621,7 +621,7 @@ void DefaultRobot::handleAcceleration( const float DELTA )
//Find if any player is ahead of this kart //Find if any player is ahead of this kart
bool player_winning = false; bool player_winning = false;
for(unsigned int i = 0; i < race_manager->getNumPlayers(); ++i ) for(unsigned int i = 0; i < race_manager->getNumPlayers(); ++i )
if( m_race_position > RaceManager::getPlayerKart(i)->getPosition() ) if( getPosition() > RaceManager::getPlayerKart(i)->getPosition() )
{ {
player_winning = true; player_winning = true;
break; break;

View File

@ -21,6 +21,8 @@
#include "irrlicht.h" #include "irrlicht.h"
#include "LinearMath/btTransform.h"
/** Constructor, takes 4 points. */ /** Constructor, takes 4 points. */
Quad::Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3) Quad::Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3)
{ {
@ -35,7 +37,7 @@ Quad::Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3)
* \param v The vertex array in which to set the vertices. * \param v The vertex array in which to set the vertices.
* \param color The color to use for this quad. * \param color The color to use for this quad.
*/ */
void Quad::setVertices(video::S3DVertex *v, const video::SColor &color) const void Quad::getVertices(video::S3DVertex *v, const video::SColor &color) const
{ {
// Eps is used to raise the track debug quads a little bit higher than // Eps is used to raise the track debug quads a little bit higher than
// the ground, so that they are actually visible. // the ground, so that they are actually visible.
@ -86,4 +88,20 @@ bool Quad::pointInQuad(const Vec3& p) const
sideOfLine2D(m_p[3], m_p[0], p) >= 0.0; sideOfLine2D(m_p[3], m_p[0], p) >= 0.0;
} }
} // pointInQuad } // pointInQuad
// ----------------------------------------------------------------------------
/** Transforms a quad by a given transform (i.e. translation+rotation). This
* function does not modify this quad, the results are stored in the quad
* specified as parameter. These functions are used for slipstreaming to
* determine the slipstream area from the original value (kart at 0,0,0 and
* no rotation) to the current value.
* \param t The transform to apply.
* \param result The quad which stores the result.
*/
void Quad::transform(const btTransform &t, Quad *result) const
{
result->m_p[0] = t(m_p[0]);
result->m_p[1] = t(m_p[1]);
result->m_p[2] = t(m_p[2]);
result->m_p[3] = t(m_p[3]);
} // transform

View File

@ -26,6 +26,7 @@
#include "utils/vec3.hpp" #include "utils/vec3.hpp"
class btTransform;
class Quad class Quad
{ {
private: private:
@ -43,9 +44,9 @@ private:
public: public:
Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3); Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3);
void setVertices(video::S3DVertex *v, const video::SColor &color) const; void getVertices(video::S3DVertex *v, const video::SColor &color) const;
bool pointInQuad(const Vec3& p) const; bool pointInQuad(const Vec3& p) const;
void transform(const btTransform &t, Quad *result) const;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the i-th. point of a quad. */ /** Returns the i-th. point of a quad. */
const Vec3& operator[](int i) const {return m_p[i]; } const Vec3& operator[](int i) const {return m_p[i]; }

View File

@ -187,7 +187,7 @@ void QuadGraph::createMesh()
c.setRed (i%2 ? 255 : 0); c.setRed (i%2 ? 255 : 0);
c.setBlue(i%2 ? 0 : 255); c.setBlue(i%2 ? 0 : 255);
// Transfer the 4 points of the current quad to the list of vertices // Transfer the 4 points of the current quad to the list of vertices
m_all_quads->getQuad(i).setVertices(new_v+4*i, c); m_all_quads->getQuad(i).getVertices(new_v+4*i, c);
// Set up the indices for the triangles // Set up the indices for the triangles
// (note, afaik with opengl we could use quads directly, but the code // (note, afaik with opengl we could use quads directly, but the code