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.

254 lines
7.9KB

  1. /*
  2. * Copyright (c) 2006-2010 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 CHARACTER_COLLISION_H
  19. #define CHARACTER_COLLISION_H
  20. /// This is a test of typical character collision scenarios. This does not
  21. /// show how you should implement a character in your application.
  22. /// Instead this is used to test smooth collision on edge chains.
  23. class CharacterCollision : public Test
  24. {
  25. public:
  26. CharacterCollision()
  27. {
  28. // Ground body
  29. {
  30. b2BodyDef bd;
  31. b2Body* ground = m_world->CreateBody(&bd);
  32. b2EdgeShape shape;
  33. shape.Set(b2Vec2(-20.0f, 0.0f), b2Vec2(20.0f, 0.0f));
  34. ground->CreateFixture(&shape, 0.0f);
  35. }
  36. // Collinear edges with no adjacency information.
  37. // This shows the problematic case where a box shape can hit
  38. // an internal vertex.
  39. {
  40. b2BodyDef bd;
  41. b2Body* ground = m_world->CreateBody(&bd);
  42. b2EdgeShape shape;
  43. shape.Set(b2Vec2(-8.0f, 1.0f), b2Vec2(-6.0f, 1.0f));
  44. ground->CreateFixture(&shape, 0.0f);
  45. shape.Set(b2Vec2(-6.0f, 1.0f), b2Vec2(-4.0f, 1.0f));
  46. ground->CreateFixture(&shape, 0.0f);
  47. shape.Set(b2Vec2(-4.0f, 1.0f), b2Vec2(-2.0f, 1.0f));
  48. ground->CreateFixture(&shape, 0.0f);
  49. }
  50. // Chain shape
  51. {
  52. b2BodyDef bd;
  53. bd.angle = 0.25f * b2_pi;
  54. b2Body* ground = m_world->CreateBody(&bd);
  55. b2Vec2 vs[4];
  56. vs[0].Set(5.0f, 7.0f);
  57. vs[1].Set(6.0f, 8.0f);
  58. vs[2].Set(7.0f, 8.0f);
  59. vs[3].Set(8.0f, 7.0f);
  60. b2ChainShape shape;
  61. shape.CreateChain(vs, 4);
  62. ground->CreateFixture(&shape, 0.0f);
  63. }
  64. // Square tiles. This shows that adjacency shapes may
  65. // have non-smooth collision. There is no solution
  66. // to this problem.
  67. {
  68. b2BodyDef bd;
  69. b2Body* ground = m_world->CreateBody(&bd);
  70. b2PolygonShape shape;
  71. shape.SetAsBox(1.0f, 1.0f, b2Vec2(4.0f, 3.0f), 0.0f);
  72. ground->CreateFixture(&shape, 0.0f);
  73. shape.SetAsBox(1.0f, 1.0f, b2Vec2(6.0f, 3.0f), 0.0f);
  74. ground->CreateFixture(&shape, 0.0f);
  75. shape.SetAsBox(1.0f, 1.0f, b2Vec2(8.0f, 3.0f), 0.0f);
  76. ground->CreateFixture(&shape, 0.0f);
  77. }
  78. // Square made from an edge loop. Collision should be smooth.
  79. {
  80. b2BodyDef bd;
  81. b2Body* ground = m_world->CreateBody(&bd);
  82. b2Vec2 vs[4];
  83. vs[0].Set(-1.0f, 3.0f);
  84. vs[1].Set(1.0f, 3.0f);
  85. vs[2].Set(1.0f, 5.0f);
  86. vs[3].Set(-1.0f, 5.0f);
  87. b2ChainShape shape;
  88. shape.CreateLoop(vs, 4);
  89. ground->CreateFixture(&shape, 0.0f);
  90. }
  91. // Edge loop. Collision should be smooth.
  92. {
  93. b2BodyDef bd;
  94. bd.position.Set(-10.0f, 4.0f);
  95. b2Body* ground = m_world->CreateBody(&bd);
  96. b2Vec2 vs[10];
  97. vs[0].Set(0.0f, 0.0f);
  98. vs[1].Set(6.0f, 0.0f);
  99. vs[2].Set(6.0f, 2.0f);
  100. vs[3].Set(4.0f, 1.0f);
  101. vs[4].Set(2.0f, 2.0f);
  102. vs[5].Set(0.0f, 2.0f);
  103. vs[6].Set(-2.0f, 2.0f);
  104. vs[7].Set(-4.0f, 3.0f);
  105. vs[8].Set(-6.0f, 2.0f);
  106. vs[9].Set(-6.0f, 0.0f);
  107. b2ChainShape shape;
  108. shape.CreateLoop(vs, 10);
  109. ground->CreateFixture(&shape, 0.0f);
  110. }
  111. // Square character 1
  112. {
  113. b2BodyDef bd;
  114. bd.position.Set(-3.0f, 8.0f);
  115. bd.type = b2_dynamicBody;
  116. bd.fixedRotation = true;
  117. bd.allowSleep = false;
  118. b2Body* body = m_world->CreateBody(&bd);
  119. b2PolygonShape shape;
  120. shape.SetAsBox(0.5f, 0.5f);
  121. b2FixtureDef fd;
  122. fd.shape = &shape;
  123. fd.density = 20.0f;
  124. body->CreateFixture(&fd);
  125. }
  126. // Square character 2
  127. {
  128. b2BodyDef bd;
  129. bd.position.Set(-5.0f, 5.0f);
  130. bd.type = b2_dynamicBody;
  131. bd.fixedRotation = true;
  132. bd.allowSleep = false;
  133. b2Body* body = m_world->CreateBody(&bd);
  134. b2PolygonShape shape;
  135. shape.SetAsBox(0.25f, 0.25f);
  136. b2FixtureDef fd;
  137. fd.shape = &shape;
  138. fd.density = 20.0f;
  139. body->CreateFixture(&fd);
  140. }
  141. // Hexagon character
  142. {
  143. b2BodyDef bd;
  144. bd.position.Set(-5.0f, 8.0f);
  145. bd.type = b2_dynamicBody;
  146. bd.fixedRotation = true;
  147. bd.allowSleep = false;
  148. b2Body* body = m_world->CreateBody(&bd);
  149. float32 angle = 0.0f;
  150. float32 delta = b2_pi / 3.0f;
  151. b2Vec2 vertices[6];
  152. for (int32 i = 0; i < 6; ++i)
  153. {
  154. vertices[i].Set(0.5f * cosf(angle), 0.5f * sinf(angle));
  155. angle += delta;
  156. }
  157. b2PolygonShape shape;
  158. shape.Set(vertices, 6);
  159. b2FixtureDef fd;
  160. fd.shape = &shape;
  161. fd.density = 20.0f;
  162. body->CreateFixture(&fd);
  163. }
  164. // Circle character
  165. {
  166. b2BodyDef bd;
  167. bd.position.Set(3.0f, 5.0f);
  168. bd.type = b2_dynamicBody;
  169. bd.fixedRotation = true;
  170. bd.allowSleep = false;
  171. b2Body* body = m_world->CreateBody(&bd);
  172. b2CircleShape shape;
  173. shape.m_radius = 0.5f;
  174. b2FixtureDef fd;
  175. fd.shape = &shape;
  176. fd.density = 20.0f;
  177. body->CreateFixture(&fd);
  178. }
  179. // Circle character
  180. {
  181. b2BodyDef bd;
  182. bd.position.Set(-7.0f, 6.0f);
  183. bd.type = b2_dynamicBody;
  184. bd.allowSleep = false;
  185. m_character = m_world->CreateBody(&bd);
  186. b2CircleShape shape;
  187. shape.m_radius = 0.25f;
  188. b2FixtureDef fd;
  189. fd.shape = &shape;
  190. fd.density = 20.0f;
  191. fd.friction = 1.0f;
  192. m_character->CreateFixture(&fd);
  193. }
  194. }
  195. void Step(Settings* settings)
  196. {
  197. b2Vec2 v = m_character->GetLinearVelocity();
  198. v.x = -5.0f;
  199. m_character->SetLinearVelocity(v);
  200. Test::Step(settings);
  201. m_debugDraw.DrawString(5, m_textLine, "This tests various character collision shapes.");
  202. m_textLine += 15;
  203. m_debugDraw.DrawString(5, m_textLine, "Limitation: square and hexagon can snag on aligned boxes.");
  204. m_textLine += 15;
  205. m_debugDraw.DrawString(5, m_textLine, "Feature: edge chains have smooth collision inside and out.");
  206. m_textLine += 15;
  207. }
  208. static Test* Create()
  209. {
  210. return new CharacterCollision;
  211. }
  212. b2Body* m_character;
  213. };
  214. #endif