CharacterBase.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Core/Reference.h>
  6. #include <Jolt/Core/NonCopyable.h>
  7. #include <Jolt/Physics/Body/BodyID.h>
  8. #include <Jolt/Physics/Collision/Shape/Shape.h>
  9. #include <Jolt/Physics/Collision/Shape/SubShapeID.h>
  10. #include <Jolt/Physics/Collision/PhysicsMaterial.h>
  11. JPH_NAMESPACE_BEGIN
  12. class PhysicsSystem;
  13. class StateRecorder;
  14. /// Base class for configuration of a character
  15. class JPH_EXPORT CharacterBaseSettings : public RefTarget<CharacterBaseSettings>
  16. {
  17. public:
  18. JPH_OVERRIDE_NEW_DELETE
  19. /// Constructor
  20. CharacterBaseSettings() = default;
  21. CharacterBaseSettings(const CharacterBaseSettings &inSettings) = default;
  22. CharacterBaseSettings & operator = (const CharacterBaseSettings &inSettings) = default;
  23. /// Virtual destructor
  24. virtual ~CharacterBaseSettings() = default;
  25. /// Vector indicating the up direction of the character
  26. Vec3 mUp = Vec3::sAxisY();
  27. /// Plane, defined in local space relative to the character. Every contact behind this plane can support the
  28. /// character, every contact in front of this plane is treated as only colliding with the player.
  29. /// Default: Accept any contact.
  30. Plane mSupportingVolume { Vec3::sAxisY(), -1.0e10f };
  31. /// Maximum angle of slope that character can still walk on (radians).
  32. float mMaxSlopeAngle = DegreesToRadians(50.0f);
  33. /// Initial shape that represents the character's volume.
  34. /// Usually this is a capsule, make sure the shape is made so that the bottom of the shape is at (0, 0, 0).
  35. RefConst<Shape> mShape;
  36. };
  37. /// Base class for character class
  38. class JPH_EXPORT CharacterBase : public RefTarget<CharacterBase>, public NonCopyable
  39. {
  40. public:
  41. JPH_OVERRIDE_NEW_DELETE
  42. /// Constructor
  43. CharacterBase(const CharacterBaseSettings *inSettings, PhysicsSystem *inSystem);
  44. /// Destructor
  45. virtual ~CharacterBase() = default;
  46. /// Set the maximum angle of slope that character can still walk on (radians)
  47. void SetMaxSlopeAngle(float inMaxSlopeAngle) { mCosMaxSlopeAngle = Cos(inMaxSlopeAngle); }
  48. float GetCosMaxSlopeAngle() const { return mCosMaxSlopeAngle; }
  49. /// Set the up vector for the character
  50. void SetUp(Vec3Arg inUp) { mUp = inUp; }
  51. Vec3 GetUp() const { return mUp; }
  52. /// Check if the normal of the ground surface is too steep to walk on
  53. bool IsSlopeTooSteep(Vec3Arg inNormal) const
  54. {
  55. // If cos max slope angle is close to one the system is turned off,
  56. // otherwise check the angle between the up and normal vector
  57. return mCosMaxSlopeAngle < cNoMaxSlopeAngle && inNormal.Dot(mUp) < mCosMaxSlopeAngle;
  58. }
  59. /// Get the current shape that the character is using.
  60. const Shape * GetShape() const { return mShape; }
  61. enum class EGroundState
  62. {
  63. OnGround, ///< Character is on the ground and can move freely.
  64. OnSteepGround, ///< Character is on a slope that is too steep and can't climb up any further. The caller should start applying downward velocity if sliding from the slope is desired.
  65. NotSupported, ///< Character is touching an object, but is not supported by it and should fall. The GetGroundXXX functions will return information about the touched object.
  66. InAir, ///< Character is in the air and is not touching anything.
  67. };
  68. /// Debug function to convert enum values to string
  69. static const char * sToString(EGroundState inState);
  70. ///@name Properties of the ground this character is standing on
  71. /// Current ground state
  72. EGroundState GetGroundState() const { return mGroundState; }
  73. /// Returns true if the player is supported by normal or steep ground
  74. bool IsSupported() const { return mGroundState == EGroundState::OnGround || mGroundState == EGroundState::OnSteepGround; }
  75. /// Get the contact point with the ground
  76. RVec3 GetGroundPosition() const { return mGroundPosition; }
  77. /// Get the contact normal with the ground
  78. Vec3 GetGroundNormal() const { return mGroundNormal; }
  79. /// Velocity in world space of ground
  80. Vec3 GetGroundVelocity() const { return mGroundVelocity; }
  81. /// Material that the character is standing on
  82. const PhysicsMaterial * GetGroundMaterial() const { return mGroundMaterial; }
  83. /// BodyID of the object the character is standing on. Note may have been removed!
  84. BodyID GetGroundBodyID() const { return mGroundBodyID; }
  85. /// Sub part of the body that we're standing on.
  86. SubShapeID GetGroundSubShapeID() const { return mGroundBodySubShapeID; }
  87. /// User data value of the body that we're standing on
  88. uint64 GetGroundUserData() const { return mGroundUserData; }
  89. // Saving / restoring state for replay
  90. virtual void SaveState(StateRecorder &inStream) const;
  91. virtual void RestoreState(StateRecorder &inStream);
  92. protected:
  93. // Cached physics system
  94. PhysicsSystem * mSystem;
  95. // The shape that the body currently has
  96. RefConst<Shape> mShape;
  97. // The character's world space up axis
  98. Vec3 mUp;
  99. // Every contact behind this plane can support the character
  100. Plane mSupportingVolume;
  101. // Beyond this value there is no max slope
  102. static constexpr float cNoMaxSlopeAngle = 0.9999f;
  103. // Cosine of the maximum angle of slope that character can still walk on
  104. float mCosMaxSlopeAngle;
  105. // Ground properties
  106. EGroundState mGroundState = EGroundState::InAir;
  107. BodyID mGroundBodyID;
  108. SubShapeID mGroundBodySubShapeID;
  109. RVec3 mGroundPosition = RVec3::sZero();
  110. Vec3 mGroundNormal = Vec3::sZero();
  111. Vec3 mGroundVelocity = Vec3::sZero();
  112. RefConst<PhysicsMaterial> mGroundMaterial = PhysicsMaterial::sDefault;
  113. uint64 mGroundUserData = 0;
  114. };
  115. JPH_NAMESPACE_END