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 // Inspired by a contribution by roman_m 20 // Dimensions scooped from APE (http://www.cove.org/ape/index.htm) 21 22 #ifndef THEO_JANSEN_H 23 #define THEO_JANSEN_H 24 25 class TheoJansen : public Test 26 { 27 public: 28 CreateLeg(float32 s,const b2Vec2 & wheelAnchor)29 void CreateLeg(float32 s, const b2Vec2& wheelAnchor) 30 { 31 b2Vec2 p1(5.4f * s, -6.1f); 32 b2Vec2 p2(7.2f * s, -1.2f); 33 b2Vec2 p3(4.3f * s, -1.9f); 34 b2Vec2 p4(3.1f * s, 0.8f); 35 b2Vec2 p5(6.0f * s, 1.5f); 36 b2Vec2 p6(2.5f * s, 3.7f); 37 38 b2FixtureDef fd1, fd2; 39 fd1.filter.groupIndex = -1; 40 fd2.filter.groupIndex = -1; 41 fd1.density = 1.0f; 42 fd2.density = 1.0f; 43 44 b2PolygonShape poly1, poly2; 45 46 if (s > 0.0f) 47 { 48 b2Vec2 vertices[3]; 49 50 vertices[0] = p1; 51 vertices[1] = p2; 52 vertices[2] = p3; 53 poly1.Set(vertices, 3); 54 55 vertices[0] = b2Vec2_zero; 56 vertices[1] = p5 - p4; 57 vertices[2] = p6 - p4; 58 poly2.Set(vertices, 3); 59 } 60 else 61 { 62 b2Vec2 vertices[3]; 63 64 vertices[0] = p1; 65 vertices[1] = p3; 66 vertices[2] = p2; 67 poly1.Set(vertices, 3); 68 69 vertices[0] = b2Vec2_zero; 70 vertices[1] = p6 - p4; 71 vertices[2] = p5 - p4; 72 poly2.Set(vertices, 3); 73 } 74 75 fd1.shape = &poly1; 76 fd2.shape = &poly2; 77 78 b2BodyDef bd1, bd2; 79 bd1.type = b2_dynamicBody; 80 bd2.type = b2_dynamicBody; 81 bd1.position = m_offset; 82 bd2.position = p4 + m_offset; 83 84 bd1.angularDamping = 10.0f; 85 bd2.angularDamping = 10.0f; 86 87 b2Body* body1 = m_world->CreateBody(&bd1); 88 b2Body* body2 = m_world->CreateBody(&bd2); 89 90 body1->CreateFixture(&fd1); 91 body2->CreateFixture(&fd2); 92 93 b2DistanceJointDef djd; 94 95 // Using a soft distance constraint can reduce some jitter. 96 // It also makes the structure seem a bit more fluid by 97 // acting like a suspension system. 98 djd.dampingRatio = 0.5f; 99 djd.frequencyHz = 10.0f; 100 101 djd.Initialize(body1, body2, p2 + m_offset, p5 + m_offset); 102 m_world->CreateJoint(&djd); 103 104 djd.Initialize(body1, body2, p3 + m_offset, p4 + m_offset); 105 m_world->CreateJoint(&djd); 106 107 djd.Initialize(body1, m_wheel, p3 + m_offset, wheelAnchor + m_offset); 108 m_world->CreateJoint(&djd); 109 110 djd.Initialize(body2, m_wheel, p6 + m_offset, wheelAnchor + m_offset); 111 m_world->CreateJoint(&djd); 112 113 b2RevoluteJointDef rjd; 114 115 rjd.Initialize(body2, m_chassis, p4 + m_offset); 116 m_world->CreateJoint(&rjd); 117 } 118 TheoJansen()119 TheoJansen() 120 { 121 m_offset.Set(0.0f, 8.0f); 122 m_motorSpeed = 2.0f; 123 m_motorOn = true; 124 b2Vec2 pivot(0.0f, 0.8f); 125 126 // Ground 127 { 128 b2BodyDef bd; 129 b2Body* ground = m_world->CreateBody(&bd); 130 131 b2EdgeShape shape; 132 shape.Set(b2Vec2(-50.0f, 0.0f), b2Vec2(50.0f, 0.0f)); 133 ground->CreateFixture(&shape, 0.0f); 134 135 shape.Set(b2Vec2(-50.0f, 0.0f), b2Vec2(-50.0f, 10.0f)); 136 ground->CreateFixture(&shape, 0.0f); 137 138 shape.Set(b2Vec2(50.0f, 0.0f), b2Vec2(50.0f, 10.0f)); 139 ground->CreateFixture(&shape, 0.0f); 140 } 141 142 // Balls 143 for (int32 i = 0; i < 40; ++i) 144 { 145 b2CircleShape shape; 146 shape.m_radius = 0.25f; 147 148 b2BodyDef bd; 149 bd.type = b2_dynamicBody; 150 bd.position.Set(-40.0f + 2.0f * i, 0.5f); 151 152 b2Body* body = m_world->CreateBody(&bd); 153 body->CreateFixture(&shape, 1.0f); 154 } 155 156 // Chassis 157 { 158 b2PolygonShape shape; 159 shape.SetAsBox(2.5f, 1.0f); 160 161 b2FixtureDef sd; 162 sd.density = 1.0f; 163 sd.shape = &shape; 164 sd.filter.groupIndex = -1; 165 b2BodyDef bd; 166 bd.type = b2_dynamicBody; 167 bd.position = pivot + m_offset; 168 m_chassis = m_world->CreateBody(&bd); 169 m_chassis->CreateFixture(&sd); 170 } 171 172 { 173 b2CircleShape shape; 174 shape.m_radius = 1.6f; 175 176 b2FixtureDef sd; 177 sd.density = 1.0f; 178 sd.shape = &shape; 179 sd.filter.groupIndex = -1; 180 b2BodyDef bd; 181 bd.type = b2_dynamicBody; 182 bd.position = pivot + m_offset; 183 m_wheel = m_world->CreateBody(&bd); 184 m_wheel->CreateFixture(&sd); 185 } 186 187 { 188 b2RevoluteJointDef jd; 189 jd.Initialize(m_wheel, m_chassis, pivot + m_offset); 190 jd.collideConnected = false; 191 jd.motorSpeed = m_motorSpeed; 192 jd.maxMotorTorque = 400.0f; 193 jd.enableMotor = m_motorOn; 194 m_motorJoint = (b2RevoluteJoint*)m_world->CreateJoint(&jd); 195 } 196 197 b2Vec2 wheelAnchor; 198 199 wheelAnchor = pivot + b2Vec2(0.0f, -0.8f); 200 201 CreateLeg(-1.0f, wheelAnchor); 202 CreateLeg(1.0f, wheelAnchor); 203 204 m_wheel->SetTransform(m_wheel->GetPosition(), 120.0f * b2_pi / 180.0f); 205 CreateLeg(-1.0f, wheelAnchor); 206 CreateLeg(1.0f, wheelAnchor); 207 208 m_wheel->SetTransform(m_wheel->GetPosition(), -120.0f * b2_pi / 180.0f); 209 CreateLeg(-1.0f, wheelAnchor); 210 CreateLeg(1.0f, wheelAnchor); 211 } 212 Step(Settings * settings)213 void Step(Settings* settings) 214 { 215 m_debugDraw.DrawString(5, m_textLine, "Keys: left = a, brake = s, right = d, toggle motor = m"); 216 m_textLine += 15; 217 218 Test::Step(settings); 219 } 220 Keyboard(unsigned char key)221 void Keyboard(unsigned char key) 222 { 223 switch (key) 224 { 225 case 'a': 226 m_motorJoint->SetMotorSpeed(-m_motorSpeed); 227 break; 228 229 case 's': 230 m_motorJoint->SetMotorSpeed(0.0f); 231 break; 232 233 case 'd': 234 m_motorJoint->SetMotorSpeed(m_motorSpeed); 235 break; 236 237 case 'm': 238 m_motorJoint->EnableMotor(!m_motorJoint->IsMotorEnabled()); 239 break; 240 } 241 } 242 Create()243 static Test* Create() 244 { 245 return new TheoJansen; 246 } 247 248 b2Vec2 m_offset; 249 b2Body* m_chassis; 250 b2Body* m_wheel; 251 b2RevoluteJoint* m_motorJoint; 252 bool m_motorOn; 253 float32 m_motorSpeed; 254 }; 255 256 #endif // THEO_JANSEN_H 257