diff options
author | chai <chaifix@163.com> | 2021-12-13 00:07:19 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-12-13 00:07:19 +0800 |
commit | 60cbbdec07ab7a5636eac5b3c024ae44e937f4d4 (patch) | |
tree | b2c7b0a868f18159dbc43d8954e1bd7668549a88 /Client/ThirdParty/Box2D/testbed/tests/collision_processing.cpp |
+init
Diffstat (limited to 'Client/ThirdParty/Box2D/testbed/tests/collision_processing.cpp')
-rw-r--r-- | Client/ThirdParty/Box2D/testbed/tests/collision_processing.cpp | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/Client/ThirdParty/Box2D/testbed/tests/collision_processing.cpp b/Client/ThirdParty/Box2D/testbed/tests/collision_processing.cpp new file mode 100644 index 0000000..1c684bd --- /dev/null +++ b/Client/ThirdParty/Box2D/testbed/tests/collision_processing.cpp @@ -0,0 +1,191 @@ +// 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" + +#include <algorithm> + +// This test shows collision processing and tests +// deferred body destruction. +class CollisionProcessing : public Test +{ +public: + CollisionProcessing() + { + // Ground body + { + b2EdgeShape shape; + shape.SetTwoSided(b2Vec2(-50.0f, 0.0f), b2Vec2(50.0f, 0.0f)); + + b2FixtureDef sd; + sd.shape = &shape;; + + b2BodyDef bd; + b2Body* ground = m_world->CreateBody(&bd); + ground->CreateFixture(&sd); + } + + float xLo = -5.0f, xHi = 5.0f; + float yLo = 2.0f, yHi = 35.0f; + + // Small triangle + b2Vec2 vertices[3]; + vertices[0].Set(-1.0f, 0.0f); + vertices[1].Set(1.0f, 0.0f); + vertices[2].Set(0.0f, 2.0f); + + b2PolygonShape polygon; + polygon.Set(vertices, 3); + + b2FixtureDef triangleShapeDef; + triangleShapeDef.shape = &polygon; + triangleShapeDef.density = 1.0f; + + b2BodyDef triangleBodyDef; + triangleBodyDef.type = b2_dynamicBody; + triangleBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi)); + + b2Body* body1 = m_world->CreateBody(&triangleBodyDef); + body1->CreateFixture(&triangleShapeDef); + + // Large triangle (recycle definitions) + vertices[0] *= 2.0f; + vertices[1] *= 2.0f; + vertices[2] *= 2.0f; + polygon.Set(vertices, 3); + + triangleBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi)); + + b2Body* body2 = m_world->CreateBody(&triangleBodyDef); + body2->CreateFixture(&triangleShapeDef); + + // Small box + polygon.SetAsBox(1.0f, 0.5f); + + b2FixtureDef boxShapeDef; + boxShapeDef.shape = &polygon; + boxShapeDef.density = 1.0f; + + b2BodyDef boxBodyDef; + boxBodyDef.type = b2_dynamicBody; + boxBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi)); + + b2Body* body3 = m_world->CreateBody(&boxBodyDef); + body3->CreateFixture(&boxShapeDef); + + // Large box (recycle definitions) + polygon.SetAsBox(2.0f, 1.0f); + boxBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi)); + + b2Body* body4 = m_world->CreateBody(&boxBodyDef); + body4->CreateFixture(&boxShapeDef); + + // Small circle + b2CircleShape circle; + circle.m_radius = 1.0f; + + b2FixtureDef circleShapeDef; + circleShapeDef.shape = &circle; + circleShapeDef.density = 1.0f; + + b2BodyDef circleBodyDef; + circleBodyDef.type = b2_dynamicBody; + circleBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi)); + + b2Body* body5 = m_world->CreateBody(&circleBodyDef); + body5->CreateFixture(&circleShapeDef); + + // Large circle + circle.m_radius *= 2.0f; + circleBodyDef.position.Set(RandomFloat(xLo, xHi), RandomFloat(yLo, yHi)); + + b2Body* body6 = m_world->CreateBody(&circleBodyDef); + body6->CreateFixture(&circleShapeDef); + } + + void Step(Settings& settings) override + { + Test::Step(settings); + + // We are going to destroy some bodies according to contact + // points. We must buffer the bodies that should be destroyed + // because they may belong to multiple contact points. + const int32 k_maxNuke = 6; + b2Body* nuke[k_maxNuke]; + int32 nukeCount = 0; + + // Traverse the contact results. Destroy bodies that + // are touching heavier bodies. + for (int32 i = 0; i < m_pointCount; ++i) + { + ContactPoint* point = m_points + i; + + b2Body* body1 = point->fixtureA->GetBody(); + b2Body* body2 = point->fixtureB->GetBody(); + float mass1 = body1->GetMass(); + float mass2 = body2->GetMass(); + + if (mass1 > 0.0f && mass2 > 0.0f) + { + if (mass2 > mass1) + { + nuke[nukeCount++] = body1; + } + else + { + nuke[nukeCount++] = body2; + } + + if (nukeCount == k_maxNuke) + { + break; + } + } + } + + // Sort the nuke array to group duplicates. + std::sort(nuke, nuke + nukeCount); + + // Destroy the bodies, skipping duplicates. + int32 i = 0; + while (i < nukeCount) + { + b2Body* b = nuke[i++]; + while (i < nukeCount && nuke[i] == b) + { + ++i; + } + + if (b != m_bomb) + { + m_world->DestroyBody(b); + } + } + } + + static Test* Create() + { + return new CollisionProcessing; + } +}; + +static int testIndex = RegisterTest("Examples", "Collision Processing", CollisionProcessing::Create); |