Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • Alexandre.Meyer/m1if37-animation
  • Alexandre.Meyer/m2-apprentissage-profond-image
  • Alexandre.Meyer/m2-animation
  • Alexandre.Meyer/hugo-web-minimal
  • Alexandre.Meyer/lifami
  • Alexandre.Meyer/lifapcd
  • Alexandre.Meyer/www
  • Alexandre.Meyer/lifstage
8 results
Show changes
/*
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef REVOLUTE_H
#define REVOLUTE_H
class Revolute : public Test
{
public:
Revolute()
{
b2Body* ground = NULL;
{
b2BodyDef bd;
ground = m_world->CreateBody(&bd);
b2EdgeShape shape;
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
b2FixtureDef fd;
fd.shape = &shape;
//fd.filter.categoryBits = 2;
ground->CreateFixture(&fd);
}
{
b2CircleShape shape;
shape.m_radius = 0.5f;
b2BodyDef bd;
bd.type = b2_dynamicBody;
b2RevoluteJointDef rjd;
bd.position.Set(-10.0f, 20.0f);
b2Body* body = m_world->CreateBody(&bd);
body->CreateFixture(&shape, 5.0f);
float32 w = 100.0f;
body->SetAngularVelocity(w);
body->SetLinearVelocity(b2Vec2(-8.0f * w, 0.0f));
rjd.Initialize(ground, body, b2Vec2(-10.0f, 12.0f));
rjd.motorSpeed = 1.0f * b2_pi;
rjd.maxMotorTorque = 10000.0f;
rjd.enableMotor = false;
rjd.lowerAngle = -0.25f * b2_pi;
rjd.upperAngle = 0.5f * b2_pi;
rjd.enableLimit = true;
rjd.collideConnected = true;
m_joint = (b2RevoluteJoint*)m_world->CreateJoint(&rjd);
}
{
b2CircleShape circle_shape;
circle_shape.m_radius = 3.0f;
b2BodyDef circle_bd;
circle_bd.type = b2_dynamicBody;
circle_bd.position.Set(5.0f, 30.0f);
b2FixtureDef fd;
fd.density = 5.0f;
fd.filter.maskBits = 1;
fd.shape = &circle_shape;
m_ball = m_world->CreateBody(&circle_bd);
m_ball->CreateFixture(&fd);
b2PolygonShape polygon_shape;
polygon_shape.SetAsBox(10.0f, 0.2f, b2Vec2 (-10.0f, 0.0f), 0.0f);
b2BodyDef polygon_bd;
polygon_bd.position.Set(20.0f, 10.0f);
polygon_bd.type = b2_dynamicBody;
polygon_bd.bullet = true;
b2Body* polygon_body = m_world->CreateBody(&polygon_bd);
polygon_body->CreateFixture(&polygon_shape, 2.0f);
b2RevoluteJointDef rjd;
rjd.Initialize(ground, polygon_body, b2Vec2(20.0f, 10.0f));
rjd.lowerAngle = -0.25f * b2_pi;
rjd.upperAngle = 0.0f * b2_pi;
rjd.enableLimit = true;
m_world->CreateJoint(&rjd);
}
// Tests mass computation of a small object far from the origin
{
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
b2Body* body = m_world->CreateBody(&bodyDef);
b2PolygonShape polyShape;
b2Vec2 verts[3];
verts[0].Set( 17.63f, 36.31f );
verts[1].Set( 17.52f, 36.69f );
verts[2].Set( 17.19f, 36.36f );
polyShape.Set(verts, 3);
b2FixtureDef polyFixtureDef;
polyFixtureDef.shape = &polyShape;
polyFixtureDef.density = 1;
body->CreateFixture(&polyFixtureDef); //assertion hits inside here
}
}
void Keyboard(int key)
{
switch (key)
{
case GLFW_KEY_L:
m_joint->EnableLimit(!m_joint->IsLimitEnabled());
break;
case GLFW_KEY_M:
m_joint->EnableMotor(!m_joint->IsMotorEnabled());
break;
}
}
void Step(Settings* settings)
{
Test::Step(settings);
g_debugDraw.DrawString(5, m_textLine, "Keys: (l) limits, (m) motor");
m_textLine += DRAW_STRING_NEW_LINE;
//if (m_stepCount == 360)
//{
// m_ball->SetTransform(b2Vec2(0.0f, 0.5f), 0.0f);
//}
//float32 torque1 = m_joint1->GetMotorTorque();
//g_debugDraw.DrawString(5, m_textLine, "Motor Torque = %4.0f, %4.0f : Motor Force = %4.0f", (float) torque1, (float) torque2, (float) force3);
//m_textLine += DRAW_STRING_NEW_LINE;
}
static Test* Create()
{
return new Revolute;
}
b2Body* m_ball;
b2RevoluteJoint* m_joint;
};
#endif
/*
* Copyright (c) 2011 Erin Catto http://box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef ROPE_H
#define ROPE_H
///
class Rope : public Test
{
public:
Rope()
{
const int32 N = 40;
b2Vec2 vertices[N];
float32 masses[N];
for (int32 i = 0; i < N; ++i)
{
vertices[i].Set(0.0f, 20.0f - 0.25f * i);
masses[i] = 1.0f;
}
masses[0] = 0.0f;
masses[1] = 0.0f;
b2RopeDef def;
def.vertices = vertices;
def.count = N;
def.gravity.Set(0.0f, -10.0f);
def.masses = masses;
def.damping = 0.1f;
def.k2 = 1.0f;
def.k3 = 0.5f;
m_rope.Initialize(&def);
m_angle = 0.0f;
m_rope.SetAngle(m_angle);
}
void Keyboard(unsigned char key)
{
switch (key)
{
case 'q':
m_angle = b2Max(-b2_pi, m_angle - 0.05f * b2_pi);
m_rope.SetAngle(m_angle);
break;
case 'e':
m_angle = b2Min(b2_pi, m_angle + 0.05f * b2_pi);
m_rope.SetAngle(m_angle);
break;
}
}
void Step(Settings* settings)
{
float32 dt = settings->hz > 0.0f ? 1.0f / settings->hz : 0.0f;
if (settings->pause == 1 && settings->singleStep == 0)
{
dt = 0.0f;
}
m_rope.Step(dt, 1);
Test::Step(settings);
m_rope.Draw(&m_debugDraw);
m_debugDraw.DrawString(5, m_textLine, "Press (q,e) to adjust target angle");
m_textLine += DRAW_STRING_NEW_LINE;
m_debugDraw.DrawString(5, m_textLine, "Target angle = %g degrees", m_angle * 180.0f / b2_pi);
m_textLine += DRAW_STRING_NEW_LINE;
}
static Test* Create()
{
return new Rope;
}
b2Rope m_rope;
float32 m_angle;
};
#endif
/*
* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef ROPE_JOINT_H
#define ROPE_JOINT_H
/// This test shows how a rope joint can be used to stabilize a chain of
/// bodies with a heavy payload. Notice that the rope joint just prevents
/// excessive stretching and has no other effect.
/// By disabling the rope joint you can see that the Box2D solver has trouble
/// supporting heavy bodies with light bodies. Try playing around with the
/// densities, time step, and iterations to see how they affect stability.
/// This test also shows how to use contact filtering. Filtering is configured
/// so that the payload does not collide with the chain.
class RopeJoint : public Test
{
public:
RopeJoint()
{
b2Body* ground = NULL;
{
b2BodyDef bd;
ground = m_world->CreateBody(&bd);
b2EdgeShape shape;
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
ground->CreateFixture(&shape, 0.0f);
}
{
b2PolygonShape shape;
shape.SetAsBox(0.5f, 0.125f);
b2FixtureDef fd;
fd.shape = &shape;
fd.density = 20.0f;
fd.friction = 0.2f;
fd.filter.categoryBits = 0x0001;
fd.filter.maskBits = 0xFFFF & ~0x0002;
b2RevoluteJointDef jd;
jd.collideConnected = false;
const int32 N = 10;
const float32 y = 15.0f;
m_ropeDef.localAnchorA.Set(0.0f, y);
b2Body* prevBody = ground;
for (int32 i = 0; i < N; ++i)
{
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.position.Set(0.5f + 1.0f * i, y);
if (i == N - 1)
{
shape.SetAsBox(1.5f, 1.5f);
fd.density = 100.0f;
fd.filter.categoryBits = 0x0002;
bd.position.Set(1.0f * i, y);
bd.angularDamping = 0.4f;
}
b2Body* body = m_world->CreateBody(&bd);
body->CreateFixture(&fd);
b2Vec2 anchor(float32(i), y);
jd.Initialize(prevBody, body, anchor);
m_world->CreateJoint(&jd);
prevBody = body;
}
m_ropeDef.localAnchorB.SetZero();
float32 extraLength = 0.01f;
m_ropeDef.maxLength = N - 1.0f + extraLength;
m_ropeDef.bodyB = prevBody;
}
{
m_ropeDef.bodyA = ground;
m_rope = m_world->CreateJoint(&m_ropeDef);
}
}
void Keyboard(int key)
{
switch (key)
{
case GLFW_KEY_J:
if (m_rope)
{
m_world->DestroyJoint(m_rope);
m_rope = NULL;
}
else
{
m_rope = m_world->CreateJoint(&m_ropeDef);
}
break;
}
}
void Step(Settings* settings)
{
Test::Step(settings);
g_debugDraw.DrawString(5, m_textLine, "Press (j) to toggle the rope joint.");
m_textLine += DRAW_STRING_NEW_LINE;
if (m_rope)
{
g_debugDraw.DrawString(5, m_textLine, "Rope ON");
}
else
{
g_debugDraw.DrawString(5, m_textLine, "Rope OFF");
}
m_textLine += DRAW_STRING_NEW_LINE;
}
static Test* Create()
{
return new RopeJoint;
}
b2RopeJointDef m_ropeDef;
b2Joint* m_rope;
};
#endif
/*
* Copyright (c) 2008-2009 Erin Catto http://www.box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SENSOR_TEST_H
#define SENSOR_TEST_H
// This is used to test sensor shapes.
class SensorTest : public Test
{
public:
enum
{
e_count = 7
};
SensorTest()
{
{
b2BodyDef bd;
b2Body* ground = m_world->CreateBody(&bd);
{
b2EdgeShape shape;
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
ground->CreateFixture(&shape, 0.0f);
}
#if 0
{
b2FixtureDef sd;
sd.SetAsBox(10.0f, 2.0f, b2Vec2(0.0f, 20.0f), 0.0f);
sd.isSensor = true;
m_sensor = ground->CreateFixture(&sd);
}
#else
{
b2CircleShape shape;
shape.m_radius = 5.0f;
shape.m_p.Set(0.0f, 10.0f);
b2FixtureDef fd;
fd.shape = &shape;
fd.isSensor = true;
m_sensor = ground->CreateFixture(&fd);
}
#endif
}
{
b2CircleShape shape;
shape.m_radius = 1.0f;
for (int32 i = 0; i < e_count; ++i)
{
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.position.Set(-10.0f + 3.0f * i, 20.0f);
bd.userData = m_touching + i;
m_touching[i] = false;
m_bodies[i] = m_world->CreateBody(&bd);
m_bodies[i]->CreateFixture(&shape, 1.0f);
}
}
}
// Implement contact listener.
void BeginContact(b2Contact* contact)
{
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
if (fixtureA == m_sensor)
{
void* userData = fixtureB->GetBody()->GetUserData();
if (userData)
{
bool* touching = (bool*)userData;
*touching = true;
}
}
if (fixtureB == m_sensor)
{
void* userData = fixtureA->GetBody()->GetUserData();
if (userData)
{
bool* touching = (bool*)userData;
*touching = true;
}
}
}
// Implement contact listener.
void EndContact(b2Contact* contact)
{
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
if (fixtureA == m_sensor)
{
void* userData = fixtureB->GetBody()->GetUserData();
if (userData)
{
bool* touching = (bool*)userData;
*touching = false;
}
}
if (fixtureB == m_sensor)
{
void* userData = fixtureA->GetBody()->GetUserData();
if (userData)
{
bool* touching = (bool*)userData;
*touching = false;
}
}
}
void Step(Settings* settings)
{
Test::Step(settings);
// Traverse the contact results. Apply a force on shapes
// that overlap the sensor.
for (int32 i = 0; i < e_count; ++i)
{
if (m_touching[i] == false)
{
continue;
}
b2Body* body = m_bodies[i];
b2Body* ground = m_sensor->GetBody();
b2CircleShape* circle = (b2CircleShape*)m_sensor->GetShape();
b2Vec2 center = ground->GetWorldPoint(circle->m_p);
b2Vec2 position = body->GetPosition();
b2Vec2 d = center - position;
if (d.LengthSquared() < FLT_EPSILON * FLT_EPSILON)
{
continue;
}
d.Normalize();
b2Vec2 F = 100.0f * d;
body->ApplyForce(F, position, false);
}
}
static Test* Create()
{
return new SensorTest;
}
b2Fixture* m_sensor;
b2Body* m_bodies[e_count];
bool m_touching[e_count];
};
#endif
/*
* Copyright (c) 2008-2009 Erin Catto http://www.box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SHAPE_EDITING_H
#define SHAPE_EDITING_H
class ShapeEditing : public Test
{
public:
ShapeEditing()
{
{
b2BodyDef bd;
b2Body* ground = m_world->CreateBody(&bd);
b2EdgeShape shape;
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
ground->CreateFixture(&shape, 0.0f);
}
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.position.Set(0.0f, 10.0f);
m_body = m_world->CreateBody(&bd);
b2PolygonShape shape;
shape.SetAsBox(4.0f, 4.0f, b2Vec2(0.0f, 0.0f), 0.0f);
m_fixture1 = m_body->CreateFixture(&shape, 10.0f);
m_fixture2 = NULL;
m_sensor = false;
}
void Keyboard(int key)
{
switch (key)
{
case GLFW_KEY_C:
if (m_fixture2 == NULL)
{
b2CircleShape shape;
shape.m_radius = 3.0f;
shape.m_p.Set(0.5f, -4.0f);
m_fixture2 = m_body->CreateFixture(&shape, 10.0f);
m_body->SetAwake(true);
}
break;
case GLFW_KEY_D:
if (m_fixture2 != NULL)
{
m_body->DestroyFixture(m_fixture2);
m_fixture2 = NULL;
m_body->SetAwake(true);
}
break;
case GLFW_KEY_S:
if (m_fixture2 != NULL)
{
m_sensor = !m_sensor;
m_fixture2->SetSensor(m_sensor);
}
break;
}
}
void Step(Settings* settings)
{
Test::Step(settings);
g_debugDraw.DrawString(5, m_textLine, "Press: (c) create a shape, (d) destroy a shape.");
m_textLine += DRAW_STRING_NEW_LINE;
g_debugDraw.DrawString(5, m_textLine, "sensor = %d", m_sensor);
m_textLine += DRAW_STRING_NEW_LINE;
}
static Test* Create()
{
return new ShapeEditing;
}
b2Body* m_body;
b2Fixture* m_fixture1;
b2Fixture* m_fixture2;
bool m_sensor;
};
#endif
/*
Test case for collision/jerking issue.
*/
#ifndef SKIER_H
#define SKIER_H
#include <vector>
#include <iostream>
class Skier : public Test
{
public:
Skier()
{
b2Body* ground = NULL;
{
b2BodyDef bd;
ground = m_world->CreateBody(&bd);
float const PlatformWidth = 8.0f;
/*
First angle is from the horizontal and should be negative for a downward slope.
Second angle is relative to the preceding slope, and should be positive, creating a kind of
loose 'Z'-shape from the 3 edges.
If A1 = -10, then A2 <= ~1.5 will result in the collision glitch.
If A1 = -30, then A2 <= ~10.0 will result in the glitch.
*/
float const Angle1Degrees = -30.0f;
float const Angle2Degrees = 10.0f;
/*
The larger the value of SlopeLength, the less likely the glitch will show up.
*/
float const SlopeLength = 2.0f;
float const SurfaceFriction = 0.2f;
// Convert to radians
float const Slope1Incline = -Angle1Degrees * b2_pi / 180.0f;
float const Slope2Incline = Slope1Incline - Angle2Degrees * b2_pi / 180.0f;
//
m_platform_width = PlatformWidth;
std::vector< b2Vec2 > verts;
// Horizontal platform
verts.emplace_back(-PlatformWidth, 0.0f);
verts.emplace_back(0.0f, 0.0f);
// Slope
verts.emplace_back(
verts.back().x + SlopeLength * cosf(Slope1Incline),
verts.back().y - SlopeLength * sinf(Slope1Incline)
);
verts.emplace_back(
verts.back().x + SlopeLength * cosf(Slope2Incline),
verts.back().y - SlopeLength * sinf(Slope2Incline)
);
{
b2EdgeShape shape;
shape.Set(verts[0], verts[1]);
shape.m_hasVertex3 = true;
shape.m_vertex3 = verts[2];
b2FixtureDef fd;
fd.shape = &shape;
fd.density = 0.0f;
fd.friction = SurfaceFriction;
ground->CreateFixture(&fd);
}
{
b2EdgeShape shape;
shape.Set(verts[1], verts[2]);
shape.m_hasVertex0 = true;
shape.m_hasVertex3 = true;
shape.m_vertex0 = verts[0];
shape.m_vertex3 = verts[3];
b2FixtureDef fd;
fd.shape = &shape;
fd.density = 0.0f;
fd.friction = SurfaceFriction;
ground->CreateFixture(&fd);
}
{
b2EdgeShape shape;
shape.Set(verts[2], verts[3]);
shape.m_hasVertex0 = true;
shape.m_vertex0 = verts[1];
b2FixtureDef fd;
fd.shape = &shape;
fd.density = 0.0f;
fd.friction = SurfaceFriction;
ground->CreateFixture(&fd);
}
}
{
bool const EnableCircularSkiTips = false;
float const BodyWidth = 1.0f;
float const BodyHeight = 2.5f;
float const SkiLength = 3.0f;
/*
Larger values for this seem to alleviate the issue to some extent.
*/
float const SkiThickness = 0.3f;
float const SkiFriction = 0.0f;
float const SkiRestitution = 0.15f;
b2BodyDef bd;
bd.type = b2_dynamicBody;
float initial_y = BodyHeight / 2 + SkiThickness;
if(EnableCircularSkiTips)
{
initial_y += SkiThickness / 6;
}
bd.position.Set(-m_platform_width / 2, initial_y);
b2Body* skier = m_world->CreateBody(&bd);
b2PolygonShape body;
body.SetAsBox(BodyWidth / 2, BodyHeight / 2);
b2PolygonShape ski;
std::vector< b2Vec2 > verts;
verts.emplace_back(-SkiLength / 2 - SkiThickness, -BodyHeight / 2);
verts.emplace_back(-SkiLength / 2, -BodyHeight / 2 - SkiThickness);
verts.emplace_back(SkiLength / 2, -BodyHeight / 2 - SkiThickness);
verts.emplace_back(SkiLength / 2 + SkiThickness, -BodyHeight / 2);
ski.Set(verts.data(), (int32)verts.size());
b2CircleShape ski_back_shape;
ski_back_shape.m_p.Set(-SkiLength / 2.0f, -BodyHeight / 2 - SkiThickness * (2.0f / 3));
ski_back_shape.m_radius = SkiThickness / 2;
b2CircleShape ski_front_shape;
ski_front_shape.m_p.Set(SkiLength / 2, -BodyHeight / 2 - SkiThickness * (2.0f / 3));
ski_front_shape.m_radius = SkiThickness / 2;
b2FixtureDef fd;
fd.shape = &body;
fd.density = 1.0f;
skier->CreateFixture(&fd);
fd.friction = SkiFriction;
fd.restitution = SkiRestitution;
fd.shape = &ski;
skier->CreateFixture(&fd);
if(EnableCircularSkiTips)
{
fd.shape = &ski_back_shape;
skier->CreateFixture(&fd);
fd.shape = &ski_front_shape;
skier->CreateFixture(&fd);
}
skier->SetLinearVelocity(b2Vec2(0.5f, 0.0f));
m_skier = skier;
}
g_camera.m_center = b2Vec2(m_platform_width / 2.0f, 0.0f);
g_camera.m_zoom = 0.4f;
m_fixed_camera = true;
}
void Keyboard(int key)
{
switch (key)
{
case GLFW_KEY_C:
m_fixed_camera = !m_fixed_camera;
if(m_fixed_camera)
{
g_camera.m_center = b2Vec2(m_platform_width / 2.0f, 0.0f);
}
break;
}
}
void Step(Settings* settings)
{
g_debugDraw.DrawString(5, m_textLine, "Keys: c = Camera fixed/tracking");
m_textLine += DRAW_STRING_NEW_LINE;
if(!m_fixed_camera)
{
g_camera.m_center = m_skier->GetPosition();
}
Test::Step(settings);
}
static Test* Create()
{
return new Skier;
}
b2Body* m_skier;
float m_platform_width;
bool m_fixed_camera;
};
#endif
/*
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SLIDER_CRANK_H
#define SLIDER_CRANK_H
// A motor driven slider crank with joint friction.
class SliderCrank : public Test
{
public:
SliderCrank()
{
b2Body* ground = NULL;
{
b2BodyDef bd;
ground = m_world->CreateBody(&bd);
b2EdgeShape shape;
shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
ground->CreateFixture(&shape, 0.0f);
}
{
b2Body* prevBody = ground;
// Define crank.
{
b2PolygonShape shape;
shape.SetAsBox(0.5f, 2.0f);
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.position.Set(0.0f, 7.0f);
b2Body* body = m_world->CreateBody(&bd);
body->CreateFixture(&shape, 2.0f);
b2RevoluteJointDef rjd;
rjd.Initialize(prevBody, body, b2Vec2(0.0f, 5.0f));
rjd.motorSpeed = 1.0f * b2_pi;
rjd.maxMotorTorque = 10000.0f;
rjd.enableMotor = true;
m_joint1 = (b2RevoluteJoint*)m_world->CreateJoint(&rjd);
prevBody = body;
}
// Define follower.
{
b2PolygonShape shape;
shape.SetAsBox(0.5f, 4.0f);
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.position.Set(0.0f, 13.0f);
b2Body* body = m_world->CreateBody(&bd);
body->CreateFixture(&shape, 2.0f);
b2RevoluteJointDef rjd;
rjd.Initialize(prevBody, body, b2Vec2(0.0f, 9.0f));
rjd.enableMotor = false;
m_world->CreateJoint(&rjd);
prevBody = body;
}
// Define piston
{
b2PolygonShape shape;
shape.SetAsBox(1.5f, 1.5f);
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.fixedRotation = true;
bd.position.Set(0.0f, 17.0f);
b2Body* body = m_world->CreateBody(&bd);
body->CreateFixture(&shape, 2.0f);
b2RevoluteJointDef rjd;
rjd.Initialize(prevBody, body, b2Vec2(0.0f, 17.0f));
m_world->CreateJoint(&rjd);
b2PrismaticJointDef pjd;
pjd.Initialize(ground, body, b2Vec2(0.0f, 17.0f), b2Vec2(0.0f, 1.0f));
pjd.maxMotorForce = 1000.0f;
pjd.enableMotor = true;
m_joint2 = (b2PrismaticJoint*)m_world->CreateJoint(&pjd);
}
// Create a payload
{
b2PolygonShape shape;
shape.SetAsBox(1.5f, 1.5f);
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.position.Set(0.0f, 23.0f);
b2Body* body = m_world->CreateBody(&bd);
body->CreateFixture(&shape, 2.0f);
}
}
}
void Keyboard(int key)
{
switch (key)
{
case GLFW_KEY_F:
m_joint2->EnableMotor(!m_joint2->IsMotorEnabled());
m_joint2->GetBodyB()->SetAwake(true);
break;
case GLFW_KEY_M:
m_joint1->EnableMotor(!m_joint1->IsMotorEnabled());
m_joint1->GetBodyB()->SetAwake(true);
break;
}
}
void Step(Settings* settings)
{
Test::Step(settings);
g_debugDraw.DrawString(5, m_textLine, "Keys: (f) toggle friction, (m) toggle motor");
m_textLine += DRAW_STRING_NEW_LINE;
float32 torque = m_joint1->GetMotorTorque(settings->hz);
g_debugDraw.DrawString(5, m_textLine, "Motor Torque = %5.0f", (float) torque);
m_textLine += DRAW_STRING_NEW_LINE;
}
static Test* Create()
{
return new SliderCrank;
}
b2RevoluteJoint* m_joint1;
b2PrismaticJoint* m_joint2;
};
#endif