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/BsRigidbody.h"
7#include "Scene/BsComponent.h"
8#include "Math/BsVector3.h"
9#include "Math/BsQuaternion.h"
10
11namespace bs
12{
13 /** @addtogroup Components-Core
14 * @{
15 */
16
17 /**
18 * @copydoc Rigidbody
19 *
20 * Colliders that are on the same scene object as the rigidbody, or on child scene objects are automatically considered
21 * as part of the rigidbody.
22 *
23 * @note Wraps Rigidbody as a Component.
24 */
25 class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Physics,n:Rigidbody) CRigidbody : public Component
26 {
27 public:
28 CRigidbody(const HSceneObject& parent);
29
30 /** @copydoc Rigidbody::move */
31 BS_SCRIPT_EXPORT(n:Move)
32 void move(const Vector3& position);
33
34 /** @copydoc Rigidbody::rotate */
35 BS_SCRIPT_EXPORT(n:Rotate)
36 void rotate(const Quaternion& rotation);
37
38 /** @copydoc Rigidbody::setMass */
39 BS_SCRIPT_EXPORT(n:Mass,pr:setter)
40 void setMass(float mass);
41
42 /** @copydoc Rigidbody::getMass */
43 BS_SCRIPT_EXPORT(n:Mass,pr:getter)
44 float getMass() const { return mMass; };
45
46 /** @copydoc Rigidbody::setIsKinematic */
47 BS_SCRIPT_EXPORT(n:IsKinematic,pr:setter)
48 void setIsKinematic(bool kinematic);
49
50 /** @copydoc Rigidbody::getIsKinematic */
51 BS_SCRIPT_EXPORT(n:IsKinematic,pr:getter)
52 bool getIsKinematic() const { return mIsKinematic; }
53
54 /** @copydoc Rigidbody::isSleeping */
55 BS_SCRIPT_EXPORT(n:IsSleeping,pr:getter)
56 bool isSleeping() const;
57
58 /** @copydoc Rigidbody::sleep */
59 BS_SCRIPT_EXPORT(n:Sleep)
60 void sleep();
61
62 /** @copydoc Rigidbody::wakeUp */
63 BS_SCRIPT_EXPORT(n:WakeUp)
64 void wakeUp();
65
66 /** @copydoc Rigidbody::setSleepThreshold */
67 BS_SCRIPT_EXPORT(n:SleepThreshold,pr:setter,hide)
68 void setSleepThreshold(float threshold);
69
70 /** @copydoc Rigidbody::getSleepThreshold */
71 BS_SCRIPT_EXPORT(n:SleepThreshold,pr:getter)
72 float getSleepThreshold() const { return mSleepThreshold; }
73
74 /** @copydoc Rigidbody::setUseGravity */
75 BS_SCRIPT_EXPORT(n:UseGravity,pr:setter)
76 void setUseGravity(bool gravity);
77
78 /** @copydoc Rigidbody::getUseGravity */
79 BS_SCRIPT_EXPORT(n:UseGravity,pr:getter)
80 bool getUseGravity() const { return mUseGravity; }
81
82 /** @copydoc Rigidbody::setVelocity */
83 BS_SCRIPT_EXPORT(n:Velocity,pr:setter,hide)
84 void setVelocity(const Vector3& velocity);
85
86 /** @copydoc Rigidbody::getVelocity */
87 BS_SCRIPT_EXPORT(n:Velocity,pr:getter)
88 Vector3 getVelocity() const;
89
90 /** @copydoc Rigidbody::setAngularVelocity */
91 BS_SCRIPT_EXPORT(n:AngularVelocity,pr:setter,hide)
92 void setAngularVelocity(const Vector3& velocity);
93
94 /** @copydoc Rigidbody::getAngularVelocity */
95 BS_SCRIPT_EXPORT(n:AngularVelocity,pr:getter)
96 Vector3 getAngularVelocity() const;
97
98 /** @copydoc Rigidbody::setDrag */
99 BS_SCRIPT_EXPORT(n:Drag,pr:setter)
100 void setDrag(float drag);
101
102 /** @copydoc Rigidbody::getDrag */
103 BS_SCRIPT_EXPORT(n:Drag,pr:getter)
104 float getDrag() const { return mLinearDrag; }
105
106 /** @copydoc Rigidbody::setAngularDrag */
107 BS_SCRIPT_EXPORT(n:AngularDrag,pr:setter)
108 void setAngularDrag(float drag);
109
110 /** @copydoc Rigidbody::getAngularDrag */
111 BS_SCRIPT_EXPORT(n:AngularDrag,pr:getter)
112 float getAngularDrag() const { return mAngularDrag; }
113
114 /** @copydoc Rigidbody::setInertiaTensor */
115 BS_SCRIPT_EXPORT(n:InertiaTensor,pr:setter,hide)
116 void setInertiaTensor(const Vector3& tensor);
117
118 /** @copydoc Rigidbody::getInertiaTensor */
119 BS_SCRIPT_EXPORT(n:InertiaTensor,pr:getter)
120 Vector3 getInertiaTensor() const;
121
122 /** @copydoc Rigidbody::setMaxAngularVelocity */
123 BS_SCRIPT_EXPORT(n:MaxAngularVelocity,pr:setter,hide)
124 void setMaxAngularVelocity(float maxVelocity);
125
126 /** @copydoc Rigidbody::getMaxAngularVelocity */
127 BS_SCRIPT_EXPORT(n:MaxAngularVelocity,pr:getter)
128 float getMaxAngularVelocity() const { return mMaxAngularVelocity; }
129
130 /** Determines the rigidbody's center of mass position. Only relevant if RigibodyFlag::AutoTensors is turned off. */
131 BS_SCRIPT_EXPORT(n:CenterOfMassPosition,pr:setter,hide)
132 void setCenterOfMassPosition(const Vector3& position);
133
134 /** @copydoc setCenterOfMassPosition() */
135 BS_SCRIPT_EXPORT(n:CenterOfMassPosition,pr:getter)
136 Vector3 getCenterOfMassPosition() const;
137
138 /** Determines the rigidbody's center of mass rotation. Only relevant if RigibodyFlag::AutoTensors is turned off. */
139 BS_SCRIPT_EXPORT(n:CenterOfMassRotation,pr:setter,hide)
140 void setCenterOfMassRotation(const Quaternion& rotation);
141
142 /** @copydoc setCenterOfMassRotation() */
143 BS_SCRIPT_EXPORT(n:CenterOfMassRotation,pr:getter)
144 Quaternion getCenterOfMassRotation() const;
145
146 /** @copydoc Rigidbody::setPositionSolverCount */
147 BS_SCRIPT_EXPORT(n:PositionSolverCount,pr:setter,hide)
148 void setPositionSolverCount(UINT32 count);
149
150 /** @copydoc Rigidbody::getPositionSolverCount */
151 BS_SCRIPT_EXPORT(n:PositionSolverCount,pr:getter)
152 UINT32 getPositionSolverCount() const { return mPositionSolverCount; }
153
154 /** @copydoc Rigidbody::setVelocitySolverCount */
155 BS_SCRIPT_EXPORT(n:VelocitySolverCount,pr:setter,hide)
156 void setVelocitySolverCount(UINT32 count);
157
158 /** @copydoc Rigidbody::getVelocitySolverCount */
159 BS_SCRIPT_EXPORT(n:VelocitySolverCount,pr:getter)
160 UINT32 getVelocitySolverCount() const { return mVelocitySolverCount; }
161
162 /** Sets a value that determines which (if any) collision events are reported. */
163 BS_SCRIPT_EXPORT(n:CollisionReportMode,pr:setter)
164 void setCollisionReportMode(CollisionReportMode mode);
165
166 /** Gets a value that determines which (if any) collision events are reported. */
167 BS_SCRIPT_EXPORT(n:CollisionReportMode,pr:getter)
168 CollisionReportMode getCollisionReportMode() const { return mCollisionReportMode; }
169
170 /** @copydoc Rigidbody::setFlags */
171 BS_SCRIPT_EXPORT(n:Flags,pr:setter,hide)
172 void setFlags(RigidbodyFlag flags);
173
174 /** @copydoc Rigidbody::getFlags */
175 BS_SCRIPT_EXPORT(n:Flags,pr:getter)
176 RigidbodyFlag getFlags() const { return mFlags; }
177
178 /** @copydoc Rigidbody::addForce */
179 BS_SCRIPT_EXPORT(n:AddForce)
180 void addForce(const Vector3& force, ForceMode mode = ForceMode::Force);
181
182 /** @copydoc Rigidbody::addTorque */
183 BS_SCRIPT_EXPORT(n:AddTorque)
184 void addTorque(const Vector3& torque, ForceMode mode = ForceMode::Force);
185
186 /** @copydoc Rigidbody::addForceAtPoint */
187 BS_SCRIPT_EXPORT(n:AddForceAtPoint)
188 void addForceAtPoint(const Vector3& force, const Vector3& position,
189 PointForceMode mode = PointForceMode::Force);
190
191 /** @copydoc Rigidbody::getVelocityAtPoint */
192 BS_SCRIPT_EXPORT(n:GetVelocityAtPoint)
193 Vector3 getVelocityAtPoint(const Vector3& point) const;
194
195 /** @copydoc Rigidbody::onCollisionBegin */
196 BS_SCRIPT_EXPORT(n:OnCollisionBegin)
197 Event<void(const CollisionData&)> onCollisionBegin;
198
199 /** @copydoc Rigidbody::onCollisionStay */
200 BS_SCRIPT_EXPORT(n:OnCollisionStay)
201 Event<void(const CollisionData&)> onCollisionStay;
202
203 /** @copydoc Rigidbody::onCollisionEnd */
204 BS_SCRIPT_EXPORT(n:OnCollisionEnd)
205 Event<void(const CollisionData&)> onCollisionEnd;
206
207 /** @name Internal
208 * @{
209 */
210
211 /** Returns the Rigidbody implementation wrapped by this component. */
212 Rigidbody* _getInternal() const { return mInternal.get(); }
213
214 /** Sets that joint that this rigidbody is attached to. Allows the rigidbody to notify the joint when it moves. */
215 void _setJoint(const HJoint& joint) { mParentJoint = joint; }
216
217 /** @copydoc Rigidbody::updateMassDistribution */
218 void _updateMassDistribution();
219
220 /** @} */
221 protected:
222 friend class CCollider;
223
224 using Component::destroyInternal;
225
226 /**
227 * Searches child scene objects for Collider components and attaches them to the rigidbody. Make sure to call
228 * clearColliders() if you need to clear old colliders first.
229 */
230 void updateColliders();
231
232 /** Unregisters all child colliders from the Rigidbody. */
233 void clearColliders();
234
235 /**
236 * Registers a new collider with the Rigidbody. This collider will then be used to calculate Rigidbody's geometry
237 * used for collisions, and optionally (depending on set flags) total mass, inertia tensors and center of mass.
238 */
239 void addCollider(const HCollider& collider);
240
241 /** Unregisters the collider from the Rigidbody. */
242 void removeCollider(const HCollider& collider);
243
244 /** Checks if the rigidbody is nested under another rigidbody, and throws out a warning if so. */
245 void checkForNestedRigibody();
246
247 /** Appends Component referenes for the colliders to the collision data. */
248 void processCollisionData(const CollisionDataRaw& raw, CollisionData& output);
249
250 /** Destroys the internal rigidbody representation. */
251 void destroyInternal();
252
253 /** Triggered when the internal rigidbody begins touching another object. */
254 void triggerOnCollisionBegin(const CollisionDataRaw& data);
255
256 /** Triggered when the internal rigidbody continues touching another object. */
257 void triggerOnCollisionStay(const CollisionDataRaw& data);
258
259 /** Triggered when the internal rigidbody ends touching another object. */
260 void triggerOnCollisionEnd(const CollisionDataRaw& data);
261
262 /************************************************************************/
263 /* COMPONENT OVERRIDES */
264 /************************************************************************/
265 protected:
266 friend class SceneObject;
267
268 /** @copydoc Component::onInitialized() */
269 void onInitialized() override;
270
271 /** @copydoc Component::onDestroyed() */
272 void onDestroyed() override;
273
274 /** @copydoc Component::onDisabled() */
275 void onDisabled() override;
276
277 /** @copydoc Component::onEnabled() */
278 void onEnabled() override;
279
280 /** @copydoc Component::onTransformChanged() */
281 void onTransformChanged(TransformChangedFlags flags) override;
282
283 SPtr<Rigidbody> mInternal;
284 Vector<HCollider> mChildren;
285 HJoint mParentJoint;
286
287 UINT32 mPositionSolverCount = 4;
288 UINT32 mVelocitySolverCount = 1;
289 RigidbodyFlag mFlags = (RigidbodyFlag)((UINT32)RigidbodyFlag::AutoTensors | (UINT32)RigidbodyFlag::AutoMass);
290 CollisionReportMode mCollisionReportMode = CollisionReportMode::None;
291 Vector3 mCMassPosition = Vector3::ZERO;
292 Quaternion mCMassRotation = Quaternion::IDENTITY;
293 Vector3 mInertiaTensor = Vector3::ZERO;
294 float mMass = 0.0f;
295 float mMaxAngularVelocity = std::numeric_limits<float>::max();
296 float mLinearDrag = 0.0f;
297 float mAngularDrag = 0.0f;
298 float mSleepThreshold = 0.0f;
299 bool mUseGravity = true;
300 bool mIsKinematic = false;
301
302 /************************************************************************/
303 /* RTTI */
304 /************************************************************************/
305 public:
306 friend class CRigidbodyRTTI;
307 static RTTITypeBase* getRTTIStatic();
308 RTTITypeBase* getRTTI() const override;
309
310 protected:
311 CRigidbody(); // Serialization only
312 };
313
314 /** @} */
315}