BsCCharacterController.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Components/BsCCharacterController.h"
  4. #include "Scene/BsSceneObject.h"
  5. #include "Physics/BsCollider.h"
  6. #include "Private/RTTI/BsCCharacterControllerRTTI.h"
  7. using namespace std::placeholders;
  8. namespace bs
  9. {
  10. CCharacterController::CCharacterController()
  11. {
  12. setName("CharacterController");
  13. mNotifyFlags = TCF_Transform;
  14. }
  15. CCharacterController::CCharacterController(const HSceneObject& parent)
  16. : Component(parent)
  17. {
  18. setName("CharacterController");
  19. mNotifyFlags = TCF_Transform;
  20. }
  21. CharacterCollisionFlags CCharacterController::move(const Vector3& displacement)
  22. {
  23. CharacterCollisionFlags output;
  24. if (mInternal == nullptr)
  25. return output;
  26. output = mInternal->move(displacement);
  27. updatePositionFromController();
  28. return output;
  29. }
  30. Vector3 CCharacterController::getFootPosition() const
  31. {
  32. if (mInternal == nullptr)
  33. return Vector3::ZERO;
  34. return mInternal->getFootPosition();
  35. }
  36. void CCharacterController::setFootPosition(const Vector3& position)
  37. {
  38. if (mInternal == nullptr)
  39. return;
  40. mInternal->setFootPosition(position);
  41. updatePositionFromController();
  42. }
  43. void CCharacterController::setRadius(float radius)
  44. {
  45. mDesc.radius = radius;
  46. if (mInternal != nullptr)
  47. updateDimensions();
  48. }
  49. void CCharacterController::setHeight(float height)
  50. {
  51. mDesc.height = height;
  52. if (mInternal != nullptr)
  53. updateDimensions();
  54. }
  55. void CCharacterController::setUp(const Vector3& up)
  56. {
  57. mDesc.up = up;
  58. if (mInternal != nullptr)
  59. mInternal->setUp(up);
  60. }
  61. void CCharacterController::setClimbingMode(CharacterClimbingMode mode)
  62. {
  63. mDesc.climbingMode = mode;
  64. if (mInternal != nullptr)
  65. mInternal->setClimbingMode(mode);
  66. }
  67. void CCharacterController::setNonWalkableMode(CharacterNonWalkableMode mode)
  68. {
  69. mDesc.nonWalkableMode = mode;
  70. if (mInternal != nullptr)
  71. mInternal->setNonWalkableMode(mode);
  72. }
  73. void CCharacterController::setMinMoveDistance(float value)
  74. {
  75. mDesc.minMoveDistance = value;
  76. if (mInternal != nullptr)
  77. mInternal->setMinMoveDistance(value);
  78. }
  79. void CCharacterController::setContactOffset(float value)
  80. {
  81. mDesc.contactOffset = value;
  82. if (mInternal != nullptr)
  83. mInternal->setContactOffset(value);
  84. }
  85. void CCharacterController::setStepOffset(float value)
  86. {
  87. mDesc.stepOffset = value;
  88. if (mInternal != nullptr)
  89. mInternal->setStepOffset(value);
  90. }
  91. void CCharacterController::setSlopeLimit(Radian value)
  92. {
  93. mDesc.slopeLimit = value;
  94. if (mInternal != nullptr)
  95. mInternal->setSlopeLimit(value);
  96. }
  97. void CCharacterController::setLayer(UINT64 layer)
  98. {
  99. mLayer = layer;
  100. if (mInternal != nullptr)
  101. mInternal->setLayer(layer);
  102. }
  103. void CCharacterController::onInitialized()
  104. {
  105. }
  106. void CCharacterController::onDestroyed()
  107. {
  108. destroyInternal();
  109. }
  110. void CCharacterController::onDisabled()
  111. {
  112. destroyInternal();
  113. }
  114. void CCharacterController::onEnabled()
  115. {
  116. mDesc.position = SO()->getTransform().getPosition();
  117. mInternal = CharacterController::create(mDesc);
  118. mInternal->_setOwner(PhysicsOwnerType::Component, this);
  119. mInternal->onColliderHit.connect(std::bind(&CCharacterController::triggerOnColliderHit, this, _1));
  120. mInternal->onControllerHit.connect(std::bind(&CCharacterController::triggerOnControllerHit, this, _1));
  121. mInternal->setLayer(mLayer);
  122. updateDimensions();
  123. }
  124. void CCharacterController::onTransformChanged(TransformChangedFlags flags)
  125. {
  126. if (!SO()->getActive() || mInternal == nullptr)
  127. return;
  128. mInternal->setPosition(SO()->getTransform().getPosition());
  129. }
  130. void CCharacterController::updatePositionFromController()
  131. {
  132. mNotifyFlags = (TransformChangedFlags)0;
  133. SO()->setWorldPosition(mInternal->getPosition());
  134. mNotifyFlags = TCF_Transform;
  135. }
  136. void CCharacterController::updateDimensions()
  137. {
  138. Vector3 scale = SO()->getTransform().getScale();
  139. float height = mDesc.height * Math::abs(scale.y);
  140. float radius = mDesc.radius * Math::abs(std::max(scale.x, scale.z));
  141. mInternal->setHeight(height);
  142. mInternal->setRadius(radius);
  143. }
  144. void CCharacterController::destroyInternal()
  145. {
  146. // This should release the last reference and destroy the internal controller
  147. if(mInternal)
  148. {
  149. mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
  150. mInternal = nullptr;
  151. }
  152. }
  153. void CCharacterController::triggerOnColliderHit(const ControllerColliderCollision& value)
  154. {
  155. // Const-cast and modify is okay because we're the only object receiving this event
  156. ControllerColliderCollision& hit = const_cast<ControllerColliderCollision&>(value);
  157. hit.collider = mThisHandle;
  158. onColliderHit(hit);
  159. }
  160. void CCharacterController::triggerOnControllerHit(const ControllerControllerCollision& value)
  161. {
  162. // Const-cast and modify is okay because we're the only object receiving this event
  163. ControllerControllerCollision& hit = const_cast<ControllerControllerCollision&>(value);
  164. hit.controller = mThisHandle;
  165. onControllerHit(hit);
  166. }
  167. RTTITypeBase* CCharacterController::getRTTIStatic()
  168. {
  169. return CCharacterControllerRTTI::instance();
  170. }
  171. RTTITypeBase* CCharacterController::getRTTI() const
  172. {
  173. return CCharacterController::getRTTIStatic();
  174. }
  175. }