Box2D  2.2.1
A 2D Physics Engine for Games
b2Contact.h
00001 /*
00002 * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
00003 *
00004 * This software is provided 'as-is', without any express or implied
00005 * warranty.  In no event will the authors be held liable for any damages
00006 * arising from the use of this software.
00007 * Permission is granted to anyone to use this software for any purpose,
00008 * including commercial applications, and to alter it and redistribute it
00009 * freely, subject to the following restrictions:
00010 * 1. The origin of this software must not be misrepresented; you must not
00011 * claim that you wrote the original software. If you use this software
00012 * in a product, an acknowledgment in the product documentation would be
00013 * appreciated but is not required.
00014 * 2. Altered source versions must be plainly marked as such, and must not be
00015 * misrepresented as being the original software.
00016 * 3. This notice may not be removed or altered from any source distribution.
00017 */
00018 
00019 #ifndef B2_CONTACT_H
00020 #define B2_CONTACT_H
00021 
00022 #include <Box2D/Common/b2Math.h>
00023 #include <Box2D/Collision/b2Collision.h>
00024 #include <Box2D/Collision/Shapes/b2Shape.h>
00025 #include <Box2D/Dynamics/b2Fixture.h>
00026 
00027 class b2Body;
00028 class b2Contact;
00029 class b2Fixture;
00030 class b2World;
00031 class b2BlockAllocator;
00032 class b2StackAllocator;
00033 class b2ContactListener;
00034 
00037 inline float32 b2MixFriction(float32 friction1, float32 friction2)
00038 {
00039         return std::sqrt(friction1 * friction2);
00040 }
00041 
00044 inline float32 b2MixRestitution(float32 restitution1, float32 restitution2)
00045 {
00046         return restitution1 > restitution2 ? restitution1 : restitution2;
00047 }
00048 
00049 typedef b2Contact* b2ContactCreateFcn(  b2Fixture* fixtureA, int32 indexA,
00050                                                                                 b2Fixture* fixtureB, int32 indexB,
00051                                                                                 b2BlockAllocator* allocator);
00052 typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator);
00053 
00054 struct b2ContactRegister
00055 {
00056         b2ContactCreateFcn* createFcn;
00057         b2ContactDestroyFcn* destroyFcn;
00058         bool primary;
00059 };
00060 
00066 struct b2ContactEdge
00067 {
00068         b2Body* other;                  
00069         b2Contact* contact;             
00070         b2ContactEdge* prev;    
00071         b2ContactEdge* next;    
00072 };
00073 
00077 class b2Contact
00078 {
00079 public:
00080 
00083         b2Manifold* GetManifold();
00084         const b2Manifold* GetManifold() const;
00085 
00087         void GetWorldManifold(b2WorldManifold* worldManifold) const;
00088 
00090         bool IsTouching() const;
00091 
00095         void SetEnabled(bool flag);
00096 
00098         bool IsEnabled() const;
00099 
00101         b2Contact* GetNext();
00102         const b2Contact* GetNext() const;
00103 
00105         b2Fixture* GetFixtureA();
00106         const b2Fixture* GetFixtureA() const;
00107 
00109         int32 GetChildIndexA() const;
00110 
00112         b2Fixture* GetFixtureB();
00113         const b2Fixture* GetFixtureB() const;
00114 
00116         int32 GetChildIndexB() const;
00117 
00120         void SetFriction(float32 friction);
00121 
00123         float32 GetFriction() const;
00124 
00126         void ResetFriction();
00127 
00130         void SetRestitution(float32 restitution);
00131 
00133         float32 GetRestitution() const;
00134 
00136         void ResetRestitution();
00137 
00139         virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0;
00140 
00141 protected:
00142         friend class b2ContactManager;
00143         friend class b2World;
00144         friend class b2ContactSolver;
00145         friend class b2Body;
00146         friend class b2Fixture;
00147 
00148         // Flags stored in m_flags
00149         enum
00150         {
00151                 // Used when crawling contact graph when forming islands.
00152                 e_islandFlag            = 0x0001,
00153 
00154         // Set when the shapes are touching.
00155                 e_touchingFlag          = 0x0002,
00156 
00157                 // This contact can be disabled (by user)
00158                 e_enabledFlag           = 0x0004,
00159 
00160                 // This contact needs filtering because a fixture filter was changed.
00161                 e_filterFlag            = 0x0008,
00162 
00163                 // This bullet contact had a TOI event
00164                 e_bulletHitFlag         = 0x0010,
00165 
00166                 // This contact has a valid TOI in m_toi
00167                 e_toiFlag                       = 0x0020
00168         };
00169 
00171         void FlagForFiltering();
00172 
00173         static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn,
00174                                                 b2Shape::Type typeA, b2Shape::Type typeB);
00175         static void InitializeRegisters();
00176         static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
00177         static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator);
00178         static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
00179 
00180         b2Contact() : m_fixtureA(NULL), m_fixtureB(NULL) {}
00181         b2Contact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB);
00182         virtual ~b2Contact() {}
00183 
00184         void Update(b2ContactListener* listener);
00185 
00186         static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount];
00187         static bool s_initialized;
00188 
00189         uint32 m_flags;
00190 
00191         // World pool and list pointers.
00192         b2Contact* m_prev;
00193         b2Contact* m_next;
00194 
00195         // Nodes for connecting bodies.
00196         b2ContactEdge m_nodeA;
00197         b2ContactEdge m_nodeB;
00198 
00199         b2Fixture* m_fixtureA;
00200         b2Fixture* m_fixtureB;
00201 
00202         int32 m_indexA;
00203         int32 m_indexB;
00204 
00205         b2Manifold m_manifold;
00206 
00207         int32 m_toiCount;
00208         float32 m_toi;
00209 
00210         float32 m_friction;
00211         float32 m_restitution;
00212 };
00213 
00214 inline b2Manifold* b2Contact::GetManifold()
00215 {
00216         return &m_manifold;
00217 }
00218 
00219 inline const b2Manifold* b2Contact::GetManifold() const
00220 {
00221         return &m_manifold;
00222 }
00223 
00224 inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const
00225 {
00226         const b2Body* bodyA = m_fixtureA->GetBody();
00227         const b2Body* bodyB = m_fixtureB->GetBody();
00228         const b2Shape* shapeA = m_fixtureA->GetShape();
00229         const b2Shape* shapeB = m_fixtureB->GetShape();
00230 
00231         worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius);
00232 }
00233 
00234 inline void b2Contact::SetEnabled(bool flag)
00235 {
00236         if (flag)
00237         {
00238                 m_flags |= e_enabledFlag;
00239         }
00240         else
00241         {
00242                 m_flags &= ~e_enabledFlag;
00243         }
00244 }
00245 
00246 inline bool b2Contact::IsEnabled() const
00247 {
00248         return (m_flags & e_enabledFlag) == e_enabledFlag;
00249 }
00250 
00251 inline bool b2Contact::IsTouching() const
00252 {
00253         return (m_flags & e_touchingFlag) == e_touchingFlag;
00254 }
00255 
00256 inline b2Contact* b2Contact::GetNext()
00257 {
00258         return m_next;
00259 }
00260 
00261 inline const b2Contact* b2Contact::GetNext() const
00262 {
00263         return m_next;
00264 }
00265 
00266 inline b2Fixture* b2Contact::GetFixtureA()
00267 {
00268         return m_fixtureA;
00269 }
00270 
00271 inline const b2Fixture* b2Contact::GetFixtureA() const
00272 {
00273         return m_fixtureA;
00274 }
00275 
00276 inline b2Fixture* b2Contact::GetFixtureB()
00277 {
00278         return m_fixtureB;
00279 }
00280 
00281 inline int32 b2Contact::GetChildIndexA() const
00282 {
00283         return m_indexA;
00284 }
00285 
00286 inline const b2Fixture* b2Contact::GetFixtureB() const
00287 {
00288         return m_fixtureB;
00289 }
00290 
00291 inline int32 b2Contact::GetChildIndexB() const
00292 {
00293         return m_indexB;
00294 }
00295 
00296 inline void b2Contact::FlagForFiltering()
00297 {
00298         m_flags |= e_filterFlag;
00299 }
00300 
00301 inline void b2Contact::SetFriction(float32 friction)
00302 {
00303         m_friction = friction;
00304 }
00305 
00306 inline float32 b2Contact::GetFriction() const
00307 {
00308         return m_friction;
00309 }
00310 
00311 inline void b2Contact::ResetFriction()
00312 {
00313         m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction);
00314 }
00315 
00316 inline void b2Contact::SetRestitution(float32 restitution)
00317 {
00318         m_restitution = restitution;
00319 }
00320 
00321 inline float32 b2Contact::GetRestitution() const
00322 {
00323         return m_restitution;
00324 }
00325 
00326 inline void b2Contact::ResetRestitution()
00327 {
00328         m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution);
00329 }
00330 
00331 #endif
 All Classes Files Functions Variables Enumerations Enumerator Defines