theo_jansen.cpp
Go to the documentation of this file.
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 // Inspired by a contribution from roman_m
24 // Dimensions scooped from APE (http://www.cove.org/ape/index.htm)
25 
26 #include "test.h"
27 
28 class TheoJansen : public Test
29 {
30 public:
31 
32  void CreateLeg(float s, const b2Vec2& wheelAnchor)
33  {
34  b2Vec2 p1(5.4f * s, -6.1f);
35  b2Vec2 p2(7.2f * s, -1.2f);
36  b2Vec2 p3(4.3f * s, -1.9f);
37  b2Vec2 p4(3.1f * s, 0.8f);
38  b2Vec2 p5(6.0f * s, 1.5f);
39  b2Vec2 p6(2.5f * s, 3.7f);
40 
41  b2FixtureDef fd1, fd2;
42  fd1.filter.groupIndex = -1;
43  fd2.filter.groupIndex = -1;
44  fd1.density = 1.0f;
45  fd2.density = 1.0f;
46 
47  b2PolygonShape poly1, poly2;
48 
49  if (s > 0.0f)
50  {
51  b2Vec2 vertices[3];
52 
53  vertices[0] = p1;
54  vertices[1] = p2;
55  vertices[2] = p3;
56  poly1.Set(vertices, 3);
57 
58  vertices[0] = b2Vec2_zero;
59  vertices[1] = p5 - p4;
60  vertices[2] = p6 - p4;
61  poly2.Set(vertices, 3);
62  }
63  else
64  {
65  b2Vec2 vertices[3];
66 
67  vertices[0] = p1;
68  vertices[1] = p3;
69  vertices[2] = p2;
70  poly1.Set(vertices, 3);
71 
72  vertices[0] = b2Vec2_zero;
73  vertices[1] = p6 - p4;
74  vertices[2] = p5 - p4;
75  poly2.Set(vertices, 3);
76  }
77 
78  fd1.shape = &poly1;
79  fd2.shape = &poly2;
80 
81  b2BodyDef bd1, bd2;
82  bd1.type = b2_dynamicBody;
83  bd2.type = b2_dynamicBody;
84  bd1.position = m_offset;
85  bd2.position = p4 + m_offset;
86 
87  bd1.angularDamping = 10.0f;
88  bd2.angularDamping = 10.0f;
89 
90  b2Body* body1 = m_world->CreateBody(&bd1);
91  b2Body* body2 = m_world->CreateBody(&bd2);
92 
93  body1->CreateFixture(&fd1);
94  body2->CreateFixture(&fd2);
95 
96  {
98 
99  // Using a soft distance constraint can reduce some jitter.
100  // It also makes the structure seem a bit more fluid by
101  // acting like a suspension system.
102  float dampingRatio = 0.5f;
103  float frequencyHz = 10.0f;
104 
105  jd.Initialize(body1, body2, p2 + m_offset, p5 + m_offset);
106  b2LinearStiffness(jd.stiffness, jd.damping, frequencyHz, dampingRatio, jd.bodyA, jd.bodyB);
107  m_world->CreateJoint(&jd);
108 
109  jd.Initialize(body1, body2, p3 + m_offset, p4 + m_offset);
110  b2LinearStiffness(jd.stiffness, jd.damping, frequencyHz, dampingRatio, jd.bodyA, jd.bodyB);
111  m_world->CreateJoint(&jd);
112 
113  jd.Initialize(body1, m_wheel, p3 + m_offset, wheelAnchor + m_offset);
114  b2LinearStiffness(jd.stiffness, jd.damping, frequencyHz, dampingRatio, jd.bodyA, jd.bodyB);
115  m_world->CreateJoint(&jd);
116 
117  jd.Initialize(body2, m_wheel, p6 + m_offset, wheelAnchor + m_offset);
118  b2LinearStiffness(jd.stiffness, jd.damping, frequencyHz, dampingRatio, jd.bodyA, jd.bodyB);
119  m_world->CreateJoint(&jd);
120  }
121 
122  {
124  jd.Initialize(body2, m_chassis, p4 + m_offset);
125  m_world->CreateJoint(&jd);
126  }
127  }
128 
130  {
131  m_offset.Set(0.0f, 8.0f);
132  m_motorSpeed = 2.0f;
133  m_motorOn = true;
134  b2Vec2 pivot(0.0f, 0.8f);
135 
136  // Ground
137  {
138  b2BodyDef bd;
139  b2Body* ground = m_world->CreateBody(&bd);
140 
141  b2EdgeShape shape;
142  shape.SetTwoSided(b2Vec2(-50.0f, 0.0f), b2Vec2(50.0f, 0.0f));
143  ground->CreateFixture(&shape, 0.0f);
144 
145  shape.SetTwoSided(b2Vec2(-50.0f, 0.0f), b2Vec2(-50.0f, 10.0f));
146  ground->CreateFixture(&shape, 0.0f);
147 
148  shape.SetTwoSided(b2Vec2(50.0f, 0.0f), b2Vec2(50.0f, 10.0f));
149  ground->CreateFixture(&shape, 0.0f);
150  }
151 
152  // Balls
153  for (int32 i = 0; i < 40; ++i)
154  {
155  b2CircleShape shape;
156  shape.m_radius = 0.25f;
157 
158  b2BodyDef bd;
159  bd.type = b2_dynamicBody;
160  bd.position.Set(-40.0f + 2.0f * i, 0.5f);
161 
162  b2Body* body = m_world->CreateBody(&bd);
163  body->CreateFixture(&shape, 1.0f);
164  }
165 
166  // Chassis
167  {
168  b2PolygonShape shape;
169  shape.SetAsBox(2.5f, 1.0f);
170 
171  b2FixtureDef sd;
172  sd.density = 1.0f;
173  sd.shape = &shape;
174  sd.filter.groupIndex = -1;
175  b2BodyDef bd;
176  bd.type = b2_dynamicBody;
177  bd.position = pivot + m_offset;
178  m_chassis = m_world->CreateBody(&bd);
179  m_chassis->CreateFixture(&sd);
180  }
181 
182  {
183  b2CircleShape shape;
184  shape.m_radius = 1.6f;
185 
186  b2FixtureDef sd;
187  sd.density = 1.0f;
188  sd.shape = &shape;
189  sd.filter.groupIndex = -1;
190  b2BodyDef bd;
191  bd.type = b2_dynamicBody;
192  bd.position = pivot + m_offset;
193  m_wheel = m_world->CreateBody(&bd);
194  m_wheel->CreateFixture(&sd);
195  }
196 
197  {
199  jd.Initialize(m_wheel, m_chassis, pivot + m_offset);
200  jd.collideConnected = false;
202  jd.maxMotorTorque = 400.0f;
203  jd.enableMotor = m_motorOn;
205  }
206 
207  b2Vec2 wheelAnchor;
208 
209  wheelAnchor = pivot + b2Vec2(0.0f, -0.8f);
210 
211  CreateLeg(-1.0f, wheelAnchor);
212  CreateLeg(1.0f, wheelAnchor);
213 
214  m_wheel->SetTransform(m_wheel->GetPosition(), 120.0f * b2_pi / 180.0f);
215  CreateLeg(-1.0f, wheelAnchor);
216  CreateLeg(1.0f, wheelAnchor);
217 
218  m_wheel->SetTransform(m_wheel->GetPosition(), -120.0f * b2_pi / 180.0f);
219  CreateLeg(-1.0f, wheelAnchor);
220  CreateLeg(1.0f, wheelAnchor);
221  }
222 
223  void Step(Settings& settings) override
224  {
225  g_debugDraw.DrawString(5, m_textLine, "Keys: left = a, brake = s, right = d, toggle motor = m");
227 
228  Test::Step(settings);
229  }
230 
231  void Keyboard(int key) override
232  {
233  switch (key)
234  {
235  case GLFW_KEY_A:
237  break;
238 
239  case GLFW_KEY_S:
241  break;
242 
243  case GLFW_KEY_D:
245  break;
246 
247  case GLFW_KEY_M:
249  break;
250  }
251  }
252 
253  static Test* Create()
254  {
255  return new TheoJansen;
256  }
257 
262  bool m_motorOn;
264 };
265 
266 static int testIndex = RegisterTest("Examples", "Theo Jansen", TheoJansen::Create);
const b2Shape * shape
Definition: b2_fixture.h:76
b2Fixture * CreateFixture(const b2FixtureDef *def)
Definition: b2_body.cpp:165
void Keyboard(int key) override
float density
The density, usually in kg/m^2.
Definition: b2_fixture.h:92
B2_API const b2Vec2 b2Vec2_zero
Useful constant.
void SetMotorSpeed(float speed)
Set the motor speed in radians per second.
f
bool IsMotorEnabled() const
Is the joint motor enabled?
void Initialize(b2Body *bodyA, b2Body *bodyB, const b2Vec2 &anchor)
void SetTransform(const b2Vec2 &position, float angle)
Definition: b2_body.cpp:415
int32 m_textLine
Definition: test.h:127
b2Body * m_chassis
Definition: test.h:80
float stiffness
The linear stiffness in N/m.
float angularDamping
Definition: b2_body.h:99
const b2Vec2 & GetPosition() const
Definition: b2_body.h:484
A solid circle shape.
A 2D column vector.
Definition: b2_math.h:41
#define GLFW_KEY_A
Definition: glfw3.h:378
signed int int32
Definition: b2_types.h:28
void SetTwoSided(const b2Vec2 &v1, const b2Vec2 &v2)
Set this as an isolated edge. Collision is two-sided.
void SetAsBox(float hx, float hy)
void EnableMotor(bool flag)
Enable/disable the joint motor.
float m_motorSpeed
b2BodyType type
Definition: b2_body.h:74
static Test * Create()
A rigid body. These are created via b2World::CreateBody.
Definition: b2_body.h:128
float m_radius
Definition: b2_shape.h:102
void Initialize(b2Body *bodyA, b2Body *bodyB, const b2Vec2 &anchorA, const b2Vec2 &anchorB)
void CreateLeg(float s, const b2Vec2 &wheelAnchor)
Definition: theo_jansen.cpp:32
b2Filter filter
Contact filtering data.
Definition: b2_fixture.h:99
b2Body * m_wheel
b2Joint * CreateJoint(const b2JointDef *def)
Definition: b2_world.cpp:220
#define GLFW_KEY_S
Definition: glfw3.h:396
bool collideConnected
Set this flag to true if the attached bodies should collide.
Definition: b2_joint.h:95
void Set(float x_, float y_)
Set this vector to some specified coordinates.
Definition: b2_math.h:53
b2RevoluteJoint * m_motorJoint
int32 m_textIncrement
Definition: test.h:135
bool enableMotor
A flag to enable the joint motor.
#define GLFW_KEY_D
Definition: glfw3.h:381
b2World * m_world
Definition: test.h:128
B2_API void b2LinearStiffness(float &stiffness, float &damping, float frequencyHertz, float dampingRatio, const b2Body *bodyA, const b2Body *bodyB)
Utility to compute linear stiffness values from frequency and damping ratio.
Definition: b2_joint.cpp:40
#define b2_pi
Definition: b2_common.h:41
#define GLFW_KEY_M
Definition: glfw3.h:390
b2Vec2 m_offset
b2Vec2 position
Definition: b2_body.h:78
float motorSpeed
The desired motor speed. Usually in radians per second.
void Set(const b2Vec2 *points, int32 count)
int RegisterTest(const char *category, const char *name, TestCreateFcn *fcn)
Definition: test.cpp:458
void DrawString(int x, int y, const char *string,...)
Definition: draw.cpp:772
int16 groupIndex
Definition: b2_fixture.h:56
virtual void Step(Settings &settings)
Definition: test.cpp:278
b2Body * bodyA
The first attached body.
Definition: b2_joint.h:89
DebugDraw g_debugDraw
Definition: draw.cpp:32
float damping
The linear damping in N*s/m.
b2Body * CreateBody(const b2BodyDef *def)
Definition: b2_world.cpp:115
b2Body * bodyB
The second attached body.
Definition: b2_joint.h:92
static int testIndex
void Step(Settings &settings) override


mvsim
Author(s):
autogenerated on Tue Jul 4 2023 03:08:21