As I wrote in Subject, Vehicle was running on a track made using btBvhTriangleMeshShape when it randomly bounces off like something got caught in a wheel.
I have already confirmed that there is no element in the mesh that can be caught in the wheel.
here's video link.
https://youtu.be/lYUlhcdB0iw
and here's how I create vehicle and control it.
void PhysicsPlayer::BuildRigidBody(const std::shared_ptr<BulletWrapper>& physics)
{
auto dynamicsWorld = physics->GetDynamicsWorld();
mOOBB.Extents = { 10.0f, 4.0f, 14.0f };
XMFLOAT3 vehicleExtents = mOOBB.Extents;
XMFLOAT3 wheelExtents = mWheel[0]->GetBoundingBox().Extents;
btTransform btCarTransform;
btCarTransform.setIdentity();
btCarTransform.setOrigin(btVector3(mPosition.x, mPosition.y, mPosition.z));
LoadConvexHullShape(L"Models\\Car_Body_Convex_Hull.obj", physics);
mBtRigidBody = physics->CreateRigidBody(1000.0f, btCarTransform, mBtCollisionShape);
mVehicleRayCaster = std::make_shared<btDefaultVehicleRaycaster>(dynamicsWorld);
mVehicle = std::make_shared<btRaycastVehicle>(mTuning, mBtRigidBody, mVehicleRayCaster.get());
mBtRigidBody = mVehicle->getRigidBody();
mBtRigidBody->setActivationState(DISABLE_DEACTIVATION);
//mBtRigidBody->setGravity(btVector3(0, -20, 0));
dynamicsWorld->addVehicle(mVehicle.get());
mVehicle->setCoordinateSystem(0, 1, 2);
btVector3 wheelDirectionCS0(0, -1, 0);
btVector3 wheelAxleCS(-1, 0, 0);
float wheelWidth = wheelExtents.x;
float wheelRadius = wheelExtents.z;
float wheelFriction = mWheelFriction;
float suspensionStiffness = 20.f;
float suspensionDamping = 2.3f;
float suspensionCompression = 4.4f;
float rollInfluence = 0.01f; //1.0f;
// 앞바퀴
bool isFrontWheel = true;
float connectionHeight = -0.9f;
btVector3 connectionPointCS0(vehicleExtents.x - 2.5f, connectionHeight, vehicleExtents.z - 2.8f);
mVehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, 0.6f, wheelRadius, mTuning, isFrontWheel);
connectionPointCS0 = btVector3(-vehicleExtents.x + 2.5f, connectionHeight, vehicleExtents.z - 2.8f);
mVehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, 0.6f, wheelRadius, mTuning, isFrontWheel);
isFrontWheel = false;
connectionPointCS0 = btVector3(vehicleExtents.x - 2.3f, connectionHeight, -vehicleExtents.z + 2.6f);
mVehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, 0.6f, wheelRadius, mTuning, isFrontWheel);
connectionPointCS0 = btVector3(-vehicleExtents.x + 2.3f, connectionHeight, -vehicleExtents.z + 2.6f);
mVehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, 0.6f, wheelRadius, mTuning, isFrontWheel);
for (int i = 0; i < mVehicle->getNumWheels(); i++)
{
btWheelInfo& wheel = mVehicle->getWheelInfo(i);
wheel.m_suspensionStiffness = suspensionStiffness;
wheel.m_wheelsDampingRelaxation = suspensionDamping;
wheel.m_wheelsDampingCompression = suspensionCompression;
wheel.m_frictionSlip = wheelFriction;
wheel.m_rollInfluence = rollInfluence;
}
}
class PhysicsPlayer : public Player
{
//Other functions and variables were excluded because they were not related to the bullet.
private:
const float mWheelFriction = 10.0f;
const float mWheelDriftFriction = 5.0f;
std::shared_ptr<WheelObject> mWheel[4];
btRaycastVehicle::btVehicleTuning mTuning;
std::shared_ptr<btVehicleRaycaster> mVehicleRayCaster;
std::shared_ptr<btRaycastVehicle> mVehicle;
float mBoosterLeft = 0.0f;
float mBoosterTime = 5.0f;
float mEngineForce = 0.f;
float mMaxEngineForce = 8000.f;
float mMaxBackwardEngineForce = 10000.f;
float mBoosterEngineForce = 300000.f;
float mVehicleSteering = 0.f;
float mSteeringIncrement = 5.0f;
float mSteeringClamp = 0.6f;
float mCurrentSpeed = 0.0f;
float mMaxSpeed = 1000.0f;
float mBreakingForce = 0.0f;
float mFovCoefficient = 1.0f;
int mItemNum = 0;
float mDriftGauge = 0.0f;
};
void PhysicsPlayer::OnPreciseKeyInput(float Elapsed)
{
if (mVehicle)
mCurrentSpeed = mVehicle->getCurrentSpeedKmHour();
mEngineForce = 0.0f;
mBreakingForce = 10.0f;
if (mBoosterLeft > 0.0f)
{
mMaxSpeed = 1500.0f;
mBoosterLeft -= Elapsed;
mRimLightOn = true;
}
if (mBoosterLeft < 0.0f)
{
mMaxSpeed = 1000.0f;
mBoosterLeft = 0.0f;
mRimLightOn = false;
}
if (mVehicleSteering > 0)
{
mVehicleSteering -= mSteeringIncrement * Elapsed;
if (mVehicleSteering < 0)
{
mVehicleSteering = 0;
}
}
else if (mVehicleSteering < 0)
{
mVehicleSteering += mSteeringIncrement * Elapsed;
if (mVehicleSteering > 0)
{
mVehicleSteering = 0;
}
}
if (GetAsyncKeyState(VK_LEFT) & 0x8000)
{
mVehicleSteering -= mSteeringIncrement * Elapsed;
if (mVehicleSteering < -mSteeringClamp)
mVehicleSteering = -mSteeringClamp;
}
if (GetAsyncKeyState(VK_RIGHT) & 0x8000)
{
mVehicleSteering += mSteeringIncrement * Elapsed;
if (mVehicleSteering > mSteeringClamp)
mVehicleSteering = mSteeringClamp;
}
if (GetAsyncKeyState(VK_UP) & 0x8000)
{
if (mCurrentSpeed < 0.0f)
mBreakingForce = 150.0f;
else if (mMaxSpeed > mCurrentSpeed)
mEngineForce = mMaxEngineForce;
else
{
mBreakingForce = 100.0f;
mEngineForce = 0.0f;
}
}
if (GetAsyncKeyState(VK_DOWN) & 0x8000)
{
if (mCurrentSpeed > 0.0f)
mBreakingForce = 150.0f;
else if (-mMaxSpeed < mCurrentSpeed)
mEngineForce = -mMaxBackwardEngineForce;
else
{
mBreakingForce = 100.0f;
mEngineForce = 0.0f;
}
}
if (GetAsyncKeyState('Z') & 0x8000/*&&mItemNum>0*/)
{
#ifdef STANDALONE
if (mBoosterLeft == 0.0f)
mBoosterLeft = mBoosterTime;
#endif
//mItemNum-=1;
}
// if (GetAsyncKeyState('X') & 0x8000/*&&mItemNum>0*/)
//{
//
//}
if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
{
for (int i = 2; i < 4; ++i)
{
if (mVehicle) mVehicle->getWheelInfo(i).m_frictionSlip = mWheelDriftFriction;
}
float Epsilon = 50.0f / 180.0f;
auto camLook = mCamera->GetLook();
camLook.y = 0.0f;
camLook = Vector3::Normalize(camLook);
auto playerLook = mLook;
playerLook.y = 0.0f;
playerLook = Vector3::Normalize(playerLook);
float angle = acos(Vector3::Dot(camLook, playerLook) / (Vector3::Length(camLook) * Vector3::Length(playerLook)));
if (Epsilon < angle && mDriftGauge < 1.0f)
{
mDriftGauge += Elapsed / 2.0f;
}
if (mDriftGauge > 1.0f)
{
mDriftGauge = 0.0f;
if (mItemNum < 2)
mItemNum++;
}
}
else
{
for (int i = 2; i < 4; ++i)
{
if(mVehicle) mVehicle->getWheelInfo(i).m_frictionSlip = mWheelFriction;
}
}
if (mBoosterLeft && mMaxSpeed < mCurrentSpeed)
mEngineForce = mBoosterEngineForce;
for (int i = 0; i < 2; ++i)
{
if (mVehicle)
{
mVehicle->applyEngineForce(mEngineForce, i);
mVehicle->setBrake(mBreakingForce, i);
}
}
if (mVehicle)
{
int wheelIndex = 0;
mVehicle->setSteeringValue(mVehicleSteering, wheelIndex);
wheelIndex = 1;
mVehicle->setSteeringValue(mVehicleSteering, wheelIndex);
}
}
void PhysicsPlayer::Update(float elapsedTime, float updateRate)
{
GameObject::Update(elapsedTime, updateRate);
for (int i = 0; i < 4; ++i)
{
if (mVehicle)
{
btTransform wheelTransform = mVehicle->getWheelTransformWS(i);
mWheel[i]->UpdatePosition(elapsedTime, wheelTransform);
}
}
//btVector3 linearVel = mBtRigidBody->getLinearVelocity();
//mBtRigidBody->applyCentralImpulse(btVector3(0, -linearVel.length() / 10, 0));
if (mBoosterLeft > 0.0f)
{
if (mFovCoefficient < 1.1f)
mFovCoefficient += elapsedTime * 5.0f * (1.1f - mFovCoefficient);
else
mFovCoefficient = 1.1f;
}
else
{
if (mFovCoefficient > 1.0f)
mFovCoefficient -= elapsedTime * 5.0f * (mFovCoefficient - 1.0f);
else
mFovCoefficient = 1.0f;
}
}
Update runs after OnPreciseKeyInput runs.
The vehicle chassis was created using a Hull Shape created by the V-HACD.
And I don't know if this is going to be an impact, but because the vehicle modeling is pretty big, all the objects have been scaled six times accordingly.
That is, 1 meter is 6 in the code internal value.
I'm not sure what part of the code is causing this sudden bounce. Is there any guideline for tuning the Raycast Vehicle?