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/Contacts/b2Contact.h>
00026 #include <Box2D/Dynamics/b2Fixture.h>
00027
00028 class b2Body;
00029 class b2Contact;
00030 class b2Fixture;
00031 class b2World;
00032 class b2BlockAllocator;
00033 class b2StackAllocator;
00034 class b2ContactListener;
00035
00036 typedef b2Contact* b2ContactCreateFcn(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator);
00037 typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator);
00038
00039 struct b2ContactRegister
00040 {
00041 b2ContactCreateFcn* createFcn;
00042 b2ContactDestroyFcn* destroyFcn;
00043 bool primary;
00044 };
00045
00051 struct b2ContactEdge
00052 {
00053 b2Body* other;
00054 b2Contact* contact;
00055 b2ContactEdge* prev;
00056 b2ContactEdge* next;
00057 };
00058
00062 class b2Contact
00063 {
00064 public:
00065
00068 b2Manifold* GetManifold();
00069 const b2Manifold* GetManifold() const;
00070
00072 void GetWorldManifold(b2WorldManifold* worldManifold) const;
00073
00075 bool IsTouching() const;
00076
00080 void SetEnabled(bool flag);
00081
00083 bool IsEnabled() const;
00084
00086 b2Contact* GetNext();
00087 const b2Contact* GetNext() const;
00088
00090 b2Fixture* GetFixtureA();
00091 const b2Fixture* GetFixtureA() const;
00092
00094 b2Fixture* GetFixtureB();
00095 const b2Fixture* GetFixtureB() const;
00096
00098 virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0;
00099
00100 protected:
00101 friend class b2ContactManager;
00102 friend class b2World;
00103 friend class b2ContactSolver;
00104 friend class b2Body;
00105 friend class b2Fixture;
00106
00107
00108 enum
00109 {
00110
00111 e_islandFlag = 0x0001,
00112
00113
00114 e_touchingFlag = 0x0002,
00115
00116
00117 e_enabledFlag = 0x0004,
00118
00119
00120 e_filterFlag = 0x0008,
00121 };
00122
00124 void FlagForFiltering();
00125
00126 static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn,
00127 b2Shape::Type typeA, b2Shape::Type typeB);
00128 static void InitializeRegisters();
00129 static b2Contact* Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator);
00130 static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator);
00131 static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
00132
00133 b2Contact() : m_fixtureA(NULL), m_fixtureB(NULL) {}
00134 b2Contact(b2Fixture* fixtureA, b2Fixture* fixtureB);
00135 virtual ~b2Contact() {}
00136
00137 void Update(b2ContactListener* listener);
00138
00139 static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount];
00140 static bool s_initialized;
00141
00142 uint32 m_flags;
00143
00144
00145 b2Contact* m_prev;
00146 b2Contact* m_next;
00147
00148
00149 b2ContactEdge m_nodeA;
00150 b2ContactEdge m_nodeB;
00151
00152 b2Fixture* m_fixtureA;
00153 b2Fixture* m_fixtureB;
00154
00155 b2Manifold m_manifold;
00156
00157 int32 m_toiCount;
00158
00159 };
00160
00161 inline b2Manifold* b2Contact::GetManifold()
00162 {
00163 return &m_manifold;
00164 }
00165
00166 inline const b2Manifold* b2Contact::GetManifold() const
00167 {
00168 return &m_manifold;
00169 }
00170
00171 inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const
00172 {
00173 const b2Body* bodyA = m_fixtureA->GetBody();
00174 const b2Body* bodyB = m_fixtureB->GetBody();
00175 const b2Shape* shapeA = m_fixtureA->GetShape();
00176 const b2Shape* shapeB = m_fixtureB->GetShape();
00177
00178 worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius);
00179 }
00180
00181 inline void b2Contact::SetEnabled(bool flag)
00182 {
00183 if (flag)
00184 {
00185 m_flags |= e_enabledFlag;
00186 }
00187 else
00188 {
00189 m_flags &= ~e_enabledFlag;
00190 }
00191 }
00192
00193 inline bool b2Contact::IsEnabled() const
00194 {
00195 return (m_flags & e_enabledFlag) == e_enabledFlag;
00196 }
00197
00198 inline bool b2Contact::IsTouching() const
00199 {
00200 return (m_flags & e_touchingFlag) == e_touchingFlag;
00201 }
00202
00203 inline b2Contact* b2Contact::GetNext()
00204 {
00205 return m_next;
00206 }
00207
00208 inline const b2Contact* b2Contact::GetNext() const
00209 {
00210 return m_next;
00211 }
00212
00213 inline b2Fixture* b2Contact::GetFixtureA()
00214 {
00215 return m_fixtureA;
00216 }
00217
00218 inline const b2Fixture* b2Contact::GetFixtureA() const
00219 {
00220 return m_fixtureA;
00221 }
00222
00223 inline b2Fixture* b2Contact::GetFixtureB()
00224 {
00225 return m_fixtureB;
00226 }
00227
00228 inline const b2Fixture* b2Contact::GetFixtureB() const
00229 {
00230 return m_fixtureB;
00231 }
00232
00233 inline void b2Contact::FlagForFiltering()
00234 {
00235 m_flags |= e_filterFlag;
00236 }
00237
00238 #endif