From 79873e2d4562447c403bb15d5ef2af12070b7c86 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 29 Sep 2014 11:54:46 +1000 Subject: [PATCH 1/3] Added (some) support for driving on walls, added documentation. --- src/physics/btKart.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp index 169610cd8..b065fbc1f 100644 --- a/src/physics/btKart.cpp +++ b/src/physics/btKart.cpp @@ -314,15 +314,33 @@ btScalar btKart::rayCast(unsigned int index) } else { + // The raycast either hit nothing (object=NULL), or it hit something, + // but not in the maximum suspension range. If it hit something, + // check for the need of cushioning: if(object) { + // If the raycast hit something, see if the jump needs cushioning: + // i.e. a slowdown in fall speed in order to avoid that on landing + // the chassis hits the ground (causing a severe slowdown of the + // kart). The cushioning is done if the fall distance (v_down * dt) + // in this physics step is large enough that the kart would hit the + // ground, i.e. the maximum suspension length plus fall distance + // is larger than the distance to the object that was just detected. - if(depth + m_chassisBody->getLinearVelocity().getY() *1./60.f < max_susp_len) + // To allow for wall driving, properly project the velocity + // onto the normal + btVector3 v = m_chassisBody->getLinearVelocity(); + btVector3 down(0, 1, 0); + btVector3 v_down = (v * down) * down; + + if(depth < max_susp_len + v_down.length() *1./60.f) { - btVector3 v = -0.25f*0.5f*m_chassisBody->getLinearVelocity(); - v.setZ(0); - v.setX(0); - m_chassisBody->applyCentralImpulse(v/m_chassisBody->getInvMass()); + // Apply an impulse that will roughly half the speed. Since + // there are 4 wheels, a single wheel should apply 1/4 of + // the necessary impulse: + btVector3 impulse = (-0.25f*0.5f/m_chassisBody->getInvMass()) + * v_down; + m_chassisBody->applyCentralImpulse(impulse); } } depth = btScalar(-1.0); From 11916dd187d91a4279c4c3275e0a0fe95bde70ea Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 30 Sep 2014 23:13:48 +1000 Subject: [PATCH 2/3] Different implementation of soft-landing. --- .../src/BulletDynamics/Vehicle/btWheelInfo.h | 4 +- src/physics/btKart.cpp | 64 +++++++++---------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/lib/bullet/src/BulletDynamics/Vehicle/btWheelInfo.h b/lib/bullet/src/BulletDynamics/Vehicle/btWheelInfo.h index f916053ec..daf4157ad 100644 --- a/lib/bullet/src/BulletDynamics/Vehicle/btWheelInfo.h +++ b/lib/bullet/src/BulletDynamics/Vehicle/btWheelInfo.h @@ -77,6 +77,8 @@ struct btWheelInfo bool m_bIsFrontWheel; + bool m_was_on_ground; + void* m_clientInfo;//can be used to store pointer to sync transforms... btWheelInfo(btWheelInfoConstructionInfo& ci) @@ -102,7 +104,7 @@ struct btWheelInfo m_rollInfluence = btScalar(0.1); m_bIsFrontWheel = ci.m_bIsFrontWheel; m_maxSuspensionForce = ci.m_maxSuspensionForce; - + m_was_on_ground = true; } void updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo); diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp index b065fbc1f..576477b75 100644 --- a/src/physics/btKart.cpp +++ b/src/physics/btKart.cpp @@ -260,18 +260,15 @@ btScalar btKart::rayCast(unsigned int index) depth = raylen * rayResults.m_distFraction; if (object && depth < max_susp_len) { - param = rayResults.m_distFraction; wheel.m_raycastInfo.m_contactNormalWS = rayResults.m_hitNormalInWorld; wheel.m_raycastInfo.m_contactNormalWS.normalize(); wheel.m_raycastInfo.m_isInContact = true; ///@todo for driving on dynamic/movable objects!; wheel.m_raycastInfo.m_groundObject = &getFixedBody(); - btScalar hitDistance = param*raylen; - wheel.m_raycastInfo.m_suspensionLength = - hitDistance - wheel.m_wheelsRadius; - //clamp on max suspension travel + wheel.m_raycastInfo.m_suspensionLength = depth - wheel.m_wheelsRadius; + //clamp on max suspension travel btScalar minSuspensionLength = wheel.getSuspensionRestLength() - wheel.m_maxSuspensionTravelCm*btScalar(0.01); btScalar maxSuspensionLength = wheel.getSuspensionRestLength() @@ -314,35 +311,6 @@ btScalar btKart::rayCast(unsigned int index) } else { - // The raycast either hit nothing (object=NULL), or it hit something, - // but not in the maximum suspension range. If it hit something, - // check for the need of cushioning: - if(object) - { - // If the raycast hit something, see if the jump needs cushioning: - // i.e. a slowdown in fall speed in order to avoid that on landing - // the chassis hits the ground (causing a severe slowdown of the - // kart). The cushioning is done if the fall distance (v_down * dt) - // in this physics step is large enough that the kart would hit the - // ground, i.e. the maximum suspension length plus fall distance - // is larger than the distance to the object that was just detected. - - // To allow for wall driving, properly project the velocity - // onto the normal - btVector3 v = m_chassisBody->getLinearVelocity(); - btVector3 down(0, 1, 0); - btVector3 v_down = (v * down) * down; - - if(depth < max_susp_len + v_down.length() *1./60.f) - { - // Apply an impulse that will roughly half the speed. Since - // there are 4 wheels, a single wheel should apply 1/4 of - // the necessary impulse: - btVector3 impulse = (-0.25f*0.5f/m_chassisBody->getInvMass()) - * v_down; - m_chassisBody->applyCentralImpulse(impulse); - } - } depth = btScalar(-1.0); //put wheel info as in rest position wheel.m_raycastInfo.m_suspensionLength = wheel.getSuspensionRestLength(); @@ -422,6 +390,32 @@ void btKart::updateVehicle( btScalar step ) m_num_wheels_on_ground++; } + bool needs_cushioning_test = false; + for(int i=0; igetLinearVelocity(); + btVector3 down(0, 1, 0); + btVector3 v_down = (v * down) * down; + btScalar max_compensate_speed = m_wheelInfo[0].m_maxSuspensionForce * m_chassisBody->getInvMass() * step *4; + if(-v_down.getY() > max_compensate_speed) + { + btVector3 impulse = down * (-v_down.getY() - max_compensate_speed) / m_chassisBody->getInvMass(); + Log::verbose("physics", "Cushioning %f", impulse.getY()); + m_chassisBody->applyCentralImpulse(impulse); + } + } + for(int i=0; iapplyTorqueImpulse(axis * m_kart->getKartProperties()->getSmoothFlyingImpulse()); } - + // Work around: make sure that either both wheels on one axis // are on ground, or none of them. This avoids the problem of // the kart suddenly getting additional angular velocity because From e55959555e7e3003e9e7d6e560cce28b86aeb26f Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 30 Sep 2014 23:59:17 +1000 Subject: [PATCH 3/3] Added more debug output. --- src/physics/btKart.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp index 576477b75..2b807b322 100644 --- a/src/physics/btKart.cpp +++ b/src/physics/btKart.cpp @@ -409,8 +409,10 @@ void btKart::updateVehicle( btScalar step ) if(-v_down.getY() > max_compensate_speed) { btVector3 impulse = down * (-v_down.getY() - max_compensate_speed) / m_chassisBody->getInvMass(); - Log::verbose("physics", "Cushioning %f", impulse.getY()); + float v_old = m_chassisBody->getLinearVelocity().getY(); m_chassisBody->applyCentralImpulse(impulse); + Log::verbose("physics", "Cushioning %f from %f m/s to %f m/s", impulse.getY(), + v_old, m_chassisBody->getLinearVelocity().getY()); } } for(int i=0; i