Character.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Core/Reference.h>
  5. #include <Physics/EActivation.h>
  6. namespace JPH {
  7. class Character;
  8. class PhysicsSystem;
  9. /// Contains the configuration of a character
  10. class CharacterSettings : public RefTarget<CharacterSettings>
  11. {
  12. public:
  13. /// Layer that this character will be added to
  14. ObjectLayer mLayer = 0;
  15. /// Mass of the character
  16. float mMass = 80.0f;
  17. /// Maximum angle of slope that character can still walk on (radians)
  18. float mMaxSlopeAngle = DegreesToRadians(50.0f);
  19. /// Friction for the character
  20. float mFriction = 0.2f;
  21. /// Value to multiply gravity with for this character
  22. float mGravityFactor = 1.0f;
  23. /// Initial shape that represents the character's volume.
  24. /// Usually this is a capsule, make sure the shape is made so that the bottom of the shape is at (0, 0, 0).
  25. RefConst<Shape> mShape;
  26. };
  27. /// Runtime character object.
  28. /// This object usually represents the player or a humanoid AI. It uses a single rigid body,
  29. /// usually with a capsule shape to simulate movement and collision for the character.
  30. /// The character is a keyframed object, the application controls it by setting the velocity.
  31. class Character : public RefTarget<Character>
  32. {
  33. public:
  34. /// Constructor
  35. /// @param inSettings The settings for the character
  36. /// @param inPosition Initial position for the character
  37. /// @param inRotation Initial rotation for the character (usually only around Y)
  38. /// @param inUserData Application specific data pointer
  39. /// @param inSystem Physics system that this character will be added to later
  40. Character(CharacterSettings *inSettings, Vec3Arg inPosition, QuatArg inRotation, void *inUserData, PhysicsSystem *inSystem);
  41. /// Destructor
  42. ~Character();
  43. /// Add bodies and constraints to the system and optionally activate the bodies
  44. void AddToPhysicsSystem(EActivation inActivationMode = EActivation::Activate, bool inLockBodies = true);
  45. /// Remove bodies and constraints from the system
  46. void RemoveFromPhysicsSystem(bool inLockBodies = true);
  47. /// Wake up the character
  48. void Activate(bool inLockBodies = true);
  49. /// Needs to be called after every PhysicsSystem::Update
  50. /// @param inMaxSeparationDistance Max distance between the floor and the character to still consider the character standing on the floor
  51. /// @param inLockBodies If the collision query should use the locking body interface (true) or the non locking body interface (false)
  52. void PostSimulation(float inMaxSeparationDistance, bool inLockBodies = true);
  53. /// Control the velocity of the character
  54. void SetLinearAndAngularVelocity(Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity, bool inLockBodies = true);
  55. /// Get the linear velocity of the character (m / s)
  56. Vec3 GetLinearVelocity(bool inLockBodies = true) const;
  57. /// Set the linear velocity of the character (m / s)
  58. void SetLinearVelocity(Vec3Arg inLinearVelocity, bool inLockBodies = true);
  59. /// Add world space linear velocity to current velocity (m / s)
  60. void AddLinearVelocity(Vec3Arg inLinearVelocity, bool inLockBodies = true);
  61. /// Add impulse to the center of mass of the character
  62. void AddImpulse(Vec3Arg inImpulse, bool inLockBodies = true);
  63. /// Get the body associated with this character
  64. BodyID GetBodyID() const { return mBodyID; }
  65. /// Get position / rotation of the body
  66. void GetPositionAndRotation(Vec3 &outPosition, Quat &outRotation, bool inLockBodies = true) const;
  67. /// Set the position / rotation of the body, optionally activating it.
  68. void SetPositionAndRotation(Vec3Arg inPosition, QuatArg inRotation, EActivation inActivationMode = EActivation::Activate, bool inLockBodies = true) const;
  69. /// Get the position of the character
  70. Vec3 GetPosition(bool inLockBodies = true) const;
  71. /// Set the position of the character, optionally activating it.
  72. void SetPosition(Vec3Arg inPostion, EActivation inActivationMode = EActivation::Activate, bool inLockBodies = true);
  73. /// Get the rotation of the character
  74. Quat GetRotation(bool inLockBodies = true) const;
  75. /// Set the rotation of the character, optionally activating it.
  76. void SetRotation(QuatArg inRotation, EActivation inActivationMode = EActivation::Activate, bool inLockBodies = true);
  77. /// Position of the center of mass of the underlying rigid body
  78. Vec3 GetCenterOfMassPosition(bool inLockBodies = true) const;
  79. /// Update the layer of the character
  80. void SetLayer(ObjectLayer inLayer, bool inLockBodies = true);
  81. /// Set the maximum angle of slope that character can still walk on (radians)
  82. void SetMaxSlopeAngle(float inMaxSlopeAngle) { mCosMaxSlopeAngle = cos(inMaxSlopeAngle); }
  83. /// Switch the shape of the character (e.g. for stance). When inMaxPenetrationDepth is not FLT_MAX, it checks
  84. /// if the new shape collides before switching shape. Returns true if the switch succeeded.
  85. bool SetShape(const Shape *inShape, float inMaxPenetrationDepth, bool inLockBodies = true);
  86. /// Get the current shape that the character is using.
  87. const Shape * GetShape() const { return mShape; }
  88. enum class EGroundState
  89. {
  90. OnGround, ///< Character is on the ground and can move freely
  91. Sliding, ///< Character is on a slope that is too steep and should start sliding
  92. InAir, ///< Character is in the air
  93. };
  94. ///@name Properties of the ground this character is standing on
  95. /// Current ground state (updated during PostSimlulation())
  96. EGroundState GetGroundState() const;
  97. /// Get the contact point with the ground
  98. Vec3 GetGroundPosition() const { return mGroundPosition; }
  99. /// Get the contact normal with the ground
  100. Vec3 GetGroundNormal() const { return mGroundNormal; }
  101. /// Velocity in world space of the point that we're standing on
  102. Vec3 GetGroundVelocity(bool inLockBodies = true) const;
  103. /// Material that the character is standing on.
  104. const PhysicsMaterial * GetGroundMaterial() const { return mGroundMaterial; }
  105. /// BodyID of the object the character is standing on. Note may have been removed!
  106. BodyID GetGroundBodyID() const { return mGroundBodyID; }
  107. /// Sub part of the body that we're standing on.
  108. SubShapeID GetGroundSubShapeID() const { return mGroundBodySubShapeID; }
  109. /// User data pointer of the body that we're standing on
  110. void * GetGroundUserData(bool inLockBodies = true) const;
  111. private:
  112. /// Check collisions between inShape and the world
  113. void CheckCollision(const Shape *inShape, float inMaxSeparationDistance, CollideShapeCollector &ioCollector, bool inLockBodies = true) const;
  114. /// The body of this character
  115. BodyID mBodyID;
  116. /// The layer the body is in
  117. ObjectLayer mLayer;
  118. /// Cosine of the maximum angle of slope that character can still walk on
  119. float mCosMaxSlopeAngle;
  120. /// The shape that the body currently has
  121. RefConst<Shape> mShape;
  122. /// Cached physics system
  123. PhysicsSystem * mSystem;
  124. // Ground properties
  125. BodyID mGroundBodyID;
  126. SubShapeID mGroundBodySubShapeID;
  127. Vec3 mGroundPosition = Vec3::sZero();
  128. Vec3 mGroundNormal = Vec3::sZero();
  129. RefConst<PhysicsMaterial> mGroundMaterial;
  130. };
  131. } // JPH