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 | |
11 | namespace 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 | } |