BsCCharacterController.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsCCharacterController.h"
  4. #include "BsSceneObject.h"
  5. #include "BsCollider.h"
  6. #include "BsCCharacterControllerRTTI.h"
  7. using namespace std::placeholders;
  8. namespace BansheeEngine
  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. // This should release the last reference and destroy the internal controller
  104. mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
  105. mInternal = nullptr;
  106. }
  107. void CCharacterController::onDisabled()
  108. {
  109. // This should release the last reference and destroy the internal controller
  110. mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
  111. mInternal = nullptr;
  112. }
  113. void CCharacterController::onEnabled()
  114. {
  115. mDesc.position = SO()->getWorldPosition();
  116. mInternal = CharacterController::create(mDesc);
  117. mInternal->_setOwner(PhysicsOwnerType::Component, this);
  118. mInternal->onColliderHit.connect(std::bind(&CCharacterController::triggerOnColliderHit, this, _1));
  119. mInternal->onControllerHit.connect(std::bind(&CCharacterController::triggerOnControllerHit, this, _1));
  120. mInternal->setLayer(mLayer);
  121. updateDimensions();
  122. }
  123. void CCharacterController::onTransformChanged(TransformChangedFlags flags)
  124. {
  125. if (!SO()->getActive() || mInternal == nullptr)
  126. return;
  127. mInternal->setPosition(SO()->getWorldPosition());
  128. }
  129. void CCharacterController::updatePositionFromController()
  130. {
  131. mNotifyFlags = (TransformChangedFlags)0;
  132. SO()->setWorldPosition(mInternal->getPosition());
  133. mNotifyFlags = TCF_Transform;
  134. }
  135. void CCharacterController::updateDimensions()
  136. {
  137. Vector3 scale = SO()->getWorldScale();
  138. float height = mDesc.height * Math::abs(scale.y);
  139. float radius = mDesc.radius * Math::abs(std::max(scale.x, scale.z));
  140. mInternal->setHeight(height);
  141. mInternal->setRadius(radius);
  142. }
  143. void CCharacterController::triggerOnColliderHit(const ControllerColliderCollision& value)
  144. {
  145. // Const-cast and modify is okay because we're the only object receiving this event
  146. ControllerColliderCollision& hit = const_cast<ControllerColliderCollision&>(value);
  147. hit.collider = mThisHandle;
  148. onColliderHit(hit);
  149. }
  150. void CCharacterController::triggerOnControllerHit(const ControllerControllerCollision& value)
  151. {
  152. // Const-cast and modify is okay because we're the only object receiving this event
  153. ControllerControllerCollision& hit = const_cast<ControllerControllerCollision&>(value);
  154. hit.controller = mThisHandle;
  155. onControllerHit(hit);
  156. }
  157. RTTITypeBase* CCharacterController::getRTTIStatic()
  158. {
  159. return CCharacterControllerRTTI::instance();
  160. }
  161. RTTITypeBase* CCharacterController::getRTTI() const
  162. {
  163. return CCharacterController::getRTTIStatic();
  164. }
  165. }