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);
b2Cross
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
b2ContactImpulse::normalImpulses
float normalImpulses[b2_maxManifoldPoints]
Definition: b2_world_callbacks.h:72
b2EdgeShape
Definition: b2_edge_shape.h:32
b2Body::GetLinearVelocity
const b2Vec2 & GetLinearVelocity() const
Definition: b2_body.h:519
b2Body::GetAngularVelocity
float GetAngularVelocity() const
Definition: b2_body.h:539
Breakable::m_body1
b2Body * m_body1
Definition: breakable.cpp:146
NULL
#define NULL
Breakable::m_shape2
b2PolygonShape m_shape2
Definition: breakable.cpp:150
Breakable::Create
static Test * Create()
Definition: breakable.cpp:141
b2ContactImpulse
Definition: b2_world_callbacks.h:70
Breakable::m_shape1
b2PolygonShape m_shape1
Definition: breakable.cpp:149
b2Body
A rigid body. These are created via b2World::CreateBody.
Definition: b2_body.h:128
b2Vec2::Set
void Set(float x_, float y_)
Set this vector to some specified coordinates.
Definition: b2_math.h:53
b2Vec2
A 2D column vector.
Definition: b2_math.h:41
b2Body::SetAngularVelocity
void SetAngularVelocity(float omega)
Definition: b2_body.h:524
b2Body::DestroyFixture
void DestroyFixture(b2Fixture *fixture)
Definition: b2_body.cpp:213
b2EdgeShape::SetTwoSided
void SetTwoSided(const b2Vec2 &v1, const b2Vec2 &v2)
Set this as an isolated edge. Collision is two-sided.
Definition: b2_edge_shape.cpp:36
b2Body::SetLinearVelocity
void SetLinearVelocity(const b2Vec2 &v)
Definition: b2_body.h:504
f
f
b2Max
T b2Max(T a, T b)
Definition: b2_math.h:637
b2BodyDef::type
b2BodyType type
Definition: b2_body.h:74
Breakable::m_break
bool m_break
Definition: breakable.cpp:155
b2Manifold::pointCount
int32 pointCount
the number of manifold points
Definition: b2_collision.h:112
b2_pi
#define b2_pi
Definition: b2_common.h:41
Breakable::m_piece1
b2Fixture * m_piece1
Definition: breakable.cpp:151
b2Contact
Definition: b2_contact.h:88
b2_dynamicBody
@ b2_dynamicBody
Definition: b2_body.h:47
b2Body::GetWorldCenter
const b2Vec2 & GetWorldCenter() const
Get the world position of the center of mass.
Definition: b2_body.h:494
Breakable
Definition: breakable.cpp:26
b2BodyDef::angle
float angle
The world angle of the body in radians.
Definition: b2_body.h:81
b2Fixture
Definition: b2_fixture.h:116
b2PolygonShape::SetAsBox
void SetAsBox(float hx, float hy)
Definition: b2_polygon_shape.cpp:36
b2BodyDef
Definition: b2_body.h:52
Breakable::m_broke
bool m_broke
Definition: breakable.cpp:154
Breakable::Breakable
Breakable()
Definition: breakable.cpp:35
Settings
Definition: settings.h:25
b2Body::GetAngle
float GetAngle() const
Definition: b2_body.h:489
b2World::CreateBody
b2Body * CreateBody(const b2BodyDef *def)
Definition: b2_world.cpp:115
b2PolygonShape
Definition: b2_polygon_shape.h:32
RegisterTest
int RegisterTest(const char *category, const char *name, TestCreateFcn *fcn)
Definition: test.cpp:458
b2Contact::GetManifold
b2Manifold * GetManifold()
Definition: b2_contact.h:244
Breakable::PostSolve
void PostSolve(b2Contact *contact, const b2ContactImpulse *impulse) override
Definition: breakable.cpp:66
Breakable::m_angularVelocity
float m_angularVelocity
Definition: breakable.cpp:148
int32
signed int int32
Definition: b2_types.h:28
Breakable::Break
void Break()
Definition: breakable.cpp:90
Test
Definition: test.h:80
Breakable::m_velocity
b2Vec2 m_velocity
Definition: breakable.cpp:147
Breakable::m_piece2
b2Fixture * m_piece2
Definition: breakable.cpp:152
b2Body::GetPosition
const b2Vec2 & GetPosition() const
Definition: b2_body.h:484
b2BodyDef::position
b2Vec2 position
Definition: b2_body.h:78
Breakable::e_count
@ e_count
Definition: breakable.cpp:32
testIndex
static int testIndex
Definition: breakable.cpp:158
Test::Step
virtual void Step(Settings &settings)
Definition: test.cpp:278
Breakable::Step
void Step(Settings &settings) override
Definition: breakable.cpp:122
b2Fixture::GetBody
b2Body * GetBody()
Definition: b2_fixture.h:283
Test::m_world
b2World * m_world
Definition: test.h:128
b2Body::CreateFixture
b2Fixture * CreateFixture(const b2FixtureDef *def)
Definition: b2_body.cpp:165


mvsim
Author(s):
autogenerated on Wed May 28 2025 02:13:07