CharacterBase.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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 CharacterBaseSettings : public RefTarget<CharacterBaseSettings>
  16. {
  17. public:
  18. JPH_OVERRIDE_NEW_DELETE
  19. /// Virtual destructor
  20. virtual ~CharacterBaseSettings() = default;
  21. /// Vector indicating the up direction of the character
  22. Vec3 mUp = Vec3::sAxisY();
  23. /// Plane, defined in local space relative to the character. Every contact behind this plane can support the
  24. /// character, every contact in front of this plane is treated as only colliding with the player.
  25. /// Default: Accept any contact.
  26. Plane mSupportingVolume { Vec3::sAxisY(), -1.0e10f };
  27. /// Maximum angle of slope that character can still walk on (radians).
  28. float mMaxSlopeAngle = DegreesToRadians(50.0f);
  29. /// Initial shape that represents the character's volume.
  30. /// Usually this is a capsule, make sure the shape is made so that the bottom of the shape is at (0, 0, 0).
  31. RefConst<Shape> mShape;
  32. };
  33. /// Base class for character class
  34. class CharacterBase : public RefTarget<CharacterBase>, public NonCopyable
  35. {
  36. public:
  37. JPH_OVERRIDE_NEW_DELETE
  38. /// Constructor
  39. CharacterBase(const CharacterBaseSettings *inSettings, PhysicsSystem *inSystem);
  40. /// Destructor
  41. virtual ~CharacterBase() = default;
  42. /// Set the maximum angle of slope that character can still walk on (radians)
  43. void SetMaxSlopeAngle(float inMaxSlopeAngle) { mCosMaxSlopeAngle = Cos(inMaxSlopeAngle); }
  44. float GetCosMaxSlopeAngle() const { return mCosMaxSlopeAngle; }
  45. /// Set the up vector for the character
  46. void SetUp(Vec3Arg inUp) { mUp = inUp; }
  47. Vec3 GetUp() const { return mUp; }
  48. /// Check if the normal of the ground surface is too steep to walk on
  49. bool IsSlopeTooSteep(Vec3Arg inNormal) const
  50. {
  51. // If cos max slope angle is close to one the system is turned off,
  52. // otherwise check the angle between the up and normal vector
  53. return mCosMaxSlopeAngle < cNoMaxSlopeAngle && inNormal.Dot(mUp) < mCosMaxSlopeAngle;
  54. }
  55. /// Get the current shape that the character is using.
  56. const Shape * GetShape() const { return mShape; }
  57. enum class EGroundState
  58. {
  59. OnGround, ///< Character is on the ground and can move freely.
  60. 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.
  61. 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.
  62. InAir, ///< Character is in the air and is not touching anything.
  63. };
  64. ///@name Properties of the ground this character is standing on
  65. /// Current ground state
  66. EGroundState GetGroundState() const { return mGroundState; }
  67. /// Returns true if the player is supported by normal or steep ground
  68. bool IsSupported() const { return mGroundState == EGroundState::OnGround || mGroundState == EGroundState::OnSteepGround; }
  69. /// Get the contact point with the ground
  70. RVec3 GetGroundPosition() const { return mGroundPosition; }
  71. /// Get the contact normal with the ground
  72. Vec3 GetGroundNormal() const { return mGroundNormal; }
  73. /// Velocity in world space of ground
  74. Vec3 GetGroundVelocity() const { return mGroundVelocity; }
  75. /// Material that the character is standing on
  76. const PhysicsMaterial * GetGroundMaterial() const { return mGroundMaterial; }
  77. /// BodyID of the object the character is standing on. Note may have been removed!
  78. BodyID GetGroundBodyID() const { return mGroundBodyID; }
  79. /// Sub part of the body that we're standing on.
  80. SubShapeID GetGroundSubShapeID() const { return mGroundBodySubShapeID; }
  81. /// User data value of the body that we're standing on
  82. uint64 GetGroundUserData() const { return mGroundUserData; }
  83. // Saving / restoring state for replay
  84. virtual void SaveState(StateRecorder &inStream) const;
  85. virtual void RestoreState(StateRecorder &inStream);
  86. protected:
  87. // Cached physics system
  88. PhysicsSystem * mSystem;
  89. // The shape that the body currently has
  90. RefConst<Shape> mShape;
  91. // The character's world space up axis
  92. Vec3 mUp;
  93. // Every contact behind this plane can support the character
  94. Plane mSupportingVolume;
  95. // Beyond this value there is no max slope
  96. static constexpr float cNoMaxSlopeAngle = 0.9999f;
  97. // Cosine of the maximum angle of slope that character can still walk on
  98. float mCosMaxSlopeAngle;
  99. // Ground properties
  100. EGroundState mGroundState = EGroundState::InAir;
  101. BodyID mGroundBodyID;
  102. SubShapeID mGroundBodySubShapeID;
  103. RVec3 mGroundPosition = RVec3::sZero();
  104. Vec3 mGroundNormal = Vec3::sZero();
  105. Vec3 mGroundVelocity = Vec3::sZero();
  106. RefConst<PhysicsMaterial> mGroundMaterial = PhysicsMaterial::sDefault;
  107. uint64 mGroundUserData = 0;
  108. };
  109. JPH_NAMESPACE_END