BsCCharacterController.cpp 5.1 KB

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