collision_processing.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 "test.h"
24 
25 #include <algorithm>
26 
27 // This test shows collision processing and tests
28 // deferred body destruction.
29 class CollisionProcessing : public Test
30 {
31 public:
33  {
34  // Ground body
35  {
36  b2EdgeShape shape;
37  shape.SetTwoSided(b2Vec2(-50.0f, 0.0f), b2Vec2(50.0f, 0.0f));
38 
39  b2FixtureDef sd;
40  sd.shape = &shape;;
41 
42  b2BodyDef bd;
43  b2Body* ground = m_world->CreateBody(&bd);
44  ground->CreateFixture(&sd);
45  }
46 
47  float xLo = -5.0f, xHi = 5.0f;
48  float yLo = 2.0f, yHi = 35.0f;
49 
50  // Small triangle
51  b2Vec2 vertices[3];
52  vertices[0].Set(-1.0f, 0.0f);
53  vertices[1].Set(1.0f, 0.0f);
54  vertices[2].Set(0.0f, 2.0f);
55 
56  b2PolygonShape polygon;
57  polygon.Set(vertices, 3);
58 
59  b2FixtureDef triangleShapeDef;
60  triangleShapeDef.shape = &polygon;
61  triangleShapeDef.density = 1.0f;
62 
63  b2BodyDef triangleBodyDef;
64  triangleBodyDef.type = b2_dynamicBody;
65  triangleBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi));
66 
67  b2Body* body1 = m_world->CreateBody(&triangleBodyDef);
68  body1->CreateFixture(&triangleShapeDef);
69 
70  // Large triangle (recycle definitions)
71  vertices[0] *= 2.0f;
72  vertices[1] *= 2.0f;
73  vertices[2] *= 2.0f;
74  polygon.Set(vertices, 3);
75 
76  triangleBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi));
77 
78  b2Body* body2 = m_world->CreateBody(&triangleBodyDef);
79  body2->CreateFixture(&triangleShapeDef);
80 
81  // Small box
82  polygon.SetAsBox(1.0f, 0.5f);
83 
84  b2FixtureDef boxShapeDef;
85  boxShapeDef.shape = &polygon;
86  boxShapeDef.density = 1.0f;
87 
88  b2BodyDef boxBodyDef;
89  boxBodyDef.type = b2_dynamicBody;
90  boxBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi));
91 
92  b2Body* body3 = m_world->CreateBody(&boxBodyDef);
93  body3->CreateFixture(&boxShapeDef);
94 
95  // Large box (recycle definitions)
96  polygon.SetAsBox(2.0f, 1.0f);
97  boxBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi));
98 
99  b2Body* body4 = m_world->CreateBody(&boxBodyDef);
100  body4->CreateFixture(&boxShapeDef);
101 
102  // Small circle
103  b2CircleShape circle;
104  circle.m_radius = 1.0f;
105 
106  b2FixtureDef circleShapeDef;
107  circleShapeDef.shape = &circle;
108  circleShapeDef.density = 1.0f;
109 
110  b2BodyDef circleBodyDef;
111  circleBodyDef.type = b2_dynamicBody;
112  circleBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi));
113 
114  b2Body* body5 = m_world->CreateBody(&circleBodyDef);
115  body5->CreateFixture(&circleShapeDef);
116 
117  // Large circle
118  circle.m_radius *= 2.0f;
119  circleBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi));
120 
121  b2Body* body6 = m_world->CreateBody(&circleBodyDef);
122  body6->CreateFixture(&circleShapeDef);
123  }
124 
125  void Step(Settings& settings) override
126  {
127  Test::Step(settings);
128 
129  // We are going to destroy some bodies according to contact
130  // points. We must buffer the bodies that should be destroyed
131  // because they may belong to multiple contact points.
132  const int32 k_maxNuke = 6;
133  b2Body* nuke[k_maxNuke];
134  int32 nukeCount = 0;
135 
136  // Traverse the contact results. Destroy bodies that
137  // are touching heavier bodies.
138  for (int32 i = 0; i < m_pointCount; ++i)
139  {
140  ContactPoint* point = m_points + i;
141 
142  b2Body* body1 = point->fixtureA->GetBody();
143  b2Body* body2 = point->fixtureB->GetBody();
144  float mass1 = body1->GetMass();
145  float mass2 = body2->GetMass();
146 
147  if (mass1 > 0.0f && mass2 > 0.0f)
148  {
149  if (mass2 > mass1)
150  {
151  nuke[nukeCount++] = body1;
152  }
153  else
154  {
155  nuke[nukeCount++] = body2;
156  }
157 
158  if (nukeCount == k_maxNuke)
159  {
160  break;
161  }
162  }
163  }
164 
165  // Sort the nuke array to group duplicates.
166  std::sort(nuke, nuke + nukeCount);
167 
168  // Destroy the bodies, skipping duplicates.
169  int32 i = 0;
170  while (i < nukeCount)
171  {
172  b2Body* b = nuke[i++];
173  while (i < nukeCount && nuke[i] == b)
174  {
175  ++i;
176  }
177 
178  if (b != m_bomb)
179  {
180  m_world->DestroyBody(b);
181  }
182  }
183  }
184 
185  static Test* Create()
186  {
187  return new CollisionProcessing;
188  }
189 };
190 
191 static int testIndex = RegisterTest("Examples", "Collision Processing", CollisionProcessing::Create);
const b2Shape * shape
Definition: b2_fixture.h:76
ContactPoint m_points[k_maxContactPoints]
Definition: test.h:124
float GetMass() const
Definition: b2_body.h:544
b2Fixture * CreateFixture(const b2FixtureDef *def)
Definition: b2_body.cpp:165
float density
The density, usually in kg/m^2.
Definition: b2_fixture.h:92
f
Definition: test.h:80
float RandomFloat()
Random number in range [-1,1].
Definition: test.h:37
void Step(Settings &settings) override
int32 m_pointCount
Definition: test.h:125
A solid circle shape.
A 2D column vector.
Definition: b2_math.h:41
signed int int32
Definition: b2_types.h:28
void SetTwoSided(const b2Vec2 &v1, const b2Vec2 &v2)
Set this as an isolated edge. Collision is two-sided.
void SetAsBox(float hx, float hy)
b2Body * m_bomb
Definition: test.h:129
b2BodyType type
Definition: b2_body.h:74
A rigid body. These are created via b2World::CreateBody.
Definition: b2_body.h:128
float m_radius
Definition: b2_shape.h:102
void Set(float x_, float y_)
Set this vector to some specified coordinates.
Definition: b2_math.h:53
b2World * m_world
Definition: test.h:128
b2Vec2 position
Definition: b2_body.h:78
void Set(const b2Vec2 *points, int32 count)
b2Fixture * fixtureB
Definition: test.h:71
void DestroyBody(b2Body *body)
Definition: b2_world.cpp:139
int RegisterTest(const char *category, const char *name, TestCreateFcn *fcn)
Definition: test.cpp:458
b2Fixture * fixtureA
Definition: test.h:70
virtual void Step(Settings &settings)
Definition: test.cpp:278
b2Body * CreateBody(const b2BodyDef *def)
Definition: b2_world.cpp:115
b2Body * GetBody()
Definition: b2_fixture.h:283
static int testIndex


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