| 1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
| 2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
| 3 | #include "Components/BsCCapsuleCollider.h" |
| 4 | #include "Scene/BsSceneObject.h" |
| 5 | #include "Components/BsCRigidbody.h" |
| 6 | #include "Private/RTTI/BsCCapsuleColliderRTTI.h" |
| 7 | #include "Scene/BsSceneManager.h" |
| 8 | |
| 9 | namespace bs |
| 10 | { |
| 11 | CCapsuleCollider::CCapsuleCollider() |
| 12 | { |
| 13 | setName("CapsuleCollider" ); |
| 14 | |
| 15 | mLocalRotation = Quaternion::getRotationFromTo(Vector3::UNIT_X, mNormal); |
| 16 | } |
| 17 | |
| 18 | CCapsuleCollider::CCapsuleCollider(const HSceneObject& parent, float radius, float halfHeight) |
| 19 | : CCollider(parent), mRadius(radius), mHalfHeight(halfHeight) |
| 20 | { |
| 21 | setName("CapsuleCollider" ); |
| 22 | |
| 23 | mLocalRotation = Quaternion::getRotationFromTo(Vector3::UNIT_X, mNormal); |
| 24 | } |
| 25 | |
| 26 | void CCapsuleCollider::setNormal(const Vector3& normal) |
| 27 | { |
| 28 | if (mNormal == normal) |
| 29 | return; |
| 30 | |
| 31 | mNormal = bs::Vector3::normalize(normal); |
| 32 | mLocalRotation = Quaternion::getRotationFromTo(Vector3::UNIT_X, mNormal); |
| 33 | |
| 34 | if (mInternal != nullptr) |
| 35 | updateTransform(); |
| 36 | } |
| 37 | |
| 38 | void CCapsuleCollider::setCenter(const Vector3& center) |
| 39 | { |
| 40 | if (mLocalPosition == center) |
| 41 | return; |
| 42 | |
| 43 | mLocalPosition = center; |
| 44 | |
| 45 | if (mInternal != nullptr) |
| 46 | updateTransform(); |
| 47 | } |
| 48 | |
| 49 | void CCapsuleCollider::setHalfHeight(float halfHeight) |
| 50 | { |
| 51 | float clampedHalfHeight = std::max(halfHeight, 0.01f); |
| 52 | if (mHalfHeight == clampedHalfHeight) |
| 53 | return; |
| 54 | |
| 55 | mHalfHeight = clampedHalfHeight; |
| 56 | |
| 57 | if (mInternal != nullptr) |
| 58 | { |
| 59 | _getInternal()->setHalfHeight(clampedHalfHeight); |
| 60 | |
| 61 | if (mParent != nullptr) |
| 62 | mParent->_updateMassDistribution(); |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | void CCapsuleCollider::setRadius(float radius) |
| 67 | { |
| 68 | float clampedRadius = std::max(radius, 0.01f); |
| 69 | if (mRadius == clampedRadius) |
| 70 | return; |
| 71 | |
| 72 | mRadius = clampedRadius; |
| 73 | |
| 74 | if (mInternal != nullptr) |
| 75 | { |
| 76 | _getInternal()->setRadius(clampedRadius); |
| 77 | |
| 78 | if (mParent != nullptr) |
| 79 | mParent->_updateMassDistribution(); |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | SPtr<Collider> CCapsuleCollider::createInternal() |
| 84 | { |
| 85 | const SPtr<SceneInstance>& scene = SO()->getScene(); |
| 86 | const Transform& tfrm = SO()->getTransform(); |
| 87 | |
| 88 | SPtr<Collider> collider = CapsuleCollider::create(*scene->getPhysicsScene(), mRadius, mHalfHeight, |
| 89 | tfrm.getPosition(), tfrm.getRotation()); |
| 90 | |
| 91 | collider->_setOwner(PhysicsOwnerType::Component, this); |
| 92 | return collider; |
| 93 | } |
| 94 | |
| 95 | RTTITypeBase* CCapsuleCollider::getRTTIStatic() |
| 96 | { |
| 97 | return CCapsuleColliderRTTI::instance(); |
| 98 | } |
| 99 | |
| 100 | RTTITypeBase* CCapsuleCollider::getRTTI() const |
| 101 | { |
| 102 | return CCapsuleCollider::getRTTIStatic(); |
| 103 | } |
| 104 | } |
| 105 | |