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