1 /*
2 * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty.  In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 * 1. The origin of this software must not be misrepresented; you must not
11 * claim that you wrote the original software. If you use this software
12 * in a product, an acknowledgment in the product documentation would be
13 * appreciated but is not required.
14 * 2. Altered source versions must be plainly marked as such, and must not be
15 * misrepresented as being the original software.
16 * 3. This notice may not be removed or altered from any source distribution.
17 */
18 
19 #ifndef WEB_H
20 #define WEB_H
21 
22 // This tests distance joints, body destruction, and joint destruction.
23 class Web : public Test
24 {
25 public:
Web()26     Web()
27     {
28         b2Body* ground = NULL;
29         {
30             b2BodyDef bd;
31             ground = m_world->CreateBody(&bd);
32 
33             b2EdgeShape shape;
34             shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
35             ground->CreateFixture(&shape, 0.0f);
36         }
37 
38         {
39             b2PolygonShape shape;
40             shape.SetAsBox(0.5f, 0.5f);
41 
42             b2BodyDef bd;
43             bd.type = b2_dynamicBody;
44 
45             bd.position.Set(-5.0f, 5.0f);
46             m_bodies[0] = m_world->CreateBody(&bd);
47             m_bodies[0]->CreateFixture(&shape, 5.0f);
48 
49             bd.position.Set(5.0f, 5.0f);
50             m_bodies[1] = m_world->CreateBody(&bd);
51             m_bodies[1]->CreateFixture(&shape, 5.0f);
52 
53             bd.position.Set(5.0f, 15.0f);
54             m_bodies[2] = m_world->CreateBody(&bd);
55             m_bodies[2]->CreateFixture(&shape, 5.0f);
56 
57             bd.position.Set(-5.0f, 15.0f);
58             m_bodies[3] = m_world->CreateBody(&bd);
59             m_bodies[3]->CreateFixture(&shape, 5.0f);
60 
61             b2DistanceJointDef jd;
62             b2Vec2 p1, p2, d;
63 
64             jd.frequencyHz = 2.0f;
65             jd.dampingRatio = 0.0f;
66 
67             jd.bodyA = ground;
68             jd.bodyB = m_bodies[0];
69             jd.localAnchorA.Set(-10.0f, 0.0f);
70             jd.localAnchorB.Set(-0.5f, -0.5f);
71             p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
72             p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
73             d = p2 - p1;
74             jd.length = d.Length();
75             m_joints[0] = m_world->CreateJoint(&jd);
76 
77             jd.bodyA = ground;
78             jd.bodyB = m_bodies[1];
79             jd.localAnchorA.Set(10.0f, 0.0f);
80             jd.localAnchorB.Set(0.5f, -0.5f);
81             p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
82             p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
83             d = p2 - p1;
84             jd.length = d.Length();
85             m_joints[1] = m_world->CreateJoint(&jd);
86 
87             jd.bodyA = ground;
88             jd.bodyB = m_bodies[2];
89             jd.localAnchorA.Set(10.0f, 20.0f);
90             jd.localAnchorB.Set(0.5f, 0.5f);
91             p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
92             p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
93             d = p2 - p1;
94             jd.length = d.Length();
95             m_joints[2] = m_world->CreateJoint(&jd);
96 
97             jd.bodyA = ground;
98             jd.bodyB = m_bodies[3];
99             jd.localAnchorA.Set(-10.0f, 20.0f);
100             jd.localAnchorB.Set(-0.5f, 0.5f);
101             p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
102             p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
103             d = p2 - p1;
104             jd.length = d.Length();
105             m_joints[3] = m_world->CreateJoint(&jd);
106 
107             jd.bodyA = m_bodies[0];
108             jd.bodyB = m_bodies[1];
109             jd.localAnchorA.Set(0.5f, 0.0f);
110             jd.localAnchorB.Set(-0.5f, 0.0f);;
111             p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
112             p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
113             d = p2 - p1;
114             jd.length = d.Length();
115             m_joints[4] = m_world->CreateJoint(&jd);
116 
117             jd.bodyA = m_bodies[1];
118             jd.bodyB = m_bodies[2];
119             jd.localAnchorA.Set(0.0f, 0.5f);
120             jd.localAnchorB.Set(0.0f, -0.5f);
121             p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
122             p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
123             d = p2 - p1;
124             jd.length = d.Length();
125             m_joints[5] = m_world->CreateJoint(&jd);
126 
127             jd.bodyA = m_bodies[2];
128             jd.bodyB = m_bodies[3];
129             jd.localAnchorA.Set(-0.5f, 0.0f);
130             jd.localAnchorB.Set(0.5f, 0.0f);
131             p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
132             p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
133             d = p2 - p1;
134             jd.length = d.Length();
135             m_joints[6] = m_world->CreateJoint(&jd);
136 
137             jd.bodyA = m_bodies[3];
138             jd.bodyB = m_bodies[0];
139             jd.localAnchorA.Set(0.0f, -0.5f);
140             jd.localAnchorB.Set(0.0f, 0.5f);
141             p1 = jd.bodyA->GetWorldPoint(jd.localAnchorA);
142             p2 = jd.bodyB->GetWorldPoint(jd.localAnchorB);
143             d = p2 - p1;
144             jd.length = d.Length();
145             m_joints[7] = m_world->CreateJoint(&jd);
146         }
147     }
148 
Keyboard(unsigned char key)149     void Keyboard(unsigned char key)
150     {
151         switch (key)
152         {
153         case 'b':
154             for (int32 i = 0; i < 4; ++i)
155             {
156                 if (m_bodies[i])
157                 {
158                     m_world->DestroyBody(m_bodies[i]);
159                     m_bodies[i] = NULL;
160                     break;
161                 }
162             }
163             break;
164 
165         case 'j':
166             for (int32 i = 0; i < 8; ++i)
167             {
168                 if (m_joints[i])
169                 {
170                     m_world->DestroyJoint(m_joints[i]);
171                     m_joints[i] = NULL;
172                     break;
173                 }
174             }
175             break;
176         }
177     }
178 
Step(Settings * settings)179     void Step(Settings* settings)
180     {
181         Test::Step(settings);
182         m_debugDraw.DrawString(5, m_textLine, "This demonstrates a soft distance joint.");
183         m_textLine += 15;
184         m_debugDraw.DrawString(5, m_textLine, "Press: (b) to delete a body, (j) to delete a joint");
185         m_textLine += 15;
186     }
187 
JointDestroyed(b2Joint * joint)188     void JointDestroyed(b2Joint* joint)
189     {
190         for (int32 i = 0; i < 8; ++i)
191         {
192             if (m_joints[i] == joint)
193             {
194                 m_joints[i] = NULL;
195                 break;
196             }
197         }
198     }
199 
Create()200     static Test* Create()
201     {
202         return new Web;
203     }
204 
205     b2Body* m_bodies[4];
206     b2Joint* m_joints[8];
207 };
208 
209 #endif
210