b2_fixture.cpp
Go to the documentation of this file.
1 // MIT License
2 
3 // Copyright (c) 2019 Erin Catto
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 // SOFTWARE.
22 
23 #include "box2d/b2_fixture.h"
25 #include "box2d/b2_broad_phase.h"
26 #include "box2d/b2_chain_shape.h"
27 #include "box2d/b2_circle_shape.h"
28 #include "box2d/b2_collision.h"
29 #include "box2d/b2_contact.h"
30 #include "box2d/b2_edge_shape.h"
31 #include "box2d/b2_polygon_shape.h"
32 #include "box2d/b2_world.h"
33 
35 {
36  m_body = nullptr;
37  m_next = nullptr;
38  m_proxies = nullptr;
39  m_proxyCount = 0;
40  m_shape = nullptr;
41  m_density = 0.0f;
42 }
43 
44 void b2Fixture::Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def)
45 {
46  m_userData = def->userData;
47  m_friction = def->friction;
50 
51  m_body = body;
52  m_next = nullptr;
53 
54  m_filter = def->filter;
55 
56  m_isSensor = def->isSensor;
57 
58  m_shape = def->shape->Clone(allocator);
59 
60  // Reserve proxy space
61  int32 childCount = m_shape->GetChildCount();
62  m_proxies = (b2FixtureProxy*)allocator->Allocate(childCount * sizeof(b2FixtureProxy));
63  for (int32 i = 0; i < childCount; ++i)
64  {
65  m_proxies[i].fixture = nullptr;
67  }
68  m_proxyCount = 0;
69 
70  m_density = def->density;
71 }
72 
74 {
75  // The proxies must be destroyed before calling this.
76  b2Assert(m_proxyCount == 0);
77 
78  // Free the proxy array.
79  int32 childCount = m_shape->GetChildCount();
80  allocator->Free(m_proxies, childCount * sizeof(b2FixtureProxy));
81  m_proxies = nullptr;
82 
83  // Free the child shape.
84  switch (m_shape->m_type)
85  {
86  case b2Shape::e_circle:
87  {
89  s->~b2CircleShape();
90  allocator->Free(s, sizeof(b2CircleShape));
91  }
92  break;
93 
94  case b2Shape::e_edge:
95  {
97  s->~b2EdgeShape();
98  allocator->Free(s, sizeof(b2EdgeShape));
99  }
100  break;
101 
102  case b2Shape::e_polygon:
103  {
105  s->~b2PolygonShape();
106  allocator->Free(s, sizeof(b2PolygonShape));
107  }
108  break;
109 
110  case b2Shape::e_chain:
111  {
113  s->~b2ChainShape();
114  allocator->Free(s, sizeof(b2ChainShape));
115  }
116  break;
117 
118  default:
119  b2Assert(false);
120  break;
121  }
122 
123  m_shape = nullptr;
124 }
125 
127 {
128  b2Assert(m_proxyCount == 0);
129 
130  // Create proxies in the broad-phase.
132 
133  for (int32 i = 0; i < m_proxyCount; ++i)
134  {
135  b2FixtureProxy* proxy = m_proxies + i;
136  m_shape->ComputeAABB(&proxy->aabb, xf, i);
137  proxy->proxyId = broadPhase->CreateProxy(proxy->aabb, proxy);
138  proxy->fixture = this;
139  proxy->childIndex = i;
140  }
141 }
142 
144 {
145  // Destroy proxies in the broad-phase.
146  for (int32 i = 0; i < m_proxyCount; ++i)
147  {
148  b2FixtureProxy* proxy = m_proxies + i;
149  broadPhase->DestroyProxy(proxy->proxyId);
151  }
152 
153  m_proxyCount = 0;
154 }
155 
156 void b2Fixture::Synchronize(b2BroadPhase* broadPhase, const b2Transform& transform1, const b2Transform& transform2)
157 {
158  if (m_proxyCount == 0)
159  {
160  return;
161  }
162 
163  for (int32 i = 0; i < m_proxyCount; ++i)
164  {
165  b2FixtureProxy* proxy = m_proxies + i;
166 
167  // Compute an AABB that covers the swept shape (may miss some rotation effect).
168  b2AABB aabb1, aabb2;
169  m_shape->ComputeAABB(&aabb1, transform1, proxy->childIndex);
170  m_shape->ComputeAABB(&aabb2, transform2, proxy->childIndex);
171 
172  proxy->aabb.Combine(aabb1, aabb2);
173 
174  b2Vec2 displacement = aabb2.GetCenter() - aabb1.GetCenter();
175 
176  broadPhase->MoveProxy(proxy->proxyId, proxy->aabb, displacement);
177  }
178 }
179 
181 {
182  m_filter = filter;
183 
184  Refilter();
185 }
186 
188 {
189  if (m_body == nullptr)
190  {
191  return;
192  }
193 
194  // Flag associated contacts for filtering.
196  while (edge)
197  {
198  b2Contact* contact = edge->contact;
199  b2Fixture* fixtureA = contact->GetFixtureA();
200  b2Fixture* fixtureB = contact->GetFixtureB();
201  if (fixtureA == this || fixtureB == this)
202  {
203  contact->FlagForFiltering();
204  }
205 
206  edge = edge->next;
207  }
208 
209  b2World* world = m_body->GetWorld();
210 
211  if (world == nullptr)
212  {
213  return;
214  }
215 
216  // Touch each proxy so that new pairs may be created
217  b2BroadPhase* broadPhase = &world->m_contactManager.m_broadPhase;
218  for (int32 i = 0; i < m_proxyCount; ++i)
219  {
220  broadPhase->TouchProxy(m_proxies[i].proxyId);
221  }
222 }
223 
224 void b2Fixture::SetSensor(bool sensor)
225 {
226  if (sensor != m_isSensor)
227  {
228  m_body->SetAwake(true);
229  m_isSensor = sensor;
230  }
231 }
232 
233 void b2Fixture::Dump(int32 bodyIndex)
234 {
235  b2Dump(" b2FixtureDef fd;\n");
236  b2Dump(" fd.friction = %.9g;\n", m_friction);
237  b2Dump(" fd.restitution = %.9g;\n", m_restitution);
238  b2Dump(" fd.restitutionThreshold = %.9g;\n", m_restitutionThreshold);
239  b2Dump(" fd.density = %.9g;\n", m_density);
240  b2Dump(" fd.isSensor = bool(%d);\n", m_isSensor);
241  b2Dump(" fd.filter.categoryBits = uint16(%d);\n", m_filter.categoryBits);
242  b2Dump(" fd.filter.maskBits = uint16(%d);\n", m_filter.maskBits);
243  b2Dump(" fd.filter.groupIndex = int16(%d);\n", m_filter.groupIndex);
244 
245  switch (m_shape->m_type)
246  {
247  case b2Shape::e_circle:
248  {
250  b2Dump(" b2CircleShape shape;\n");
251  b2Dump(" shape.m_radius = %.9g;\n", s->m_radius);
252  b2Dump(" shape.m_p.Set(%.9g, %.9g);\n", s->m_p.x, s->m_p.y);
253  }
254  break;
255 
256  case b2Shape::e_edge:
257  {
259  b2Dump(" b2EdgeShape shape;\n");
260  b2Dump(" shape.m_radius = %.9g;\n", s->m_radius);
261  b2Dump(" shape.m_vertex0.Set(%.9g, %.9g);\n", s->m_vertex0.x, s->m_vertex0.y);
262  b2Dump(" shape.m_vertex1.Set(%.9g, %.9g);\n", s->m_vertex1.x, s->m_vertex1.y);
263  b2Dump(" shape.m_vertex2.Set(%.9g, %.9g);\n", s->m_vertex2.x, s->m_vertex2.y);
264  b2Dump(" shape.m_vertex3.Set(%.9g, %.9g);\n", s->m_vertex3.x, s->m_vertex3.y);
265  b2Dump(" shape.m_oneSided = bool(%d);\n", s->m_oneSided);
266  }
267  break;
268 
269  case b2Shape::e_polygon:
270  {
272  b2Dump(" b2PolygonShape shape;\n");
273  b2Dump(" b2Vec2 vs[%d];\n", b2_maxPolygonVertices);
274  for (int32 i = 0; i < s->m_count; ++i)
275  {
276  b2Dump(" vs[%d].Set(%.9g, %.9g);\n", i, s->m_vertices[i].x, s->m_vertices[i].y);
277  }
278  b2Dump(" shape.Set(vs, %d);\n", s->m_count);
279  }
280  break;
281 
282  case b2Shape::e_chain:
283  {
285  b2Dump(" b2ChainShape shape;\n");
286  b2Dump(" b2Vec2 vs[%d];\n", s->m_count);
287  for (int32 i = 0; i < s->m_count; ++i)
288  {
289  b2Dump(" vs[%d].Set(%.9g, %.9g);\n", i, s->m_vertices[i].x, s->m_vertices[i].y);
290  }
291  b2Dump(" shape.CreateChain(vs, %d);\n", s->m_count);
292  b2Dump(" shape.m_prevVertex.Set(%.9g, %.9g);\n", s->m_prevVertex.x, s->m_prevVertex.y);
293  b2Dump(" shape.m_nextVertex.Set(%.9g, %.9g);\n", s->m_nextVertex.x, s->m_nextVertex.y);
294  }
295  break;
296 
297  default:
298  return;
299  }
300 
301  b2Dump("\n");
302  b2Dump(" fd.shape = &shape;\n");
303  b2Dump("\n");
304  b2Dump(" bodies[%d]->CreateFixture(&fd);\n", bodyIndex);
305 }
const b2Shape * shape
Definition: b2_fixture.h:76
b2Vec2 m_nextVertex
void Combine(const b2AABB &aabb)
Combine an AABB into this one.
Definition: b2_collision.h:194
b2Vec2 * m_vertices
The vertices. Owned by this class.
float m_friction
Definition: b2_fixture.h:239
void Create(b2BlockAllocator *allocator, b2Body *body, const b2FixtureDef *def)
Definition: b2_fixture.cpp:44
float density
The density, usually in kg/m^2.
Definition: b2_fixture.h:92
b2ContactManager m_contactManager
Definition: b2_world.h:232
virtual b2Shape * Clone(b2BlockAllocator *allocator) const =0
Clone the concrete shape using the provided allocator.
void Dump(int32 bodyIndex)
Dump this fixture to the log file.
Definition: b2_fixture.cpp:233
float x
Definition: b2_math.h:128
float y
Definition: b2_math.h:128
b2Fixture * fixture
Definition: b2_fixture.h:106
b2Filter m_filter
Definition: b2_fixture.h:246
b2Fixture * GetFixtureB()
Get fixture B in this contact.
Definition: b2_contact.h:306
void Refilter()
Call this if you want to establish collision that was previously disabled by b2ContactFilter::ShouldC...
Definition: b2_fixture.cpp:187
XmlRpcServer s
b2Fixture * m_next
Definition: b2_fixture.h:234
b2ContactEdge * GetContactList()
Definition: b2_body.h:714
void Synchronize(b2BroadPhase *broadPhase, const b2Transform &xf1, const b2Transform &xf2)
Definition: b2_fixture.cpp:156
b2Vec2 m_vertex0
Optional adjacent vertices. These are used for smooth collision.
Definition: b2_edge_shape.h:69
void Free(void *p, int32 size)
Free memory. This will use b2Free if the size is larger than b2_maxBlockSize.
int32 m_proxyCount
Definition: b2_fixture.h:244
void SetFilterData(const b2Filter &filter)
Definition: b2_fixture.cpp:180
~b2ChainShape()
The destructor frees the vertices using b2Free.
This proxy is used internally to connect fixtures to the broad-phase.
Definition: b2_fixture.h:103
b2ContactEdge * next
the next contact edge in the body&#39;s contact list
Definition: b2_contact.h:82
void FlagForFiltering()
Flag this contact for filtering. Filtering will occur the next time step.
Definition: b2_contact.h:326
A solid circle shape.
A 2D column vector.
Definition: b2_math.h:41
b2Contact * contact
the contact
Definition: b2_contact.h:80
b2Vec2 GetCenter() const
Get the center of the AABB.
Definition: b2_collision.h:174
signed int int32
Definition: b2_types.h:28
b2Vec2 m_p
Position.
virtual int32 GetChildCount() const =0
Get the number of child primitives.
A rigid body. These are created via b2World::CreateBody.
Definition: b2_body.h:128
float m_radius
Definition: b2_shape.h:102
void * Allocate(int32 size)
Allocate memory. This will use b2Alloc if the size is larger than b2_maxBlockSize.
int32 CreateProxy(const b2AABB &aabb, void *userData)
b2Filter filter
Contact filtering data.
Definition: b2_fixture.h:99
This holds contact filtering data.
Definition: b2_fixture.h:37
float restitutionThreshold
Definition: b2_fixture.h:89
b2FixtureUserData userData
Use this to store application specific fixture data.
Definition: b2_fixture.h:79
float m_density
Definition: b2_fixture.h:232
b2Vec2 m_vertices[b2_maxPolygonVertices]
void DestroyProxy(int32 proxyId)
Destroy a proxy. It is up to the client to remove any pairs.
void Destroy(b2BlockAllocator *allocator)
Definition: b2_fixture.cpp:73
b2Vec2 m_vertex3
Definition: b2_edge_shape.h:69
void SetSensor(bool sensor)
Set if this fixture is a sensor.
Definition: b2_fixture.cpp:224
bool isSensor
Definition: b2_fixture.h:96
b2Fixture * GetFixtureA()
Get fixture A in this contact.
Definition: b2_contact.h:296
b2BroadPhase m_broadPhase
An axis aligned bounding box.
Definition: b2_collision.h:168
b2FixtureUserData m_userData
Definition: b2_fixture.h:250
int32 childIndex
Definition: b2_fixture.h:107
b2Body * m_body
Definition: b2_fixture.h:235
void TouchProxy(int32 proxyId)
Call to trigger a re-processing of it&#39;s pairs on the next call to UpdatePairs.
void b2Dump(const char *string,...)
Definition: b2_settings.cpp:57
b2Vec2 m_vertex1
These are the edge vertices.
Definition: b2_edge_shape.h:66
Type m_type
Definition: b2_shape.h:98
void DestroyProxies(b2BroadPhase *broadPhase)
Definition: b2_fixture.cpp:143
b2Vec2 m_vertex2
Definition: b2_edge_shape.h:66
void CreateProxies(b2BroadPhase *broadPhase, const b2Transform &xf)
Definition: b2_fixture.cpp:126
#define b2_maxPolygonVertices
Definition: b2_settings.h:53
bool m_oneSided
Uses m_vertex0 and m_vertex3 to create smooth collision.
Definition: b2_edge_shape.h:72
b2FixtureProxy * m_proxies
Definition: b2_fixture.h:243
b2Shape * m_shape
Definition: b2_fixture.h:237
int16 groupIndex
Definition: b2_fixture.h:56
int32 m_count
The vertex count.
bool m_isSensor
Definition: b2_fixture.h:248
void MoveProxy(int32 proxyId, const b2AABB &aabb, const b2Vec2 &displacement)
virtual void ComputeAABB(b2AABB *aabb, const b2Transform &xf, int32 childIndex) const =0
uint16 categoryBits
The collision category bits. Normally you would just set one bit.
Definition: b2_fixture.h:47
b2Vec2 m_prevVertex
float restitution
The restitution (elasticity) usually in the range [0,1].
Definition: b2_fixture.h:85
uint16 maskBits
Definition: b2_fixture.h:51
#define b2Assert(A)
Definition: b2_common.h:37
float m_restitutionThreshold
Definition: b2_fixture.h:241
void SetAwake(bool flag)
Definition: b2_body.h:638
float m_restitution
Definition: b2_fixture.h:240
float friction
The friction coefficient, usually in the range [0,1].
Definition: b2_fixture.h:82
b2World * GetWorld()
Get the parent world of this body.
Definition: b2_body.h:871


mvsim
Author(s):
autogenerated on Tue Jul 4 2023 03:08:19