Merge branch 'physics-tweaks'
This commit is contained in:
commit
4e35fe8fb8
@ -101,12 +101,35 @@
|
||||
any track/library pbject.
|
||||
default-moveable-friction: Default friction to be used for any moveable,
|
||||
e.g. karts, bowling balls, ...
|
||||
solver-iteation: Number of solver iterations. A lower number reduces
|
||||
the quality, but can reduce bouncing effect.
|
||||
solver-split-impulse:: by default bullet solves for velocity and
|
||||
position at the same time, which can introduce bounce. Setting
|
||||
this to 1 can reduce bounce.
|
||||
solver-split-impulse-threshold: Penetration threshold for using split
|
||||
impulse (ignored if solver-split-impulse is false).
|
||||
solver-mode: Bullet's solver mode is a bit mask, which can be modified.
|
||||
This entry contains a space-separated list of mode-names to either
|
||||
set or unset in this bit mask. Any name starting with a '-' indicate
|
||||
that the bit is to be set to 0, otherwise the bit will be set.
|
||||
|
||||
This field takes two
|
||||
values: the first value is 'and'ed with bullet's default values
|
||||
(i.e. it can be used to unset bullet defaults), the second value
|
||||
is 'or'ed (i.e. is used to set a bit). A value of -1 for 'and'
|
||||
means to keep all bits. The valid names are listed in stk_config.cpp
|
||||
and correspond to the definitions in btContactSolverInfo.h, e.g.:
|
||||
'randomized_order' corresponds to the bit SOLVER_RANDMIZE_ORDER.
|
||||
-->
|
||||
<physics smooth-normals="true"
|
||||
smooth-angle-limit="0.65"
|
||||
fps="120"
|
||||
default-track-friction="0.5"
|
||||
default-moveable-friction="0.5" />
|
||||
default-moveable-friction="0.5"
|
||||
solver-iterations="4"
|
||||
solver-split-impulse="true"
|
||||
solver-split-impulse-threshold="-0.00001"
|
||||
solver-mode=""/>
|
||||
|
||||
<!-- The title music. -->
|
||||
<music title="main_theme.music"/>
|
||||
@ -412,6 +435,11 @@
|
||||
period, which results in less abrupt changes. If set to 0,
|
||||
the impulse is only applied once.
|
||||
resitution: restitution value to be used for the kart rigid bodies.
|
||||
The restitution used depends on the speed to avoid physics issues
|
||||
(a collision with high speed and high restitution will push the
|
||||
kart high up into the air). The values specified are
|
||||
speed:restitution pairs, the actual restitution will be
|
||||
interpolated based on the points specified here.
|
||||
bevel-factor: for each point of the chassis collision box one
|
||||
additional point is added, resulting in a bevelled box shape.
|
||||
The original Z coordinate of the chassis is multiplied by
|
||||
@ -431,7 +459,7 @@
|
||||
behaviour of the karts. -->
|
||||
<collision impulse-type="normal"
|
||||
impulse="3000" impulse-time="0.1" terrain-impulse="160"
|
||||
restitution="1.0" bevel-factor="0.5 0.0 0.3"
|
||||
restitution="0:1.0 5:1.0 20:0.2" bevel-factor="0.5 0.0 0.3"
|
||||
physical-wheel-position="0" />
|
||||
|
||||
<!-- Skidding: increase: multiplicative increase of skidding factor in each frame.
|
||||
@ -503,7 +531,7 @@
|
||||
Use a slow but high quality colour compressor.
|
||||
kColourClusterFit = (32),
|
||||
Use a fast but low quality colour compressor.
|
||||
kColourRangeFit = (64),
|
||||
kColourRangeFit = (64),
|
||||
Use a very slow but very high quality colour compressor.
|
||||
kColourIterativeClusterFit = (256),
|
||||
STK default the low quality.
|
||||
|
55
src/config/stk_config.cpp
Normal file → Executable file
55
src/config/stk_config.cpp
Normal file → Executable file
@ -154,6 +154,9 @@ void STKConfig::load(const std::string &filename)
|
||||
CHECK_NEG(m_network_state_frequeny, "network state-frequency" );
|
||||
CHECK_NEG(m_network_steering_reduction,"network steering-reduction" );
|
||||
CHECK_NEG(m_default_moveable_friction, "physics default-moveable-friction");
|
||||
CHECK_NEG(m_solver_iterations, "physics: solver-iterations" );
|
||||
CHECK_NEG(m_network_state_frequeny, "network solver-state-frequency" );
|
||||
CHECK_NEG(m_solver_split_impulse_thresh,"physics: solver-split-impulse-threshold");
|
||||
|
||||
// Square distance to make distance checks cheaper (no sqrt)
|
||||
m_default_kart_properties->checkAllSet(filename);
|
||||
@ -166,11 +169,11 @@ void STKConfig::load(const std::string &filename)
|
||||
*/
|
||||
void STKConfig::init_defaults()
|
||||
{
|
||||
m_bomb_time = m_bomb_time_increase =
|
||||
m_explosion_impulse_objects = m_music_credit_time =
|
||||
m_delay_finish_time = m_skid_fadeout_time =
|
||||
m_near_ground =
|
||||
m_smooth_angle_limit = m_default_track_friction =
|
||||
m_bomb_time = m_bomb_time_increase =
|
||||
m_explosion_impulse_objects = m_music_credit_time =
|
||||
m_delay_finish_time = m_skid_fadeout_time =
|
||||
m_near_ground = m_solver_split_impulse_thresh =
|
||||
m_smooth_angle_limit = m_default_track_friction =
|
||||
m_default_moveable_friction = UNDEFINED;
|
||||
m_item_switch_ticks = -100;
|
||||
m_penalty_ticks = -100;
|
||||
@ -196,8 +199,12 @@ void STKConfig::init_defaults()
|
||||
m_donate_url = "";
|
||||
m_password_reset_url = "";
|
||||
m_network_state_frequeny = -100;
|
||||
m_network_steering_reduction = 1.0f;
|
||||
m_solver_iterations = -100;
|
||||
m_solver_set_flags = 0;
|
||||
m_solver_reset_flags = 0;
|
||||
m_network_steering_reduction = -100;
|
||||
m_title_music = NULL;
|
||||
m_solver_split_impulse = false;
|
||||
m_smooth_normals = false;
|
||||
m_same_powerup_mode = POWERUP_MODE_ONLY_IF_SAME;
|
||||
m_ai_acceleration = 1.0f;
|
||||
@ -282,6 +289,42 @@ void STKConfig::getAllData(const XMLNode * root)
|
||||
physics_node->get("default-moveable-friction",
|
||||
&m_default_moveable_friction);
|
||||
physics_node->get("fps", &m_physics_fps );
|
||||
physics_node->get("solver-iterations", &m_solver_iterations );
|
||||
physics_node->get("solver-split-impulse", &m_solver_split_impulse );
|
||||
physics_node->get("solver-split-impulse-threshold",
|
||||
&m_solver_split_impulse_thresh);
|
||||
std::vector<std::string> solver_modes;
|
||||
physics_node->get("solver-mode", &solver_modes );
|
||||
m_solver_set_flags=0, m_solver_reset_flags = 0;
|
||||
int *p;
|
||||
for (auto mode : solver_modes)
|
||||
{
|
||||
std::string s = mode;
|
||||
p = &m_solver_set_flags;
|
||||
if (s[0] == '-')
|
||||
{
|
||||
s.erase(s.begin());
|
||||
p = &m_solver_reset_flags;
|
||||
}
|
||||
s = StringUtils::toLowerCase(s);
|
||||
if (s == "randmize_order" ) *p |= 1;
|
||||
else if (s == "friction_separate" ) *p |= 2;
|
||||
else if (s == "use_warmstarting" ) *p |= 4;
|
||||
else if (s == "use_friction_warmstarting" ) *p |= 8;
|
||||
else if (s == "use_2_friction_directions" ) *p |= 16;
|
||||
else if (s == "enable_friction_direction_caching" ) *p |= 32;
|
||||
else if (s == "disable_velocity_dependent_friction_direction") *p |= 64;
|
||||
else if (s == "cache_friendly" ) *p |= 128;
|
||||
else if (s == "simd" ) *p |= 256;
|
||||
else if (s == "cuda" ) *p |= 512;
|
||||
else
|
||||
{
|
||||
Log::fatal("STK-Config",
|
||||
"Unknown option '%s' for solver-mode - ignored.",
|
||||
s.c_str());
|
||||
}
|
||||
} // for mode in solver_modes
|
||||
|
||||
}
|
||||
|
||||
if (const XMLNode *startup_node= root->getNode("startup"))
|
||||
|
@ -105,6 +105,19 @@ public:
|
||||
/** Default friction to be used for any moveable, e.g. karts, balls. */
|
||||
float m_default_moveable_friction;
|
||||
|
||||
/** Number of solver iterations. */
|
||||
int m_solver_iterations;
|
||||
|
||||
/** If position and velocity constraints are solved separately. */
|
||||
bool m_solver_split_impulse;
|
||||
|
||||
/** Threshold when to use the split impulse approach. */
|
||||
float m_solver_split_impulse_thresh;
|
||||
|
||||
/** Bit flags to modify the solver mode. Bits set in set_flags are
|
||||
* added to the solver mode, bits set in reset_flags are removed. */
|
||||
int m_solver_set_flags, m_solver_reset_flags;
|
||||
|
||||
int m_max_skidmarks; /**<Maximum number of skid marks/kart. */
|
||||
float m_skid_fadeout_time; /**<Time till skidmarks fade away. */
|
||||
float m_near_ground; /**<Determines when a kart is not near
|
||||
|
@ -723,7 +723,7 @@ void Kart::createPhysics()
|
||||
btTransform trans;
|
||||
trans.setIdentity();
|
||||
createBody(mass, trans, &m_kart_chassis,
|
||||
m_kart_properties->getRestitution());
|
||||
m_kart_properties->getRestitution(0.0f));
|
||||
std::vector<float> ang_fact = m_kart_properties->getStabilityAngularFactor();
|
||||
// The angular factor (with X and Z values <1) helps to keep the kart
|
||||
// upright, especially in case of a collision.
|
||||
@ -1273,6 +1273,13 @@ void Kart::eliminate()
|
||||
*/
|
||||
void Kart::update(int ticks)
|
||||
{
|
||||
// Make the restitution depend on speed: this avoids collision issues,
|
||||
// otherwise a collision with high speed can see a kart being push
|
||||
// high up in the air (and out of control). So for higher speed we
|
||||
// reduce the restitution, meaning the karts will get less of a push
|
||||
// based on the collision speed.
|
||||
m_body->setRestitution(m_kart_properties->getRestitution(fabsf(m_speed)));
|
||||
|
||||
// Reset any instand speed increase in the bullet kart
|
||||
m_vehicle->setMinSpeed(0);
|
||||
|
||||
|
@ -82,7 +82,7 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
// Set all other values to undefined, so that it can later be tested
|
||||
// if everything is defined properly.
|
||||
m_wheel_base = m_friction_slip = m_collision_terrain_impulse =
|
||||
m_collision_impulse = m_restitution = m_collision_impulse_time =
|
||||
m_collision_impulse = m_collision_impulse_time =
|
||||
m_max_lean = m_lean_speed = m_physical_wheel_position = UNDEFINED;
|
||||
|
||||
m_terrain_impulse_type = IMPULSE_NONE;
|
||||
@ -499,7 +499,7 @@ void KartProperties::getAllData(const XMLNode * root)
|
||||
void KartProperties::checkAllSet(const std::string &filename)
|
||||
{
|
||||
#define CHECK_NEG( a,strA) if(a<=UNDEFINED) { \
|
||||
Log::fatal("[KartProperties]", \
|
||||
Log::fatal("KartProperties", \
|
||||
"Missing default value for '%s' in '%s'.", \
|
||||
strA,filename.c_str()); \
|
||||
}
|
||||
@ -508,9 +508,11 @@ void KartProperties::checkAllSet(const std::string &filename)
|
||||
CHECK_NEG(m_collision_terrain_impulse, "collision terrain-impulse" );
|
||||
CHECK_NEG(m_collision_impulse, "collision impulse" );
|
||||
CHECK_NEG(m_collision_impulse_time, "collision impulse-time" );
|
||||
CHECK_NEG(m_restitution, "collision restitution" );
|
||||
CHECK_NEG(m_physical_wheel_position, "collision physical-wheel-position");
|
||||
|
||||
if(m_restitution.size()<1)
|
||||
Log::fatal("KartProperties", "Missing restitution value.");
|
||||
|
||||
for(unsigned int i=0; i<RaceManager::DIFFICULTY_COUNT; i++)
|
||||
m_ai_properties[i]->checkAllSet(filename);
|
||||
} // checkAllSet
|
||||
|
@ -201,9 +201,8 @@ private:
|
||||
/** How long the collision impulse should be applied. */
|
||||
float m_collision_impulse_time;
|
||||
|
||||
/** The restitution factor to be used in collsions for this kart. */
|
||||
float m_restitution;
|
||||
|
||||
/** Restitution depending on speed. */
|
||||
InterpolationArray m_restitution;
|
||||
|
||||
void load (const std::string &filename,
|
||||
const std::string &node);
|
||||
@ -340,7 +339,7 @@ public:
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the restitution factor for this kart. */
|
||||
float getRestitution () const { return m_restitution; }
|
||||
float getRestitution(float speed) const { return m_restitution.get(speed);}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a pointer to the AI properties. */
|
||||
|
@ -123,6 +123,7 @@ BareNetworkString* KartRewinder::saveState(std::vector<std::string>* ru)
|
||||
buffer->addFloat(m_vehicle->getMinSpeed());
|
||||
buffer->addFloat(m_vehicle->getTimedRotationTime());
|
||||
buffer->add(m_vehicle->getTimedRotation());
|
||||
buffer->addUInt8(m_vehicle->getCushioningDisableTime());
|
||||
|
||||
// 2) Steering and other player controls
|
||||
// -------------------------------------
|
||||
@ -189,6 +190,8 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
|
||||
float time_rot = buffer->getFloat();
|
||||
// Set timed rotation divides by time_rot
|
||||
m_vehicle->setTimedRotation(time_rot, time_rot*buffer->getVec3());
|
||||
m_vehicle->setCushioningDisableTime(buffer->getUInt8());
|
||||
|
||||
// For the raycast to determine the current material under the kart
|
||||
// the m_hardPointWS of the wheels is used. So after a rewind we
|
||||
// must restore the m_hardPointWS to the new values, otherwise they
|
||||
|
@ -321,7 +321,6 @@ void MainLoop::run()
|
||||
|
||||
left_over_time += getLimitedDt();
|
||||
int num_steps = stk_config->time2Ticks(left_over_time);
|
||||
|
||||
float dt = stk_config->ticks2Time(1);
|
||||
left_over_time -= num_steps * dt ;
|
||||
|
||||
@ -371,8 +370,6 @@ void MainLoop::run()
|
||||
input_manager->update(frame_duration);
|
||||
GUIEngine::update(frame_duration);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
if (World::getWorld() && history->replayHistory())
|
||||
history->updateReplay(World::getWorld()->getTicksSinceStart());
|
||||
PROFILER_PUSH_CPU_MARKER("Music", 0x7F, 0x00, 0x00);
|
||||
SFXManager::get()->update();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
@ -408,8 +405,11 @@ void MainLoop::run()
|
||||
}
|
||||
m_ticks_adjustment.unlock();
|
||||
|
||||
for (int i = 0; i < num_steps; i++)
|
||||
for(int i=0; i<num_steps; i++)
|
||||
{
|
||||
if (World::getWorld() && history->replayHistory())
|
||||
history->updateReplay(World::getWorld()->getTicksSinceStart());
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("Protocol manager update",
|
||||
0x7F, 0x00, 0x7F);
|
||||
if (auto pm = ProtocolManager::lock())
|
||||
|
@ -26,6 +26,10 @@
|
||||
#include "karts/kart.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#undef DEBUG_CUSHIONING
|
||||
#ifdef DEBUG_CUSHIONING
|
||||
#include "modes/world.hpp"
|
||||
#endif
|
||||
#include "physics/triangle_mesh.hpp"
|
||||
#include "tracks/terrain_info.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
@ -125,6 +129,7 @@ void btKart::reset()
|
||||
m_time_additional_rotation = 0;
|
||||
m_max_speed = -1.0f;
|
||||
m_min_speed = 0.0f;
|
||||
m_cushioning_disable_time = 0;
|
||||
|
||||
// Set the brakes so that karts don't slide downhill
|
||||
setAllBrakes(5.0f);
|
||||
@ -434,48 +439,7 @@ void btKart::updateAllWheelPositions()
|
||||
void btKart::updateVehicle( btScalar step )
|
||||
{
|
||||
updateAllWheelTransformsWS();
|
||||
// Test if the kart is falling so fast
|
||||
// that the chassis might hit the track
|
||||
// ------------------------------------
|
||||
bool needs_cushioning_test = false;
|
||||
for(int i=0; i<m_wheelInfo.size(); i++)
|
||||
{
|
||||
btWheelInfo &wheel = m_wheelInfo[i];
|
||||
if(!wheel.m_was_on_ground && wheel.m_raycastInfo.m_isInContact)
|
||||
{
|
||||
needs_cushioning_test = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(needs_cushioning_test)
|
||||
{
|
||||
const btVector3 &v = m_chassisBody->getLinearVelocity();
|
||||
btVector3 down(0, 1, 0);
|
||||
btVector3 v_down = (v * down) * down;
|
||||
// Estimate what kind of downward speed can be compensated by the
|
||||
// suspension. Atm the parameters are set that the suspension is
|
||||
// actually capped at max suspension force, so the maximum
|
||||
// speed that can be caught by the suspension without the chassis
|
||||
// hitting the ground can be based on that. Note that there are
|
||||
// 4 suspensions, all adding together.
|
||||
btScalar max_compensate_speed = m_wheelInfo[0].m_maxSuspensionForce
|
||||
* m_chassisBody->getInvMass()
|
||||
* step * 4;
|
||||
// If the downward speed is too fast to be caught by the suspension,
|
||||
// slow down the falling speed by applying an appropriately impulse:
|
||||
if(-v_down.getY() > max_compensate_speed)
|
||||
{
|
||||
btVector3 impulse = down * (-v_down.getY() - max_compensate_speed)
|
||||
/ m_chassisBody->getInvMass()*0.5f;
|
||||
//float v_old = m_chassisBody->getLinearVelocity().getY();
|
||||
//float x = m_wheelInfo[0].m_raycastInfo.m_isInContact ? m_wheelInfo[0].m_raycastInfo.m_contactPointWS.getY() : -100;
|
||||
m_chassisBody->applyCentralImpulse(impulse);
|
||||
//Log::verbose("physics", "Cushioning %f from %f m/s to %f m/s wheel %f kart %f", impulse.getY(),
|
||||
// v_old, m_chassisBody->getLinearVelocity().getY(), x,
|
||||
// m_chassisBody->getWorldTransform().getOrigin().getY()
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<m_wheelInfo.size(); i++)
|
||||
m_wheelInfo[i].m_was_on_ground = m_wheelInfo[i].m_raycastInfo.m_isInContact;
|
||||
|
||||
@ -530,6 +494,93 @@ void btKart::updateVehicle( btScalar step )
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Test if the kart is falling so fast
|
||||
// that the chassis might hit the track
|
||||
// ------------------------------------
|
||||
int wheel_index = 0;
|
||||
float min_susp = m_wheelInfo[0].m_raycastInfo.m_suspensionLength;
|
||||
for (int i = 1; i<m_wheelInfo.size(); i++)
|
||||
{
|
||||
btWheelInfo &wheel = m_wheelInfo[i];
|
||||
if (wheel.m_raycastInfo.m_suspensionLength < min_susp)
|
||||
{
|
||||
min_susp = wheel.m_raycastInfo.m_suspensionLength;
|
||||
wheel_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Cushioning test: if the kart is falling fast, the suspension might
|
||||
// not be strong enough to prevent the chassis from hitting the ground.
|
||||
// Try to detect this upcoming crash, and apply an upward impulse if
|
||||
// necessary that will slow down the falling speed.
|
||||
if(m_cushioning_disable_time>0) m_cushioning_disable_time --;
|
||||
|
||||
bool needed_cushioning = false;
|
||||
btVector3 v =
|
||||
m_chassisBody->getVelocityInLocalPoint(m_wheelInfo[wheel_index]
|
||||
.m_chassisConnectionPointCS);
|
||||
btVector3 down = -m_chassisBody->getGravity();
|
||||
down.normalize();
|
||||
btVector3 v_down = (v * down) * down;
|
||||
btScalar offset=0.1f;
|
||||
|
||||
#ifdef DEBUG_CUSHIONING
|
||||
Log::verbose("physics",
|
||||
"World %d wheel %d lsuspl %f vdown %f overall speed %f lenght %f",
|
||||
World::getWorld()->getTimeTicks(),
|
||||
wheel_index,
|
||||
m_wheelInfo[wheel_index].m_raycastInfo.m_suspensionLength,
|
||||
-v_down.getY(),
|
||||
-v_down.getY() + 9.8*step,
|
||||
step * (-v_down.getY() + 9.8*step)+offset);
|
||||
#endif
|
||||
// If the kart is falling, estimate the distance the kart will fall
|
||||
// in the next time step: the speed gets increased by the gravity*dt.
|
||||
// This approximation is still not good enough (either because of
|
||||
// kart rotation that can be changed, or perhaps because of the
|
||||
// collision threshold used by bullet) - i.e. it would sometimes not
|
||||
// predict the upcoming collision correcty - so we add an offset
|
||||
// to the predicted kart movement, which was found experimentally:
|
||||
btScalar gravity = m_chassisBody->getGravity().length();
|
||||
if (v_down.getY()<0 && m_cushioning_disable_time==0 &&
|
||||
m_wheelInfo[wheel_index].m_raycastInfo.m_suspensionLength
|
||||
< step * (-v_down.getY()+gravity*step)+offset)
|
||||
{
|
||||
// Disable more cushioning for 1 second. This avoids the problem
|
||||
// of hovering: a kart gets cushioned on a down-sloping area, still
|
||||
// moves forwards, gets cushioned again etc. --> kart is hovering
|
||||
// and not controllable.
|
||||
m_cushioning_disable_time = 120;
|
||||
|
||||
needed_cushioning = true;
|
||||
btVector3 impulse = down * (-v_down.getY() + gravity*step)
|
||||
/ m_chassisBody->getInvMass();
|
||||
#ifdef DEBUG_CUSHIONING
|
||||
float v_old = m_chassisBody->getLinearVelocity().getY();
|
||||
#endif
|
||||
m_chassisBody->applyCentralImpulse(impulse);
|
||||
#ifdef DEBUG_CUSHIONING
|
||||
Log::verbose("physics",
|
||||
"World %d Cushioning imp %f vdown %f from %f m/s to %f m/s "
|
||||
"contact %f kart %f susp %f relspeed %f",
|
||||
World::getWorld()->getTimeTicks(),
|
||||
impulse.getY(),
|
||||
-v_down.getY(),
|
||||
v_old,
|
||||
m_chassisBody->getLinearVelocity().getY(),
|
||||
m_wheelInfo[wheel_index].m_raycastInfo.m_isInContact ?
|
||||
m_wheelInfo[wheel_index].m_raycastInfo.m_contactPointWS.getY()
|
||||
: -100,
|
||||
m_chassisBody->getWorldTransform().getOrigin().getY(),
|
||||
m_wheelInfo[wheel_index].m_raycastInfo.m_suspensionLength,
|
||||
m_chassisBody->getVelocityInLocalPoint(m_wheelInfo[wheel_index]
|
||||
.m_chassisConnectionPointCS)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Update friction (i.e. forward force)
|
||||
// ------------------------------------
|
||||
updateFriction( step);
|
||||
@ -537,7 +588,7 @@ void btKart::updateVehicle( btScalar step )
|
||||
// If configured, add a force to keep karts on the track
|
||||
// -----------------------------------------------------
|
||||
float dif = m_kart->getKartProperties()->getStabilityDownwardImpulseFactor();
|
||||
if(dif!=0 && m_num_wheels_on_ground==4)
|
||||
if(dif!=0 && m_num_wheels_on_ground==4 && !needed_cushioning)
|
||||
{
|
||||
float f = -fabsf(m_kart->getSpeed()) * dif;
|
||||
btVector3 downwards_impulse = m_chassisBody->getWorldTransform().getBasis()
|
||||
@ -648,6 +699,10 @@ void btKart::updateSuspension(btScalar deltaTime)
|
||||
// a force pulling the axis down (towards the ground). Note that it
|
||||
// is already guaranteed that either both or no wheels on one axis
|
||||
// are on the ground, so we have to test only one of the wheels
|
||||
// In hindsight it turns out that this code basically adds
|
||||
// additional gravity when a kart is flying. So if this code would
|
||||
// be removed some jumps (esp. Enterprise) do not work as expected
|
||||
// anymore.
|
||||
wheel_info.m_wheelsSuspensionForce =
|
||||
-m_kart->getKartProperties()->getStabilityTrackConnectionAccel()
|
||||
* chassisMass;
|
||||
|
@ -93,6 +93,9 @@ private:
|
||||
/** Number of wheels that touch the ground. */
|
||||
int m_num_wheels_on_ground;
|
||||
|
||||
/** Number of time steps during which cushioning is disabled. */
|
||||
unsigned int m_cushioning_disable_time;
|
||||
|
||||
/** Index of the right axis. */
|
||||
int m_indexRightAxis;
|
||||
/** Index of the up axis. */
|
||||
@ -245,6 +248,19 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
float getTimedRotationTime() const { return m_time_additional_rotation; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time cushioning is disabled. Used for networking state
|
||||
* saving. */
|
||||
unsigned int getCushioningDisableTime() const
|
||||
{
|
||||
return m_cushioning_disable_time;
|
||||
} // getCushioningDisableTime
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the cushioning disable time. Used for networking state saving. */
|
||||
void setCushioningDisableTime(unsigned int cdt)
|
||||
{
|
||||
m_cushioning_disable_time = cdt;
|
||||
} // setCushioningDisableTime
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the maximum speed for this kart. */
|
||||
void setMaxSpeed(float new_max_speed)
|
||||
{
|
||||
|
@ -74,6 +74,17 @@ void Physics::init(const Vec3 &world_min, const Vec3 &world_max)
|
||||
0.0f));
|
||||
m_debug_drawer = new IrrDebugDrawer();
|
||||
m_dynamics_world->setDebugDrawer(m_debug_drawer);
|
||||
|
||||
// Get the solver settings from the config file
|
||||
btContactSolverInfo& info = m_dynamics_world->getSolverInfo();
|
||||
info.m_numIterations = stk_config->m_solver_iterations;
|
||||
info.m_splitImpulse = stk_config->m_solver_split_impulse;
|
||||
info.m_splitImpulsePenetrationThreshold =
|
||||
stk_config->m_solver_split_impulse_thresh;
|
||||
|
||||
// Modify the mode according to the bits of the solver mode:
|
||||
info.m_solverMode = (info.m_solverMode & (~stk_config->m_solver_reset_flags))
|
||||
| stk_config->m_solver_set_flags;
|
||||
} // init
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user