![]() |
Box2D
2.2.1
A 2D Physics Engine for Games
|
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