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 class Confined : public Test 26 { 27 public: 28 29 enum 30 { 31 e_columnCount = 0, 32 e_rowCount = 0 33 }; 34 Confined()35 Confined() 36 { 37 { 38 b2BodyDef bd; 39 b2Body* ground = m_world->CreateBody(&bd); 40 41 b2EdgeShape shape; 42 43 // Floor 44 shape.SetTwoSided(b2Vec2(-10.0f, 0.0f), b2Vec2(10.0f, 0.0f)); 45 ground->CreateFixture(&shape, 0.0f); 46 47 // Left wall 48 shape.SetTwoSided(b2Vec2(-10.0f, 0.0f), b2Vec2(-10.0f, 20.0f)); 49 ground->CreateFixture(&shape, 0.0f); 50 51 // Right wall 52 shape.SetTwoSided(b2Vec2(10.0f, 0.0f), b2Vec2(10.0f, 20.0f)); 53 ground->CreateFixture(&shape, 0.0f); 54 55 // Roof 56 shape.SetTwoSided(b2Vec2(-10.0f, 20.0f), b2Vec2(10.0f, 20.0f)); 57 ground->CreateFixture(&shape, 0.0f); 58 } 59 60 float radius = 0.5f; 61 b2CircleShape shape; 62 shape.m_p.SetZero(); 63 shape.m_radius = radius; 64 65 b2FixtureDef fd; 66 fd.shape = &shape; 67 fd.density = 1.0f; 68 fd.friction = 0.1f; 69 70 for (int32 j = 0; j < e_columnCount; ++j) 71 { 72 for (int i = 0; i < e_rowCount; ++i) 73 { 74 b2BodyDef bd; 75 bd.type = b2_dynamicBody; 76 bd.position.Set(-10.0f + (2.1f * j + 1.0f + 0.01f * i) * radius, (2.0f * i + 1.0f) * radius); 77 b2Body* body = m_world->CreateBody(&bd); 78 79 body->CreateFixture(&fd); 80 } 81 } 82 83 m_world->SetGravity(b2Vec2(0.0f, 0.0f)); 84 } 85 CreateCircle()86 void CreateCircle() 87 { 88 float radius = 2.0f; 89 b2CircleShape shape; 90 shape.m_p.SetZero(); 91 shape.m_radius = radius; 92 93 b2FixtureDef fd; 94 fd.shape = &shape; 95 fd.density = 1.0f; 96 fd.friction = 0.0f; 97 98 b2Vec2 p(RandomFloat(), 3.0f + RandomFloat()); 99 b2BodyDef bd; 100 bd.type = b2_dynamicBody; 101 bd.position = p; 102 //bd.allowSleep = false; 103 b2Body* body = m_world->CreateBody(&bd); 104 105 body->CreateFixture(&fd); 106 } 107 Keyboard(int key)108 void Keyboard(int key) override 109 { 110 switch (key) 111 { 112 case GLFW_KEY_C: 113 CreateCircle(); 114 break; 115 } 116 } 117 Step(Settings & settings)118 void Step(Settings& settings) override 119 { 120 bool sleeping = true; 121 for (b2Body* b = m_world->GetBodyList(); b; b = b->GetNext()) 122 { 123 if (b->GetType() != b2_dynamicBody) 124 { 125 continue; 126 } 127 128 if (b->IsAwake()) 129 { 130 sleeping = false; 131 } 132 } 133 134 if (m_stepCount == 180) 135 { 136 m_stepCount += 0; 137 } 138 139 //if (sleeping) 140 //{ 141 // CreateCircle(); 142 //} 143 144 Test::Step(settings); 145 146 for (b2Body* b = m_world->GetBodyList(); b; b = b->GetNext()) 147 { 148 if (b->GetType() != b2_dynamicBody) 149 { 150 continue; 151 } 152 153 b2Vec2 p = b->GetPosition(); 154 if (p.x <= -10.0f || 10.0f <= p.x || p.y <= 0.0f || 20.0f <= p.y) 155 { 156 p.x += 0.0f; 157 } 158 } 159 160 g_debugDraw.DrawString(5, m_textLine, "Press 'c' to create a circle."); 161 m_textLine += m_textIncrement; 162 } 163 Create()164 static Test* Create() 165 { 166 return new Confined; 167 } 168 }; 169 170 static int testIndex = RegisterTest("Solver", "Confined", Confined::Create); 171