File indexing completed on 2025-08-03 03:49:57
0001 /* 0002 * Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com 0003 * 0004 * This software is provided 'as-is', without any express or implied 0005 * warranty. In no event will the authors be held liable for any damages 0006 * arising from the use of this software. 0007 * Permission is granted to anyone to use this software for any purpose, 0008 * including commercial applications, and to alter it and redistribute it 0009 * freely, subject to the following restrictions: 0010 * 1. The origin of this software must not be misrepresented; you must not 0011 * claim that you wrote the original software. If you use this software 0012 * in a product, an acknowledgment in the product documentation would be 0013 * appreciated but is not required. 0014 * 2. Altered source versions must be plainly marked as such, and must not be 0015 * misrepresented as being the original software. 0016 * 3. This notice may not be removed or altered from any source distribution. 0017 */ 0018 0019 #ifndef B2_CONTACT_H 0020 #define B2_CONTACT_H 0021 0022 #include <Box2D/Common/b2Math.h> 0023 #include <Box2D/Collision/b2Collision.h> 0024 #include <Box2D/Collision/Shapes/b2Shape.h> 0025 #include <Box2D/Dynamics/b2Fixture.h> 0026 0027 class b2Body; 0028 class b2Contact; 0029 class b2Fixture; 0030 class b2World; 0031 class b2BlockAllocator; 0032 class b2ContactListener; 0033 0034 typedef b2Contact* b2ContactCreateFcn( b2Fixture* fixtureA, int32 indexA, 0035 b2Fixture* fixtureB, int32 indexB, 0036 b2BlockAllocator* allocator); 0037 typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator); 0038 0039 struct b2ContactRegister 0040 { 0041 b2ContactCreateFcn* createFcn; 0042 b2ContactDestroyFcn* destroyFcn; 0043 bool primary; 0044 }; 0045 0046 /// A contact edge is used to connect bodies and contacts together 0047 /// in a contact graph where each body is a node and each contact 0048 /// is an edge. A contact edge belongs to a doubly linked list 0049 /// maintained in each attached body. Each contact has two contact 0050 /// nodes, one for each attached body. 0051 struct b2ContactEdge 0052 { 0053 b2Body* other; ///< provides quick access to the other body attached. 0054 b2Contact* contact; ///< the contact 0055 b2ContactEdge* prev; ///< the previous contact edge in the body's contact list 0056 b2ContactEdge* next; ///< the next contact edge in the body's contact list 0057 }; 0058 0059 /// The class manages contact between two shapes. A contact exists for each overlapping 0060 /// AABB in the broad-phase (except if filtered). Therefore a contact object may exist 0061 /// that has no contact points. 0062 class b2Contact 0063 { 0064 public: 0065 0066 /// Get the contact manifold. Do not modify the manifold unless you understand the 0067 /// internals of Box2D. 0068 b2Manifold* GetManifold(); 0069 const b2Manifold* GetManifold() const; 0070 0071 /// Get the world manifold. 0072 void GetWorldManifold(b2WorldManifold* worldManifold) const; 0073 0074 /// Is this contact touching? 0075 bool IsTouching() const; 0076 0077 /// Enable/disable this contact. This can be used inside the pre-solve 0078 /// contact listener. The contact is only disabled for the current 0079 /// time step (or sub-step in continuous collisions). 0080 void SetEnabled(bool flag); 0081 0082 /// Has this contact been disabled? 0083 bool IsEnabled() const; 0084 0085 /// Get the next contact in the world's contact list. 0086 b2Contact* GetNext(); 0087 const b2Contact* GetNext() const; 0088 0089 /// Get fixture A in this contact. 0090 b2Fixture* GetFixtureA(); 0091 const b2Fixture* GetFixtureA() const; 0092 0093 /// Get the child primitive index for fixture A. 0094 int32 GetChildIndexA() const; 0095 0096 /// Get fixture B in this contact. 0097 b2Fixture* GetFixtureB(); 0098 const b2Fixture* GetFixtureB() const; 0099 0100 /// Get the child primitive index for fixture B. 0101 int32 GetChildIndexB() const; 0102 0103 /// Evaluate this contact with your own manifold and transforms. 0104 virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0; 0105 0106 protected: 0107 friend class b2ContactManager; 0108 friend class b2World; 0109 friend class b2ContactSolver; 0110 friend class b2Body; 0111 friend class b2Fixture; 0112 0113 // Flags stored in m_flags 0114 enum 0115 { 0116 // Used when crawling contact graph when forming islands. 0117 e_islandFlag = 0x0001, 0118 0119 // Set when the shapes are touching. 0120 e_touchingFlag = 0x0002, 0121 0122 // This contact can be disabled (by user) 0123 e_enabledFlag = 0x0004, 0124 0125 // This contact needs filtering because a fixture filter was changed. 0126 e_filterFlag = 0x0008, 0127 0128 // This bullet contact had a TOI event 0129 e_bulletHitFlag = 0x0010, 0130 0131 // This contact has a valid TOI in m_toi 0132 e_toiFlag = 0x0020 0133 }; 0134 0135 /// Flag this contact for filtering. Filtering will occur the next time step. 0136 void FlagForFiltering(); 0137 0138 static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn, 0139 b2Shape::Type typeA, b2Shape::Type typeB); 0140 static void InitializeRegisters(); 0141 static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator); 0142 static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator); 0143 static void Destroy(b2Contact* contact, b2BlockAllocator* allocator); 0144 0145 b2Contact() : m_fixtureA(NULL), m_fixtureB(NULL) {} 0146 b2Contact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB); 0147 virtual ~b2Contact() {} 0148 0149 void Update(b2ContactListener* listener); 0150 0151 static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount]; 0152 static bool s_initialized; 0153 0154 uint32 m_flags; 0155 0156 // World pool and list pointers. 0157 b2Contact* m_prev; 0158 b2Contact* m_next; 0159 0160 // Nodes for connecting bodies. 0161 b2ContactEdge m_nodeA; 0162 b2ContactEdge m_nodeB; 0163 0164 b2Fixture* m_fixtureA; 0165 b2Fixture* m_fixtureB; 0166 0167 int32 m_indexA; 0168 int32 m_indexB; 0169 0170 b2Manifold m_manifold; 0171 0172 int32 m_toiCount; 0173 qreal m_toi; 0174 }; 0175 0176 inline b2Manifold* b2Contact::GetManifold() 0177 { 0178 return &m_manifold; 0179 } 0180 0181 inline const b2Manifold* b2Contact::GetManifold() const 0182 { 0183 return &m_manifold; 0184 } 0185 0186 inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const 0187 { 0188 const b2Body* bodyA = m_fixtureA->GetBody(); 0189 const b2Body* bodyB = m_fixtureB->GetBody(); 0190 const b2Shape* shapeA = m_fixtureA->GetShape(); 0191 const b2Shape* shapeB = m_fixtureB->GetShape(); 0192 0193 worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius); 0194 } 0195 0196 inline void b2Contact::SetEnabled(bool flag) 0197 { 0198 if (flag) 0199 { 0200 m_flags |= e_enabledFlag; 0201 } 0202 else 0203 { 0204 m_flags &= ~e_enabledFlag; 0205 } 0206 } 0207 0208 inline bool b2Contact::IsEnabled() const 0209 { 0210 return (m_flags & e_enabledFlag) == e_enabledFlag; 0211 } 0212 0213 inline bool b2Contact::IsTouching() const 0214 { 0215 return (m_flags & e_touchingFlag) == e_touchingFlag; 0216 } 0217 0218 inline b2Contact* b2Contact::GetNext() 0219 { 0220 return m_next; 0221 } 0222 0223 inline const b2Contact* b2Contact::GetNext() const 0224 { 0225 return m_next; 0226 } 0227 0228 inline b2Fixture* b2Contact::GetFixtureA() 0229 { 0230 return m_fixtureA; 0231 } 0232 0233 inline const b2Fixture* b2Contact::GetFixtureA() const 0234 { 0235 return m_fixtureA; 0236 } 0237 0238 inline b2Fixture* b2Contact::GetFixtureB() 0239 { 0240 return m_fixtureB; 0241 } 0242 0243 inline int32 b2Contact::GetChildIndexA() const 0244 { 0245 return m_indexA; 0246 } 0247 0248 inline const b2Fixture* b2Contact::GetFixtureB() const 0249 { 0250 return m_fixtureB; 0251 } 0252 0253 inline int32 b2Contact::GetChildIndexB() const 0254 { 0255 return m_indexB; 0256 } 0257 0258 inline void b2Contact::FlagForFiltering() 0259 { 0260 m_flags |= e_filterFlag; 0261 } 0262 0263 #endif