b2Contact.cpp
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 * 1. The origin of this software must not be misrepresented; you must not
11 * claim that you wrote the original software. If you use this software
12 * in a product, an acknowledgment in the product documentation would be
13 * appreciated but is not required.
14 * 2. Altered source versions must be plainly marked as such, and must not be
15 * misrepresented as being the original software.
16 * 3. This notice may not be removed or altered from any source distribution.
17 */
18 
28 
33 #include <Box2D/Dynamics/b2Body.h>
35 #include <Box2D/Dynamics/b2World.h>
36 
38 bool b2Contact::s_initialized = false;
39 
41 {
49 }
50 
52  b2Shape::Type type1, b2Shape::Type type2)
53 {
54  b2Assert(0 <= type1 && type1 < b2Shape::e_typeCount);
55  b2Assert(0 <= type2 && type2 < b2Shape::e_typeCount);
56 
57  s_registers[type1][type2].createFcn = createFcn;
58  s_registers[type1][type2].destroyFcn = destoryFcn;
59  s_registers[type1][type2].primary = true;
60 
61  if (type1 != type2)
62  {
63  s_registers[type2][type1].createFcn = createFcn;
64  s_registers[type2][type1].destroyFcn = destoryFcn;
65  s_registers[type2][type1].primary = false;
66  }
67 }
68 
69 b2Contact* b2Contact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator)
70 {
71  if (s_initialized == false)
72  {
74  s_initialized = true;
75  }
76 
77  b2Shape::Type type1 = fixtureA->GetType();
78  b2Shape::Type type2 = fixtureB->GetType();
79 
80  b2Assert(0 <= type1 && type1 < b2Shape::e_typeCount);
81  b2Assert(0 <= type2 && type2 < b2Shape::e_typeCount);
82 
83  b2ContactCreateFcn* createFcn = s_registers[type1][type2].createFcn;
84  if (createFcn)
85  {
86  if (s_registers[type1][type2].primary)
87  {
88  return createFcn(fixtureA, indexA, fixtureB, indexB, allocator);
89  }
90  else
91  {
92  return createFcn(fixtureB, indexB, fixtureA, indexA, allocator);
93  }
94  }
95  else
96  {
97  return NULL;
98  }
99 }
100 
102 {
103  b2Assert(s_initialized == true);
104 
105  b2Fixture* fixtureA = contact->m_fixtureA;
106  b2Fixture* fixtureB = contact->m_fixtureB;
107 
108  if (contact->m_manifold.pointCount > 0 &&
109  fixtureA->IsSensor() == false &&
110  fixtureB->IsSensor() == false)
111  {
112  fixtureA->GetBody()->SetAwake(true);
113  fixtureB->GetBody()->SetAwake(true);
114  }
115 
116  b2Shape::Type typeA = fixtureA->GetType();
117  b2Shape::Type typeB = fixtureB->GetType();
118 
119  b2Assert(0 <= typeA && typeB < b2Shape::e_typeCount);
120  b2Assert(0 <= typeA && typeB < b2Shape::e_typeCount);
121 
122  b2ContactDestroyFcn* destroyFcn = s_registers[typeA][typeB].destroyFcn;
123  destroyFcn(contact, allocator);
124 }
125 
127 {
129 
130  m_fixtureA = fA;
131  m_fixtureB = fB;
132 
133  m_indexA = indexA;
134  m_indexB = indexB;
135 
137 
138  m_prev = NULL;
139  m_next = NULL;
140 
141  m_nodeA.contact = NULL;
142  m_nodeA.prev = NULL;
143  m_nodeA.next = NULL;
144  m_nodeA.other = NULL;
145 
146  m_nodeB.contact = NULL;
147  m_nodeB.prev = NULL;
148  m_nodeB.next = NULL;
149  m_nodeB.other = NULL;
150 
151  m_toiCount = 0;
152 
155 
156  m_tangentSpeed = 0.0f;
157 }
158 
159 // Update the contact manifold and touching status.
160 // Note: do not assume the fixture AABBs are overlapping or are valid.
162 {
163  b2Manifold oldManifold = m_manifold;
164 
165  // Re-enable this contact.
167 
168  bool touching = false;
169  bool wasTouching = (m_flags & e_touchingFlag) == e_touchingFlag;
170 
171  bool sensorA = m_fixtureA->IsSensor();
172  bool sensorB = m_fixtureB->IsSensor();
173  bool sensor = sensorA || sensorB;
174 
175  b2Body* bodyA = m_fixtureA->GetBody();
176  b2Body* bodyB = m_fixtureB->GetBody();
177  const b2Transform& xfA = bodyA->GetTransform();
178  const b2Transform& xfB = bodyB->GetTransform();
179 
180  // Is this contact a sensor?
181  if (sensor)
182  {
183  const b2Shape* shapeA = m_fixtureA->GetShape();
184  const b2Shape* shapeB = m_fixtureB->GetShape();
185  touching = b2TestOverlap(shapeA, m_indexA, shapeB, m_indexB, xfA, xfB);
186 
187  // Sensors don't generate manifolds.
189  }
190  else
191  {
192  Evaluate(&m_manifold, xfA, xfB);
193  touching = m_manifold.pointCount > 0;
194 
195  // Match old contact ids to new contact ids and copy the
196  // stored impulses to warm start the solver.
197  for (int32 i = 0; i < m_manifold.pointCount; ++i)
198  {
199  b2ManifoldPoint* mp2 = m_manifold.points + i;
200  mp2->normalImpulse = 0.0f;
201  mp2->tangentImpulse = 0.0f;
202  b2ContactID id2 = mp2->id;
203 
204  for (int32 j = 0; j < oldManifold.pointCount; ++j)
205  {
206  b2ManifoldPoint* mp1 = oldManifold.points + j;
207 
208  if (mp1->id.key == id2.key)
209  {
210  mp2->normalImpulse = mp1->normalImpulse;
211  mp2->tangentImpulse = mp1->tangentImpulse;
212  break;
213  }
214  }
215  }
216 
217  if (touching != wasTouching)
218  {
219  bodyA->SetAwake(true);
220  bodyB->SetAwake(true);
221  }
222  }
223 
224  if (touching)
225  {
227  }
228  else
229  {
231  }
232 
233  if (wasTouching == false && touching == true && listener)
234  {
235  listener->BeginContact(this);
236  }
237 
238  if (wasTouching == true && touching == false && listener)
239  {
240  listener->EndContact(this);
241  }
242 
243  if (sensor == false && touching && listener)
244  {
245  listener->PreSolve(this, &oldManifold);
246  }
247 }
float32 m_friction
Definition: b2Fixture.h:225
b2Fixture * m_fixtureB
Definition: b2Contact.h:206
void Update(b2ContactListener *listener)
Definition: b2Contact.cpp:161
void b2ContactDestroyFcn(b2Contact *contact, b2BlockAllocator *allocator)
Definition: b2Contact.h:52
float32 m_friction
Definition: b2Contact.h:216
static void Destroy(b2Contact *contact, b2BlockAllocator *allocator)
Contact ids to facilitate warm starting.
Definition: b2Collision.h:53
b2Shape::Type GetType() const
Definition: b2Fixture.h:238
float32 m_tangentSpeed
Definition: b2Contact.h:219
virtual void EndContact(b2Contact *contact)
Called when two fixtures cease to touch.
static void AddType(b2ContactCreateFcn *createFcn, b2ContactDestroyFcn *destroyFcn, b2Shape::Type typeA, b2Shape::Type typeB)
Definition: b2Contact.cpp:51
b2Fixture * m_fixtureA
Definition: b2Contact.h:205
static void Destroy(b2Contact *contact, b2BlockAllocator *allocator)
virtual void BeginContact(b2Contact *contact)
Called when two fixtures begin to touch.
float32 b2MixFriction(float32 friction1, float32 friction2)
Definition: b2Contact.h:37
static void Destroy(b2Contact *contact, b2BlockAllocator *allocator)
b2ContactID id
uniquely identifies a contact point between two shapes
Definition: b2Collision.h:74
b2Contact * b2ContactCreateFcn(b2Fixture *fixtureA, int32 indexA, b2Fixture *fixtureB, int32 indexB, b2BlockAllocator *allocator)
Definition: b2Contact.h:49
static b2Contact * Create(b2Fixture *fixtureA, int32 indexA, b2Fixture *fixtureB, int32 indexB, b2BlockAllocator *allocator)
uint32 key
Used to quickly compare contact ids.
Definition: b2Collision.h:56
static b2Contact * Create(b2Fixture *fixtureA, int32 indexA, b2Fixture *fixtureB, int32 indexB, b2BlockAllocator *allocator)
static void Destroy(b2Contact *contact, b2BlockAllocator *allocator)
float32 m_restitution
Definition: b2Fixture.h:226
static bool s_initialized
Definition: b2Contact.h:193
b2ContactEdge * next
the next contact edge in the body&#39;s contact list
Definition: b2Contact.h:71
b2Contact * contact
the contact
Definition: b2Contact.h:69
signed int int32
Definition: b2Settings.h:31
A rigid body. These are created via b2World::CreateBody.
Definition: b2Body.h:126
static b2Contact * Create(b2Fixture *fixtureA, int32 indexA, b2Fixture *fixtureB, int32 indexB, b2BlockAllocator *allocator)
static void Destroy(b2Contact *contact, b2BlockAllocator *allocator)
float32 m_restitution
Definition: b2Contact.h:217
static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount]
Definition: b2Contact.h:192
static b2Contact * Create(b2Fixture *fixtureA, int32 indexA, b2Fixture *fixtureB, int32 indexB, b2BlockAllocator *allocator)
int32 m_indexB
Definition: b2Contact.h:209
static b2Contact * Create(b2Fixture *fixtureA, int32 indexA, b2Fixture *fixtureB, int32 indexB, b2BlockAllocator *allocator)
b2ContactCreateFcn * createFcn
Definition: b2Contact.h:56
int32 pointCount
the number of manifold points
Definition: b2Collision.h:106
virtual void Evaluate(b2Manifold *manifold, const b2Transform &xfA, const b2Transform &xfB)=0
Evaluate this contact with your own manifold and transforms.
int32 m_toiCount
Definition: b2Contact.h:213
static b2Contact * Create(b2Fixture *fixtureA, int32 indexA, b2Fixture *fixtureB, int32 indexB, b2BlockAllocator *allocator)
b2ContactDestroyFcn * destroyFcn
Definition: b2Contact.h:57
bool IsSensor() const
Definition: b2Fixture.h:253
float32 tangentImpulse
the friction impulse
Definition: b2Collision.h:73
b2ContactEdge m_nodeA
Definition: b2Contact.h:202
static void Destroy(b2Contact *contact, b2BlockAllocator *allocator)
static b2Contact * Create(b2Fixture *fixtureA, int32 indexA, b2Fixture *fixtureB, int32 indexB, b2BlockAllocator *allocator)
b2ManifoldPoint points[b2_maxManifoldPoints]
the points of contact
Definition: b2Collision.h:102
b2Body * other
provides quick access to the other body attached.
Definition: b2Contact.h:68
#define b2Assert(A)
Definition: b2Settings.h:27
static b2Contact * Create(b2Fixture *fixtureA, int32 indexA, b2Fixture *fixtureB, int32 indexB, b2BlockAllocator *allocator)
Definition: b2Contact.cpp:69
b2Contact * m_prev
Definition: b2Contact.h:198
b2ContactEdge m_nodeB
Definition: b2Contact.h:203
const b2Transform & GetTransform() const
Definition: b2Body.h:474
int32 m_indexA
Definition: b2Contact.h:208
static void InitializeRegisters()
Definition: b2Contact.cpp:40
b2Shape * GetShape()
Definition: b2Fixture.h:243
b2Manifold m_manifold
Definition: b2Contact.h:211
uint32 m_flags
Definition: b2Contact.h:195
float32 b2MixRestitution(float32 restitution1, float32 restitution2)
Definition: b2Contact.h:44
bool b2TestOverlap(const b2Shape *shapeA, int32 indexA, const b2Shape *shapeB, int32 indexB, const b2Transform &xfA, const b2Transform &xfB)
Determine if two generic shapes overlap.
b2Contact * m_next
Definition: b2Contact.h:199
void SetAwake(bool flag)
Definition: b2Body.h:633
virtual void PreSolve(b2Contact *contact, const b2Manifold *oldManifold)
b2Body * GetBody()
Definition: b2Fixture.h:273
b2ContactEdge * prev
the previous contact edge in the body&#39;s contact list
Definition: b2Contact.h:70
static void Destroy(b2Contact *contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator *allocator)
static void Destroy(b2Contact *contact, b2BlockAllocator *allocator)
float32 normalImpulse
the non-penetration impulse
Definition: b2Collision.h:72


mvsim
Author(s):
autogenerated on Fri May 7 2021 03:05:51