1 /********************************************************************************
2 * ReactPhysics3D physics library, http://www.reactphysics3d.com *
3 * Copyright (c) 2010-2020 Daniel Chappuis *
4 *********************************************************************************
5 * *
6 * This software is provided 'as-is', without any express or implied warranty. *
7 * In no event will the authors be held liable for any damages arising from the *
8 * use of this software. *
9 * *
10 * Permission is granted to anyone to use this software for any purpose, *
11 * including commercial applications, and to alter it and redistribute it *
12 * freely, subject to the following restrictions: *
13 * *
14 * 1. The origin of this software must not be misrepresented; you must not claim *
15 * that you wrote the original software. If you use this software in a *
16 * product, an acknowledgment in the product documentation would be *
17 * appreciated but is not required. *
18 * *
19 * 2. Altered source versions must be plainly marked as such, and must not be *
20 * misrepresented as being the original software. *
21 * *
22 * 3. This notice may not be removed or altered from any source distribution. *
23 * *
24 ********************************************************************************/
25
26 #ifndef REACTPHYSICS3D_BROAD_PHASE_ALGORITHM_H
27 #define REACTPHYSICS3D_BROAD_PHASE_ALGORITHM_H
28
29 // Libraries
30 #include <reactphysics3d/collision/broadphase/DynamicAABBTree.h>
31 #include <reactphysics3d/containers/LinkedList.h>
32 #include <reactphysics3d/containers/Set.h>
33 #include <reactphysics3d/components/ColliderComponents.h>
34 #include <reactphysics3d/components/TransformComponents.h>
35 #include <reactphysics3d/components/RigidBodyComponents.h>
36 #include <cstring>
37
38 /// Namespace ReactPhysics3D
39 namespace reactphysics3d {
40
41 // Declarations
42 class CollisionDetectionSystem;
43 class BroadPhaseSystem;
44 class CollisionBody;
45 class Collider;
46 class MemoryManager;
47 class Profiler;
48
49 // class AABBOverlapCallback
50 class AABBOverlapCallback : public DynamicAABBTreeOverlapCallback {
51
52 public:
53
54 List<int>& mOverlappingNodes;
55
56 // Constructor
AABBOverlapCallback(List<int> & overlappingNodes)57 AABBOverlapCallback(List<int>& overlappingNodes) : mOverlappingNodes(overlappingNodes) {
58
59 }
60
61 // Called when a overlapping node has been found during the call to
62 // DynamicAABBTree:reportAllShapesOverlappingWithAABB()
63 virtual void notifyOverlappingNode(int nodeId) override;
64
65 };
66
67 // Class BroadPhaseRaycastCallback
68 /**
69 * Callback called when the AABB of a leaf node is hit by a ray the
70 * broad-phase Dynamic AABB Tree.
71 */
72 class BroadPhaseRaycastCallback : public DynamicAABBTreeRaycastCallback {
73
74 private :
75
76 const DynamicAABBTree& mDynamicAABBTree;
77
78 unsigned short mRaycastWithCategoryMaskBits;
79
80 RaycastTest& mRaycastTest;
81
82 public:
83
84 // Constructor
BroadPhaseRaycastCallback(const DynamicAABBTree & dynamicAABBTree,unsigned short raycastWithCategoryMaskBits,RaycastTest & raycastTest)85 BroadPhaseRaycastCallback(const DynamicAABBTree& dynamicAABBTree, unsigned short raycastWithCategoryMaskBits,
86 RaycastTest& raycastTest)
87 : mDynamicAABBTree(dynamicAABBTree), mRaycastWithCategoryMaskBits(raycastWithCategoryMaskBits),
88 mRaycastTest(raycastTest) {
89
90 }
91
92 // Destructor
93 virtual ~BroadPhaseRaycastCallback() override = default;
94
95 // Called for a broad-phase shape that has to be tested for raycast
96 virtual decimal raycastBroadPhaseShape(int32 nodeId, const Ray& ray) override;
97
98 };
99
100 // Class BroadPhaseSystem
101 /**
102 * This class represents the broad-phase collision detection. The
103 * goal of the broad-phase collision detection is to compute the pairs of colliders
104 * that have their AABBs overlapping. Only those pairs of bodies will be tested
105 * later for collision during the narrow-phase collision detection. A dynamic AABB
106 * tree data structure is used for fast broad-phase collision detection.
107 */
108 class BroadPhaseSystem {
109
110 protected :
111
112 // -------------------- Attributes -------------------- //
113
114 /// Dynamic AABB tree
115 DynamicAABBTree mDynamicAABBTree;
116
117 /// Reference to the colliders components
118 ColliderComponents& mCollidersComponents;
119
120 /// Reference to the transform components
121 TransformComponents& mTransformsComponents;
122
123 /// Reference to the rigid body components
124 RigidBodyComponents& mRigidBodyComponents;
125
126 /// Set with the broad-phase IDs of all collision shapes that have moved (or have been
127 /// created) during the last simulation step. Those are the shapes that need to be tested
128 /// for overlapping in the next simulation step.
129 Set<int> mMovedShapes;
130
131 /// Reference to the collision detection object
132 CollisionDetectionSystem& mCollisionDetection;
133
134 #ifdef IS_RP3D_PROFILING_ENABLED
135
136 /// Pointer to the profiler
137 Profiler* mProfiler;
138
139 #endif
140 // -------------------- Methods -------------------- //
141
142 /// Notify the Dynamic AABB tree that a collider needs to be updated
143 void updateColliderInternal(int32 broadPhaseId, Collider* collider, const AABB& aabb,
144 bool forceReInsert);
145
146 /// Update the broad-phase state of some colliders components
147 void updateCollidersComponents(uint32 startIndex, uint32 nbItems, decimal timeStep);
148
149 public :
150
151 // -------------------- Methods -------------------- //
152
153 /// Constructor
154 BroadPhaseSystem(CollisionDetectionSystem& collisionDetection, ColliderComponents& collidersComponents,
155 TransformComponents& transformComponents, RigidBodyComponents& rigidBodyComponents);
156
157 /// Destructor
158 ~BroadPhaseSystem() = default;
159
160 /// Deleted copy-constructor
161 BroadPhaseSystem(const BroadPhaseSystem& algorithm) = delete;
162
163 /// Deleted assignment operator
164 BroadPhaseSystem& operator=(const BroadPhaseSystem& algorithm) = delete;
165
166 /// Add a collider into the broad-phase collision detection
167 void addCollider(Collider* collider, const AABB& aabb);
168
169 /// Remove a collider from the broad-phase collision detection
170 void removeCollider(Collider* collider);
171
172 /// Update the broad-phase state of a single collider
173 void updateCollider(Entity colliderEntity, decimal timeStep);
174
175 /// Update the broad-phase state of all the enabled colliders
176 void updateColliders(decimal timeStep);
177
178 /// Add a collider in the array of colliders that have moved in the last simulation step
179 /// and that need to be tested again for broad-phase overlapping.
180 void addMovedCollider(int broadPhaseID, Collider* collider);
181
182 /// Remove a collider from the array of colliders that have moved in the last simulation
183 /// step and that need to be tested again for broad-phase overlapping.
184 void removeMovedCollider(int broadPhaseID);
185
186 /// Compute all the overlapping pairs of collision shapes
187 void computeOverlappingPairs(MemoryManager& memoryManager, List<Pair<int32, int32>>& overlappingNodes);
188
189 /// Return the collider corresponding to the broad-phase node id in parameter
190 Collider* getColliderForBroadPhaseId(int broadPhaseId) const;
191
192 /// Return true if the two broad-phase collision shapes are overlapping
193 bool testOverlappingShapes(int32 shape1BroadPhaseId, int32 shape2BroadPhaseId) const;
194
195 /// Return the fat AABB of a given broad-phase shape
196 const AABB& getFatAABB(int broadPhaseId) const;
197
198 /// Ray casting method
199 void raycast(const Ray& ray, RaycastTest& raycastTest, unsigned short raycastWithCategoryMaskBits) const;
200
201 #ifdef IS_RP3D_PROFILING_ENABLED
202
203 /// Set the profiler
204 void setProfiler(Profiler* profiler);
205
206 #endif
207
208 };
209
210 // Return the fat AABB of a given broad-phase shape
getFatAABB(int broadPhaseId)211 inline const AABB& BroadPhaseSystem::getFatAABB(int broadPhaseId) const {
212 return mDynamicAABBTree.getFatAABB(broadPhaseId);
213 }
214
215 // Remove a collider from the array of colliders that have moved in the last simulation step
216 // and that need to be tested again for broad-phase overlapping.
removeMovedCollider(int broadPhaseID)217 inline void BroadPhaseSystem::removeMovedCollider(int broadPhaseID) {
218
219 // Remove the broad-phase ID from the set
220 mMovedShapes.remove(broadPhaseID);
221 }
222
223 // Return the collider corresponding to the broad-phase node id in parameter
getColliderForBroadPhaseId(int broadPhaseId)224 inline Collider* BroadPhaseSystem::getColliderForBroadPhaseId(int broadPhaseId) const {
225 return static_cast<Collider*>(mDynamicAABBTree.getNodeDataPointer(broadPhaseId));
226 }
227
228 #ifdef IS_RP3D_PROFILING_ENABLED
229
230 // Set the profiler
setProfiler(Profiler * profiler)231 inline void BroadPhaseSystem::setProfiler(Profiler* profiler) {
232 mProfiler = profiler;
233 mDynamicAABBTree.setProfiler(profiler);
234 }
235
236 #endif
237
238 }
239
240 #endif
241
242