breakable.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 // This is used to test sensor shapes.
26 class Breakable : public Test
27 {
28 public:
29 
30  enum
31  {
32  e_count = 7
33  };
34 
36  {
37  // Ground body
38  {
39  b2BodyDef bd;
40  b2Body* ground = m_world->CreateBody(&bd);
41 
42  b2EdgeShape shape;
43  shape.SetTwoSided(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
44  ground->CreateFixture(&shape, 0.0f);
45  }
46 
47  // Breakable dynamic body
48  {
49  b2BodyDef bd;
50  bd.type = b2_dynamicBody;
51  bd.position.Set(0.0f, 40.0f);
52  bd.angle = 0.25f * b2_pi;
53  m_body1 = m_world->CreateBody(&bd);
54 
55  m_shape1.SetAsBox(0.5f, 0.5f, b2Vec2(-0.5f, 0.0f), 0.0f);
57 
58  m_shape2.SetAsBox(0.5f, 0.5f, b2Vec2(0.5f, 0.0f), 0.0f);
60  }
61 
62  m_break = false;
63  m_broke = false;
64  }
65 
66  void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) override
67  {
68  if (m_broke)
69  {
70  // The body already broke.
71  return;
72  }
73 
74  // Should the body break?
75  int32 count = contact->GetManifold()->pointCount;
76 
77  float maxImpulse = 0.0f;
78  for (int32 i = 0; i < count; ++i)
79  {
80  maxImpulse = b2Max(maxImpulse, impulse->normalImpulses[i]);
81  }
82 
83  if (maxImpulse > 40.0f)
84  {
85  // Flag the body for breaking.
86  m_break = true;
87  }
88  }
89 
90  void Break()
91  {
92  // Create two bodies from one.
93  b2Body* body1 = m_piece1->GetBody();
94  b2Vec2 center = body1->GetWorldCenter();
95 
96  body1->DestroyFixture(m_piece2);
97  m_piece2 = NULL;
98 
99  b2BodyDef bd;
100  bd.type = b2_dynamicBody;
101  bd.position = body1->GetPosition();
102  bd.angle = body1->GetAngle();
103 
104  b2Body* body2 = m_world->CreateBody(&bd);
105  m_piece2 = body2->CreateFixture(&m_shape2, 1.0f);
106 
107  // Compute consistent velocities for new bodies based on
108  // cached velocity.
109  b2Vec2 center1 = body1->GetWorldCenter();
110  b2Vec2 center2 = body2->GetWorldCenter();
111 
112  b2Vec2 velocity1 = m_velocity + b2Cross(m_angularVelocity, center1 - center);
113  b2Vec2 velocity2 = m_velocity + b2Cross(m_angularVelocity, center2 - center);
114 
116  body1->SetLinearVelocity(velocity1);
117 
119  body2->SetLinearVelocity(velocity2);
120  }
121 
122  void Step(Settings& settings) override
123  {
124  if (m_break)
125  {
126  Break();
127  m_broke = true;
128  m_break = false;
129  }
130 
131  // Cache velocities to improve movement on breakage.
132  if (m_broke == false)
133  {
136  }
137 
138  Test::Step(settings);
139  }
140 
141  static Test* Create()
142  {
143  return new Breakable;
144  }
145 
153 
154  bool m_broke;
155  bool m_break;
156 };
157 
158 static int testIndex = RegisterTest("Examples", "Breakable", Breakable::Create);
b2PolygonShape m_shape1
Definition: breakable.cpp:149
b2Fixture * CreateFixture(const b2FixtureDef *def)
Definition: b2_body.cpp:165
f
float m_angularVelocity
Definition: breakable.cpp:148
float GetAngularVelocity() const
Definition: b2_body.h:539
b2Vec2 m_velocity
Definition: breakable.cpp:147
b2Fixture * m_piece2
Definition: breakable.cpp:152
Definition: test.h:80
const b2Vec2 & GetPosition() const
Definition: b2_body.h:484
b2Body * m_body1
Definition: breakable.cpp:146
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)
static int testIndex
Definition: breakable.cpp:158
bool m_broke
Definition: breakable.cpp:154
b2BodyType type
Definition: b2_body.h:74
A rigid body. These are created via b2World::CreateBody.
Definition: b2_body.h:128
b2Manifold * GetManifold()
Definition: b2_contact.h:244
void DestroyFixture(b2Fixture *fixture)
Definition: b2_body.cpp:213
void SetLinearVelocity(const b2Vec2 &v)
Definition: b2_body.h:504
void Break()
Definition: breakable.cpp:90
const b2Vec2 & GetLinearVelocity() const
Definition: b2_body.h:519
T b2Max(T a, T b)
Definition: b2_math.h:637
void Set(float x_, float y_)
Set this vector to some specified coordinates.
Definition: b2_math.h:53
float b2Cross(const b2Vec2 &a, const b2Vec2 &b)
Perform the cross product on two vectors. In 2D this produces a scalar.
Definition: b2_math.h:401
int32 pointCount
the number of manifold points
Definition: b2_collision.h:112
float GetAngle() const
Definition: b2_body.h:489
b2World * m_world
Definition: test.h:128
float angle
The world angle of the body in radians.
Definition: b2_body.h:81
#define b2_pi
Definition: b2_common.h:41
b2Vec2 position
Definition: b2_body.h:78
int RegisterTest(const char *category, const char *name, TestCreateFcn *fcn)
Definition: test.cpp:458
static Test * Create()
Definition: breakable.cpp:141
void SetAngularVelocity(float omega)
Definition: b2_body.h:524
b2Fixture * m_piece1
Definition: breakable.cpp:151
virtual void Step(Settings &settings)
Definition: test.cpp:278
void Step(Settings &settings) override
Definition: breakable.cpp:122
b2PolygonShape m_shape2
Definition: breakable.cpp:150
const b2Vec2 & GetWorldCenter() const
Get the world position of the center of mass.
Definition: b2_body.h:494
b2Body * CreateBody(const b2BodyDef *def)
Definition: b2_world.cpp:115
b2Body * GetBody()
Definition: b2_fixture.h:283
float normalImpulses[b2_maxManifoldPoints]
void PostSolve(b2Contact *contact, const b2ContactImpulse *impulse) override
Definition: breakable.cpp:66
bool m_break
Definition: breakable.cpp:155


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