The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
8.5KB

  1. /*
  2. * Copyright (c) 2006-2011 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. #ifndef CAR_H
  19. #define CAR_H
  20. // This is a fun demo that shows off the wheel joint
  21. class Car : public Test
  22. {
  23. public:
  24. Car()
  25. {
  26. m_hz = 4.0f;
  27. m_zeta = 0.7f;
  28. m_speed = 50.0f;
  29. b2Body* ground = NULL;
  30. {
  31. b2BodyDef bd;
  32. ground = m_world->CreateBody(&bd);
  33. b2EdgeShape shape;
  34. b2FixtureDef fd;
  35. fd.shape = &shape;
  36. fd.density = 0.0f;
  37. fd.friction = 0.6f;
  38. shape.Set(b2Vec2(-20.0f, 0.0f), b2Vec2(20.0f, 0.0f));
  39. ground->CreateFixture(&fd);
  40. float32 hs[10] = {0.25f, 1.0f, 4.0f, 0.0f, 0.0f, -1.0f, -2.0f, -2.0f, -1.25f, 0.0f};
  41. float32 x = 20.0f, y1 = 0.0f, dx = 5.0f;
  42. for (int32 i = 0; i < 10; ++i)
  43. {
  44. float32 y2 = hs[i];
  45. shape.Set(b2Vec2(x, y1), b2Vec2(x + dx, y2));
  46. ground->CreateFixture(&fd);
  47. y1 = y2;
  48. x += dx;
  49. }
  50. for (int32 i = 0; i < 10; ++i)
  51. {
  52. float32 y2 = hs[i];
  53. shape.Set(b2Vec2(x, y1), b2Vec2(x + dx, y2));
  54. ground->CreateFixture(&fd);
  55. y1 = y2;
  56. x += dx;
  57. }
  58. shape.Set(b2Vec2(x, 0.0f), b2Vec2(x + 40.0f, 0.0f));
  59. ground->CreateFixture(&fd);
  60. x += 80.0f;
  61. shape.Set(b2Vec2(x, 0.0f), b2Vec2(x + 40.0f, 0.0f));
  62. ground->CreateFixture(&fd);
  63. x += 40.0f;
  64. shape.Set(b2Vec2(x, 0.0f), b2Vec2(x + 10.0f, 5.0f));
  65. ground->CreateFixture(&fd);
  66. x += 20.0f;
  67. shape.Set(b2Vec2(x, 0.0f), b2Vec2(x + 40.0f, 0.0f));
  68. ground->CreateFixture(&fd);
  69. x += 40.0f;
  70. shape.Set(b2Vec2(x, 0.0f), b2Vec2(x, 20.0f));
  71. ground->CreateFixture(&fd);
  72. }
  73. // Teeter
  74. {
  75. b2BodyDef bd;
  76. bd.position.Set(140.0f, 1.0f);
  77. bd.type = b2_dynamicBody;
  78. b2Body* body = m_world->CreateBody(&bd);
  79. b2PolygonShape box;
  80. box.SetAsBox(10.0f, 0.25f);
  81. body->CreateFixture(&box, 1.0f);
  82. b2RevoluteJointDef jd;
  83. jd.Initialize(ground, body, body->GetPosition());
  84. jd.lowerAngle = -8.0f * b2_pi / 180.0f;
  85. jd.upperAngle = 8.0f * b2_pi / 180.0f;
  86. jd.enableLimit = true;
  87. m_world->CreateJoint(&jd);
  88. body->ApplyAngularImpulse(100.0f);
  89. }
  90. // Bridge
  91. {
  92. int32 N = 20;
  93. b2PolygonShape shape;
  94. shape.SetAsBox(1.0f, 0.125f);
  95. b2FixtureDef fd;
  96. fd.shape = &shape;
  97. fd.density = 1.0f;
  98. fd.friction = 0.6f;
  99. b2RevoluteJointDef jd;
  100. b2Body* prevBody = ground;
  101. for (int32 i = 0; i < N; ++i)
  102. {
  103. b2BodyDef bd;
  104. bd.type = b2_dynamicBody;
  105. bd.position.Set(161.0f + 2.0f * i, -0.125f);
  106. b2Body* body = m_world->CreateBody(&bd);
  107. body->CreateFixture(&fd);
  108. b2Vec2 anchor(160.0f + 2.0f * i, -0.125f);
  109. jd.Initialize(prevBody, body, anchor);
  110. m_world->CreateJoint(&jd);
  111. prevBody = body;
  112. }
  113. b2Vec2 anchor(160.0f + 2.0f * N, -0.125f);
  114. jd.Initialize(prevBody, ground, anchor);
  115. m_world->CreateJoint(&jd);
  116. }
  117. // Boxes
  118. {
  119. b2PolygonShape box;
  120. box.SetAsBox(0.5f, 0.5f);
  121. b2Body* body = NULL;
  122. b2BodyDef bd;
  123. bd.type = b2_dynamicBody;
  124. bd.position.Set(230.0f, 0.5f);
  125. body = m_world->CreateBody(&bd);
  126. body->CreateFixture(&box, 0.5f);
  127. bd.position.Set(230.0f, 1.5f);
  128. body = m_world->CreateBody(&bd);
  129. body->CreateFixture(&box, 0.5f);
  130. bd.position.Set(230.0f, 2.5f);
  131. body = m_world->CreateBody(&bd);
  132. body->CreateFixture(&box, 0.5f);
  133. bd.position.Set(230.0f, 3.5f);
  134. body = m_world->CreateBody(&bd);
  135. body->CreateFixture(&box, 0.5f);
  136. bd.position.Set(230.0f, 4.5f);
  137. body = m_world->CreateBody(&bd);
  138. body->CreateFixture(&box, 0.5f);
  139. }
  140. // Car
  141. {
  142. b2PolygonShape chassis;
  143. b2Vec2 vertices[8];
  144. vertices[0].Set(-1.5f, -0.5f);
  145. vertices[1].Set(1.5f, -0.5f);
  146. vertices[2].Set(1.5f, 0.0f);
  147. vertices[3].Set(0.0f, 0.9f);
  148. vertices[4].Set(-1.15f, 0.9f);
  149. vertices[5].Set(-1.5f, 0.2f);
  150. chassis.Set(vertices, 6);
  151. b2CircleShape circle;
  152. circle.m_radius = 0.4f;
  153. b2BodyDef bd;
  154. bd.type = b2_dynamicBody;
  155. bd.position.Set(0.0f, 1.0f);
  156. m_car = m_world->CreateBody(&bd);
  157. m_car->CreateFixture(&chassis, 1.0f);
  158. b2FixtureDef fd;
  159. fd.shape = &circle;
  160. fd.density = 1.0f;
  161. fd.friction = 0.9f;
  162. bd.position.Set(-1.0f, 0.35f);
  163. m_wheel1 = m_world->CreateBody(&bd);
  164. m_wheel1->CreateFixture(&fd);
  165. bd.position.Set(1.0f, 0.4f);
  166. m_wheel2 = m_world->CreateBody(&bd);
  167. m_wheel2->CreateFixture(&fd);
  168. b2WheelJointDef jd;
  169. b2Vec2 axis(0.0f, 1.0f);
  170. jd.Initialize(m_car, m_wheel1, m_wheel1->GetPosition(), axis);
  171. jd.motorSpeed = 0.0f;
  172. jd.maxMotorTorque = 20.0f;
  173. jd.enableMotor = true;
  174. jd.frequencyHz = m_hz;
  175. jd.dampingRatio = m_zeta;
  176. m_spring1 = (b2WheelJoint*)m_world->CreateJoint(&jd);
  177. jd.Initialize(m_car, m_wheel2, m_wheel2->GetPosition(), axis);
  178. jd.motorSpeed = 0.0f;
  179. jd.maxMotorTorque = 10.0f;
  180. jd.enableMotor = false;
  181. jd.frequencyHz = m_hz;
  182. jd.dampingRatio = m_zeta;
  183. m_spring2 = (b2WheelJoint*)m_world->CreateJoint(&jd);
  184. }
  185. }
  186. void Keyboard(unsigned char key)
  187. {
  188. switch (key)
  189. {
  190. case 'a':
  191. m_spring1->SetMotorSpeed(m_speed);
  192. break;
  193. case 's':
  194. m_spring1->SetMotorSpeed(0.0f);
  195. break;
  196. case 'd':
  197. m_spring1->SetMotorSpeed(-m_speed);
  198. break;
  199. case 'q':
  200. m_hz = b2Max(0.0f, m_hz - 1.0f);
  201. m_spring1->SetSpringFrequencyHz(m_hz);
  202. m_spring2->SetSpringFrequencyHz(m_hz);
  203. break;
  204. case 'e':
  205. m_hz += 1.0f;
  206. m_spring1->SetSpringFrequencyHz(m_hz);
  207. m_spring2->SetSpringFrequencyHz(m_hz);
  208. break;
  209. }
  210. }
  211. void Step(Settings* settings)
  212. {
  213. m_debugDraw.DrawString(5, m_textLine, "Keys: left = a, brake = s, right = d, hz down = q, hz up = e");
  214. m_textLine += 15;
  215. m_debugDraw.DrawString(5, m_textLine, "frequency = %g hz, damping ratio = %g", m_hz, m_zeta);
  216. m_textLine += 15;
  217. settings->viewCenter.x = m_car->GetPosition().x;
  218. Test::Step(settings);
  219. }
  220. static Test* Create()
  221. {
  222. return new Car;
  223. }
  224. b2Body* m_car;
  225. b2Body* m_wheel1;
  226. b2Body* m_wheel2;
  227. float32 m_hz;
  228. float32 m_zeta;
  229. float32 m_speed;
  230. b2WheelJoint* m_spring1;
  231. b2WheelJoint* m_spring2;
  232. };
  233. #endif