Made skidding more controllable: now once the kart
started to skid, you can influence the turn radius to a certain degree (stk_config.xml, reduce-turn-min and -max). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10954 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
f0e65ed092
commit
73176a8d28
@ -183,9 +183,9 @@
|
||||
which is used to reduce the turn angle used to reduce the turn angle. -->
|
||||
<skid increase="1.05" decrease="0.95" max="2.5" time-till-max="0.5"
|
||||
visual="1.0" visual-time="0"
|
||||
time-till-bonus="1.5 2.5"
|
||||
time-till-bonus="1.5 2.5"
|
||||
bonus-speed="100 200" bonus-time="3.0 4.0"
|
||||
post-skid-rotate-factor="1" reduce-turn-min="0.6"
|
||||
post-skid-rotate-factor="1" reduce-turn-min="0.3"
|
||||
reduce-turn-max="0.8"/>
|
||||
|
||||
<!-- Slipstream: length: How far behind a kart slipstream works
|
||||
|
@ -72,13 +72,16 @@ public:
|
||||
virtual void finishedRace (float time) {};
|
||||
virtual bool isPlayerController () const {return false;}
|
||||
virtual bool isNetworkController() const {return false;}
|
||||
virtual const irr::core::stringw& getNamePostfix() const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Default: ignore actions. Only PlayerController get them. */
|
||||
virtual void action (PlayerAction action, int value) {}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Callback whenever a new lap is triggered. Used by the AI
|
||||
* to trigger a recomputation of the way to use. */
|
||||
virtual void newLap (int lap) {}
|
||||
virtual const irr::core::stringw& getNamePostfix() const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void skidBonusTriggered() {}
|
||||
}; // Controller
|
||||
|
||||
#endif
|
||||
|
@ -245,6 +245,15 @@ void PlayerController::steer(float dt, int steer_val)
|
||||
|
||||
} // steer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Callback when the skidding bonus is triggered. The player controller
|
||||
* resets the current steering to 0, which makes the kart easier to control.
|
||||
*/
|
||||
void PlayerController::skidBonusTriggered()
|
||||
{
|
||||
m_controls->m_steer = 0;
|
||||
} // skidBonusTriggered
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Updates the player kart, called once each timestep.
|
||||
*/
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
void handleZipper (bool play_sound);
|
||||
void collectedItem (const Item &item, int add_info=-1,
|
||||
float previous_energy=0);
|
||||
virtual void skidBonusTriggered();
|
||||
virtual void setPosition (int p);
|
||||
virtual void finishedRace (float time);
|
||||
bool isPlayerController() const {return true;}
|
||||
|
@ -328,7 +328,7 @@ void Kart::setController(Controller *controller)
|
||||
m_controller = controller;
|
||||
} // setController
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Sets the position in race this kart has .
|
||||
* The position in this race for this kart (1<=p<=n)
|
||||
*/
|
||||
@ -339,6 +339,7 @@ void Kart::setPosition(int p)
|
||||
} // setPosition
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/** Returns a transform that will align an object with the kart: the heading
|
||||
* and the pitch will be set appropriately. A custom pitch value can be
|
||||
* specified in order to overwrite the terrain pitch (which would be used
|
||||
@ -1627,9 +1628,7 @@ void Kart::updatePhysics(float dt)
|
||||
m_skidding->update(dt, isOnGround(), m_controls.m_steer,
|
||||
m_controls.m_skid);
|
||||
|
||||
float steering = m_skidding->getSteering(m_controls.m_steer,
|
||||
getMaxSteerAngle());
|
||||
|
||||
float steering = getMaxSteerAngle() * m_skidding->getSteeringFraction();
|
||||
m_vehicle->setSteeringValue(steering, 0);
|
||||
m_vehicle->setSteeringValue(steering, 1);
|
||||
|
||||
@ -2071,7 +2070,7 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
|
||||
m_kart_gfx->resizeBox(KartGFX::KGFX_ZIPPER, getSpeed(), dt);
|
||||
|
||||
Moveable::updateGraphics(dt, center_shift,
|
||||
btQuaternion(m_skidding->getVisualSkidOffset(),
|
||||
btQuaternion(m_skidding->getVisualSkidRotation(),
|
||||
0, 0));
|
||||
|
||||
/*
|
||||
@ -2105,7 +2104,8 @@ void Kart::updateGraphics(float dt, const Vec3& offset_xyz,
|
||||
// ----------------------------------------------------------------------------
|
||||
btQuaternion Kart::getVisualRotation() const
|
||||
{
|
||||
return getRotation() * btQuaternion(m_skidding->getVisualSkidOffset(), 0, 0);
|
||||
return getRotation()
|
||||
* btQuaternion(m_skidding->getVisualSkidRotation(), 0, 0);
|
||||
} // getVisualRotation
|
||||
|
||||
|
||||
|
@ -27,8 +27,9 @@
|
||||
*/
|
||||
Skidding::Skidding(Kart *kart, const SkiddingProperties *sp)
|
||||
{
|
||||
m_kart = kart;
|
||||
m_kart = kart;
|
||||
copyFrom(sp);
|
||||
m_skid_reduce_turn_delta = m_skid_reduce_turn_max - m_skid_reduce_turn_min;
|
||||
reset();
|
||||
} // Skidding
|
||||
|
||||
@ -37,28 +38,61 @@ Skidding::Skidding(Kart *kart, const SkiddingProperties *sp)
|
||||
*/
|
||||
void Skidding::reset()
|
||||
{
|
||||
m_skid_time = 0.0f;
|
||||
m_skid_state = m_skid_visual_time<=0 ? SKID_OLD : SKID_NONE;
|
||||
m_skid_factor = 1.0f;
|
||||
m_skid_time = 0.0f;
|
||||
m_skid_state = m_skid_visual_time<=0 ? SKID_OLD : SKID_NONE;
|
||||
m_skid_factor = 1.0f;
|
||||
m_real_steering = 0.0f;
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
float Skidding::getSteering(float steer, float max_steer_angle)
|
||||
/** Computes the actual steering fraction to be used in the physics, and
|
||||
* stores it in m_real_skidding. This is later used by kart to set the
|
||||
* physical steering. The real steering takes skidding into account: if the
|
||||
* kart skids either left or right, the steering fraction is bound by
|
||||
* reduce-turn-min and reduce-turn-max.
|
||||
*/
|
||||
void Skidding::updateSteering(float steer)
|
||||
{
|
||||
float steering = steer * max_steer_angle;
|
||||
|
||||
if(m_skid_state==SKID_OLD)
|
||||
{
|
||||
float speed = m_kart->getSpeed();
|
||||
float current_max_speed = m_kart->getCurrentMaxSpeed();
|
||||
float speed_ratio = speed / current_max_speed;
|
||||
m_real_steering = steer * m_skid_factor;
|
||||
m_visual_rotation = m_real_steering /m_skid_max * speed_ratio;
|
||||
return;
|
||||
}
|
||||
// Now only new skidding is happening
|
||||
switch(m_skid_state)
|
||||
{
|
||||
case SKID_OLD: assert(false);
|
||||
break;
|
||||
case SKID_NONE:
|
||||
case SKID_SHOW_GFX:
|
||||
case SKID_OLD: steering *= m_skid_factor;
|
||||
case SKID_ACCUMULATE_LEFT:
|
||||
m_real_steering = steer;
|
||||
break;
|
||||
case SKID_SHOW_GFX_RIGHT:
|
||||
case SKID_ACCUMULATE_RIGHT:
|
||||
steering *= m_skid_reduce_turn_min
|
||||
* sqrt(m_skid_max / m_skid_factor);
|
||||
{
|
||||
float f = (1.0f+steer)*0.5f; // map [-1,1] --> [0, 1]
|
||||
m_real_steering = m_skid_reduce_turn_min+
|
||||
m_skid_reduce_turn_delta*f;
|
||||
break;
|
||||
}
|
||||
case SKID_SHOW_GFX_LEFT:
|
||||
case SKID_ACCUMULATE_LEFT:
|
||||
{
|
||||
float f = (-1.0f+steer)*0.5f; // map [-1,1] --> [-1, 0]
|
||||
m_real_steering = -m_skid_reduce_turn_min+
|
||||
m_skid_reduce_turn_delta*f;
|
||||
break;
|
||||
}
|
||||
} // switch m_skid_state
|
||||
return steering;
|
||||
} // getSteering
|
||||
m_visual_rotation = m_skid_visual * m_real_steering;
|
||||
|
||||
float st = fabsf(m_skid_time);
|
||||
if(st<m_skid_visual_time)
|
||||
m_visual_rotation *= st/m_skid_visual_time;
|
||||
} // updateSteering
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Updates skidding status.
|
||||
@ -92,6 +126,7 @@ void Skidding::update(float dt, bool is_on_ground,
|
||||
else
|
||||
if(m_skid_factor<1.0f) m_skid_factor = 1.0f;
|
||||
|
||||
updateSteering(steering);
|
||||
// FIXME hiker: remove once the new skidding code is finished.
|
||||
if(m_skid_state == SKID_OLD)
|
||||
return;
|
||||
@ -103,7 +138,7 @@ void Skidding::update(float dt, bool is_on_ground,
|
||||
// by m_skid_state:
|
||||
// SKID_NONE: no skidding is happening. From here SKID_ACCUMULATE
|
||||
// is reached when the skid key is pressed.
|
||||
// SKID_ACCUMULATE:
|
||||
// SKID_ACCUMULATE_{LEFT,RIGHT}:
|
||||
// The kart is still skidding. The skidding time will be
|
||||
// accumulated in m_skid_time, and once the minimum time for a
|
||||
// bonus is reached, the "bonus gfx now available" gfx is shown.
|
||||
@ -111,7 +146,7 @@ void Skidding::update(float dt, bool is_on_ground,
|
||||
// a potential bonus. Also the rotation of the physical body to
|
||||
// be in synch with the graphical kart is started (which is
|
||||
// independently handled in the kart physics).
|
||||
// SKID_SHOW_GFX
|
||||
// SKID_SHOW_GFX_{LEFT<RIGHT}
|
||||
// Shows the skidding gfx while the bonus is available.
|
||||
// FIXME: what should we do if skid key is pressed while still in
|
||||
// SKID_SHOW_GFX??? Adjusting the body rotation is difficult.
|
||||
@ -122,9 +157,14 @@ void Skidding::update(float dt, bool is_on_ground,
|
||||
case SKID_NONE:
|
||||
// If skidding is pressed while the kart is going straight,
|
||||
// do nothing (till the kart starts to steer in one direction).
|
||||
if(!skidding || steering==0) break;
|
||||
m_skid_state = steering > 0 ? SKID_ACCUMULATE_LEFT
|
||||
: SKID_ACCUMULATE_RIGHT;
|
||||
// Just testing for the sign of steering can result in unexpected
|
||||
// beahviour, e.g. if a player is still turning left, but already
|
||||
// presses right (it will take a few frames for this steering to
|
||||
// actuallu take place, see player_controller) - the kart would skid
|
||||
// to the left. So we test for a 'clear enough' steering direction.
|
||||
if(!skidding || fabsf(steering)<0.3f) break;
|
||||
m_skid_state = steering > 0 ? SKID_ACCUMULATE_RIGHT
|
||||
: SKID_ACCUMULATE_LEFT;
|
||||
m_skid_time = 0; // fallthrough
|
||||
case SKID_ACCUMULATE_LEFT:
|
||||
case SKID_ACCUMULATE_RIGHT:
|
||||
@ -136,14 +176,16 @@ void Skidding::update(float dt, bool is_on_ground,
|
||||
// If at least level 1 bonus is reached, show appropriate gfx
|
||||
if(level>0) m_kart->getKartGFX()->setSkidLevel(level);
|
||||
// If player stops skidding, trigger bonus, and change state to
|
||||
// SKID_SHOW_GFX
|
||||
// SKID_SHOW_GFX_*
|
||||
if(!skidding)
|
||||
{
|
||||
m_skid_state = SKID_SHOW_GFX;
|
||||
m_skid_state = m_skid_state == SKID_ACCUMULATE_LEFT
|
||||
? SKID_SHOW_GFX_LEFT
|
||||
: SKID_SHOW_GFX_RIGHT;
|
||||
float t = (m_skid_time <= m_skid_visual_time)
|
||||
? m_skid_time
|
||||
: m_skid_visual_time;
|
||||
float vso = getVisualSkidOffset();
|
||||
float vso = getVisualSkidRotation();
|
||||
btVector3 rot(0, vso*m_post_skid_rotate_factor, 0);
|
||||
m_kart->getVehicle()->setTimedRotation(t, rot);
|
||||
// skid_time is used to count backwards for the GFX
|
||||
@ -163,7 +205,8 @@ void Skidding::update(float dt, bool is_on_ground,
|
||||
}
|
||||
break;
|
||||
} // case
|
||||
case SKID_SHOW_GFX:
|
||||
case SKID_SHOW_GFX_LEFT:
|
||||
case SKID_SHOW_GFX_RIGHT:
|
||||
m_skid_time -= dt;
|
||||
if(m_skid_time<=0)
|
||||
{
|
||||
@ -196,35 +239,3 @@ unsigned int Skidding::getSkidBonus(float *bonus_time,
|
||||
return m_skid_bonus_speed.size();
|
||||
} // getSkidBonusForce
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Determines how much the graphics model of the kart should be rotated
|
||||
* additionally (for skidding), depending on how long the kart has been
|
||||
* skidding etc.
|
||||
* \return Returns the angle of the additional rotation of the kart.
|
||||
*/
|
||||
float Skidding::getVisualSkidOffset() const
|
||||
{
|
||||
float speed = m_kart->getSpeed();
|
||||
float steer_percent = m_kart->getSteerPercent();
|
||||
float current_max_speed = m_kart->getCurrentMaxSpeed();
|
||||
if(m_skid_visual_time==0)
|
||||
{
|
||||
float speed_ratio = speed / current_max_speed;
|
||||
float r = m_skid_factor / m_skid_max;
|
||||
return steer_percent * speed_ratio * r;
|
||||
}
|
||||
|
||||
// New skidding code
|
||||
float f = m_skid_visual * steer_percent;
|
||||
//if(m_kart->getSpeed() < m_kart->getKartProperties()->getMaxSpeed())
|
||||
// f *= m_kart->getSpeed()/m_kart->getKartProperties()->getMaxSpeed();
|
||||
|
||||
float st = fabsf(m_skid_time);
|
||||
if(st<m_skid_visual_time)
|
||||
f *= st/m_skid_visual_time;
|
||||
|
||||
return f;
|
||||
|
||||
} // getVisualSkidOffset
|
||||
|
||||
/* EOF */
|
||||
|
@ -36,6 +36,17 @@ class Skidding : public SkiddingProperties
|
||||
public:
|
||||
LEAK_CHECK();
|
||||
private:
|
||||
/** This is m_skid_reduce_turn_max - m_skid_reduce_turn_min. */
|
||||
float m_skid_reduce_turn_delta;
|
||||
|
||||
/** This is the actual steering (in fraction of max-steering-angle)
|
||||
* to be used by this kart. */
|
||||
float m_real_steering;
|
||||
|
||||
/** An additional rotation (heading) of the kart while skidding. This
|
||||
* is only a graphical effect, the actual physics body is not rotated. */
|
||||
float m_visual_rotation;
|
||||
|
||||
/** Accumulated skidding factor. */
|
||||
float m_skid_factor;
|
||||
|
||||
@ -48,29 +59,38 @@ private:
|
||||
* SKID_ACCUMULATE_LEFT: Kart is skidding to the left and accumulating
|
||||
* for bonus.
|
||||
* SKID_ACCUMULATE_RIGHT: Similar for turning right
|
||||
* SKID_SHOW_GFX: Shows the gfx, while the bonus is actibe. */
|
||||
* SKID_SHOW_GFX_LEFT: Shows the gfx, while the bonus is active,
|
||||
* and the kart was turning left.
|
||||
* SKID_SHOW_GFX_RIGHT: Similar for turning right. */
|
||||
enum {SKID_OLD, SKID_NONE, SKID_ACCUMULATE_LEFT, SKID_ACCUMULATE_RIGHT,
|
||||
SKID_SHOW_GFX}
|
||||
SKID_SHOW_GFX_LEFT, SKID_SHOW_GFX_RIGHT}
|
||||
m_skid_state;
|
||||
|
||||
/** A read-only pointer to the kart's properties. */
|
||||
Kart *m_kart;
|
||||
|
||||
unsigned int getSkidBonus(float *bonus_time, float *bonus_speed) const;
|
||||
|
||||
void updateSteering(float steer);
|
||||
public:
|
||||
Skidding(Kart *kart, const SkiddingProperties *sp);
|
||||
void reset();
|
||||
void update(float dt, bool is_on_ground, float steer,
|
||||
bool skidding);
|
||||
float getVisualSkidOffset() const;
|
||||
float getSteering(float steer, float max_steer_angle);
|
||||
// ----------------------------------------------------------------------
|
||||
/** Determines how much the graphics model of the kart should be rotated
|
||||
* additionally (for skidding), depending on how long the kart has been
|
||||
* skidding etc. */
|
||||
float getVisualSkidRotation() const { return m_visual_rotation; };
|
||||
// ----------------------------------------------------------------------
|
||||
/** Returns the current skid factor in [1, skid_max_for_this_kart]. */
|
||||
float getSkidFactor() const { return m_skid_factor; }
|
||||
// ----------------------------------------------------------------------
|
||||
/** Returns true if the kart is skidding. */
|
||||
bool isSkidding() const { return m_skid_factor>1.0f; }
|
||||
// ----------------------------------------------------------------------
|
||||
/** Returns the steering fraction to be used by the physics. This is
|
||||
* a fraction of the maximum steering angle ( so in [-1, 1]). */
|
||||
float getSteeringFraction() { return m_real_steering; }
|
||||
|
||||
}; // Skidding
|
||||
|
||||
|
@ -131,7 +131,6 @@ public:
|
||||
float getSkidReduceTurnMax () const { return m_skid_reduce_turn_max; }
|
||||
|
||||
|
||||
|
||||
}; // SkiddingProperties
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user