diff options
author | Erwin Coumans <blender@erwincoumans.com> | 2006-02-21 09:08:58 +0300 |
---|---|---|
committer | Erwin Coumans <blender@erwincoumans.com> | 2006-02-21 09:08:58 +0300 |
commit | e4d8bd59848c5da98d2c4fd2f4468a26694fcaeb (patch) | |
tree | d9d430a1c11e261e3751cc0d2b4d1fcdd352e511 /extern | |
parent | 5913414bf4314e9426b7b230afd029f25cd94acb (diff) |
added vehicle specific files + updated scons file (Makefile/projectfiles need updating)
Diffstat (limited to 'extern')
-rwxr-xr-x | extern/bullet/BulletDynamics/Vehicle/RaycastVehicle.cpp | 603 | ||||
-rwxr-xr-x | extern/bullet/BulletDynamics/Vehicle/RaycastVehicle.h | 147 | ||||
-rwxr-xr-x | extern/bullet/BulletDynamics/Vehicle/VehicleRaycaster.h | 31 | ||||
-rwxr-xr-x | extern/bullet/BulletDynamics/Vehicle/WheelInfo.cpp | 55 | ||||
-rwxr-xr-x | extern/bullet/BulletDynamics/Vehicle/WheelInfo.h | 113 | ||||
-rw-r--r-- | extern/bullet/SConscript | 4 |
6 files changed, 952 insertions, 1 deletions
diff --git a/extern/bullet/BulletDynamics/Vehicle/RaycastVehicle.cpp b/extern/bullet/BulletDynamics/Vehicle/RaycastVehicle.cpp new file mode 100755 index 00000000000..2099aa9b880 --- /dev/null +++ b/extern/bullet/BulletDynamics/Vehicle/RaycastVehicle.cpp @@ -0,0 +1,603 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ + +#include "RaycastVehicle.h" +#include "ConstraintSolver/Solve2LinearConstraint.h" +#include "ConstraintSolver/JacobianEntry.h" +#include "SimdQuaternion.h" +#include "SimdVector3.h" +#include "VehicleRaycaster.h" +#include "WheelInfo.h" + + +#include "Dynamics/MassProps.h" +#include "ConstraintSolver/ContactConstraint.h" + + + +static RigidBody s_fixedObject( MassProps ( 0.0f, SimdVector3(0,0,0) ),0.f,0.f,0.f,0.f); + +RaycastVehicle::RaycastVehicle(const VehicleTuning& tuning,RigidBody* chassis, VehicleRaycaster* raycaster ) +:m_vehicleRaycaster(raycaster), +m_pitchControl(0.f) +{ + m_chassisBody = chassis; + m_indexRightAxis = 0; + m_indexUpAxis = 2; + m_indexForwardAxis = 1; + DefaultInit(tuning); +} + + +void RaycastVehicle::DefaultInit(const VehicleTuning& tuning) +{ + m_currentVehicleSpeedKmHour = 0.f; + m_steeringValue = 0.f; + +} + + + +RaycastVehicle::~RaycastVehicle() +{ +} + + +// +// basically most of the code is general for 2 or 4 wheel vehicles, but some of it needs to be reviewed +// +WheelInfo& RaycastVehicle::AddWheel( const SimdVector3& connectionPointCS, const SimdVector3& wheelDirectionCS0,const SimdVector3& wheelAxleCS, SimdScalar suspensionRestLength, SimdScalar wheelRadius,const VehicleTuning& tuning, bool isFrontWheel) +{ + + WheelInfoConstructionInfo ci; + + ci.m_chassisConnectionCS = connectionPointCS; + ci.m_wheelDirectionCS = wheelDirectionCS0; + ci.m_wheelAxleCS = wheelAxleCS; + ci.m_suspensionRestLength = suspensionRestLength; + ci.m_wheelRadius = wheelRadius; + ci.m_suspensionStiffness = tuning.m_suspensionStiffness; + ci.m_wheelsDampingCompression = tuning.m_suspensionCompression; + ci.m_wheelsDampingRelaxation = tuning.m_suspensionDamping; + ci.m_frictionSlip = tuning.m_frictionSlip; + ci.m_bIsFrontWheel = isFrontWheel; + ci.m_maxSuspensionTravelCm = tuning.m_maxSuspensionTravelCm; + + m_wheelInfo.push_back( WheelInfo(ci)); + + WheelInfo& wheel = m_wheelInfo[GetNumWheels()-1]; + + UpdateWheelTransformsWS( wheel ); + return wheel; +} + + + + +const SimdTransform& RaycastVehicle::GetWheelTransformWS( int wheelIndex ) const +{ + assert(wheelIndex < GetNumWheels()); + const WheelInfo& wheel = m_wheelInfo[wheelIndex]; + return wheel.m_worldTransform; + +} + +void RaycastVehicle::UpdateWheelTransform( int wheelIndex ) +{ + WheelInfo& wheel = m_wheelInfo[ wheelIndex ]; + SimdVector3 up = -wheel.m_raycastInfo.m_wheelDirectionWS; + const SimdVector3& right = wheel.m_raycastInfo.m_wheelAxleWS; + SimdVector3 fwd = up.cross(right); + fwd = fwd.normalize(); + //rotate around steering over de wheelAxleWS + float steering = wheel.m_steering; + + SimdQuaternion steeringOrn(up,steering);//wheel.m_steering); + SimdMatrix3x3 steeringMat(steeringOrn); + + SimdQuaternion rotatingOrn(right,wheel.m_rotation); + SimdMatrix3x3 rotatingMat(rotatingOrn); + + SimdMatrix3x3 basis2( + right[0],fwd[0],up[0], + right[1],fwd[1],up[1], + right[2],fwd[2],up[2] + ); + + wheel.m_worldTransform.setBasis(steeringMat * rotatingMat * basis2); + wheel.m_worldTransform.setOrigin( + wheel.m_raycastInfo.m_hardPointWS + wheel.m_raycastInfo.m_wheelDirectionWS * wheel.m_raycastInfo.m_suspensionLength + ); +} + +void RaycastVehicle::ResetSuspension() +{ + + std::vector<WheelInfo>::iterator wheelIt; + for (wheelIt = m_wheelInfo.begin(); + !(wheelIt == m_wheelInfo.end());wheelIt++) + { + WheelInfo& wheel = *wheelIt; + wheel.m_raycastInfo.m_suspensionLength = wheel.GetSuspensionRestLength(); + wheel.m_suspensionRelativeVelocity = 0.0f; + + wheel.m_raycastInfo.m_contactNormalWS = - wheel.m_raycastInfo.m_wheelDirectionWS; + //wheel_info.setContactFriction(0.0f); + wheel.m_clippedInvContactDotSuspension = 1.0f; + } +} + +void RaycastVehicle::UpdateWheelTransformsWS(WheelInfo& wheel ) +{ + wheel.m_raycastInfo.m_isInContact = false; + + const SimdTransform& chassisTrans = GetRigidBody()->getCenterOfMassTransform(); + + wheel.m_raycastInfo.m_hardPointWS = chassisTrans( wheel.m_chassisConnectionPointCS ); + wheel.m_raycastInfo.m_wheelDirectionWS = chassisTrans.getBasis() * wheel.m_wheelDirectionCS ; + wheel.m_raycastInfo.m_wheelAxleWS = chassisTrans.getBasis() * wheel.m_wheelAxleCS; +} + +SimdScalar RaycastVehicle::Raycast(WheelInfo& wheel) +{ + UpdateWheelTransformsWS( wheel ); + + + SimdScalar depth = -1; + + SimdScalar raylen = wheel.GetSuspensionRestLength()+wheel.m_wheelsRadius; + + SimdVector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen); + const SimdVector3& source = wheel.m_raycastInfo.m_hardPointWS; + wheel.m_raycastInfo.m_contactPointWS = source + rayvector; + const SimdVector3& target = wheel.m_raycastInfo.m_contactPointWS; + + SimdScalar param = 0.f; + + VehicleRaycaster::VehicleRaycasterResult rayResults; + + void* object = m_vehicleRaycaster->CastRay(source,target,rayResults); + + wheel.m_raycastInfo.m_groundObject = 0; + + if (object) + { + param = rayResults.m_distFraction; + depth = raylen * rayResults.m_distFraction; + wheel.m_raycastInfo.m_contactNormalWS = rayResults.m_hitNormalInWorld; + wheel.m_raycastInfo.m_isInContact = true; + + wheel.m_raycastInfo.m_groundObject = &s_fixedObject;//todo for driving on dynamic/movable objects!; + //wheel.m_raycastInfo.m_groundObject = object; + + + SimdScalar hitDistance = param*raylen; + wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelsRadius; + //clamp on max suspension travel + + float minSuspensionLength = wheel.GetSuspensionRestLength() - wheel.m_maxSuspensionTravelCm*0.01f; + float maxSuspensionLength = wheel.GetSuspensionRestLength()+ wheel.m_maxSuspensionTravelCm*0.01f; + if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength) + { + wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength; + } + if (wheel.m_raycastInfo.m_suspensionLength > maxSuspensionLength) + { + wheel.m_raycastInfo.m_suspensionLength = maxSuspensionLength; + } + + wheel.m_raycastInfo.m_contactPointWS = rayResults.m_hitPointInWorld; + + SimdScalar denominator= wheel.m_raycastInfo.m_contactNormalWS.dot( wheel.m_raycastInfo.m_wheelDirectionWS ); + + SimdVector3 chassis_velocity_at_contactPoint; + SimdVector3 relpos = wheel.m_raycastInfo.m_contactPointWS-GetRigidBody()->getCenterOfMassPosition(); + + chassis_velocity_at_contactPoint = GetRigidBody()->getVelocityInLocalPoint(relpos); + + SimdScalar projVel = wheel.m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint ); + + if ( denominator >= -0.1f) + { + wheel.m_suspensionRelativeVelocity = 0.0f; + wheel.m_clippedInvContactDotSuspension = 1.0f / 0.1f; + } + else + { + SimdScalar inv = -1.f / denominator; + wheel.m_suspensionRelativeVelocity = projVel * inv; + wheel.m_clippedInvContactDotSuspension = inv; + } + + } else + { + //put wheel info as in rest position + wheel.m_raycastInfo.m_suspensionLength = wheel.GetSuspensionRestLength(); + wheel.m_suspensionRelativeVelocity = 0.0f; + wheel.m_raycastInfo.m_contactNormalWS = - wheel.m_raycastInfo.m_wheelDirectionWS; + wheel.m_clippedInvContactDotSuspension = 1.0f; + } + + return depth; +} + + +void RaycastVehicle::UpdateVehicle( SimdScalar step ) +{ + + m_currentVehicleSpeedKmHour = 3.6f * GetRigidBody()->getLinearVelocity().length(); + + const SimdTransform& chassisTrans = GetRigidBody()->getCenterOfMassTransform(); + SimdVector3 forwardW ( + chassisTrans.getBasis()[0][m_indexForwardAxis], + chassisTrans.getBasis()[1][m_indexForwardAxis], + chassisTrans.getBasis()[2][m_indexForwardAxis]); + + if (forwardW.dot(GetRigidBody()->getLinearVelocity()) < 0.f) + { + m_currentVehicleSpeedKmHour *= -1.f; + } + + // + // simulate suspension + // + std::vector<WheelInfo>::iterator wheelIt; + int i=0; + for (wheelIt = m_wheelInfo.begin(); + !(wheelIt == m_wheelInfo.end());wheelIt++,i++) + { + WheelInfo& wheelInfo = *wheelIt; + + SimdScalar depth; + depth = Raycast( *wheelIt ); + } + + UpdateSuspension(step); + + + for (wheelIt = m_wheelInfo.begin(); + !(wheelIt == m_wheelInfo.end());wheelIt++) + { + //apply suspension force + WheelInfo& wheel = *wheelIt; + + float suspensionForce = wheel.m_wheelsSuspensionForce; + + float gMaxSuspensionForce = 6000.f; + if (suspensionForce > gMaxSuspensionForce) + { + suspensionForce = gMaxSuspensionForce; + } + SimdVector3 impulse = wheel.m_raycastInfo.m_contactNormalWS * suspensionForce * step; + SimdVector3 relpos = wheel.m_raycastInfo.m_contactPointWS - GetRigidBody()->getCenterOfMassPosition(); + + GetRigidBody()->applyImpulse(impulse, relpos); + + } + + + + UpdateFriction( step); + + + for (wheelIt = m_wheelInfo.begin(); + !(wheelIt == m_wheelInfo.end());wheelIt++) + { + WheelInfo& wheel = *wheelIt; + SimdVector3 relpos = wheel.m_raycastInfo.m_hardPointWS - GetRigidBody()->getCenterOfMassPosition(); + SimdVector3 vel = GetRigidBody()->getVelocityInLocalPoint( relpos ); + + if (wheel.m_raycastInfo.m_isInContact) + { + SimdVector3 fwd ( + GetRigidBody()->getCenterOfMassTransform().getBasis()[0][m_indexForwardAxis], + GetRigidBody()->getCenterOfMassTransform().getBasis()[1][m_indexForwardAxis], + GetRigidBody()->getCenterOfMassTransform().getBasis()[2][m_indexForwardAxis]); + + SimdScalar proj = fwd.dot(wheel.m_raycastInfo.m_contactNormalWS); + fwd -= wheel.m_raycastInfo.m_contactNormalWS * proj; + + SimdScalar proj2 = fwd.dot(vel); + + wheel.m_deltaRotation = (proj2 * step) / (wheel.m_wheelsRadius); + wheel.m_rotation += wheel.m_deltaRotation; + + } else + { + wheel.m_rotation += wheel.m_deltaRotation; + } + + wheel.m_deltaRotation *= 0.99f;//damping of rotation when not in contact + + } + + + +} + + +void RaycastVehicle::SetSteeringValue(SimdScalar steering,int wheel) +{ + assert(wheel>=0 && wheel < GetNumWheels()); + + WheelInfo& wheelInfo = GetWheelInfo(wheel); + wheelInfo.m_steering = steering; +} + + + +SimdScalar RaycastVehicle::GetSteeringValue(int wheel) const +{ + return GetWheelInfo(wheel).m_steering; +} + + +void RaycastVehicle::ApplyEngineForce(SimdScalar force, int wheel) +{ + for (int i=0;i<GetNumWheels();i++) + { + WheelInfo& wheelInfo = GetWheelInfo(i); + + bool applyOnFrontWheel = !wheel; + + if (applyOnFrontWheel == wheelInfo.m_bIsFrontWheel) + { + wheelInfo.m_engineForce = force; + } + } +} + + +const WheelInfo& RaycastVehicle::GetWheelInfo(int index) const +{ + ASSERT((index >= 0) && (index < GetNumWheels())); + + return m_wheelInfo[index]; +} + +WheelInfo& RaycastVehicle::GetWheelInfo(int index) +{ + ASSERT((index >= 0) && (index < GetNumWheels())); + + return m_wheelInfo[index]; +} + +void RaycastVehicle::SetBrake(float brake,int wheelIndex) +{ + ASSERT((wheelIndex >= 0) && (wheelIndex < GetNumWheels())); + GetWheelInfo(wheelIndex).m_brake; +} + + +void RaycastVehicle::UpdateSuspension(SimdScalar deltaTime) +{ + + SimdScalar chassisMass = 1.f / m_chassisBody->getInvMass(); + + for (int w_it=0; w_it<GetNumWheels(); w_it++) + { + WheelInfo &wheel_info = m_wheelInfo[w_it]; + + if ( wheel_info.m_raycastInfo.m_isInContact ) + { + SimdScalar force; + // Spring + { + SimdScalar susp_length = wheel_info.GetSuspensionRestLength(); + SimdScalar current_length = wheel_info.m_raycastInfo.m_suspensionLength; + + SimdScalar length_diff = (susp_length - current_length); + + force = wheel_info.m_suspensionStiffness + * length_diff * wheel_info.m_clippedInvContactDotSuspension; + } + + // Damper + { + SimdScalar projected_rel_vel = wheel_info.m_suspensionRelativeVelocity; + { + SimdScalar susp_damping; + if ( projected_rel_vel < 0.0f ) + { + susp_damping = wheel_info.m_wheelsDampingCompression; + } + else + { + susp_damping = wheel_info.m_wheelsDampingRelaxation; + } + force -= susp_damping * projected_rel_vel; + } + } + + // RESULT + wheel_info.m_wheelsSuspensionForce = force * chassisMass; + if (wheel_info.m_wheelsSuspensionForce < 0.f) + { + wheel_info.m_wheelsSuspensionForce = 0.f; + } + } + else + { + wheel_info.m_wheelsSuspensionForce = 0.0f; + } + } + +} + +float sideFrictionStiffness2 = 1.0f; +void RaycastVehicle::UpdateFriction(SimdScalar timeStep) +{ + + //calculate the impulse, so that the wheels don't move sidewards + int numWheel = GetNumWheels(); + if (!numWheel) + return; + + + SimdVector3* forwardWS = new SimdVector3[numWheel]; + SimdVector3* axle = new SimdVector3[numWheel]; + SimdScalar* forwardImpulse = new SimdScalar[numWheel]; + SimdScalar* sideImpulse = new SimdScalar[numWheel]; + + int numWheelsOnGround = 0; + + + //collapse all those loops into one! + for (int i=0;i<GetNumWheels();i++) + { + WheelInfo& wheelInfo = m_wheelInfo[i]; + class RigidBody* groundObject = (class RigidBody*) wheelInfo.m_raycastInfo.m_groundObject; + if (groundObject) + numWheelsOnGround++; + sideImpulse[i] = 0.f; + forwardImpulse[i] = 0.f; + + } + + { + + for (int i=0;i<GetNumWheels();i++) + { + + WheelInfo& wheelInfo = m_wheelInfo[i]; + + class RigidBody* groundObject = (class RigidBody*) wheelInfo.m_raycastInfo.m_groundObject; + + if (groundObject) + { + + const SimdTransform& wheelTrans = GetWheelTransformWS( i ); + + SimdMatrix3x3 wheelBasis0 = wheelTrans.getBasis(); + axle[i] = SimdVector3( + wheelBasis0[0][m_indexRightAxis], + wheelBasis0[1][m_indexRightAxis], + wheelBasis0[2][m_indexRightAxis]); + + const SimdVector3& surfNormalWS = wheelInfo.m_raycastInfo.m_contactNormalWS; + SimdScalar proj = axle[i].dot(surfNormalWS); + axle[i] -= surfNormalWS * proj; + axle[i] = axle[i].normalize(); + + forwardWS[i] = surfNormalWS.cross(axle[i]); + forwardWS[i].normalize(); + + + resolveSingleBilateral(*m_chassisBody, wheelInfo.m_raycastInfo.m_contactPointWS, + *groundObject, wheelInfo.m_raycastInfo.m_contactPointWS, + 0.f, axle[i],sideImpulse[i],timeStep); + + sideImpulse[i] *= sideFrictionStiffness2; + + } + + + } + } + + SimdScalar sideFactor = 1.f; + SimdScalar fwdFactor = 0.5; + + bool sliding = false; + { + for (int wheel =0;wheel <GetNumWheels();wheel++) + { + WheelInfo& wheelInfo = m_wheelInfo[wheel]; + class RigidBody* groundObject = (class RigidBody*) wheelInfo.m_raycastInfo.m_groundObject; + + + forwardImpulse[wheel] = 0.f; + m_wheelInfo[wheel].m_skidInfo= 1.f; + + if (groundObject) + { + m_wheelInfo[wheel].m_skidInfo= 1.f; + + SimdScalar maximp = wheelInfo.m_wheelsSuspensionForce * timeStep * wheelInfo.m_frictionSlip; + SimdScalar maximpSide = maximp; + + SimdScalar maximpSquared = maximp * maximpSide; + + forwardImpulse[wheel] = wheelInfo.m_engineForce* timeStep; + + float x = (forwardImpulse[wheel] ) * fwdFactor; + float y = (sideImpulse[wheel] ) * sideFactor; + + float impulseSquared = (x*x + y*y); + + if (impulseSquared > maximpSquared) + { + sliding = true; + + SimdScalar factor = maximp / sqrtf(impulseSquared); + + m_wheelInfo[wheel].m_skidInfo *= factor; + } + } + + } + } + + + + + if (sliding) + { + for (int wheel = 0;wheel < GetNumWheels(); wheel++) + { + if (sideImpulse[wheel] != 0.f) + { + if (m_wheelInfo[wheel].m_skidInfo< 1.f) + { + forwardImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo; + sideImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo; + } + } + } + } + + // apply the impulses + { + for (int wheel = 0;wheel<GetNumWheels() ; wheel++) + { + WheelInfo& wheelInfo = m_wheelInfo[wheel]; + + SimdVector3 rel_pos = wheelInfo.m_raycastInfo.m_contactPointWS - + m_chassisBody->getCenterOfMassPosition(); + + if (forwardImpulse[wheel] != 0.f) + { + m_chassisBody->applyImpulse(forwardWS[wheel]*(forwardImpulse[wheel]),rel_pos); + } + if (sideImpulse[wheel] != 0.f) + { + class RigidBody* groundObject = (class RigidBody*) m_wheelInfo[wheel].m_raycastInfo.m_groundObject; + + SimdVector3 rel_pos2 = wheelInfo.m_raycastInfo.m_contactPointWS - + groundObject->getCenterOfMassPosition(); + + + SimdVector3 sideImp = axle[wheel] * sideImpulse[wheel]; + + rel_pos[2] *= 0.1; + m_chassisBody->applyImpulse(sideImp,rel_pos); + + //apply friction impulse on the ground + groundObject->applyImpulse(-sideImp,rel_pos2); + } + } + } + + delete []forwardWS; + delete [] axle; + delete[]forwardImpulse; + delete[] sideImpulse; +} diff --git a/extern/bullet/BulletDynamics/Vehicle/RaycastVehicle.h b/extern/bullet/BulletDynamics/Vehicle/RaycastVehicle.h new file mode 100755 index 00000000000..70f7318feca --- /dev/null +++ b/extern/bullet/BulletDynamics/Vehicle/RaycastVehicle.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef RAYCASTVEHICLE_H +#define RAYCASTVEHICLE_H + +#include "Dynamics/RigidBody.h" +#include "ConstraintSolver/TypedConstraint.h" + +struct MassProps; +struct WheelInfo; +struct VehicleRaycaster; +class VehicleTuning; + +///Raycast vehicle, very special constraint that turn a rigidbody into a vehicle. +class RaycastVehicle : public TypedConstraint +{ +public: + class VehicleTuning + { + public: + + VehicleTuning() + :m_suspensionStiffness(5.88f), + m_suspensionCompression(0.83f), + m_suspensionDamping(0.88f), + m_maxSuspensionTravelCm(500.f), + m_frictionSlip(10.5f) + { + } + float m_suspensionStiffness; + float m_suspensionCompression; + float m_suspensionDamping; + float m_maxSuspensionTravelCm; + float m_frictionSlip; + + }; +private: + + SimdScalar m_tau; + SimdScalar m_damping; + VehicleRaycaster* m_vehicleRaycaster; + float m_pitchControl; + float m_steeringValue; + float m_currentVehicleSpeedKmHour; + + RigidBody* m_chassisBody; + + int m_indexRightAxis; + int m_indexUpAxis; + int m_indexForwardAxis; + + void DefaultInit(const VehicleTuning& tuning); + +public: + + //constructor to create a car from an existing rigidbody + RaycastVehicle(const VehicleTuning& tuning,RigidBody* chassis, VehicleRaycaster* raycaster ); + + virtual ~RaycastVehicle() ; + + + + + + SimdScalar Raycast(WheelInfo& wheel); + + virtual void UpdateVehicle(SimdScalar step); + + void ResetSuspension(); + + SimdScalar GetSteeringValue(int wheel) const; + + void SetSteeringValue(SimdScalar steering,int wheel); + + + void ApplyEngineForce(SimdScalar force, int wheel); + + const SimdTransform& GetWheelTransformWS( int wheelIndex ) const; + + void UpdateWheelTransform( int wheelIndex ); + + void SetRaycastWheelInfo( int wheelIndex , bool isInContact, const SimdVector3& hitPoint, const SimdVector3& hitNormal,SimdScalar depth); + + WheelInfo& AddWheel( const SimdVector3& connectionPointCS0, const SimdVector3& wheelDirectionCS0,const SimdVector3& wheelAxleCS,SimdScalar suspensionRestLength,SimdScalar wheelRadius,const VehicleTuning& tuning, bool isFrontWheel); + + inline int GetNumWheels() const { + return m_wheelInfo.size(); + } + + std::vector<WheelInfo> m_wheelInfo; + + + const WheelInfo& GetWheelInfo(int index) const; + + WheelInfo& GetWheelInfo(int index); + + void UpdateWheelTransformsWS(WheelInfo& wheel ); + + + void SetBrake(float brake,int wheelIndex); + + void SetPitchControl(float pitch) + { + m_pitchControl = pitch; + } + + void UpdateSuspension(SimdScalar deltaTime); + + void UpdateFriction(SimdScalar timeStep); + + + + inline RigidBody* GetRigidBody() + { + return m_chassisBody; + } + + const RigidBody* GetRigidBody() const + { + return m_chassisBody; + } + + inline int GetRightAxis() const + { + return m_indexRightAxis; + } + inline int GetUpAxis() const + { + return m_indexUpAxis; + } + + inline int GetForwardAxis() const + { + return m_indexForwardAxis; + } + +}; + +#endif //RAYCASTVEHICLE_H
\ No newline at end of file diff --git a/extern/bullet/BulletDynamics/Vehicle/VehicleRaycaster.h b/extern/bullet/BulletDynamics/Vehicle/VehicleRaycaster.h new file mode 100755 index 00000000000..12119700120 --- /dev/null +++ b/extern/bullet/BulletDynamics/Vehicle/VehicleRaycaster.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef VEHICLE_RAYCASTER_H +#define VEHICLE_RAYCASTER_H + +#include "SimdVector3.h" + +/// VehicleRaycaster is provides interface for between vehicle simulation and raycasting +struct VehicleRaycaster +{ + struct VehicleRaycasterResult + { + VehicleRaycasterResult() :m_distFraction(-1.f){}; + SimdVector3 m_hitPointInWorld; + SimdVector3 m_hitNormalInWorld; + SimdScalar m_distFraction; + }; + + virtual void* CastRay(const SimdVector3& from,const SimdVector3& to, VehicleRaycasterResult& result) = 0; + +}; + +#endif //VEHICLE_RAYCASTER_H
\ No newline at end of file diff --git a/extern/bullet/BulletDynamics/Vehicle/WheelInfo.cpp b/extern/bullet/BulletDynamics/Vehicle/WheelInfo.cpp new file mode 100755 index 00000000000..480fb484671 --- /dev/null +++ b/extern/bullet/BulletDynamics/Vehicle/WheelInfo.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#include "WheelInfo.h" +#include "Dynamics/RigidBody.h" // for pointvelocity + + +SimdScalar WheelInfo::GetSuspensionRestLength() const +{ + + return m_suspensionRestLength1; + +} + +void WheelInfo::UpdateWheel(const RigidBody& chassis,RaycastInfo& raycastInfo) +{ + + + if (m_raycastInfo.m_isInContact) + + { + SimdScalar project= m_raycastInfo.m_contactNormalWS.dot( m_raycastInfo.m_wheelDirectionWS ); + SimdVector3 chassis_velocity_at_contactPoint; + SimdVector3 relpos = m_raycastInfo.m_contactPointWS - chassis.getCenterOfMassPosition(); + chassis_velocity_at_contactPoint = chassis.getVelocityInLocalPoint( relpos ); + SimdScalar projVel = m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint ); + if ( project >= -0.1f) + { + m_suspensionRelativeVelocity = 0.0f; + m_clippedInvContactDotSuspension = 1.0f / 0.1f; + } + else + { + SimdScalar inv = -1.f / project; + m_suspensionRelativeVelocity = projVel * inv; + m_clippedInvContactDotSuspension = inv; + } + + } + + else // Not in contact : position wheel in a nice (rest length) position + { + m_raycastInfo.m_suspensionLength = this->GetSuspensionRestLength(); + m_suspensionRelativeVelocity = 0.0f; + m_raycastInfo.m_contactNormalWS = -m_raycastInfo.m_wheelDirectionWS; + m_clippedInvContactDotSuspension = 1.0f; + } +} diff --git a/extern/bullet/BulletDynamics/Vehicle/WheelInfo.h b/extern/bullet/BulletDynamics/Vehicle/WheelInfo.h new file mode 100755 index 00000000000..bd69a634597 --- /dev/null +++ b/extern/bullet/BulletDynamics/Vehicle/WheelInfo.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/ + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies. + * Erwin Coumans makes no representations about the suitability + * of this software for any purpose. + * It is provided "as is" without express or implied warranty. +*/ +#ifndef WHEEL_INFO_H +#define WHEEL_INFO_H + +#include "SimdVector3.h" +#include "SimdTransform.h" + +class RigidBody; + +struct WheelInfoConstructionInfo +{ + SimdVector3 m_chassisConnectionCS; + SimdVector3 m_wheelDirectionCS; + SimdVector3 m_wheelAxleCS; + SimdScalar m_suspensionRestLength; + SimdScalar m_maxSuspensionTravelCm; + SimdScalar m_wheelRadius; + + float m_suspensionStiffness; + float m_wheelsDampingCompression; + float m_wheelsDampingRelaxation; + float m_frictionSlip; + bool m_bIsFrontWheel; + +}; + +/// WheelInfo contains information per wheel about friction and suspension. +struct WheelInfo +{ + struct RaycastInfo + { + //set by raycaster + SimdVector3 m_contactNormalWS;//contactnormal + SimdVector3 m_contactPointWS;//raycast hitpoint + SimdScalar m_suspensionLength; + SimdVector3 m_hardPointWS;//raycast starting point + SimdVector3 m_wheelDirectionWS; //direction in worldspace + SimdVector3 m_wheelAxleWS; // axle in worldspace + bool m_isInContact; + void* m_groundObject; //could be general void* ptr + }; + + RaycastInfo m_raycastInfo; + + SimdTransform m_worldTransform; + + SimdVector3 m_chassisConnectionPointCS; //const + SimdVector3 m_wheelDirectionCS;//const + SimdVector3 m_wheelAxleCS; // const or modified by steering + SimdScalar m_suspensionRestLength1;//const + SimdScalar m_maxSuspensionTravelCm; + SimdScalar GetSuspensionRestLength() const; + SimdScalar m_wheelsRadius;//const + SimdScalar m_suspensionStiffness;//const + SimdScalar m_wheelsDampingCompression;//const + SimdScalar m_wheelsDampingRelaxation;//const + SimdScalar m_frictionSlip; + SimdScalar m_steering; + SimdScalar m_rotation; + SimdScalar m_deltaRotation; + + SimdScalar m_engineForce; + + SimdScalar m_brake; + + bool m_bIsFrontWheel; + + void* m_clientInfo;//can be used to store pointer to sync transforms... + + WheelInfo(WheelInfoConstructionInfo& ci) + + { + + m_suspensionRestLength1 = ci.m_suspensionRestLength; + m_maxSuspensionTravelCm = ci.m_maxSuspensionTravelCm; + + m_wheelsRadius = ci.m_wheelRadius; + m_suspensionStiffness = ci.m_suspensionStiffness; + m_wheelsDampingCompression = ci.m_wheelsDampingCompression; + m_wheelsDampingRelaxation = ci.m_wheelsDampingRelaxation; + m_chassisConnectionPointCS = ci.m_chassisConnectionCS; + m_wheelDirectionCS = ci.m_wheelDirectionCS; + m_wheelAxleCS = ci.m_wheelAxleCS; + m_frictionSlip = ci.m_frictionSlip; + m_steering = 0.f; + m_engineForce = 0.f; + m_rotation = 0.f; + m_deltaRotation = 0.f; + m_brake = 0.f; + m_bIsFrontWheel = ci.m_bIsFrontWheel; + + } + + void UpdateWheel(const RigidBody& chassis,RaycastInfo& raycastInfo); + + SimdScalar m_clippedInvContactDotSuspension; + SimdScalar m_suspensionRelativeVelocity; + //calculated by suspension + SimdScalar m_wheelsSuspensionForce; + SimdScalar m_skidInfo; + +}; + +#endif //WHEEL_INFO_H
\ No newline at end of file diff --git a/extern/bullet/SConscript b/extern/bullet/SConscript index b6a92b43e8b..1974cedb87b 100644 --- a/extern/bullet/SConscript +++ b/extern/bullet/SConscript @@ -84,7 +84,9 @@ sources = [ 'Bullet/BroadphaseCollision/BroadphaseProxy.cpp', 'Bullet/CollisionDispatch/UnionFind.cpp', 'Bullet/NarrowPhaseCollision/CollisionObject.cpp', 'Bullet/CollisionDispatch/CollisionWorld.cpp', - + 'BulletDynamics/Vehicle/RaycastVehicle.cpp', + 'BulletDynamics/Vehicle/WheelInfo.cpp', + 'BulletDynamics/ConstraintSolver/ContactConstraint.cpp', 'BulletDynamics/ConstraintSolver/OdeConstraintSolver.cpp', 'BulletDynamics/ConstraintSolver/Point2PointConstraint.cpp', |