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
9namespace 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