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