CharacterBase.h 5.4 KB

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