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 SLIDER_CRANK_H
20 #define SLIDER_CRANK_H
21 
22 // A motor driven slider crank with joint friction.
23 
24 class SliderCrank : public Test
25 {
26 public:
SliderCrank()27 	SliderCrank()
28 	{
29 		b2Body* ground = NULL;
30 		{
31 			b2BodyDef bd;
32 			ground = m_world->CreateBody(&bd);
33 
34 			b2EdgeShape shape;
35 			shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
36 			ground->CreateFixture(&shape, 0.0f);
37 		}
38 
39 		{
40 			b2Body* prevBody = ground;
41 
42 			// Define crank.
43 			{
44 				b2PolygonShape shape;
45 				shape.SetAsBox(0.5f, 2.0f);
46 
47 				b2BodyDef bd;
48 				bd.type = b2_dynamicBody;
49 				bd.position.Set(0.0f, 7.0f);
50 				b2Body* body = m_world->CreateBody(&bd);
51 				body->CreateFixture(&shape, 2.0f);
52 
53 				b2RevoluteJointDef rjd;
54 				rjd.Initialize(prevBody, body, b2Vec2(0.0f, 5.0f));
55 				rjd.motorSpeed = 1.0f * b2_pi;
56 				rjd.maxMotorTorque = 10000.0f;
57 				rjd.enableMotor = true;
58 				m_joint1 = (b2RevoluteJoint*)m_world->CreateJoint(&rjd);
59 
60 				prevBody = body;
61 			}
62 
63 			// Define follower.
64 			{
65 				b2PolygonShape shape;
66 				shape.SetAsBox(0.5f, 4.0f);
67 
68 				b2BodyDef bd;
69 				bd.type = b2_dynamicBody;
70 				bd.position.Set(0.0f, 13.0f);
71 				b2Body* body = m_world->CreateBody(&bd);
72 				body->CreateFixture(&shape, 2.0f);
73 
74 				b2RevoluteJointDef rjd;
75 				rjd.Initialize(prevBody, body, b2Vec2(0.0f, 9.0f));
76 				rjd.enableMotor = false;
77 				m_world->CreateJoint(&rjd);
78 
79 				prevBody = body;
80 			}
81 
82 			// Define piston
83 			{
84 				b2PolygonShape shape;
85 				shape.SetAsBox(1.5f, 1.5f);
86 
87 				b2BodyDef bd;
88 				bd.type = b2_dynamicBody;
89 				bd.fixedRotation = true;
90 				bd.position.Set(0.0f, 17.0f);
91 				b2Body* body = m_world->CreateBody(&bd);
92 				body->CreateFixture(&shape, 2.0f);
93 
94 				b2RevoluteJointDef rjd;
95 				rjd.Initialize(prevBody, body, b2Vec2(0.0f, 17.0f));
96 				m_world->CreateJoint(&rjd);
97 
98 				b2PrismaticJointDef pjd;
99 				pjd.Initialize(ground, body, b2Vec2(0.0f, 17.0f), b2Vec2(0.0f, 1.0f));
100 
101 				pjd.maxMotorForce = 1000.0f;
102 				pjd.enableMotor = true;
103 
104 				m_joint2 = (b2PrismaticJoint*)m_world->CreateJoint(&pjd);
105 			}
106 
107 			// Create a payload
108 			{
109 				b2PolygonShape shape;
110 				shape.SetAsBox(1.5f, 1.5f);
111 
112 				b2BodyDef bd;
113 				bd.type = b2_dynamicBody;
114 				bd.position.Set(0.0f, 23.0f);
115 				b2Body* body = m_world->CreateBody(&bd);
116 				body->CreateFixture(&shape, 2.0f);
117 			}
118 		}
119 	}
120 
Keyboard(int key)121 	void Keyboard(int key)
122 	{
123 		switch (key)
124 		{
125 		case GLFW_KEY_F:
126 			m_joint2->EnableMotor(!m_joint2->IsMotorEnabled());
127 			m_joint2->GetBodyB()->SetAwake(true);
128 			break;
129 
130 		case GLFW_KEY_M:
131 			m_joint1->EnableMotor(!m_joint1->IsMotorEnabled());
132 			m_joint1->GetBodyB()->SetAwake(true);
133 			break;
134 		}
135 	}
136 
Step(Settings * settings)137 	void Step(Settings* settings)
138 	{
139 		Test::Step(settings);
140 		g_debugDraw.DrawString(5, m_textLine, "Keys: (f) toggle friction, (m) toggle motor");
141 		m_textLine += DRAW_STRING_NEW_LINE;
142 		float32 torque = m_joint1->GetMotorTorque(settings->hz);
143 		g_debugDraw.DrawString(5, m_textLine, "Motor Torque = %5.0f", (float) torque);
144 		m_textLine += DRAW_STRING_NEW_LINE;
145 	}
146 
Create()147 	static Test* Create()
148 	{
149 		return new SliderCrank;
150 	}
151 
152 	b2RevoluteJoint* m_joint1;
153 	b2PrismaticJoint* m_joint2;
154 };
155 
156 #endif
157