PolyShapes.h
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:7k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /*
  2. * Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
  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 POLY_SHAPES_H
  19. #define POLY_SHAPES_H
  20. /// This tests stacking. It also shows how to use b2World::Query
  21. /// and b2TestOverlap.
  22. const int32 k_maxBodies = 256;
  23. /// This callback is called by b2World::QueryAABB. We find all the fixtures
  24. /// that overlap an AABB. Of those, we use b2TestOverlap to determine which fixtures
  25. /// overlap a circle. Up to 4 overlapped fixtures will be highlighted with a yellow border.
  26. class PolyShapesCallback : public b2QueryCallback
  27. {
  28. public:
  29. enum
  30. {
  31. e_maxCount = 4
  32. };
  33. PolyShapesCallback()
  34. {
  35. m_count = 0;
  36. }
  37. void DrawFixture(b2Fixture* fixture)
  38. {
  39. b2Color color(0.95f, 0.95f, 0.6f);
  40. const b2Transform& xf = fixture->GetBody()->GetTransform();
  41. switch (fixture->GetType())
  42. {
  43. case b2Shape::e_circle:
  44. {
  45. b2CircleShape* circle = (b2CircleShape*)fixture->GetShape();
  46. b2Vec2 center = b2Mul(xf, circle->m_p);
  47. float32 radius = circle->m_radius;
  48. m_debugDraw->DrawCircle(center, radius, color);
  49. }
  50. break;
  51. case b2Shape::e_polygon:
  52. {
  53. b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape();
  54. int32 vertexCount = poly->m_vertexCount;
  55. b2Assert(vertexCount <= b2_maxPolygonVertices);
  56. b2Vec2 vertices[b2_maxPolygonVertices];
  57. for (int32 i = 0; i < vertexCount; ++i)
  58. {
  59. vertices[i] = b2Mul(xf, poly->m_vertices[i]);
  60. }
  61. m_debugDraw->DrawPolygon(vertices, vertexCount, color);
  62. }
  63. break;
  64. }
  65. }
  66. /// Called for each fixture found in the query AABB.
  67. /// @return false to terminate the query.
  68. bool ReportFixture(b2Fixture* fixture)
  69. {
  70. if (m_count == e_maxCount)
  71. {
  72. return false;
  73. }
  74. b2Body* body = fixture->GetBody();
  75. b2Shape* shape = fixture->GetShape();
  76. bool overlap = b2TestOverlap(shape, &m_circle, body->GetTransform(), m_transform);
  77. if (overlap)
  78. {
  79. DrawFixture(fixture);
  80. ++m_count;
  81. }
  82. return true;
  83. }
  84. b2CircleShape m_circle;
  85. b2Transform m_transform;
  86. b2DebugDraw* m_debugDraw;
  87. int32 m_count;
  88. };
  89. class PolyShapes : public Test
  90. {
  91. public:
  92. PolyShapes()
  93. {
  94. // Ground body
  95. {
  96. b2BodyDef bd;
  97. b2Body* ground = m_world->CreateBody(&bd);
  98. b2PolygonShape shape;
  99. shape.SetAsEdge(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
  100. ground->CreateFixture(&shape, 0.0f);
  101. }
  102. {
  103. b2Vec2 vertices[3];
  104. vertices[0].Set(-0.5f, 0.0f);
  105. vertices[1].Set(0.5f, 0.0f);
  106. vertices[2].Set(0.0f, 1.5f);
  107. m_polygons[0].Set(vertices, 3);
  108. }
  109. {
  110. b2Vec2 vertices[3];
  111. vertices[0].Set(-0.1f, 0.0f);
  112. vertices[1].Set(0.1f, 0.0f);
  113. vertices[2].Set(0.0f, 1.5f);
  114. m_polygons[1].Set(vertices, 3);
  115. }
  116. {
  117. float32 w = 1.0f;
  118. float32 b = w / (2.0f + sqrtf(2.0f));
  119. float32 s = sqrtf(2.0f) * b;
  120. b2Vec2 vertices[8];
  121. vertices[0].Set(0.5f * s, 0.0f);
  122. vertices[1].Set(0.5f * w, b);
  123. vertices[2].Set(0.5f * w, b + s);
  124. vertices[3].Set(0.5f * s, w);
  125. vertices[4].Set(-0.5f * s, w);
  126. vertices[5].Set(-0.5f * w, b + s);
  127. vertices[6].Set(-0.5f * w, b);
  128. vertices[7].Set(-0.5f * s, 0.0f);
  129. m_polygons[2].Set(vertices, 8);
  130. }
  131. {
  132. m_polygons[3].SetAsBox(0.5f, 0.5f);
  133. }
  134. {
  135. m_circle.m_radius = 0.5f;
  136. }
  137. m_bodyIndex = 0;
  138. memset(m_bodies, 0, sizeof(m_bodies));
  139. }
  140. void Create(int32 index)
  141. {
  142. if (m_bodies[m_bodyIndex] != NULL)
  143. {
  144. m_world->DestroyBody(m_bodies[m_bodyIndex]);
  145. m_bodies[m_bodyIndex] = NULL;
  146. }
  147. b2BodyDef bd;
  148. bd.type = b2_dynamicBody;
  149. float32 x = RandomFloat(-2.0f, 2.0f);
  150. bd.position.Set(x, 10.0f);
  151. bd.angle = RandomFloat(-b2_pi, b2_pi);
  152. if (index == 4)
  153. {
  154. bd.angularDamping = 0.02f;
  155. }
  156. m_bodies[m_bodyIndex] = m_world->CreateBody(&bd);
  157. if (index < 4)
  158. {
  159. b2FixtureDef fd;
  160. fd.shape = m_polygons + index;
  161. fd.density = 1.0f;
  162. fd.friction = 0.3f;
  163. m_bodies[m_bodyIndex]->CreateFixture(&fd);
  164. }
  165. else
  166. {
  167. b2FixtureDef fd;
  168. fd.shape = &m_circle;
  169. fd.density = 1.0f;
  170. fd.friction = 0.3f;
  171. m_bodies[m_bodyIndex]->CreateFixture(&fd);
  172. }
  173. m_bodyIndex = (m_bodyIndex + 1) % k_maxBodies;
  174. }
  175. void DestroyBody()
  176. {
  177. for (int32 i = 0; i < k_maxBodies; ++i)
  178. {
  179. if (m_bodies[i] != NULL)
  180. {
  181. m_world->DestroyBody(m_bodies[i]);
  182. m_bodies[i] = NULL;
  183. return;
  184. }
  185. }
  186. }
  187. void Keyboard(unsigned char key)
  188. {
  189. switch (key)
  190. {
  191. case '1':
  192. case '2':
  193. case '3':
  194. case '4':
  195. case '5':
  196. Create(key - '1');
  197. break;
  198. case 'a':
  199. for (int32 i = 0; i < k_maxBodies; i += 2)
  200. {
  201. if (m_bodies[i])
  202. {
  203. bool active = m_bodies[i]->IsActive();
  204. m_bodies[i]->SetActive(!active);
  205. }
  206. }
  207. break;
  208. case 'd':
  209. DestroyBody();
  210. break;
  211. }
  212. }
  213. void Step(Settings* settings)
  214. {
  215. Test::Step(settings);
  216. PolyShapesCallback callback;
  217. callback.m_circle.m_radius = 2.0f;
  218. callback.m_circle.m_p.Set(0.0f, 2.1f);
  219. callback.m_transform.SetIdentity();
  220. callback.m_debugDraw = &m_debugDraw;
  221. b2AABB aabb;
  222. callback.m_circle.ComputeAABB(&aabb, callback.m_transform);
  223. m_world->QueryAABB(&callback, aabb);
  224. b2Color color(0.4f, 0.7f, 0.8f);
  225. m_debugDraw.DrawCircle(callback.m_circle.m_p, callback.m_circle.m_radius, color);
  226. m_debugDraw.DrawString(5, m_textLine, "Press 1-5 to drop stuff");
  227. m_textLine += 15;
  228. m_debugDraw.DrawString(5, m_textLine, "Press 'a' to (de)activate some bodies");
  229. m_textLine += 15;
  230. m_debugDraw.DrawString(5, m_textLine, "Press 'd' to destroy a body");
  231. m_textLine += 15;
  232. }
  233. static Test* Create()
  234. {
  235. return new PolyShapes;
  236. }
  237. int32 m_bodyIndex;
  238. b2Body* m_bodies[k_maxBodies];
  239. b2PolygonShape m_polygons[4];
  240. b2CircleShape m_circle;
  241. };
  242. #endif