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#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "Physics/BsCollider.h"
7#include "Scene/BsComponent.h"
8
9namespace bs
10{
11 /** @addtogroup Components-Core
12 * @{
13 */
14
15 /**
16 * @copydoc Collider
17 *
18 * Wraps Collider as a Component.
19 */
20 class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Physics,n:Collider) CCollider : public Component
21 {
22 public:
23 CCollider(const HSceneObject& parent);
24 virtual ~CCollider() = default;
25
26 /** @copydoc Collider::setIsTrigger */
27 BS_SCRIPT_EXPORT(n:Trigger,pr:setter)
28 void setIsTrigger(bool value);
29
30 /** @copydoc Collider::getIsTrigger */
31 BS_SCRIPT_EXPORT(n:Trigger,pr:getter)
32 bool getIsTrigger() const { return mIsTrigger; }
33
34 /** @copydoc Collider::setMass */
35 BS_SCRIPT_EXPORT(n:Mass,pr:setter)
36 void setMass(float mass);
37
38 /** @copydoc Collider::getMass */
39 BS_SCRIPT_EXPORT(n:Mass,pr:getter)
40 float getMass() const { return mMass; }
41
42 /** @copydoc Collider::setMaterial */
43 BS_SCRIPT_EXPORT(n:Material,pr:setter)
44 void setMaterial(const HPhysicsMaterial& material);
45
46 /** @copydoc Collider::getMaterial */
47 BS_SCRIPT_EXPORT(n:Material,pr:getter)
48 HPhysicsMaterial getMaterial() const { return mMaterial; }
49
50 /** @copydoc Collider::setContactOffset */
51 BS_SCRIPT_EXPORT(n:ContactOffset,pr:setter)
52 void setContactOffset(float value);
53
54 /** @copydoc Collider::getContactOffset */
55 BS_SCRIPT_EXPORT(n:ContactOffset,pr:getter)
56 float getContactOffset() const { return mContactOffset; }
57
58 /** @copydoc Collider::setRestOffset */
59 BS_SCRIPT_EXPORT(n:RestOffset,pr:setter)
60 void setRestOffset(float value);
61
62 /** @copydoc Collider::getRestOffset */
63 BS_SCRIPT_EXPORT(n:RestOffset,pr:getter)
64 float getRestOffset() const { return mRestOffset; }
65
66 /** @copydoc Collider::setLayer */
67 BS_SCRIPT_EXPORT(n:Layer,pr:setter,layerMask)
68 void setLayer(UINT64 layer);
69
70 /** @copydoc Collider::getLayer */
71 BS_SCRIPT_EXPORT(n:Layer,pr:getter,layerMask)
72 UINT64 getLayer() const { return mLayer; }
73
74 /** @copydoc Collider::setCollisionReportMode */
75 BS_SCRIPT_EXPORT(n:CollisionReportMode,pr:setter)
76 void setCollisionReportMode(CollisionReportMode mode);
77
78 /** @copydoc Collider::getCollisionReportMode */
79 BS_SCRIPT_EXPORT(n:CollisionReportMode,pr:getter)
80 CollisionReportMode getCollisionReportMode() const { return mCollisionReportMode; }
81
82 /** @copydoc Collider::getRigidbody */
83 HRigidbody getRigidbody() const { return mParent; }
84
85 /** @copydoc Collider::rayCast(const Ray&, PhysicsQueryHit&, float) const */
86 bool rayCast(const Ray& ray, PhysicsQueryHit& hit, float maxDist = FLT_MAX) const;
87
88 /** @copydoc Collider::rayCast(const Vector3&, const Vector3&, PhysicsQueryHit&, float) const */
89 bool rayCast(const Vector3& origin, const Vector3& unitDir, PhysicsQueryHit& hit,
90 float maxDist = FLT_MAX) const;
91
92 /** @copydoc Collider::onCollisionBegin */
93 BS_SCRIPT_EXPORT(n:OnCollisionBegin)
94 Event<void(const CollisionData&)> onCollisionBegin;
95
96 /** @copydoc Collider::onCollisionStay */
97 BS_SCRIPT_EXPORT(n:OnCollisionStay)
98 Event<void(const CollisionData&)> onCollisionStay;
99
100 /** @copydoc Collider::onCollisionEnd */
101 BS_SCRIPT_EXPORT(n:OnCollisionEnd)
102 Event<void(const CollisionData&)> onCollisionEnd;
103
104 /** @name Internal
105 * @{
106 */
107
108 /** Returns the Collider implementation wrapped by this component. */
109 Collider* _getInternal() const { return mInternal.get(); }
110
111 /** @} */
112
113 /************************************************************************/
114 /* COMPONENT OVERRIDES */
115 /************************************************************************/
116 protected:
117 friend class SceneObject;
118 friend class CRigidbody;
119
120 /** @copydoc Component::onInitialized() */
121 void onInitialized() override;
122
123 /** @copydoc Component::onDestroyed() */
124 void onDestroyed() override;
125
126 /** @copydoc Component::onDisabled() */
127 void onDisabled() override;
128
129 /** @copydoc Component::onEnabled() */
130 void onEnabled() override;
131
132 /** @copydoc Component::onTransformChanged() */
133 void onTransformChanged(TransformChangedFlags flags) override;
134
135 protected:
136 using Component::destroyInternal;
137
138 /** Creates the internal representation of the Collider for use by the component. */
139 virtual SPtr<Collider> createInternal() = 0;
140
141 /** Creates the internal representation of the Collider and restores the values saved by the Component. */
142 virtual void restoreInternal();
143
144 /** Destroys the internal collider representation. */
145 void destroyInternal();
146
147 /**
148 * Checks is the provided rigidbody a valid parent for this collider.
149 *
150 * @note This is required because certain colliders are limited in how they can be used. */
151 virtual bool isValidParent(const HRigidbody& parent) const { return true; }
152
153 /**
154 * Changes the rigidbody parent of the collider. Meant to be called from the Rigidbody itself.
155 *
156 * @param[in] rigidbody New rigidbody to assign as the parent to the collider.
157 * @param[in] internal If true the rigidbody will just be changed internally, but parent rigidbody will not be
158 * notified.
159 */
160 void setRigidbody(const HRigidbody& rigidbody, bool internal = false);
161
162 /**
163 * Updates the transform of the internal Collider representation from the transform of the component's scene object.
164 */
165 void updateTransform();
166
167 /** Applies the collision report mode to the internal collider depending on the current state. */
168 void updateCollisionReportMode();
169
170 /** Searches the parent scene object hierarchy to find a parent Rigidbody component. */
171 void updateParentRigidbody();
172
173 /** Triggered when the internal collider begins touching another object. */
174 void triggerOnCollisionBegin(const CollisionDataRaw& data);
175
176 /** Triggered when the internal collider continues touching another object. */
177 void triggerOnCollisionStay(const CollisionDataRaw& data);
178
179 /** Triggered when the internal collider ends touching another object. */
180 void triggerOnCollisionEnd(const CollisionDataRaw& data);
181
182 SPtr<Collider> mInternal;
183
184 UINT64 mLayer = 1;
185 CollisionReportMode mCollisionReportMode = CollisionReportMode::None;
186 float mRestOffset = 0.0f;
187 float mContactOffset = 0.02f;
188 HPhysicsMaterial mMaterial;
189 float mMass = 1.0f;
190 bool mIsTrigger = false;
191 Vector3 mLocalPosition = Vector3::ZERO;
192 Quaternion mLocalRotation = Quaternion::IDENTITY;
193
194 HRigidbody mParent;
195
196 /************************************************************************/
197 /* RTTI */
198 /************************************************************************/
199 public:
200 friend class CColliderRTTI;
201 static RTTITypeBase* getRTTIStatic();
202 RTTITypeBase* getRTTI() const override;
203
204 protected:
205 CCollider(); // Serialization only
206 };
207
208 /** @} */
209}