apply_force.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 #include "test.h"
24 
25 // This test shows how to apply forces and torques to a body.
26 // It also shows how to use the friction joint that can be useful
27 // for overhead games.
28 class ApplyForce : public Test
29 {
30 public:
32  {
33  m_world->SetGravity(b2Vec2(0.0f, 0.0f));
34 
35  const float k_restitution = 0.4f;
36 
37  b2Body* ground;
38  {
39  b2BodyDef bd;
40  bd.position.Set(0.0f, 20.0f);
41  ground = m_world->CreateBody(&bd);
42 
43  b2EdgeShape shape;
44 
45  b2FixtureDef sd;
46  sd.shape = &shape;
47  sd.density = 0.0f;
48  sd.restitution = k_restitution;
49 
50  // Left vertical
51  shape.SetTwoSided(b2Vec2(-20.0f, -20.0f), b2Vec2(-20.0f, 20.0f));
52  ground->CreateFixture(&sd);
53 
54  // Right vertical
55  shape.SetTwoSided(b2Vec2(20.0f, -20.0f), b2Vec2(20.0f, 20.0f));
56  ground->CreateFixture(&sd);
57 
58  // Top horizontal
59  shape.SetTwoSided(b2Vec2(-20.0f, 20.0f), b2Vec2(20.0f, 20.0f));
60  ground->CreateFixture(&sd);
61 
62  // Bottom horizontal
63  shape.SetTwoSided(b2Vec2(-20.0f, -20.0f), b2Vec2(20.0f, -20.0f));
64  ground->CreateFixture(&sd);
65  }
66 
67  {
68  b2Transform xf1;
69  xf1.q.Set(0.3524f * b2_pi);
70  xf1.p = xf1.q.GetXAxis();
71 
72  b2Vec2 vertices[3];
73  vertices[0] = b2Mul(xf1, b2Vec2(-1.0f, 0.0f));
74  vertices[1] = b2Mul(xf1, b2Vec2(1.0f, 0.0f));
75  vertices[2] = b2Mul(xf1, b2Vec2(0.0f, 0.5f));
76 
77  b2PolygonShape poly1;
78  poly1.Set(vertices, 3);
79 
80  b2FixtureDef sd1;
81  sd1.shape = &poly1;
82  sd1.density = 2.0f;
83 
84  b2Transform xf2;
85  xf2.q.Set(-0.3524f * b2_pi);
86  xf2.p = -xf2.q.GetXAxis();
87 
88  vertices[0] = b2Mul(xf2, b2Vec2(-1.0f, 0.0f));
89  vertices[1] = b2Mul(xf2, b2Vec2(1.0f, 0.0f));
90  vertices[2] = b2Mul(xf2, b2Vec2(0.0f, 0.5f));
91 
92  b2PolygonShape poly2;
93  poly2.Set(vertices, 3);
94 
95  b2FixtureDef sd2;
96  sd2.shape = &poly2;
97  sd2.density = 2.0f;
98 
99  b2BodyDef bd;
100  bd.type = b2_dynamicBody;
101 
102  bd.position.Set(0.0f, 3.0);
103  bd.angle = b2_pi;
104  bd.allowSleep = false;
105  m_body = m_world->CreateBody(&bd);
106  m_body->CreateFixture(&sd1);
107  m_body->CreateFixture(&sd2);
108 
109  float gravity = 10.0f;
110  float I = m_body->GetInertia();
111  float mass = m_body->GetMass();
112 
113  // Compute an effective radius that can be used to
114  // set the max torque for a friction joint
115  // For a circle: I = 0.5 * m * r * r ==> r = sqrt(2 * I / m)
116  float radius = b2Sqrt(2.0f * I / mass);
117 
119  jd.bodyA = ground;
120  jd.bodyB = m_body;
121  jd.localAnchorA.SetZero();
123  jd.collideConnected = true;
124  jd.maxForce = 0.5f * mass * gravity;
125  jd.maxTorque = 0.2f * mass * radius * gravity;
126 
127  m_world->CreateJoint(&jd);
128  }
129 
130  {
131  b2PolygonShape shape;
132  shape.SetAsBox(0.5f, 0.5f);
133 
134  b2FixtureDef fd;
135  fd.shape = &shape;
136  fd.density = 1.0f;
137  fd.friction = 0.3f;
138 
139  for (int i = 0; i < 10; ++i)
140  {
141  b2BodyDef bd;
142  bd.type = b2_dynamicBody;
143 
144  bd.position.Set(0.0f, 7.0f + 1.54f * i);
145  b2Body* body = m_world->CreateBody(&bd);
146 
147  body->CreateFixture(&fd);
148 
149  float gravity = 10.0f;
150  float I = body->GetInertia();
151  float mass = body->GetMass();
152 
153  // For a circle: I = 0.5 * m * r * r ==> r = sqrt(2 * I / m)
154  float radius = b2Sqrt(2.0f * I / mass);
155 
157  jd.localAnchorA.SetZero();
158  jd.localAnchorB.SetZero();
159  jd.bodyA = ground;
160  jd.bodyB = body;
161  jd.collideConnected = true;
162  jd.maxForce = mass * gravity;
163  jd.maxTorque = 0.1f * mass * radius * gravity;
164 
165  m_world->CreateJoint(&jd);
166  }
167  }
168  }
169 
170  void Step(Settings& settings) override
171  {
172  g_debugDraw.DrawString(5, m_textLine, "Forward (W), Turn (A) and (D)");
174 
176  {
177  b2Vec2 f = m_body->GetWorldVector(b2Vec2(0.0f, -50.0f));
178  b2Vec2 p = m_body->GetWorldPoint(b2Vec2(0.0f, 3.0f));
179  m_body->ApplyForce(f, p, true);
180  }
181 
183  {
184  m_body->ApplyTorque(10.0f, true);
185  }
186 
188  {
189  m_body->ApplyTorque(-10.0f, true);
190  }
191 
192  Test::Step(settings);
193  }
194 
195  static Test* Create()
196  {
197  return new ApplyForce;
198  }
199 
201 };
202 
203 static int testIndex = RegisterTest("Forces", "Apply Force", ApplyForce::Create);
const b2Shape * shape
Definition: b2_fixture.h:76
float GetMass() const
Definition: b2_body.h:544
float maxForce
The maximum friction force in N.
#define b2Sqrt(x)
Definition: b2_math.h:37
b2Fixture * CreateFixture(const b2FixtureDef *def)
Definition: b2_body.cpp:165
b2Vec2 localAnchorA
The local anchor point relative to bodyA&#39;s origin.
b2Vec2 b2Mul(const b2Mat22 &A, const b2Vec2 &v)
Definition: b2_math.h:422
float density
The density, usually in kg/m^2.
Definition: b2_fixture.h:92
b2Vec2 p
Definition: b2_math.h:360
const b2Vec2 & GetLocalCenter() const
Get the local position of the center of mass.
Definition: b2_body.h:499
b2Body * m_body
float GetInertia() const
Definition: b2_body.h:549
b2Rot q
Definition: b2_math.h:361
static int testIndex
f
void SetGravity(const b2Vec2 &gravity)
Change the global gravity vector.
Definition: b2_world.h:309
float maxTorque
The maximum friction torque in N-m.
b2Vec2 localAnchorB
The local anchor point relative to bodyB&#39;s origin.
int32 m_textLine
Definition: test.h:127
void ApplyForce(const b2Vec2 &force, const b2Vec2 &point, bool wake)
Definition: b2_body.h:739
static Test * Create()
Definition: test.h:80
b2Vec2 GetXAxis() const
Get the x-axis.
Definition: b2_math.h:321
void SetZero()
Set this vector to all zeros.
Definition: b2_math.h:50
A 2D column vector.
Definition: b2_math.h:41
#define GLFW_KEY_A
Definition: glfw3.h:378
void SetTwoSided(const b2Vec2 &v1, const b2Vec2 &v2)
Set this as an isolated edge. Collision is two-sided.
Friction joint definition.
void SetAsBox(float hx, float hy)
void Step(Settings &settings) override
b2BodyType type
Definition: b2_body.h:74
A rigid body. These are created via b2World::CreateBody.
Definition: b2_body.h:128
b2Joint * CreateJoint(const b2JointDef *def)
Definition: b2_world.cpp:220
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
#define GLFW_KEY_W
Definition: glfw3.h:400
b2Vec2 GetWorldVector(const b2Vec2 &localVector) const
Definition: b2_body.h:566
int32 m_textIncrement
Definition: test.h:135
#define GLFW_KEY_D
Definition: glfw3.h:381
b2World * m_world
Definition: test.h:128
float angle
The world angle of the body in radians.
Definition: b2_body.h:81
#define b2_pi
Definition: b2_common.h:41
b2Vec2 position
Definition: b2_body.h:78
void Set(const b2Vec2 *points, int32 count)
void ApplyTorque(float torque, bool wake)
Definition: b2_body.h:778
b2Vec2 GetWorldPoint(const b2Vec2 &localPoint) const
Definition: b2_body.h:561
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
bool allowSleep
Definition: b2_body.h:103
GLFWwindow * g_mainWindow
Definition: main.cpp:42
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 restitution
The restitution (elasticity) usually in the range [0,1].
Definition: b2_fixture.h:85
#define GLFW_PRESS
The key or mouse button was pressed.
Definition: glfw3.h:304
GLFWAPI int glfwGetKey(GLFWwindow *window, int key)
Returns the last reported state of a keyboard key for the specified window.
Definition: input.c:591
b2Body * CreateBody(const b2BodyDef *def)
Definition: b2_world.cpp:115
b2Body * bodyB
The second attached body.
Definition: b2_joint.h:92
float friction
The friction coefficient, usually in the range [0,1].
Definition: b2_fixture.h:82
void Set(float angle)
Set using an angle in radians.
Definition: b2_math.h:300


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