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