Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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 b2Sqrt(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 void SetTangentSpeed(float32 speed);
00140
00142 float32 GetTangentSpeed() const;
00143
00145 virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0;
00146
00147 protected:
00148 friend class b2ContactManager;
00149 friend class b2World;
00150 friend class b2ContactSolver;
00151 friend class b2Body;
00152 friend class b2Fixture;
00153
00154
00155 enum
00156 {
00157
00158 e_islandFlag = 0x0001,
00159
00160
00161 e_touchingFlag = 0x0002,
00162
00163
00164 e_enabledFlag = 0x0004,
00165
00166
00167 e_filterFlag = 0x0008,
00168
00169
00170 e_bulletHitFlag = 0x0010,
00171
00172
00173 e_toiFlag = 0x0020
00174 };
00175
00177 void FlagForFiltering();
00178
00179 static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn,
00180 b2Shape::Type typeA, b2Shape::Type typeB);
00181 static void InitializeRegisters();
00182 static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
00183 static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator);
00184 static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
00185
00186 b2Contact() : m_fixtureA(NULL), m_fixtureB(NULL) {}
00187 b2Contact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB);
00188 virtual ~b2Contact() {}
00189
00190 void Update(b2ContactListener* listener);
00191
00192 static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount];
00193 static bool s_initialized;
00194
00195 uint32 m_flags;
00196
00197
00198 b2Contact* m_prev;
00199 b2Contact* m_next;
00200
00201
00202 b2ContactEdge m_nodeA;
00203 b2ContactEdge m_nodeB;
00204
00205 b2Fixture* m_fixtureA;
00206 b2Fixture* m_fixtureB;
00207
00208 int32 m_indexA;
00209 int32 m_indexB;
00210
00211 b2Manifold m_manifold;
00212
00213 int32 m_toiCount;
00214 float32 m_toi;
00215
00216 float32 m_friction;
00217 float32 m_restitution;
00218
00219 float32 m_tangentSpeed;
00220 };
00221
00222 inline b2Manifold* b2Contact::GetManifold()
00223 {
00224 return &m_manifold;
00225 }
00226
00227 inline const b2Manifold* b2Contact::GetManifold() const
00228 {
00229 return &m_manifold;
00230 }
00231
00232 inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const
00233 {
00234 const b2Body* bodyA = m_fixtureA->GetBody();
00235 const b2Body* bodyB = m_fixtureB->GetBody();
00236 const b2Shape* shapeA = m_fixtureA->GetShape();
00237 const b2Shape* shapeB = m_fixtureB->GetShape();
00238
00239 worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius);
00240 }
00241
00242 inline void b2Contact::SetEnabled(bool flag)
00243 {
00244 if (flag)
00245 {
00246 m_flags |= e_enabledFlag;
00247 }
00248 else
00249 {
00250 m_flags &= ~e_enabledFlag;
00251 }
00252 }
00253
00254 inline bool b2Contact::IsEnabled() const
00255 {
00256 return (m_flags & e_enabledFlag) == e_enabledFlag;
00257 }
00258
00259 inline bool b2Contact::IsTouching() const
00260 {
00261 return (m_flags & e_touchingFlag) == e_touchingFlag;
00262 }
00263
00264 inline b2Contact* b2Contact::GetNext()
00265 {
00266 return m_next;
00267 }
00268
00269 inline const b2Contact* b2Contact::GetNext() const
00270 {
00271 return m_next;
00272 }
00273
00274 inline b2Fixture* b2Contact::GetFixtureA()
00275 {
00276 return m_fixtureA;
00277 }
00278
00279 inline const b2Fixture* b2Contact::GetFixtureA() const
00280 {
00281 return m_fixtureA;
00282 }
00283
00284 inline b2Fixture* b2Contact::GetFixtureB()
00285 {
00286 return m_fixtureB;
00287 }
00288
00289 inline int32 b2Contact::GetChildIndexA() const
00290 {
00291 return m_indexA;
00292 }
00293
00294 inline const b2Fixture* b2Contact::GetFixtureB() const
00295 {
00296 return m_fixtureB;
00297 }
00298
00299 inline int32 b2Contact::GetChildIndexB() const
00300 {
00301 return m_indexB;
00302 }
00303
00304 inline void b2Contact::FlagForFiltering()
00305 {
00306 m_flags |= e_filterFlag;
00307 }
00308
00309 inline void b2Contact::SetFriction(float32 friction)
00310 {
00311 m_friction = friction;
00312 }
00313
00314 inline float32 b2Contact::GetFriction() const
00315 {
00316 return m_friction;
00317 }
00318
00319 inline void b2Contact::ResetFriction()
00320 {
00321 m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction);
00322 }
00323
00324 inline void b2Contact::SetRestitution(float32 restitution)
00325 {
00326 m_restitution = restitution;
00327 }
00328
00329 inline float32 b2Contact::GetRestitution() const
00330 {
00331 return m_restitution;
00332 }
00333
00334 inline void b2Contact::ResetRestitution()
00335 {
00336 m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution);
00337 }
00338
00339 inline void b2Contact::SetTangentSpeed(float32 speed)
00340 {
00341 m_tangentSpeed = speed;
00342 }
00343
00344 inline float32 b2Contact::GetTangentSpeed() const
00345 {
00346 return m_tangentSpeed;
00347 }
00348
00349 #endif