diff options
Diffstat (limited to 'Client/ThirdParty/Box2D/testbed/tests/breakable.cpp')
-rw-r--r-- | Client/ThirdParty/Box2D/testbed/tests/breakable.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/Client/ThirdParty/Box2D/testbed/tests/breakable.cpp b/Client/ThirdParty/Box2D/testbed/tests/breakable.cpp new file mode 100644 index 0000000..136244a --- /dev/null +++ b/Client/ThirdParty/Box2D/testbed/tests/breakable.cpp @@ -0,0 +1,158 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "test.h" + +// This is used to test sensor shapes. +class Breakable : public Test +{ +public: + + enum + { + e_count = 7 + }; + + Breakable() + { + // Ground body + { + b2BodyDef bd; + b2Body* ground = m_world->CreateBody(&bd); + + b2EdgeShape shape; + shape.SetTwoSided(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f)); + ground->CreateFixture(&shape, 0.0f); + } + + // Breakable dynamic body + { + b2BodyDef bd; + bd.type = b2_dynamicBody; + bd.position.Set(0.0f, 40.0f); + bd.angle = 0.25f * b2_pi; + m_body1 = m_world->CreateBody(&bd); + + m_shape1.SetAsBox(0.5f, 0.5f, b2Vec2(-0.5f, 0.0f), 0.0f); + m_piece1 = m_body1->CreateFixture(&m_shape1, 1.0f); + + m_shape2.SetAsBox(0.5f, 0.5f, b2Vec2(0.5f, 0.0f), 0.0f); + m_piece2 = m_body1->CreateFixture(&m_shape2, 1.0f); + } + + m_break = false; + m_broke = false; + } + + void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) override + { + if (m_broke) + { + // The body already broke. + return; + } + + // Should the body break? + int32 count = contact->GetManifold()->pointCount; + + float maxImpulse = 0.0f; + for (int32 i = 0; i < count; ++i) + { + maxImpulse = b2Max(maxImpulse, impulse->normalImpulses[i]); + } + + if (maxImpulse > 40.0f) + { + // Flag the body for breaking. + m_break = true; + } + } + + void Break() + { + // Create two bodies from one. + b2Body* body1 = m_piece1->GetBody(); + b2Vec2 center = body1->GetWorldCenter(); + + body1->DestroyFixture(m_piece2); + m_piece2 = NULL; + + b2BodyDef bd; + bd.type = b2_dynamicBody; + bd.position = body1->GetPosition(); + bd.angle = body1->GetAngle(); + + b2Body* body2 = m_world->CreateBody(&bd); + m_piece2 = body2->CreateFixture(&m_shape2, 1.0f); + + // Compute consistent velocities for new bodies based on + // cached velocity. + b2Vec2 center1 = body1->GetWorldCenter(); + b2Vec2 center2 = body2->GetWorldCenter(); + + b2Vec2 velocity1 = m_velocity + b2Cross(m_angularVelocity, center1 - center); + b2Vec2 velocity2 = m_velocity + b2Cross(m_angularVelocity, center2 - center); + + body1->SetAngularVelocity(m_angularVelocity); + body1->SetLinearVelocity(velocity1); + + body2->SetAngularVelocity(m_angularVelocity); + body2->SetLinearVelocity(velocity2); + } + + void Step(Settings& settings) override + { + if (m_break) + { + Break(); + m_broke = true; + m_break = false; + } + + // Cache velocities to improve movement on breakage. + if (m_broke == false) + { + m_velocity = m_body1->GetLinearVelocity(); + m_angularVelocity = m_body1->GetAngularVelocity(); + } + + Test::Step(settings); + } + + static Test* Create() + { + return new Breakable; + } + + b2Body* m_body1; + b2Vec2 m_velocity; + float m_angularVelocity; + b2PolygonShape m_shape1; + b2PolygonShape m_shape2; + b2Fixture* m_piece1; + b2Fixture* m_piece2; + + bool m_broke; + bool m_break; +}; + +static int testIndex = RegisterTest("Examples", "Breakable", Breakable::Create); |