VehicleConstraint.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Jolt/Physics/Constraints/Constraint.h>
  5. #include <Jolt/Physics/PhysicsStepListener.h>
  6. #include <Jolt/Physics/Constraints/ConstraintPart/AngleConstraintPart.h>
  7. #include <Jolt/Physics/Vehicle/VehicleCollisionTester.h>
  8. #include <Jolt/Physics/Vehicle/VehicleAntiRollBar.h>
  9. #include <Jolt/Physics/Vehicle/Wheel.h>
  10. JPH_NAMESPACE_BEGIN
  11. class PhysicsSystem;
  12. class VehicleController;
  13. class VehicleControllerSettings;
  14. /// Configuration for constraint that simulates a wheeled vehicle.
  15. ///
  16. /// The properties in this constraint are largely based on "Car Physics for Games" by Marco Monster.
  17. /// See: https://www.asawicki.info/Mirror/Car%20Physics%20for%20Games/Car%20Physics%20for%20Games.html
  18. class VehicleConstraintSettings : public ConstraintSettings
  19. {
  20. public:
  21. JPH_DECLARE_SERIALIZABLE_VIRTUAL(VehicleConstraintSettings)
  22. /// Saves the contents of the constraint settings in binary form to inStream.
  23. virtual void SaveBinaryState(StreamOut &inStream) const override;
  24. Vec3 mUp { 0, 1, 0 }; ///< Vector indicating the up direction of the vehicle (in local space to the body)
  25. Vec3 mForward { 0, 0, 1 }; ///< Vector indicating forward direction of the vehicle (in local space to the body)
  26. float mMaxPitchRollAngle = JPH_PI; ///< Defines the maximum pitch/roll angle (rad), can be used to avoid the car from getting upside down. The vehicle up direction will stay within a cone centered around the up axis with half top angle mMaxPitchRollAngle, set to pi to turn off.
  27. vector<Ref<WheelSettings>> mWheels; ///< List of wheels and their properties
  28. vector<VehicleAntiRollBar> mAntiRollBars; ///< List of anti rollbars and their properties
  29. Ref<VehicleControllerSettings> mController; ///< Defines how the vehicle can accelerate / decellerate
  30. protected:
  31. /// This function should not be called directly, it is used by sRestoreFromBinaryState.
  32. virtual void RestoreBinaryState(StreamIn &inStream) override;
  33. };
  34. /// Constraint that simulates a vehicle
  35. /// Note: Don't forget to register the constraint as a StepListener with the PhysicsSystem!
  36. class VehicleConstraint : public Constraint, public PhysicsStepListener
  37. {
  38. public:
  39. /// Constructor / destructor
  40. VehicleConstraint(Body &inVehicleBody, const VehicleConstraintSettings &inSettings);
  41. virtual ~VehicleConstraint() override;
  42. /// Get the type of a constraint
  43. virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Vehicle; }
  44. /// Defines the maximum pitch/roll angle (rad), can be used to avoid the car from getting upside down. The vehicle up direction will stay within a cone centered around the up axis with half top angle mMaxPitchRollAngle, set to pi to turn off.
  45. void SetMaxPitchRollAngle(float inMaxPitchRollAngle) { mCosMaxPitchRollAngle = cos(inMaxPitchRollAngle); }
  46. /// Set the interface that tests collision between wheel and ground
  47. void SetVehicleCollisionTester(const VehicleCollisionTester *inTester) { mVehicleCollisionTester = inTester; }
  48. /// Get the local space forward vector of the vehicle
  49. Vec3 GetLocalForward() const { return mForward; }
  50. /// Get the local space up vector of the vehicle
  51. Vec3 GetLocalUp() const { return mUp; }
  52. /// Access to the vehicle body
  53. Body * GetVehicleBody() const { return mBody; }
  54. /// Access to the vehicle controller interface (determines acceleration / decelleration)
  55. const VehicleController * GetController() const { return mController; }
  56. /// Access to the vehicle controller interface (determines acceleration / decelleration)
  57. VehicleController * GetController() { return mController; }
  58. /// Get the state of the wheels
  59. const Wheels & GetWheels() const { return mWheels; }
  60. /// Get the state of a wheels (writable interface, allows you to make changes to the configuration which will take effect the next time step)
  61. Wheels & GetWheels() { return mWheels; }
  62. /// Get the transform of a wheel in local space to the vehicle body, returns a matrix that transforms a cylinder aligned with the Y axis in body space (not COM space)
  63. /// @param inWheelIndex Index of the wheel to fetch
  64. /// @param inWheelRight Unit vector that indicates right in model space of the wheel (so if you only have 1 wheel model, you probably want to specify the opposite direction for the left and right wheels)
  65. /// @param inWheelUp Unit vector that indicates up in model space of the wheel
  66. Mat44 GetWheelLocalTransform(uint inWheelIndex, Vec3Arg inWheelRight, Vec3Arg inWheelUp) const;
  67. /// Get the transform of a wheel in world space, returns a matrix that transforms a cylinder aligned with the Y axis in world space
  68. /// @param inWheelIndex Index of the wheel to fetch
  69. /// @param inWheelRight Unit vector that indicates right in model space of the wheel (so if you only have 1 wheel model, you probably want to specify the opposite direction for the left and right wheels)
  70. /// @param inWheelUp Unit vector that indicates up in model space of the wheel
  71. Mat44 GetWheelWorldTransform(uint inWheelIndex, Vec3Arg inWheelRight, Vec3Arg inWheelUp) const;
  72. // Generic interface of a constraint
  73. virtual bool IsActive() const override { return mIsActive && Constraint::IsActive(); }
  74. virtual void SetupVelocityConstraint(float inDeltaTime) override;
  75. virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
  76. virtual bool SolveVelocityConstraint(float inDeltaTime) override;
  77. virtual bool SolvePositionConstraint(float inDeltaTime, float inBaumgarte) override;
  78. virtual void BuildIslands(uint32 inConstraintIndex, IslandBuilder &ioBuilder, BodyManager &inBodyManager) override;
  79. #ifdef JPH_DEBUG_RENDERER
  80. virtual void DrawConstraint(DebugRenderer *inRenderer) const override;
  81. virtual void DrawConstraintLimits(DebugRenderer *inRenderer) const override;
  82. #endif // JPH_DEBUG_RENDERER
  83. virtual void SaveState(StateRecorder &inStream) const override;
  84. virtual void RestoreState(StateRecorder &inStream) override;
  85. virtual Ref<ConstraintSettings> GetConstraintSettings() const override;
  86. private:
  87. // See: PhysicsStepListener
  88. virtual void OnStep(float inDeltaTime, PhysicsSystem &inPhysicsSystem) override;
  89. // Calculate the contact positions of the wheel in world space, relative to the center of mass of both bodies
  90. void CalculateWheelContactPoint(Mat44Arg inBodyTransform, const Wheel &inWheel, Vec3 &outR1PlusU, Vec3 &outR2) const;
  91. // Calculate the constraint properties for mPitchRollPart
  92. void CalculatePitchRollConstraintProperties(float inDeltaTime, Mat44Arg inBodyTransform);
  93. // Simluation information
  94. Body * mBody; ///< Body of the vehicle
  95. Vec3 mForward; ///< Local space forward vector for the vehicle
  96. Vec3 mUp; ///< Local space up vector for the vehicle
  97. Wheels mWheels; ///< Wheel states of the vehicle
  98. vector<VehicleAntiRollBar> mAntiRollBars; ///< Anti rollbars of the vehicle
  99. VehicleController * mController; ///< Controls the acceleration / declerration of the vehicle
  100. bool mIsActive = false; ///< If this constraint is active
  101. // Prevent vehicle from toppling over
  102. float mCosMaxPitchRollAngle; ///< Cos of the max pitch/roll angle
  103. float mCosPitchRollAngle; ///< Cos of the current pitch/roll angle
  104. Vec3 mPitchRollRotationAxis { 0, 1, 0 }; ///< Current axis along which to apply torque to prevent the car from toppling over
  105. AngleConstraintPart mPitchRollPart; ///< Constraint part that prevents the car from toppling over
  106. // Interfaces
  107. RefConst<VehicleCollisionTester> mVehicleCollisionTester; ///< Class that performs testing of collision for the wheels
  108. };
  109. JPH_NAMESPACE_END