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