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_OVERLAP_CALLBACK_H
27 #define REACTPHYSICS3D_OVERLAP_CALLBACK_H
28 
29 // Libraries
30 #include <reactphysics3d/containers/List.h>
31 #include <reactphysics3d/collision/ContactPair.h>
32 
33 /// ReactPhysics3D namespace
34 namespace reactphysics3d {
35 
36 // Declarations
37 class CollisionBody;
38 class PhysicsWorld;
39 class Collider;
40 struct Entity;
41 
42 // Class OverlapCallback
43 /**
44  * This class can be used to register a callback for collision overlap queries between bodies.
45  * You should implement your own class inherited from this one and implement the onOverlap() method.
46  */
47 class OverlapCallback {
48 
49     public:
50 
51         // Class OverlapPair
52         /**
53          * This class represents the contact between two colliders of the physics world.
54          */
55         class OverlapPair {
56 
57             public:
58 
59                 /// Enumeration EventType that describes the type of overlapping event
60                 enum class EventType {
61 
62                     /// This overlap is a new overlap between the two
63                     /// colliders (the colliders where not overlapping in the previous frame)
64                     OverlapStart,
65 
66                     /// The two colliders were already overlapping in the previous frame and this is a new or updated overlap
67                     OverlapStay,
68 
69                     /// The two colliders were overlapping in the previous frame and are not overlapping anymore
70                     OverlapExit
71                 };
72 
73             private:
74 
75                 // -------------------- Attributes -------------------- //
76 
77                 /// Contact pair
78                 ContactPair& mContactPair;
79 
80                 /// Reference to the physics world
81                 PhysicsWorld& mWorld;
82 
83                 /// True if the pair were overlapping in the previous frame but not in the current one
84                 bool mIsLostOverlapPair;
85 
86                 // -------------------- Methods -------------------- //
87 
88                 /// Constructor
89                 OverlapPair(ContactPair& contactPair, reactphysics3d::PhysicsWorld& world, bool isLostOverlappingPair);
90 
91             public:
92 
93                 // -------------------- Methods -------------------- //
94 
95                 /// Copy constructor
96                 OverlapPair(const OverlapPair& contactPair) = default;
97 
98                 /// Assignment operator
99                 OverlapPair& operator=(const OverlapPair& contactPair) = default;
100 
101                 /// Destructor
102                 ~OverlapPair() = default;
103 
104                 /// Return a pointer to the first collider in contact
105                 Collider* getCollider1() const;
106 
107                 /// Return a pointer to the second collider in contact
108                 Collider* getCollider2() const;
109 
110                 /// Return a pointer to the first body in contact
111                 CollisionBody* getBody1() const;
112 
113                 /// Return a pointer to the second body in contact
114                 CollisionBody* getBody2() const;
115 
116                 /// Return the corresponding type of event for this overlapping pair
117                 EventType getEventType() const;
118 
119                 // -------------------- Friendship -------------------- //
120 
121                 friend class OverlapCallback;
122         };
123 
124         // Class CallbackData
125         /**
126          * This class contains data about overlap between bodies
127          */
128         class CallbackData {
129 
130             private:
131 
132                 // -------------------- Attributes -------------------- //
133 
134                 /// Reference to the list of contact pairs (contains contacts and triggers events)
135                 List<ContactPair>& mContactPairs;
136 
137                 /// Reference to the list of lost contact pairs (contains contacts and triggers events)
138                 List<ContactPair>& mLostContactPairs;
139 
140                 /// List of indices of the mContactPairs list that are overlap/triggers events (not contact events)
141                 List<uint> mContactPairsIndices;
142 
143                 /// List of indices of the mLostContactPairs list that are overlap/triggers events (not contact events)
144                 List<uint> mLostContactPairsIndices;
145 
146                 /// Reference to the physics world
147                 PhysicsWorld& mWorld;
148 
149                 // -------------------- Methods -------------------- //
150 
151                 /// Constructor
152                 CallbackData(List<ContactPair>& contactPairs, List<ContactPair>& lostContactPairs, bool onlyReportTriggers, PhysicsWorld& world);
153 
154                 /// Deleted copy constructor
155                 CallbackData(const CallbackData& callbackData) = delete;
156 
157                 /// Deleted assignment operator
158                 CallbackData& operator=(const CallbackData& callbackData) = delete;
159 
160                 /// Destructor
161                 ~CallbackData() = default;
162 
163             public:
164 
165                 // -------------------- Methods -------------------- //
166 
167                 /// Return the number of overlapping pairs of bodies
168                 uint getNbOverlappingPairs() const;
169 
170                 /// Return a given overlapping pair of bodies
171                 OverlapPair getOverlappingPair(uint index) const;
172 
173                 // -------------------- Friendship -------------------- //
174 
175                 friend class CollisionDetectionSystem;
176         };
177 
178         /// Destructor
~OverlapCallback()179         virtual ~OverlapCallback() {
180 
181         }
182 
183         /// This method will be called to report bodies that overlap
184         virtual void onOverlap(CallbackData& callbackData)=0;
185 };
186 
187 // Return the number of overlapping pairs of bodies
getNbOverlappingPairs()188 inline uint OverlapCallback::CallbackData::getNbOverlappingPairs() const {
189     return mContactPairsIndices.size() + mLostContactPairsIndices.size();
190 }
191 
192 // Return a given overlapping pair of bodies
193 /// Note that the returned OverlapPair object is only valid during the call of the CollisionCallback::onOverlap()
194 /// method. Therefore, you need to get contact data from it and make a copy. Do not make a copy of the OverlapPair
195 /// object itself because it won't be valid after the CollisionCallback::onOverlap() call.
getOverlappingPair(uint index)196 inline OverlapCallback::OverlapPair OverlapCallback::CallbackData::getOverlappingPair(uint index) const {
197 
198     assert(index < getNbOverlappingPairs());
199 
200     if (index < mContactPairsIndices.size()) {
201         // Return a contact pair
202         return OverlapCallback::OverlapPair((mContactPairs)[mContactPairsIndices[index]],  mWorld, false);
203     }
204     else {
205 
206         // Return a lost contact pair
207         return OverlapCallback::OverlapPair(mLostContactPairs[mLostContactPairsIndices[index - mContactPairsIndices.size()]], mWorld, true);
208     }
209 }
210 
211 }
212 
213 #endif
214