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

游戏引擎

开发平台:

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. #include "Test.h"
  19. #include "Render.h"
  20. #include "freeglut/GL/glut.h"
  21. #include <cstdio>
  22. void DestructionListener::SayGoodbye(b2Joint* joint)
  23. {
  24. if (test->m_mouseJoint == joint)
  25. {
  26. test->m_mouseJoint = NULL;
  27. }
  28. else
  29. {
  30. test->JointDestroyed(joint);
  31. }
  32. }
  33. Test::Test()
  34. {
  35. b2Vec2 gravity;
  36. gravity.Set(0.0f, -10.0f);
  37. bool doSleep = true;
  38. m_world = new b2World(gravity, doSleep);
  39. m_bomb = NULL;
  40. m_textLine = 30;
  41. m_mouseJoint = NULL;
  42. m_pointCount = 0;
  43. m_destructionListener.test = this;
  44. m_world->SetDestructionListener(&m_destructionListener);
  45. m_world->SetContactListener(this);
  46. m_world->SetDebugDraw(&m_debugDraw);
  47. m_bombSpawning = false;
  48. m_stepCount = 0;
  49. b2BodyDef bodyDef;
  50. m_groundBody = m_world->CreateBody(&bodyDef);
  51. }
  52. Test::~Test()
  53. {
  54. // By deleting the world, we delete the bomb, mouse joint, etc.
  55. delete m_world;
  56. m_world = NULL;
  57. }
  58. void Test::PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
  59. {
  60. const b2Manifold* manifold = contact->GetManifold();
  61. if (manifold->pointCount == 0)
  62. {
  63. return;
  64. }
  65. b2Fixture* fixtureA = contact->GetFixtureA();
  66. b2Fixture* fixtureB = contact->GetFixtureB();
  67. b2PointState state1[b2_maxManifoldPoints], state2[b2_maxManifoldPoints];
  68. b2GetPointStates(state1, state2, oldManifold, manifold);
  69. b2WorldManifold worldManifold;
  70. contact->GetWorldManifold(&worldManifold);
  71. for (int32 i = 0; i < manifold->pointCount && m_pointCount < k_maxContactPoints; ++i)
  72. {
  73. ContactPoint* cp = m_points + m_pointCount;
  74. cp->fixtureA = fixtureA;
  75. cp->fixtureB = fixtureB;
  76. cp->position = worldManifold.points[i];
  77. cp->normal = worldManifold.normal;
  78. cp->state = state2[i];
  79. ++m_pointCount;
  80. }
  81. }
  82. void Test::DrawTitle(int x, int y, const char *string)
  83. {
  84.     m_debugDraw.DrawString(x, y, string);
  85. }
  86. class QueryCallback : public b2QueryCallback
  87. {
  88. public:
  89. QueryCallback(const b2Vec2& point)
  90. {
  91. m_point = point;
  92. m_fixture = NULL;
  93. }
  94. bool ReportFixture(b2Fixture* fixture)
  95. {
  96. b2Body* body = fixture->GetBody();
  97. if (body->GetType() == b2_dynamicBody)
  98. {
  99. bool inside = fixture->TestPoint(m_point);
  100. if (inside)
  101. {
  102. m_fixture = fixture;
  103. // We are done, terminate the query.
  104. return false;
  105. }
  106. }
  107. // Continue the query.
  108. return true;
  109. }
  110. b2Vec2 m_point;
  111. b2Fixture* m_fixture;
  112. };
  113. void Test::MouseDown(const b2Vec2& p)
  114. {
  115. m_mouseWorld = p;
  116. if (m_mouseJoint != NULL)
  117. {
  118. return;
  119. }
  120. // Make a small box.
  121. b2AABB aabb;
  122. b2Vec2 d;
  123. d.Set(0.001f, 0.001f);
  124. aabb.lowerBound = p - d;
  125. aabb.upperBound = p + d;
  126. // Query the world for overlapping shapes.
  127. QueryCallback callback(p);
  128. m_world->QueryAABB(&callback, aabb);
  129. if (callback.m_fixture)
  130. {
  131. b2Body* body = callback.m_fixture->GetBody();
  132. b2MouseJointDef md;
  133. md.bodyA = m_groundBody;
  134. md.bodyB = body;
  135. md.target = p;
  136. md.maxForce = 1000.0f * body->GetMass();
  137. m_mouseJoint = (b2MouseJoint*)m_world->CreateJoint(&md);
  138. body->SetAwake(true);
  139. }
  140. }
  141. void Test::SpawnBomb(const b2Vec2& worldPt)
  142. {
  143. m_bombSpawnPoint = worldPt;
  144. m_bombSpawning = true;
  145. }
  146.     
  147. void Test::CompleteBombSpawn(const b2Vec2& p)
  148. {
  149. if (m_bombSpawning == false)
  150. {
  151. return;
  152. }
  153. const float multiplier = 30.0f;
  154. b2Vec2 vel = m_bombSpawnPoint - p;
  155. vel *= multiplier;
  156. LaunchBomb(m_bombSpawnPoint,vel);
  157. m_bombSpawning = false;
  158. }
  159. void Test::ShiftMouseDown(const b2Vec2& p)
  160. {
  161. m_mouseWorld = p;
  162. if (m_mouseJoint != NULL)
  163. {
  164. return;
  165. }
  166. SpawnBomb(p);
  167. }
  168. void Test::MouseUp(const b2Vec2& p)
  169. {
  170. if (m_mouseJoint)
  171. {
  172. m_world->DestroyJoint(m_mouseJoint);
  173. m_mouseJoint = NULL;
  174. }
  175. if (m_bombSpawning)
  176. {
  177. CompleteBombSpawn(p);
  178. }
  179. }
  180. void Test::MouseMove(const b2Vec2& p)
  181. {
  182. m_mouseWorld = p;
  183. if (m_mouseJoint)
  184. {
  185. m_mouseJoint->SetTarget(p);
  186. }
  187. }
  188. void Test::LaunchBomb()
  189. {
  190. b2Vec2 p(RandomFloat(-15.0f, 15.0f), 30.0f);
  191. b2Vec2 v = -5.0f * p;
  192. LaunchBomb(p, v);
  193. }
  194. void Test::LaunchBomb(const b2Vec2& position, const b2Vec2& velocity)
  195. {
  196. if (m_bomb)
  197. {
  198. m_world->DestroyBody(m_bomb);
  199. m_bomb = NULL;
  200. }
  201. b2BodyDef bd;
  202. bd.type = b2_dynamicBody;
  203. bd.position = position;
  204. bd.bullet = true;
  205. m_bomb = m_world->CreateBody(&bd);
  206. m_bomb->SetLinearVelocity(velocity);
  207. b2CircleShape circle;
  208. circle.m_radius = 0.3f;
  209. b2FixtureDef fd;
  210. fd.shape = &circle;
  211. fd.density = 20.0f;
  212. fd.restitution = 0.0f;
  213. b2Vec2 minV = position - b2Vec2(0.3f,0.3f);
  214. b2Vec2 maxV = position + b2Vec2(0.3f,0.3f);
  215. b2AABB aabb;
  216. aabb.lowerBound = minV;
  217. aabb.upperBound = maxV;
  218. m_bomb->CreateFixture(&fd);
  219. }
  220. void Test::Step(Settings* settings)
  221. {
  222. float32 timeStep = settings->hz > 0.0f ? 1.0f / settings->hz : float32(0.0f);
  223. if (settings->pause)
  224. {
  225. if (settings->singleStep)
  226. {
  227. settings->singleStep = 0;
  228. }
  229. else
  230. {
  231. timeStep = 0.0f;
  232. }
  233. m_debugDraw.DrawString(5, m_textLine, "****PAUSED****");
  234. m_textLine += 15;
  235. }
  236. uint32 flags = 0;
  237. flags += settings->drawShapes * b2DebugDraw::e_shapeBit;
  238. flags += settings->drawJoints * b2DebugDraw::e_jointBit;
  239. flags += settings->drawAABBs * b2DebugDraw::e_aabbBit;
  240. flags += settings->drawPairs * b2DebugDraw::e_pairBit;
  241. flags += settings->drawCOMs * b2DebugDraw::e_centerOfMassBit;
  242. m_debugDraw.SetFlags(flags);
  243. m_world->SetWarmStarting(settings->enableWarmStarting > 0);
  244. m_world->SetContinuousPhysics(settings->enableContinuous > 0);
  245. m_pointCount = 0;
  246. m_world->Step(timeStep, settings->velocityIterations, settings->positionIterations);
  247. m_world->DrawDebugData();
  248. if (timeStep > 0.0f)
  249. {
  250. ++m_stepCount;
  251. }
  252. if (settings->drawStats)
  253. {
  254. m_debugDraw.DrawString(5, m_textLine, "bodies/contacts/joints/proxies = %d/%d/%d",
  255. m_world->GetBodyCount(), m_world->GetContactCount(), m_world->GetJointCount(), m_world->GetProxyCount());
  256. m_textLine += 15;
  257. }
  258. if (m_mouseJoint)
  259. {
  260. b2Vec2 p1 = m_mouseJoint->GetAnchorB();
  261. b2Vec2 p2 = m_mouseJoint->GetTarget();
  262. glPointSize(4.0f);
  263. glColor3f(0.0f, 1.0f, 0.0f);
  264. glBegin(GL_POINTS);
  265. glVertex2f(p1.x, p1.y);
  266. glVertex2f(p2.x, p2.y);
  267. glEnd();
  268. glPointSize(1.0f);
  269. glColor3f(0.8f, 0.8f, 0.8f);
  270. glBegin(GL_LINES);
  271. glVertex2f(p1.x, p1.y);
  272. glVertex2f(p2.x, p2.y);
  273. glEnd();
  274. }
  275. if (m_bombSpawning)
  276. {
  277. glPointSize(4.0f);
  278. glColor3f(0.0f, 0.0f, 1.0f);
  279. glBegin(GL_POINTS);
  280. glColor3f(0.0f, 0.0f, 1.0f);
  281. glVertex2f(m_bombSpawnPoint.x, m_bombSpawnPoint.y);
  282. glEnd();
  283. glColor3f(0.8f, 0.8f, 0.8f);
  284. glBegin(GL_LINES);
  285. glVertex2f(m_mouseWorld.x, m_mouseWorld.y);
  286. glVertex2f(m_bombSpawnPoint.x, m_bombSpawnPoint.y);
  287. glEnd();
  288. }
  289. if (settings->drawContactPoints)
  290. {
  291. //const float32 k_impulseScale = 0.1f;
  292. const float32 k_axisScale = 0.3f;
  293. for (int32 i = 0; i < m_pointCount; ++i)
  294. {
  295. ContactPoint* point = m_points + i;
  296. if (point->state == b2_addState)
  297. {
  298. // Add
  299. m_debugDraw.DrawPoint(point->position, 10.0f, b2Color(0.3f, 0.95f, 0.3f));
  300. }
  301. else if (point->state == b2_persistState)
  302. {
  303. // Persist
  304. m_debugDraw.DrawPoint(point->position, 5.0f, b2Color(0.3f, 0.3f, 0.95f));
  305. }
  306. if (settings->drawContactNormals == 1)
  307. {
  308. b2Vec2 p1 = point->position;
  309. b2Vec2 p2 = p1 + k_axisScale * point->normal;
  310. m_debugDraw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.9f));
  311. }
  312. else if (settings->drawContactForces == 1)
  313. {
  314. //b2Vec2 p1 = point->position;
  315. //b2Vec2 p2 = p1 + k_forceScale * point->normalForce * point->normal;
  316. //DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
  317. }
  318. if (settings->drawFrictionForces == 1)
  319. {
  320. //b2Vec2 tangent = b2Cross(point->normal, 1.0f);
  321. //b2Vec2 p1 = point->position;
  322. //b2Vec2 p2 = p1 + k_forceScale * point->tangentForce * tangent;
  323. //DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
  324. }
  325. }
  326. }
  327. }