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

游戏引擎

开发平台:

Visual C++

  1. /*
  2. * Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
  3. *
  4. * iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
  5. *
  6. * This software is provided 'as-is', without any express or implied
  7. * warranty.  In no event will the authors be held liable for any damages
  8. * arising from the use of this software.
  9. * Permission is granted to anyone to use this software for any purpose,
  10. * including commercial applications, and to alter it and redistribute it
  11. * freely, subject to the following restrictions:
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. */
  20. #include "iPhoneTest.h"
  21. #include "GLES-Render.h"
  22. #include <cstdio>
  23. void DestructionListener::SayGoodbye(b2Joint* joint)
  24. {
  25. if (test->m_mouseJoint == joint)
  26. {
  27. test->m_mouseJoint = NULL;
  28. }
  29. else
  30. {
  31. test->JointDestroyed(joint);
  32. }
  33. }
  34. Test::Test()
  35. : m_debugDraw()
  36. {
  37. b2Vec2 gravity;
  38. gravity.Set(0.0f, -10.0f);
  39. bool doSleep = true;
  40. m_world = new b2World(gravity, doSleep);
  41. m_bomb = NULL;
  42. m_textLine = 30;
  43. m_mouseJoint = NULL;
  44. m_pointCount = 0;
  45. m_destructionListener.test = this;
  46. m_world->SetDestructionListener(&m_destructionListener);
  47. m_world->SetContactListener(this);
  48. m_world->SetDebugDraw(&m_debugDraw);
  49. m_bombSpawning = false;
  50. m_stepCount = 0;
  51. b2BodyDef bodyDef;
  52. m_groundBody = m_world->CreateBody(&bodyDef);
  53. }
  54. Test::~Test()
  55. {
  56. // By deleting the world, we delete the bomb, mouse joint, etc.
  57. delete m_world;
  58. m_world = NULL;
  59. }
  60. void Test::SetGravity( float x, float y)
  61. {
  62. float tVectorLength=sqrt(x*x+y*y);
  63. float newGravityX=9.81f*x/tVectorLength;
  64. float newGravityY=9.81f*y/tVectorLength;
  65. m_world->SetGravity(b2Vec2(newGravityX,newGravityY));
  66. }
  67. void Test::PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
  68. {
  69. const b2Manifold* manifold = contact->GetManifold();
  70. if (manifold->m_pointCount == 0)
  71. {
  72. return;
  73. }
  74. b2Fixture* fixtureA = contact->GetFixtureA();
  75. b2Fixture* fixtureB = contact->GetFixtureB();
  76. b2PointState state1[b2_maxManifoldPoints], state2[b2_maxManifoldPoints];
  77. b2GetPointStates(state1, state2, oldManifold, manifold);
  78. b2WorldManifold worldManifold;
  79. contact->GetWorldManifold(&worldManifold);
  80. for (int32 i = 0; i < manifold->m_pointCount && m_pointCount < k_maxContactPoints; ++i)
  81. {
  82. ContactPoint* cp = m_points + m_pointCount;
  83. cp->fixtureA = fixtureA;
  84. cp->fixtureB = fixtureB;
  85. cp->position = worldManifold.m_points[i];
  86. cp->normal = worldManifold.m_normal;
  87. cp->state = state2[i];
  88. ++m_pointCount;
  89. }
  90. }
  91. void Test::DrawTitle(int x, int y, const char *string)
  92. {
  93.     m_debugDraw.DrawString(x, y, string);
  94. }
  95. class QueryCallback : public b2QueryCallback
  96. {
  97. public:
  98. QueryCallback(const b2Vec2& point)
  99. {
  100. m_point = point;
  101. m_fixture = NULL;
  102. }
  103. bool ReportFixture(b2Fixture* fixture)
  104. {
  105. b2Body* body = fixture->GetBody();
  106. if (body->GetType() == b2_dynamicBody)
  107. {
  108. bool inside = fixture->TestPoint(m_point);
  109. if (inside)
  110. {
  111. m_fixture = fixture;
  112. // We are done, terminate the query.
  113. return false;
  114. }
  115. }
  116. // Continue the query.
  117. return true;
  118. }
  119. b2Vec2 m_point;
  120. b2Fixture* m_fixture;
  121. };
  122. void Test::MouseDown(const b2Vec2& p)
  123. {
  124. m_mouseWorld = p;
  125. if (m_mouseJoint != NULL)
  126. {
  127. return;
  128. }
  129. // Make a small box.
  130. b2AABB aabb;
  131. b2Vec2 d;
  132. d.Set(0.001f, 0.001f);
  133. aabb.lowerBound = p - d;
  134. aabb.upperBound = p + d;
  135. // Query the world for overlapping shapes.
  136. QueryCallback callback(p);
  137. m_world->QueryAABB(&callback, aabb);
  138. if (callback.m_fixture)
  139. {
  140. b2Body* body = callback.m_fixture->GetBody();
  141. b2MouseJointDef md;
  142. md.bodyA = m_groundBody;
  143. md.bodyB = body;
  144. md.target = p;
  145. #ifdef TARGET_FLOAT32_IS_FIXED
  146. md.maxForce = (body->GetMass() < 16.0)? 
  147. (1000.0f * body->GetMass()) : float32(16000.0);
  148. #else
  149. md.maxForce = 1000.0f * body->GetMass();
  150. #endif
  151. m_mouseJoint = (b2MouseJoint*)m_world->CreateJoint(&md);
  152. body->SetAwake(true);
  153. }
  154. }
  155. void Test::SpawnBomb(const b2Vec2& worldPt)
  156. {
  157. m_bombSpawnPoint = worldPt;
  158. m_bombSpawning = true;
  159. }
  160. void Test::CompleteBombSpawn(const b2Vec2& p)
  161. {
  162. if (m_bombSpawning == false)
  163. {
  164. return;
  165. }
  166. const float multiplier = 30.0f;
  167. b2Vec2 vel = m_bombSpawnPoint - p;
  168. vel *= multiplier;
  169. LaunchBomb(m_bombSpawnPoint,vel);
  170. m_bombSpawning = false;
  171. }
  172. void Test::ShiftMouseDown(const b2Vec2& p)
  173. {
  174. m_mouseWorld = p;
  175. if (m_mouseJoint != NULL)
  176. {
  177. return;
  178. }
  179. SpawnBomb(p);
  180. }
  181. void Test::MouseUp(const b2Vec2& p)
  182. {
  183. if (m_mouseJoint)
  184. {
  185. m_world->DestroyJoint(m_mouseJoint);
  186. m_mouseJoint = NULL;
  187. }
  188. if (m_bombSpawning)
  189. {
  190. CompleteBombSpawn(p);
  191. }
  192. }
  193. void Test::MouseMove(const b2Vec2& p)
  194. {
  195. m_mouseWorld = p;
  196. if (m_mouseJoint)
  197. {
  198. m_mouseJoint->SetTarget(p);
  199. }
  200. }
  201. void Test::LaunchBomb()
  202. {
  203. b2Vec2 p(RandomFloat(-15.0f, 15.0f), 30.0f);
  204. b2Vec2 v = -5.0f * p;
  205. LaunchBomb(p, v);
  206. }
  207. void Test::LaunchBomb(const b2Vec2& position, const b2Vec2& velocity)
  208. {
  209. if (m_bomb)
  210. {
  211. m_world->DestroyBody(m_bomb);
  212. m_bomb = NULL;
  213. }
  214. b2BodyDef bd;
  215. bd.type = b2_dynamicBody;
  216. bd.position = position;
  217. bd.bullet = true;
  218. m_bomb = m_world->CreateBody(&bd);
  219. m_bomb->SetLinearVelocity(velocity);
  220. b2CircleShape circle;
  221. circle.m_radius = 0.3f;
  222. b2FixtureDef fd;
  223. fd.shape = &circle;
  224. fd.density = 20.0f;
  225. fd.restitution = 0.1f;
  226. b2Vec2 minV = position - b2Vec2(0.3f,0.3f);
  227. b2Vec2 maxV = position + b2Vec2(0.3f,0.3f);
  228. b2AABB aabb;
  229. aabb.lowerBound = minV;
  230. aabb.upperBound = maxV;
  231. m_bomb->CreateFixture(&fd);
  232. }
  233. void Test::Step(Settings* settings)
  234. {
  235. float32 timeStep = settings->hz > 0.0f ? 1.0f / settings->hz : float32(0.0f);
  236. if (settings->pause)
  237. {
  238. if (settings->singleStep)
  239. {
  240. settings->singleStep = 0;
  241. }
  242. else
  243. {
  244. timeStep = 0.0f;
  245. }
  246. m_debugDraw.DrawString(5, m_textLine, "****PAUSED****");
  247. m_textLine += 15;
  248. }
  249. uint32 flags = 0;
  250. flags += settings->drawShapes * b2DebugDraw::e_shapeBit;
  251. flags += settings->drawJoints * b2DebugDraw::e_jointBit;
  252. flags += settings->drawAABBs * b2DebugDraw::e_aabbBit;
  253. flags += settings->drawPairs * b2DebugDraw::e_pairBit;
  254. flags += settings->drawCOMs * b2DebugDraw::e_centerOfMassBit;
  255. m_debugDraw.SetFlags(flags);
  256. m_world->SetWarmStarting(settings->enableWarmStarting > 0);
  257. m_world->SetContinuousPhysics(settings->enableContinuous > 0);
  258. m_pointCount = 0;
  259. m_world->Step(timeStep, settings->velocityIterations, settings->positionIterations, true);
  260. m_world->DrawDebugData();
  261. if (timeStep > 0.0f)
  262. {
  263. ++m_stepCount;
  264. }
  265. if (settings->drawStats)
  266. {
  267. m_debugDraw.DrawString(5, m_textLine, "bodies/contacts/joints/proxies = %d/%d/%d",
  268.    m_world->GetBodyCount(), m_world->GetContactCount(), m_world->GetJointCount(), m_world->GetProxyCount());
  269. m_textLine += 15;
  270. m_debugDraw.DrawString(5, m_textLine, "heap bytes = %d", b2_byteCount);
  271. m_textLine += 15;
  272. }
  273. if (m_mouseJoint)
  274. {
  275. // b2Body* body = m_mouseJoint->GetBodyB();
  276. // b2Vec2 p1 = body->GetWorldPoint(m_mouseJoint->m_localAnchor);
  277. // b2Vec2 p2 = m_mouseJoint->m_target;
  278. //
  279. // glPointSize(4.0f);
  280. // glColor3f(0.0f, 1.0f, 0.0f);
  281. // glBegin(GL_POINTS);
  282. // glVertex2f(p1.x, p1.y);
  283. // glVertex2f(p2.x, p2.y);
  284. // glEnd();
  285. // glPointSize(1.0f);
  286. //
  287. // glColor3f(0.8f, 0.8f, 0.8f);
  288. // glBegin(GL_LINES);
  289. // glVertex2f(p1.x, p1.y);
  290. // glVertex2f(p2.x, p2.y);
  291. // glEnd();
  292. }
  293. if (m_bombSpawning)
  294. {
  295. // glPointSize(4.0f);
  296. // glColor3f(0.0f, 0.0f, 1.0f);
  297. // glBegin(GL_POINTS);
  298. // glColor3f(0.0f, 0.0f, 1.0f);
  299. // glVertex2f(m_bombSpawnPoint.x, m_bombSpawnPoint.y);
  300. // glEnd();
  301. //
  302. // glColor3f(0.8f, 0.8f, 0.8f);
  303. // glBegin(GL_LINES);
  304. // glVertex2f(m_mouseWorld.x, m_mouseWorld.y);
  305. // glVertex2f(m_bombSpawnPoint.x, m_bombSpawnPoint.y);
  306. // glEnd();
  307. }
  308. if (settings->drawContactPoints)
  309. {
  310. //const float32 k_impulseScale = 0.1f;
  311. const float32 k_axisScale = 0.3f;
  312. for (int32 i = 0; i < m_pointCount; ++i)
  313. {
  314. ContactPoint* point = m_points + i;
  315. if (point->state == b2_addState)
  316. {
  317. // Add
  318. m_debugDraw.DrawPoint(point->position, 10.0f, b2Color(0.3f, 0.95f, 0.3f));
  319. }
  320. else if (point->state == b2_persistState)
  321. {
  322. // Persist
  323. m_debugDraw.DrawPoint(point->position, 5.0f, b2Color(0.3f, 0.3f, 0.95f));
  324. }
  325. if (settings->drawContactNormals == 1)
  326. {
  327. b2Vec2 p1 = point->position;
  328. b2Vec2 p2 = p1 + k_axisScale * point->normal;
  329. m_debugDraw.DrawSegment(p1, p2, b2Color(0.4f, 0.9f, 0.4f));
  330. }
  331. else if (settings->drawContactForces == 1)
  332. {
  333. //b2Vec2 p1 = point->position;
  334. //b2Vec2 p2 = p1 + k_forceScale * point->normalForce * point->normal;
  335. //DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
  336. }
  337. if (settings->drawFrictionForces == 1)
  338. {
  339. //b2Vec2 tangent = b2Cross(point->normal, 1.0f);
  340. //b2Vec2 p1 = point->position;
  341. //b2Vec2 p2 = p1 + k_forceScale * point->tangentForce * tangent;
  342. //DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
  343. }
  344. }
  345. }
  346. }