Use height data to cushion only close to the ground and adjust impulse strength
This commit is contained in:
parent
6af07fac77
commit
6145aff895
@ -51,6 +51,12 @@ btKart::btKart(btRigidBody* chassis, btVehicleRaycaster* raycaster,
|
|||||||
Kart *kart)
|
Kart *kart)
|
||||||
: m_vehicleRaycaster(raycaster)
|
: m_vehicleRaycaster(raycaster)
|
||||||
{
|
{
|
||||||
|
btScalar height = 0;
|
||||||
|
for (int i=0;i<stk_config->time2Ticks(HISTORY_TIME);i++)
|
||||||
|
{
|
||||||
|
m_ground_height.push_back(height);
|
||||||
|
}
|
||||||
|
|
||||||
m_chassisBody = chassis;
|
m_chassisBody = chassis;
|
||||||
m_indexRightAxis = 0;
|
m_indexRightAxis = 0;
|
||||||
m_indexUpAxis = 1;
|
m_indexUpAxis = 1;
|
||||||
@ -121,6 +127,10 @@ void btKart::reset()
|
|||||||
wheel.m_raycastInfo.m_suspensionLength = 0;
|
wheel.m_raycastInfo.m_suspensionLength = 0;
|
||||||
updateWheelTransform(i, true);
|
updateWheelTransform(i, true);
|
||||||
}
|
}
|
||||||
|
for (int i=0;i<stk_config->time2Ticks(HISTORY_TIME);i++)
|
||||||
|
{
|
||||||
|
m_ground_height[i] = 0;
|
||||||
|
}
|
||||||
m_visual_wheels_touch_ground = false;
|
m_visual_wheels_touch_ground = false;
|
||||||
m_allow_sliding = false;
|
m_allow_sliding = false;
|
||||||
m_num_wheels_on_ground = 0;
|
m_num_wheels_on_ground = 0;
|
||||||
@ -131,6 +141,7 @@ void btKart::reset()
|
|||||||
m_max_speed = -1.0f;
|
m_max_speed = -1.0f;
|
||||||
m_min_speed = 0.0f;
|
m_min_speed = 0.0f;
|
||||||
m_cushioning_disable_time = 0;
|
m_cushioning_disable_time = 0;
|
||||||
|
m_new_ground_height = 999.9f;
|
||||||
|
|
||||||
// Set the brakes so that karts don't slide downhill
|
// Set the brakes so that karts don't slide downhill
|
||||||
setAllBrakes(5.0f);
|
setAllBrakes(5.0f);
|
||||||
@ -278,10 +289,10 @@ btScalar btKart::rayCast(unsigned int index, float fraction)
|
|||||||
btScalar max_susp_len = wheel.getSuspensionRestLength()
|
btScalar max_susp_len = wheel.getSuspensionRestLength()
|
||||||
+ wheel.m_maxSuspensionTravel;
|
+ wheel.m_maxSuspensionTravel;
|
||||||
|
|
||||||
// Do a slightly longer raycast to see if the kart might soon hit the
|
// Do a longer raycast to see if the kart might soon hit the
|
||||||
// ground and some 'cushioning' is needed to avoid that the chassis
|
// ground and some 'cushioning' is needed to avoid that the chassis
|
||||||
// hits the ground.
|
// hits the ground.
|
||||||
btScalar raylen = max_susp_len + 0.5f;
|
btScalar raylen = max_susp_len*10 + 0.5f;
|
||||||
|
|
||||||
btVector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen);
|
btVector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen);
|
||||||
const btVector3& source = wheel.m_raycastInfo.m_hardPointWS;
|
const btVector3& source = wheel.m_raycastInfo.m_hardPointWS;
|
||||||
@ -297,6 +308,9 @@ btScalar btKart::rayCast(unsigned int index, float fraction)
|
|||||||
wheel.m_raycastInfo.m_groundObject = 0;
|
wheel.m_raycastInfo.m_groundObject = 0;
|
||||||
|
|
||||||
btScalar depth = raylen * rayResults.m_distFraction;
|
btScalar depth = raylen * rayResults.m_distFraction;
|
||||||
|
|
||||||
|
if (depth < m_new_ground_height)
|
||||||
|
m_new_ground_height = depth;
|
||||||
if (object && depth < max_susp_len)
|
if (object && depth < max_susp_len)
|
||||||
{
|
{
|
||||||
wheel.m_raycastInfo.m_contactNormalWS = rayResults.m_hitNormalInWorld;
|
wheel.m_raycastInfo.m_contactNormalWS = rayResults.m_hitNormalInWorld;
|
||||||
@ -518,6 +532,7 @@ void btKart::updateVehicle( btScalar step )
|
|||||||
if(m_cushioning_disable_time>0) m_cushioning_disable_time --;
|
if(m_cushioning_disable_time>0) m_cushioning_disable_time --;
|
||||||
|
|
||||||
bool needed_cushioning = false;
|
bool needed_cushioning = false;
|
||||||
|
|
||||||
btVector3 v =
|
btVector3 v =
|
||||||
m_chassisBody->getVelocityInLocalPoint(m_wheelInfo[wheel_index]
|
m_chassisBody->getVelocityInLocalPoint(m_wheelInfo[wheel_index]
|
||||||
.m_chassisConnectionPointCS);
|
.m_chassisConnectionPointCS);
|
||||||
@ -528,7 +543,7 @@ void btKart::updateVehicle( btScalar step )
|
|||||||
|
|
||||||
#ifdef DEBUG_CUSHIONING
|
#ifdef DEBUG_CUSHIONING
|
||||||
Log::verbose("physics",
|
Log::verbose("physics",
|
||||||
"World %d wheel %d lsuspl %f vdown %f overall speed %f lenght %f",
|
"World %d wheel %d lsuspl %f vdown %f overall speed %f length %f",
|
||||||
World::getWorld()->getTimeTicks(),
|
World::getWorld()->getTimeTicks(),
|
||||||
wheel_index,
|
wheel_index,
|
||||||
m_wheelInfo[wheel_index].m_raycastInfo.m_suspensionLength,
|
m_wheelInfo[wheel_index].m_raycastInfo.m_suspensionLength,
|
||||||
@ -536,6 +551,14 @@ void btKart::updateVehicle( btScalar step )
|
|||||||
-v_down.getY() + 9.8*step,
|
-v_down.getY() + 9.8*step,
|
||||||
step * (-v_down.getY() + 9.8*step)+offset);
|
step * (-v_down.getY() + 9.8*step)+offset);
|
||||||
#endif
|
#endif
|
||||||
|
// Update the ground height history
|
||||||
|
for (int i=stk_config->time2Ticks(HISTORY_TIME)-1;i>0;i--)
|
||||||
|
{
|
||||||
|
m_ground_height[i] = m_ground_height[i-1];
|
||||||
|
}
|
||||||
|
m_ground_height[0] = m_new_ground_height;
|
||||||
|
m_new_ground_height = 999.9f;
|
||||||
|
|
||||||
// If the kart is falling, estimate the distance the kart will fall
|
// 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.
|
// in the next time step: the speed gets increased by the gravity*dt.
|
||||||
// This approximation is still not good enough (either because of
|
// This approximation is still not good enough (either because of
|
||||||
@ -544,9 +567,15 @@ void btKart::updateVehicle( btScalar step )
|
|||||||
// predict the upcoming collision correcty - so we add an offset
|
// predict the upcoming collision correcty - so we add an offset
|
||||||
// to the predicted kart movement, which was found experimentally:
|
// to the predicted kart movement, which was found experimentally:
|
||||||
btScalar gravity = m_chassisBody->getGravity().length();
|
btScalar gravity = m_chassisBody->getGravity().length();
|
||||||
|
|
||||||
|
btScalar predicted_fall = -v_down.getY() + gravity*step +
|
||||||
|
(m_ground_height[stk_config->time2Ticks(HISTORY_TIME)-1]
|
||||||
|
-m_ground_height[0])/stk_config->time2Ticks(HISTORY_TIME);
|
||||||
|
|
||||||
if (v_down.getY()<0 && m_cushioning_disable_time==0 &&
|
if (v_down.getY()<0 && m_cushioning_disable_time==0 &&
|
||||||
m_wheelInfo[wheel_index].m_raycastInfo.m_suspensionLength
|
m_ground_height[0] < step*predicted_fall + offset &&
|
||||||
< step * (-v_down.getY()+gravity*step)+offset)
|
m_ground_height[0] > 0 &&
|
||||||
|
m_ground_height[stk_config->time2Ticks(HISTORY_TIME)-1] > 0.6)
|
||||||
{
|
{
|
||||||
// Disable more cushioning for 1 second. This avoids the problem
|
// Disable more cushioning for 1 second. This avoids the problem
|
||||||
// of hovering: a kart gets cushioned on a down-sloping area, still
|
// of hovering: a kart gets cushioned on a down-sloping area, still
|
||||||
@ -555,8 +584,8 @@ void btKart::updateVehicle( btScalar step )
|
|||||||
m_cushioning_disable_time = stk_config->time2Ticks(1);
|
m_cushioning_disable_time = stk_config->time2Ticks(1);
|
||||||
|
|
||||||
needed_cushioning = true;
|
needed_cushioning = true;
|
||||||
btVector3 impulse = down * (-v_down.getY() + gravity*step)
|
btVector3 impulse = down * predicted_fall
|
||||||
/ m_chassisBody->getInvMass();
|
/ m_chassisBody->getInvMass();
|
||||||
#ifdef DEBUG_CUSHIONING
|
#ifdef DEBUG_CUSHIONING
|
||||||
float v_old = m_chassisBody->getLinearVelocity().getY();
|
float v_old = m_chassisBody->getLinearVelocity().getY();
|
||||||
#endif
|
#endif
|
||||||
@ -564,12 +593,13 @@ void btKart::updateVehicle( btScalar step )
|
|||||||
#ifdef DEBUG_CUSHIONING
|
#ifdef DEBUG_CUSHIONING
|
||||||
Log::verbose("physics",
|
Log::verbose("physics",
|
||||||
"World %d Cushioning imp %f vdown %f from %f m/s to %f m/s "
|
"World %d Cushioning imp %f vdown %f from %f m/s to %f m/s "
|
||||||
"contact %f kart %f susp %f relspeed %f",
|
"height %f contact %f kart %f susp %f relspeed %f",
|
||||||
World::getWorld()->getTimeTicks(),
|
World::getWorld()->getTimeTicks(),
|
||||||
impulse.getY(),
|
impulse.getY(),
|
||||||
-v_down.getY(),
|
-v_down.getY(),
|
||||||
v_old,
|
v_old,
|
||||||
m_chassisBody->getLinearVelocity().getY(),
|
m_chassisBody->getLinearVelocity().getY(),
|
||||||
|
m_ground_height[0],
|
||||||
m_wheelInfo[wheel_index].m_raycastInfo.m_isInContact ?
|
m_wheelInfo[wheel_index].m_raycastInfo.m_isInContact ?
|
||||||
m_wheelInfo[wheel_index].m_raycastInfo.m_contactPointWS.getY()
|
m_wheelInfo[wheel_index].m_raycastInfo.m_contactPointWS.getY()
|
||||||
: -100,
|
: -100,
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#ifndef BT_KART_HPP
|
#ifndef BT_KART_HPP
|
||||||
#define BT_KART_HPP
|
#define BT_KART_HPP
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||||
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
|
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
|
||||||
#include "physics/btKartRaycast.hpp"
|
#include "physics/btKartRaycast.hpp"
|
||||||
@ -117,6 +119,13 @@ private:
|
|||||||
* physics steps, so need to be set again by the application. */
|
* physics steps, so need to be set again by the application. */
|
||||||
btScalar m_max_speed;
|
btScalar m_max_speed;
|
||||||
|
|
||||||
|
/** Smallest wheel height to the ground, with a few frames of history */
|
||||||
|
std::vector<btScalar> m_ground_height;
|
||||||
|
const float HISTORY_TIME = 0.05f;
|
||||||
|
|
||||||
|
/** Used to get the smallest weel height in the current frame */
|
||||||
|
btScalar m_new_ground_height;
|
||||||
|
|
||||||
/** True if the visual wheels touch the ground. */
|
/** True if the visual wheels touch the ground. */
|
||||||
bool m_visual_wheels_touch_ground;
|
bool m_visual_wheels_touch_ground;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user