Split updatePhysics into several shorter functions to make the code easier to

understand. Removed and simplified some functions. This should not change
anything in actual game play.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10574 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2012-01-04 21:58:33 +00:00
parent 87865b7dec
commit e06c8a05fa
6 changed files with 282 additions and 246 deletions

View File

@ -384,32 +384,29 @@ void Kart::flyDown()
*/
void Kart::startEngineSFX()
{
if(m_engine_sound)
if(!m_engine_sound)
return;
// In multiplayer mode, sounds are NOT positional (because we have
// multiple listeners) so the engine sounds of all AIs is constantly
// heard. So reduce volume of all sounds.
if (race_manager->getNumLocalPlayers() > 1)
{
// in multiplayer mode, sounds are NOT positional (because we have multiple listeners)
// so the engine sounds of all AIs is constantly heard. So reduce volume of all sounds.
if (race_manager->getNumLocalPlayers() > 1)
{
const int np = race_manager->getNumLocalPlayers();
const int nai = race_manager->getNumberOfKarts() - np;
// player karts twice as loud as AIs toghether
const float players_volume = (np * 2.0f) / (np*2.0f + np);
if (m_controller->isPlayerController())
{
m_engine_sound->volume( players_volume / np );
}
else
{
m_engine_sound->volume( (1.0f - players_volume) / nai );
}
}
m_engine_sound->speed(0.6f);
m_engine_sound->setLoop(true);
m_engine_sound->play();
const int np = race_manager->getNumLocalPlayers();
const int nai = race_manager->getNumberOfKarts() - np;
// player karts twice as loud as AIs toghether
const float players_volume = (np * 2.0f) / (np*2.0f + np);
if (m_controller->isPlayerController())
m_engine_sound->volume( players_volume / np );
else
m_engine_sound->volume( (1.0f - players_volume) / nai );
}
m_engine_sound->speed(0.6f);
m_engine_sound->setLoop(true);
m_engine_sound->play();
} // startEngineSFX
// ----------------------------------------------------------------------------
@ -600,7 +597,7 @@ void Kart::reset()
m_vehicle->deactivateZipper();
// Set the brakes so that karts don't slide downhill
for(int i=0; i<4; i++) m_vehicle->setBrake(5.0f, i);
m_vehicle->setAllBrakes(5.0f);
setTrans(m_reset_transform);
@ -1421,17 +1418,6 @@ void Kart::setSlipstreamEffect(float f)
}
} // setSlipstreamEffect
// -----------------------------------------------------------------------------
/** 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
to zero (otherwise the brakes will be braking whenever no engine force
is set, i.e. the kart is not accelerating).
*/
void Kart::resetBrakes()
{
for(int i=0; i<4; i++) m_vehicle->setBrake(0.0f, i);
} // resetBrakes
// -----------------------------------------------------------------------------
/** Called when the kart crashes against the track (k=NULL) or another kart.
* \param k Either a kart if a kart was hit, or NULL if the track was hit.
@ -1597,10 +1583,186 @@ void Kart::updatePhysics(float dt)
m_vehicle->activateZipper(f);
MaxSpeed::increaseMaxSpeed(MS_INCREASE_ZIPPER, 0.9f*f,
5.0f, 5.0f);
}
m_bounce_back_time-=dt;
updateEnginePowerAndBrakes(dt);
// apply flying physics if relevant
if (m_flying)
updateFlying();
updateSkidding(dt);
updateSliding();
float steering = getMaxSteerAngle() * m_controls.m_steer*m_skidding;
m_vehicle->setSteeringValue(steering, 0);
m_vehicle->setSteeringValue(steering, 1);
// Handle skidding
float ang_vel = 0;
if(m_controls.m_drift)
{
if(m_controls.m_steer>0)
ang_vel = m_kart_properties->getSkidAngularVelocity();
else if (m_controls.m_steer<0)
ang_vel = -m_kart_properties->getSkidAngularVelocity();
}
m_vehicle->setSkidAngularVelocity(ang_vel);
// Only compute the current speed if this is not the client. On a client the
// speed is actually received from the server.
if(network_manager->getMode()!=NetworkManager::NW_CLIENT)
m_speed = getVehicle()->getRigidBody()->getLinearVelocity().length();
// calculate direction of m_speed
const btTransform& chassisTrans = getVehicle()->getChassisWorldTransform();
btVector3 forwardW (
chassisTrans.getBasis()[0][2],
chassisTrans.getBasis()[1][2],
chassisTrans.getBasis()[2][2]);
if (forwardW.dot(getVehicle()->getRigidBody()->getLinearVelocity()) < btScalar(0.))
m_speed *= -1.f;
// Cap speed if necessary
MaxSpeed::update(dt);
// To avoid tunneling (which can happen on long falls), clamp the
// velocity in Y direction. Tunneling can happen if the Y velocity
// is larger than the maximum suspension travel (per frame), since then
// the wheel suspension can not stop/slow down the fall (though I am
// not sure if this is enough in all cases!). So the speed is limited
// to suspensionTravel / dt with dt = 1/60 (since this is the dt
// bullet is using).
// Only apply if near ground instead of purely based on speed avoiding
// the "parachute on top" look.
const Vec3 &v = m_body->getLinearVelocity();
if(/*isNearGround() &&*/ v.getY() < - m_kart_properties->getSuspensionTravelCM()*0.01f*60)
{
Vec3 v_clamped = v;
// clamp the speed to 99% of the maxium falling speed.
v_clamped.setY(-m_kart_properties->getSuspensionTravelCM()*0.01f*60 * 0.99f);
m_body->setLinearVelocity(v_clamped);
}
//at low velocity, forces on kart push it back and forth so we ignore this
if(fabsf(m_speed) < 0.2f) // quick'n'dirty workaround for bug 1776883
m_speed = 0;
updateEngineSFX();
#ifdef XX
printf("forward %f %f %f %f side %f %f %f %f angVel %f %f %f heading %f\n"
,m_vehicle->m_forwardImpulse[0]
,m_vehicle->m_forwardImpulse[1]
,m_vehicle->m_forwardImpulse[2]
,m_vehicle->m_forwardImpulse[3]
,m_vehicle->m_sideImpulse[0]
,m_vehicle->m_sideImpulse[1]
,m_vehicle->m_sideImpulse[2]
,m_vehicle->m_sideImpulse[3]
,m_body->getAngularVelocity().getX()
,m_body->getAngularVelocity().getY()
,m_body->getAngularVelocity().getZ()
,getHeading()
);
#endif
} // updatePhysics
//-----------------------------------------------------------------------------
/** Adjust the engine sound effect depending on the speed of the kart.
*/
void Kart::updateEngineSFX()
{
// when going faster, use higher pitch for engine
if(!m_engine_sound || !sfx_manager->sfxAllowed())
return;
if(isOnGround())
{
float max_speed = MaxSpeed::getCurrentMaxSpeed();
// Engine noise is based half in total speed, half in fake gears:
// With a sawtooth graph like /|/|/| we get 3 even spaced gears,
// ignoring the gear settings from stk_config, but providing a
// good enough brrrBRRRbrrrBRRR sound effect. Speed factor makes
// it a "staired sawtooth", so more acoustically rich.
float f = m_speed/max_speed;
// Speed at this stage is not yet capped, so it can be > 1, which
// results in odd engine sfx.
if (f>1.0f) f=1.0f;
float gears = 3.0f * fmod(f, 0.333334f);
m_engine_sound->speed(0.6f + (f +gears)* 0.35f);
}
else
{
// When flying, fixed value but not too high pitch
// This gives some variation (vs previous "on wheels" one)
m_engine_sound->speed(0.9f);
}
m_engine_sound->position(getXYZ());
} // updateEngineSFX
//-----------------------------------------------------------------------------
/** Handles skidding.
*/
void Kart::updateSkidding(float dt)
{
// Skid a little when hitting a bubblegum (just enough to make the
// skiding sound)
if (m_bubblegum_time > 0.0f) m_skidding *= 1.08f;
// Still going forward while braking: skid a little when the brakes
// are hit (just enough to make the skiding sound)
if(!m_controls.m_accel && m_controls.m_brake && m_speed > 0.0f)
m_skidding *= 1.08f;
if (isOnGround())
{
if((fabs(m_controls.m_steer) > 0.001f) && m_controls.m_drift)
{
m_skidding += m_kart_properties->getSkidIncrease()
*dt/m_kart_properties->getTimeTillMaxSkid();
}
else if(m_skidding>1.0f)
{
m_skidding *= m_kart_properties->getSkidDecrease();
}
}
else
{
m_skidding = 1.0f; // Lose any skid factor as soon as we fly
}
if(m_skidding>m_kart_properties->getMaxSkid())
m_skidding = m_kart_properties->getMaxSkid();
else
if(m_skidding<1.0f) m_skidding=1.0f;
if(m_skidding>1.0f)
{
if(m_skid_sound->getStatus() != SFXManager::SFX_PLAYING &&
m_kart_properties->hasSkidmarks())
m_skid_sound->play();
}
else if(m_skid_sound->getStatus() == SFXManager::SFX_PLAYING)
{
m_skid_sound->stop();
}
} // updateSkidding
//-----------------------------------------------------------------------------
/** Sets the engine power. It considers the engine specs, items that influence
* the available power, and braking/steering.
*/
void Kart::updateEnginePowerAndBrakes(float dt)
{
float engine_power = getActualWheelForce() + handleNitro(dt)
+ m_slipstream->getSlipstreamPower();
@ -1613,67 +1775,21 @@ void Kart::updatePhysics(float dt)
{
engine_power = 0.0f;
m_body->applyTorque(btVector3(0.0, 500.0f, 0.0));
m_skidding *= 1.08f; //skid a little when hitting a bubblegum (just enough to make the skiding sound)
}
// apply flying physics if relevant
if (m_flying)
{
if (m_controls.m_accel)
{
float orientation = getHeading();
m_body->applyCentralImpulse(btVector3(60.0f*sin(orientation), 0.0, 60.0f*cos(orientation)));
}
if (m_controls.m_steer != 0.0f)
{
m_body->applyTorque(btVector3(0.0, m_controls.m_steer * 3500.0f, 0.0));
}
if (m_controls.m_brake)
{
btVector3 velocity = m_body->getLinearVelocity();
const float x = velocity.x();
if (x > 0.2f) velocity.setX(x - 0.2f);
else if (x < -0.2f) velocity.setX(x + 0.2f);
else velocity.setX(0);
const float y = velocity.y();
if (y > 0.2f) velocity.setY(y - 0.2f);
else if (y < -0.2f) velocity.setY(y + 0.2f);
else velocity.setY(0);
const float z = velocity.z();
if (z > 0.2f) velocity.setZ(z - 0.2f);
else if (z < -0.2f) velocity.setZ(z + 0.2f);
else velocity.setZ(0);
m_body->setLinearVelocity(velocity);
//float orientation = getHeading();
//m_body->applyCentralImpulse(btVector3(-60.0f*sin(orientation), 0.0, -60.0f*cos(orientation)));
}
// dampen any roll while flying, makes the kart hard to control
btVector3 velocity = m_body->getAngularVelocity();
velocity.setX(0);
velocity.setZ(0);
m_body->setAngularVelocity(velocity);
}
if(m_controls.m_accel) // accelerating
{
// For a short time after a collision disable the engine,
// so that the karts can bounce back a bit from the obstacle.
if(m_bounce_back_time>0.0f)
engine_power = 0.0f;
// let a player going backwards accelerate quickly (e.g. if a player hits a
// wall, he needs to be able to start again quickly after going backwards)
// let a player going backwards accelerate quickly (e.g. if a player
// hits a wall, he needs to be able to start again quickly after
// going backwards)
else if(m_speed < 0.0f)
engine_power *= 5.0f;
// Lose some traction when skidding, to balance the adventage
// Up to r5483 AIs were allowed to cheat in medium and high diff levels
if(m_controls.m_drift)
engine_power *= 0.5f;
@ -1683,28 +1799,27 @@ void Kart::updatePhysics(float dt)
// resetting all brakes most of the time.
if(m_vehicle->getWheelInfo(0).m_brake &&
!World::getWorld()->isStartPhase())
resetBrakes();
m_vehicle->setAllBrakes(0);
}
else
{ // not accelerating
if(m_controls.m_brake)
{ // check if the player is currently only slowing down or moving backwards
{ // check if the player is currently only slowing down
// or moving backwards
if(m_speed > 0.0f)
{ // going forward
{ // Still going forward while braking
applyEngineForce(0.f);
//apply the brakes
for(int i=0; i<4; i++) m_vehicle->setBrake(getBrakeFactor(), i);
m_skidding*= 1.08f;//skid a little when the brakes are hit (just enough to make the skiding sound)
if(m_skidding>m_kart_properties->getMaxSkid())
m_skidding=m_kart_properties->getMaxSkid();
m_vehicle->setAllBrakes(m_kart_properties->getBrakeFactor());
}
else // m_speed < 0
{
resetBrakes();
// going backward, apply reverse gear ratio (unless he goes too fast backwards)
m_vehicle->setAllBrakes(0);
// going backward, apply reverse gear ratio (unless he goes
// too fast backwards)
if ( -m_speed < MaxSpeed::getCurrentMaxSpeed()
*m_kart_properties->getMaxSpeedReverseRatio() )
*m_kart_properties->getMaxSpeedReverseRatio())
{
// The backwards acceleration is artificially increased to
// allow players to get "unstuck" quicker if they hit e.g.
@ -1724,42 +1839,18 @@ void Kart::updatePhysics(float dt)
applyEngineForce(-m_controls.m_accel*engine_power*0.1f);
// If not giving power (forward or reverse gear), and speed is low
// we are "parking" the kart, so in battle mode we can ambush people, eg
if(abs(m_speed) < 5.0f) {
for(int i=0; i<4; i++) m_vehicle->setBrake(20.0f, i);
}
// we are "parking" the kart, so in battle mode we can ambush people
if(abs(m_speed) < 5.0f)
m_vehicle->setAllBrakes(20.0f);
} // !m_brake
} // not accelerating
if (isOnGround())
{
if((fabs(m_controls.m_steer) > 0.001f) && m_controls.m_drift)
{
m_skidding += m_kart_properties->getSkidIncrease()
*dt/m_kart_properties->getTimeTillMaxSkid();
if(m_skidding>m_kart_properties->getMaxSkid())
m_skidding=m_kart_properties->getMaxSkid();
}
else if(m_skidding>1.0f)
{
m_skidding *= m_kart_properties->getSkidDecrease();
if(m_skidding<1.0f) m_skidding=1.0f;
}
}
else
{
m_skidding = 1.0f; // Lose any skid factor as soon as we fly
}
if(m_skidding>1.0f)
{
if(m_skid_sound->getStatus() != SFXManager::SFX_PLAYING &&
m_kart_properties->hasSkidmarks())
m_skid_sound->play();
}
else if(m_skid_sound->getStatus() == SFXManager::SFX_PLAYING)
{
m_skid_sound->stop();
}
} // updateEnginePowerAndBrakes
//-----------------------------------------------------------------------------
/** Handles sliding, i.e. the kart sliding off terrain that is too steep.
*/
void Kart::updateSliding()
{
// dynamically determine friction so that the kart looses its traction
// when trying to drive on too steep surfaces. Below angles of 0.25 rad,
// you have full traction; above 0.5 rad angles you have absolutely none;
@ -1805,111 +1896,55 @@ void Kart::updatePhysics(float dt)
}
m_vehicle->setSliding(enable_sliding);
float steering = getMaxSteerAngle() * m_controls.m_steer*m_skidding;
m_vehicle->setSteeringValue(steering, 0);
m_vehicle->setSteeringValue(steering, 1);
// Handle skidding
float ang_vel = 0;
if(m_controls.m_drift)
{
if(m_controls.m_steer>0)
ang_vel = m_kart_properties->getSkidAngularVelocity();
else if (m_controls.m_steer<0)
ang_vel = -m_kart_properties->getSkidAngularVelocity();
}
m_vehicle->setSkidAngularVelocity(ang_vel);
// Only compute the current speed if this is not the client. On a client the
// speed is actually received from the server.
if(network_manager->getMode()!=NetworkManager::NW_CLIENT)
m_speed = getVehicle()->getRigidBody()->getLinearVelocity().length();
// calculate direction of m_speed
const btTransform& chassisTrans = getVehicle()->getChassisWorldTransform();
btVector3 forwardW (
chassisTrans.getBasis()[0][2],
chassisTrans.getBasis()[1][2],
chassisTrans.getBasis()[2][2]);
if (forwardW.dot(getVehicle()->getRigidBody()->getLinearVelocity()) < btScalar(0.))
m_speed *= -1.f;
// Cap speed if necessary
MaxSpeed::update(dt);
// To avoid tunneling (which can happen on long falls), clamp the
// velocity in Y direction. Tunneling can happen if the Y velocity
// is larger than the maximum suspension travel (per frame), since then
// the wheel suspension can not stop/slow down the fall (though I am
// not sure if this is enough in all cases!). So the speed is limited
// to suspensionTravel / dt with dt = 1/60 (since this is the dt
// bullet is using).
// Only apply if near ground instead of purely based on speed avoiding
// the "parachute on top" look.
const Vec3 &v = m_body->getLinearVelocity();
if(/*isNearGround() &&*/ v.getY() < - m_kart_properties->getSuspensionTravelCM()*0.01f*60)
{
Vec3 v_clamped = v;
// clamp the speed to 99% of the maxium falling speed.
v_clamped.setY(-m_kart_properties->getSuspensionTravelCM()*0.01f*60 * 0.99f);
m_body->setLinearVelocity(v_clamped);
}
//at low velocity, forces on kart push it back and forth so we ignore this
if(fabsf(m_speed) < 0.2f) // quick'n'dirty workaround for bug 1776883
m_speed = 0;
// when going faster, use higher pitch for engine
if(m_engine_sound && sfx_manager->sfxAllowed())
{
if(isOnGround())
{
float max_speed = MaxSpeed::getCurrentMaxSpeed();
// Engine noise is based half in total speed, half in fake gears:
// With a sawtooth graph like /|/|/| we get 3 even spaced gears,
// ignoring the gear settings from stk_config, but providing a
// good enough brrrBRRRbrrrBRRR sound effect. Speed factor makes
// it a "staired sawtooth", so more acoustically rich.
float f = m_speed/max_speed;
// Speed at this stage is not yet capped, so it can be > 1, which
// results in odd engine sfx.
if (f>1.0f) f=1.0f;
float gears = 3.0f * fmod(f, 0.333334f);
m_engine_sound->speed(0.6f + (f +gears)* 0.35f);
}
else
{
// When flying, fixed value but not too high pitch
// This gives some variation (vs previous "on wheels" one)
m_engine_sound->speed(0.9f);
}
m_engine_sound->position(getXYZ());
}
#ifdef XX
printf("forward %f %f %f %f side %f %f %f %f angVel %f %f %f heading %f\n"
,m_vehicle->m_forwardImpulse[0]
,m_vehicle->m_forwardImpulse[1]
,m_vehicle->m_forwardImpulse[2]
,m_vehicle->m_forwardImpulse[3]
,m_vehicle->m_sideImpulse[0]
,m_vehicle->m_sideImpulse[1]
,m_vehicle->m_sideImpulse[2]
,m_vehicle->m_sideImpulse[3]
,m_body->getAngularVelocity().getX()
,m_body->getAngularVelocity().getY()
,m_body->getAngularVelocity().getZ()
,getHeading()
);
#endif
} // updatePhysics
} // updateSliding
//-----------------------------------------------------------------------------
/** Adjusts kart translation if the kart is flying (in debug mode).
*/
void Kart::updateFlying()
{
if (m_controls.m_accel)
{
float orientation = getHeading();
m_body->applyCentralImpulse(btVector3(60.0f*sin(orientation), 0.0,
60.0f*cos(orientation)));
}
if (m_controls.m_steer != 0.0f)
{
m_body->applyTorque(btVector3(0.0, m_controls.m_steer * 3500.0f, 0.0));
}
if (m_controls.m_brake)
{
btVector3 velocity = m_body->getLinearVelocity();
const float x = velocity.x();
if (x > 0.2f) velocity.setX(x - 0.2f);
else if (x < -0.2f) velocity.setX(x + 0.2f);
else velocity.setX(0);
const float y = velocity.y();
if (y > 0.2f) velocity.setY(y - 0.2f);
else if (y < -0.2f) velocity.setY(y + 0.2f);
else velocity.setY(0);
const float z = velocity.z();
if (z > 0.2f) velocity.setZ(z - 0.2f);
else if (z < -0.2f) velocity.setZ(z + 0.2f);
else velocity.setZ(0);
m_body->setLinearVelocity(velocity);
} // if brake
// dampen any roll while flying, makes the kart hard to control
btVector3 velocity = m_body->getAngularVelocity();
velocity.setX(0);
velocity.setZ(0);
m_body->setAngularVelocity(velocity);
} // updateFlying
// ----------------------------------------------------------------------------
/** Attaches the right model, creates the physics and loads all special
* effects (particle systems etc.)
*/

View File

@ -208,6 +208,11 @@ private:
void updatePhysics(float dt);
void handleMaterialSFX(const Material *material);
void handleMaterialGFX();
void updateFlying();
void updateSliding();
void updateSkidding(float dt);
void updateEnginePowerAndBrakes(float dt);
void updateEngineSFX();
protected:
const KartProperties *m_kart_properties;
@ -236,7 +241,6 @@ public:
virtual void flyUp();
virtual void flyDown();
void resetBrakes ();
void startEngineSFX ();
void adjustSpeed (float f);
void capSpeed (float max_speed);
@ -339,9 +343,6 @@ public:
/** Returns the maximum engine power for this kart. */
float getMaxPower () const {return m_kart_properties->getMaxPower(); }
// ------------------------------------------------------------------------
/** Returns the strenght of the brakes for this kart. */
float getBrakeFactor() const {return m_kart_properties->getBrakeFactor();}
// ------------------------------------------------------------------------
/** Returns the time till full steering is reached for this kart. */
float getTimeFullSteer() const
{ return m_kart_properties->getTimeFullSteer(); }

View File

@ -91,7 +91,7 @@ void MaxSpeed::increaseMaxSpeed(unsigned int category, float add_speed,
// ----------------------------------------------------------------------------
/** Handles the update of speed increase objects. The m_duration variable
* contains the remaining time - as long as this variable is positibe,
* contains the remaining time - as long as this variable is positive
* the maximum speed increase applies, while when it is between
* -m_fade_out_time and 0, the maximum speed will linearly decrease.
* \param dt Time step size.
@ -99,7 +99,7 @@ void MaxSpeed::increaseMaxSpeed(unsigned int category, float add_speed,
void MaxSpeed::SpeedIncrease::update(float dt)
{
m_duration -= dt;
// ENd of increased max speed reached.
// End of increased max speed reached.
if(m_duration < -m_fade_out_time)
{
m_current_speedup = 0;

View File

@ -302,7 +302,7 @@ void World::onGo()
// from sliding downhill)
for(unsigned int i=0; i<m_karts.size(); i++)
{
m_karts[i]->resetBrakes();
m_karts[i]->getVehicle()->setAllBrakes(0);
}
} // onGo

View File

@ -482,11 +482,11 @@ btWheelInfo& btKart::getWheelInfo(int index)
}
// ----------------------------------------------------------------------------
void btKart::setBrake(btScalar brake,int wheelIndex)
void btKart::setAllBrakes(btScalar brake)
{
btAssert((wheelIndex >= 0) && (wheelIndex < getNumWheels()));
getWheelInfo(wheelIndex).m_brake = brake;
}
for(int i=0; i<getNumWheels(); i++)
getWheelInfo(i).m_brake = brake;
} // setAllBrakes
// ----------------------------------------------------------------------------

View File

@ -151,7 +151,7 @@ public:
btWheelInfo& getWheelInfo(int index);
void updateWheelTransformsWS(btWheelInfo& wheel,
bool interpolatedTransform=true);
void setBrake(btScalar brake,int wheelIndex);
void setAllBrakes(btScalar brake);
void updateSuspension(btScalar deltaTime);
virtual void updateFriction(btScalar timeStep);
public: