Skip to content

Commit d43aeff

Browse files
committed
refactore cars physics
1 parent 40fef48 commit d43aeff

4 files changed

Lines changed: 139 additions & 107 deletions

File tree

src/GameCheatsWindow.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,11 @@ void GameCheatsWindow::DoUI(ImGuiIO& imguiContext)
189189
ImGui::TextColored(physicsPropsColor, "Front Brake Bias : %.3f", carInformation->mFrontBrakeBias);
190190
ImGui::HorzSpacing();
191191

192-
ImGui::Text("Current velocity : %.3f", currCar->mPhysicsComponent->GetCurrentVelocity());
192+
ImGui::Text("Current velocity : %.3f", currCar->mPhysicsComponent->GetCurrentSpeed());
193+
if (ImGui::Button("Clear forces"))
194+
{
195+
currCar->mPhysicsComponent->ClearForces();
196+
}
193197
}
194198
}
195199
}

src/PhysicsComponents.cpp

Lines changed: 110 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,6 @@ CarPhysicsComponent::CarPhysicsComponent(b2World* physicsWorld, CarStyle* desc,
330330

331331
mPhysicsBody = mPhysicsWorld->CreateBody(&bodyDef);
332332
debug_assert(mPhysicsBody);
333-
//physicsObject->mDepth = (1.0f * desc->mDepth) / MAP_PIXELS_PER_TILE;
334333

335334
float shape_size_w = Convert::PixelsToMeters(desc->mWidth) * 0.5f;
336335
float shape_size_h = Convert::PixelsToMeters(desc->mHeight) * 0.5f;
@@ -387,9 +386,7 @@ void CarPhysicsComponent::HandleWaterContact()
387386

388387
void CarPhysicsComponent::SimulationStep()
389388
{
390-
UpdateWheelFriction(eCarWheelID_Drive);
391-
UpdateWheelFriction(eCarWheelID_Steer);
392-
389+
UpdateFriction();
393390
UpdateDrive();
394391
UpdateSteer();
395392
}
@@ -405,9 +402,9 @@ void CarPhysicsComponent::GetChassisCorners(glm::vec2 corners[4]) const
405402
}
406403
}
407404

408-
void CarPhysicsComponent::GetWheelCorners(eCarWheelID wheelID, glm::vec2 corners[4]) const
405+
void CarPhysicsComponent::GetWheelCorners(eCarWheel wheelID, glm::vec2 corners[4]) const
409406
{
410-
debug_assert(wheelID < eCarWheelID_COUNT);
407+
debug_assert(wheelID < eCarWheel_COUNT);
411408

412409
const float wheel_size_w = Convert::PixelsToMeters(CAR_WHEEL_SIZE_W_PX) * 0.5f;
413410
const float wheel_size_h = Convert::PixelsToMeters(CAR_WHEEL_SIZE_H_PX) * 0.5f;
@@ -419,20 +416,20 @@ void CarPhysicsComponent::GetWheelCorners(eCarWheelID wheelID, glm::vec2 corners
419416
b2Vec2(-wheel_size_h, wheel_size_w),
420417
};
421418
float positionOffset = 0.0f;
422-
if (wheelID == eCarWheelID_Drive)
419+
if (wheelID == eCarWheel_Drive)
423420
{
424421
positionOffset = mDriveWheelPosition;
425422
}
426423
else
427424
{
428-
debug_assert(wheelID == eCarWheelID_Steer);
425+
debug_assert(wheelID == eCarWheel_Steer);
429426
positionOffset = mSteerWheelPosition;
430427
}
431428

432429
for (int icorner = 0; icorner < 4; ++icorner)
433430
{
434431
b2Vec2 currPoint = points[icorner];
435-
if (wheelID == eCarWheelID_Steer && mSteeringAngleRadians)
432+
if (wheelID == eCarWheel_Steer && mSteeringAngleRadians)
436433
{
437434
b2Rot rot(mSteeringAngleRadians);
438435
currPoint = b2Mul(rot, points[icorner]);
@@ -462,43 +459,39 @@ void CarPhysicsComponent::SetHandBrake(bool isEnabled)
462459
mHandBrakeEnabled = isEnabled;
463460
}
464461

465-
glm::vec2 CarPhysicsComponent::GetWheelLateralVelocity(eCarWheelID wheelID) const
462+
glm::vec2 CarPhysicsComponent::GetWheelLateralVelocity(eCarWheel wheelID) const
466463
{
467-
debug_assert(wheelID < eCarWheelID_COUNT);
464+
debug_assert(wheelID < eCarWheel_COUNT);
468465

469466
box2d::vec2 result_velocity = b2GetWheelLateralVelocity(wheelID);
470467
return result_velocity;
471468
}
472469

473-
glm::vec2 CarPhysicsComponent::GetWheelForwardVelocity(eCarWheelID wheelID) const
470+
glm::vec2 CarPhysicsComponent::GetWheelForwardVelocity(eCarWheel wheelID) const
474471
{
475-
debug_assert(wheelID < eCarWheelID_COUNT);
472+
debug_assert(wheelID < eCarWheel_COUNT);
476473

477474
box2d::vec2 result_velocity = b2GetWheelForwardVelocity(wheelID);
478475
return result_velocity;
479476
}
480477

481-
glm::vec2 CarPhysicsComponent::GetWheelPosition(eCarWheelID wheelID) const
478+
glm::vec2 CarPhysicsComponent::GetWheelPosition(eCarWheel wheelID) const
482479
{
483-
debug_assert(wheelID < eCarWheelID_COUNT);
484-
485-
b2Vec2 b2Position = b2GetWheelLocalPosition(wheelID);
480+
debug_assert(wheelID < eCarWheel_COUNT);
486481

487-
box2d::vec2 position = mPhysicsBody->GetWorldPoint(b2Position);
482+
box2d::vec2 position = b2GetWheelPoint(wheelID);
488483
return position;
489484
}
490485

491-
glm::vec2 CarPhysicsComponent::GetWheelDirection(eCarWheelID wheelID) const
486+
glm::vec2 CarPhysicsComponent::GetWheelDirection(eCarWheel wheelID) const
492487
{
493-
debug_assert(wheelID < eCarWheelID_COUNT);
494-
495-
b2Vec2 b2Direction = b2GetWheelLocalForwardVector(wheelID);
488+
debug_assert(wheelID < eCarWheel_COUNT);
496489

497-
box2d::vec2 direction = mPhysicsBody->GetWorldVector(b2Direction);
490+
box2d::vec2 direction = b2GetWheelForwardVector(wheelID);
498491
return direction;
499492
}
500493

501-
float CarPhysicsComponent::GetCurrentVelocity() const
494+
float CarPhysicsComponent::GetCurrentSpeed() const
502495
{
503496
b2Vec2 currentForwardNormal = mPhysicsBody->GetWorldVector(box2d::ForwardVector);
504497
b2Vec2 forwardVelocity = b2Dot(currentForwardNormal, mPhysicsBody->GetLinearVelocity()) * currentForwardNormal;
@@ -513,112 +506,144 @@ void CarPhysicsComponent::SetupWheels()
513506

514507
void CarPhysicsComponent::UpdateSteer()
515508
{
516-
float lockAngle = glm::radians(32.0f);
517-
float turnSpeedPerSec = glm::radians(mCarDesc->mTurning * 1.0f);
518-
float turnPerTimeStep = (turnSpeedPerSec * gTimeManager.mGameFrameDelta);
509+
//float lockAngle = glm::radians(32.0f);
510+
//float turnSpeedPerSec = glm::radians(mCarDesc->mTurning * 1.0f);
511+
//float turnPerTimeStep = (turnSpeedPerSec * gTimeManager.mGameFrameDelta);
519512

520-
float desiredAngle = lockAngle * mSteeringDirection;
521-
float angleNow = mSteeringAngleRadians;
522-
float angleToTurn = desiredAngle - angleNow;
513+
//float desiredAngle = lockAngle * mSteeringDirection;
514+
//float angleNow = mSteeringAngleRadians;
515+
//float angleToTurn = b2Clamp((desiredAngle - angleNow), -turnPerTimeStep, turnPerTimeStep);
523516

524-
angleToTurn = b2Clamp(angleToTurn, -turnPerTimeStep, turnPerTimeStep);
517+
//mSteeringAngleRadians = angleNow + angleToTurn;
518+
519+
// temporary implementation
520+
float currentSpeed = GetCurrentSpeed();
521+
float currentVelocity = fabs(currentSpeed);
522+
523+
if (mSteeringDirection)
524+
{
525+
float torqueForce = 150.0f;
526+
torqueForce *= (currentSpeed < 0.0f) ? -mSteeringDirection : mSteeringDirection;
525527

526-
mSteeringAngleRadians = angleNow + angleToTurn;
528+
if (currentVelocity < 2.0f)
529+
{
530+
torqueForce *= (currentVelocity / 4.0f);
531+
}
532+
533+
mPhysicsBody->ApplyTorque(torqueForce, true);
534+
}
527535
}
528536

529-
void CarPhysicsComponent::UpdateWheelFriction(eCarWheelID wheelID)
537+
void CarPhysicsComponent::UpdateFriction()
530538
{
531-
debug_assert(wheelID < eCarWheelID_COUNT);
539+
b2Vec2 currentForwardNormal = b2GetWheelForwardVelocity(eCarWheel_Drive);
540+
b2Vec2 impulse = mPhysicsBody->GetMass() * -b2GetWheelLateralVelocity(eCarWheel_Drive);
541+
mPhysicsBody->ApplyLinearImpulse(impulse, mPhysicsBody->GetWorldCenter(), true);
532542

533-
543+
if (currentForwardNormal.Length() < 5.99f)
544+
{
545+
mPhysicsBody->ApplyAngularImpulse((0.5f - (currentForwardNormal.Length() / 6.0f) * 0.4f) * mPhysicsBody->GetInertia() * -mPhysicsBody->GetAngularVelocity(), true);
546+
}
547+
else
548+
{
549+
mPhysicsBody->ApplyAngularImpulse(0.1f * mPhysicsBody->GetInertia() * -mPhysicsBody->GetAngularVelocity(), true);
550+
}
551+
552+
float dragForceMagnitude = -20.0f / (std::min(11.9f, currentForwardNormal.Length()) / 11.9f + 0.1f);
553+
mPhysicsBody->ApplyForce(dragForceMagnitude * currentForwardNormal, mPhysicsBody->GetWorldCenter(), true);
534554
}
535555

536556
void CarPhysicsComponent::UpdateDrive()
537557
{
538-
if (mSteeringAngleRadians)
558+
float maxForwardSpeed = 100.0f;
559+
float maxBackwardSpeed = -80.0f;
560+
561+
float driveForce = 300.0f;
562+
float brakeForce = 100.0f;
563+
float reverseForce = 250.0f;
564+
565+
float desiredSpeed = 0.0f;
566+
if (mAccelerationEnabled)
539567
{
540-
mPhysicsBody->ApplyTorque(mSteeringAngleRadians * mCarDesc->mTurnRatio, true);
568+
desiredSpeed = maxForwardSpeed;
541569
}
542570

543-
float desiredSpeed = 0.0f;
544-
if (mAccelerationEnabled)
571+
if (mDecelerationEnabled)
545572
{
546-
desiredSpeed = Convert::MapUnitsToMeters(mCarDesc->mThrust * 1.0f);
573+
desiredSpeed = maxBackwardSpeed;
547574
}
548-
if (mDecelerationEnabled)
575+
576+
//find current speed in forward direction
577+
float currentSpeed = GetCurrentSpeed();
578+
579+
if (desiredSpeed > 0.0f)
549580
{
550-
desiredSpeed = -Convert::MapUnitsToMeters(mCarDesc->mThrust * 1.5f);
581+
mPhysicsBody->ApplyForce(driveForce * b2GetWheelForwardVector(eCarWheel_Drive), mPhysicsBody->GetWorldCenter(), true);
551582
}
552-
553-
if (desiredSpeed)
583+
else if (desiredSpeed < 0.0f)
554584
{
555-
b2Vec2 b2Force = mPhysicsBody->GetWorldVector(b2GetWheelLocalForwardVector(eCarWheelID_Steer));
556-
b2Force *= desiredSpeed;
557-
558-
b2Vec2 b2Pos = mPhysicsBody->GetWorldPoint(b2GetWheelLocalPosition(eCarWheelID_Steer));
559-
mPhysicsBody->ApplyForce(b2Force, b2Pos, true);
585+
if (GetCurrentSpeed() > 0)
586+
{
587+
mPhysicsBody->ApplyForce(-brakeForce * b2GetWheelForwardVector(eCarWheel_Drive), mPhysicsBody->GetWorldCenter(), true);
588+
}
589+
else
590+
{
591+
mPhysicsBody->ApplyForce(-reverseForce * b2GetWheelForwardVector(eCarWheel_Drive), mPhysicsBody->GetWorldCenter(), true);
592+
}
560593
}
561-
562-
KillOrthogonalVelocity(0.1f);
563594
}
564595

565-
void CarPhysicsComponent::KillOrthogonalVelocity(float drift)
596+
b2Vec2 CarPhysicsComponent::b2GetWheelLateralVelocity(eCarWheel wheelID) const
566597
{
567-
b2Vec2 currentVelocity = mPhysicsBody->GetLinearVelocity();
568-
b2Vec2 forward = b2GetWheelLocalForwardVector(eCarWheelID_Drive);
569-
forward = mPhysicsBody->GetWorldVector(forward);
570-
571-
b2Vec2 right = b2GetWheelLocalLateralVector(eCarWheelID_Drive);
572-
right = mPhysicsBody->GetWorldVector(right);
573-
574-
b2Vec2 forwardVelocity = forward;
575-
forwardVelocity *= b2Dot(currentVelocity, forward);
576-
b2Vec2 rightVelocity = right;
577-
rightVelocity *= b2Dot(currentVelocity, right);
578-
rightVelocity *= drift;
579-
580-
mPhysicsBody->SetLinearVelocity(forwardVelocity + rightVelocity);
598+
b2Vec2 normal_vector = b2GetWheelLateralVector(wheelID);
599+
return b2Dot(normal_vector, mPhysicsBody->GetLinearVelocity()) * normal_vector;
581600
}
582601

583-
b2Vec2 CarPhysicsComponent::b2GetWheelLateralVelocity(eCarWheelID wheelID) const
602+
b2Vec2 CarPhysicsComponent::b2GetWheelForwardVelocity(eCarWheel wheelID) const
584603
{
585-
b2Vec2 normal_vector = b2GetWheelLocalLateralVector(wheelID);
586-
587-
normal_vector = mPhysicsBody->GetWorldVector(normal_vector);
604+
b2Vec2 normal_vector = b2GetWheelForwardVector(wheelID);
588605
return b2Dot(normal_vector, mPhysicsBody->GetLinearVelocity()) * normal_vector;
589606
}
590607

591-
b2Vec2 CarPhysicsComponent::b2GetWheelForwardVelocity(eCarWheelID wheelID) const
608+
b2Vec2 CarPhysicsComponent::b2GetWheelForwardVector(eCarWheel wheelID) const
592609
{
593-
b2Vec2 normal_vector = b2GetWheelLocalForwardVector(wheelID);
610+
b2Vec2 b2LocalVector = b2GetWheelLocalForwardVector(wheelID);
611+
return mPhysicsBody->GetWorldVector(b2LocalVector);
612+
}
594613

595-
normal_vector = mPhysicsBody->GetWorldVector(normal_vector);
596-
return b2Dot(normal_vector, mPhysicsBody->GetLinearVelocity()) * normal_vector;
614+
b2Vec2 CarPhysicsComponent::b2GetWheelLateralVector(eCarWheel wheelID) const
615+
{
616+
b2Vec2 b2LocalVector = b2GetWheelLocalLateralVector(wheelID);
617+
return mPhysicsBody->GetWorldVector(b2LocalVector);
618+
}
619+
620+
b2Vec2 CarPhysicsComponent::b2GetWheelPoint(eCarWheel wheelID) const
621+
{
622+
b2Vec2 b2LocalPoint = b2GetWheelLocalPoint(wheelID);
623+
return mPhysicsBody->GetWorldPoint(b2LocalPoint);
597624
}
598625

599-
b2Vec2 CarPhysicsComponent::b2GetWheelLocalPosition(eCarWheelID wheelID) const
626+
b2Vec2 CarPhysicsComponent::b2GetWheelLocalPoint(eCarWheel wheelID) const
600627
{
601-
if (wheelID == eCarWheelID_Drive)
628+
if (wheelID == eCarWheel_Drive)
602629
{
603630
return (box2d::ForwardVector * mDriveWheelPosition);
604631
}
605-
606-
if (wheelID == eCarWheelID_Steer)
632+
if (wheelID == eCarWheel_Steer)
607633
{
608634
return (box2d::ForwardVector * mSteerWheelPosition);
609635
}
610636
debug_assert(false);
611637
return {};
612638
}
613639

614-
b2Vec2 CarPhysicsComponent::b2GetWheelLocalForwardVector(eCarWheelID wheelID) const
640+
b2Vec2 CarPhysicsComponent::b2GetWheelLocalForwardVector(eCarWheel wheelID) const
615641
{
616-
if (wheelID == eCarWheelID_Drive)
642+
if (wheelID == eCarWheel_Drive)
617643
{
618644
return box2d::ForwardVector;
619645
}
620-
621-
if (wheelID == eCarWheelID_Steer)
646+
if (wheelID == eCarWheel_Steer)
622647
{
623648
b2Rot vectorAngle (mSteeringAngleRadians);
624649
return b2Mul(vectorAngle, box2d::ForwardVector);
@@ -627,14 +652,13 @@ b2Vec2 CarPhysicsComponent::b2GetWheelLocalForwardVector(eCarWheelID wheelID) co
627652
return {};
628653
}
629654

630-
b2Vec2 CarPhysicsComponent::b2GetWheelLocalLateralVector(eCarWheelID wheelID) const
655+
b2Vec2 CarPhysicsComponent::b2GetWheelLocalLateralVector(eCarWheel wheelID) const
631656
{
632-
if (wheelID == eCarWheelID_Drive)
657+
if (wheelID == eCarWheel_Drive)
633658
{
634659
return box2d::LateralVector;
635660
}
636-
637-
if (wheelID == eCarWheelID_Steer)
661+
if (wheelID == eCarWheel_Steer)
638662
{
639663
b2Rot vectorAngle (mSteeringAngleRadians);
640664
return b2Mul(vectorAngle, box2d::LateralVector);

0 commit comments

Comments
 (0)