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.

пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. //
  2. // BtPhysTest
  3. //
  4. // Copyright: (c) 2009-2012 Benjamin Huet <huet.benjamin@gmail.com>
  5. // (c) 2012 Sam Hocevar <sam@hocevar.net>
  6. //
  7. #if defined HAVE_CONFIG_H
  8. # include "config.h"
  9. #endif
  10. #if defined _WIN32
  11. # include <direct.h>
  12. #endif
  13. #if defined _XBOX
  14. # define _USE_MATH_DEFINES /* for M_PI */
  15. # include <xtl.h>
  16. # undef near /* Fuck Microsoft */
  17. # undef far /* Fuck Microsoft again */
  18. #elif defined _WIN32
  19. # define _USE_MATH_DEFINES /* for M_PI */
  20. # define WIN32_LEAN_AND_MEAN
  21. # include <windows.h>
  22. # undef near /* Fuck Microsoft */
  23. # undef far /* Fuck Microsoft again */
  24. #else
  25. # include <cmath>
  26. #endif
  27. #include "core.h"
  28. #include "loldebug.h"
  29. using namespace lol;
  30. #ifndef HAVE_PHYS_USE_BULLET
  31. #define HAVE_PHYS_USE_BULLET
  32. #endif /* HAVE_PHYS_USE_BULLET */
  33. #include "Physics/LolPhysics.h"
  34. #include "Physics/EasyPhysics.h"
  35. #include "PhysicObject.h"
  36. #include "BtPhysTest.h"
  37. using namespace lol::phys;
  38. #define CUBE_HALF_EXTENTS .5f
  39. #define EXTRA_HEIGHT 1.f
  40. int gNumObjects = 64;
  41. #define USE_WALL 1
  42. #define USE_PLATFORM 1
  43. #define USE_ROPE 1
  44. #define USE_BODIES 1
  45. #define USE_ROTATION 0
  46. #define USE_CHARACTER 1
  47. BtPhysTest::BtPhysTest(bool editor)
  48. {
  49. /* Create a camera that matches the settings of XNA BtPhysTest */
  50. m_camera = new Camera(vec3(0.f, 600.f, 0.f),
  51. vec3(0.f, 0.f, 0.f),
  52. vec3(0, 1, 0));
  53. m_camera->SetRotation(quat::fromeuler_xyz(0.f, 0.f, 0.f));
  54. m_camera->SetPerspective(45.f, 1280.f, 960.f, .1f, 1000.f);
  55. //m_camera->SetOrtho(1280.f / 6, 960.f / 6, -1000.f, 1000.f);
  56. Ticker::Ref(m_camera);
  57. m_ready = false;
  58. m_simulation = new Simulation();
  59. m_simulation->SetWorldLimit(vec3(-1000.0f, -1000.0f, -1000.0f), vec3(1000.0f, 1000.0f, 1000.0f));
  60. m_simulation->Init();
  61. vec3 NewGravity = vec3(.0f, -10.0f, .0f);
  62. m_simulation->SetGravity(NewGravity);
  63. m_simulation->SetContinuousDetection(true);
  64. m_simulation->SetTimestep(1.f / 120.f);
  65. Ticker::Ref(m_simulation);
  66. float offset = 29.5f;
  67. vec3 pos_offset = vec3(.0f, 30.f, .0f);
  68. if (USE_WALL)
  69. {
  70. for (int i=0; i < 6; i++)
  71. {
  72. vec3 NewPosition = vec3(.0f);
  73. quat NewRotation = quat(1.f);
  74. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation);
  75. int idx = i/2;
  76. NewPosition = pos_offset;
  77. NewPosition[idx] += offset;
  78. offset *= -1.f;
  79. if (idx != 1)
  80. {
  81. vec3 axis = vec3(.0f);
  82. axis[2 - idx] = 1;
  83. NewRotation = quat::rotate(90.f, axis);
  84. }
  85. NewPhyobj->SetTransform(NewPosition, NewRotation);
  86. Ticker::Ref(NewPhyobj);
  87. m_ground_list << NewPhyobj;
  88. }
  89. }
  90. if (USE_PLATFORM)
  91. {
  92. quat NewRotation = quat::fromeuler_xyz(5.f, 0.f, 0.f);
  93. vec3 NewPosition = pos_offset + vec3(5.0f, -25.0f, -15.0f);
  94. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  95. m_platform_list << NewPhyobj;
  96. Ticker::Ref(NewPhyobj);
  97. NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f);
  98. NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  99. m_platform_list << NewPhyobj;
  100. Ticker::Ref(NewPhyobj);
  101. }
  102. if (USE_CHARACTER)
  103. {
  104. quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
  105. vec3 NewPosition = pos_offset + vec3(.0f, 20.0f, .0f);
  106. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2);
  107. m_character_list << NewPhyobj;
  108. Ticker::Ref(NewPhyobj);
  109. }
  110. if (USE_BODIES)
  111. {
  112. for (int x=0; x < 6; x++)
  113. {
  114. for (int y=0; y < 6; y++)
  115. {
  116. for (int z=0; z < 5; z++)
  117. {
  118. PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
  119. vec3(-20.f, 15.f, -20.f) +
  120. vec3(8.f * (float)x, 8.f * (float)y, 8.f * (float)z));
  121. m_physobj_list << new_physobj;
  122. Ticker::Ref(new_physobj);
  123. }
  124. }
  125. }
  126. }
  127. if (USE_ROPE)
  128. {
  129. Array<PhysicsObject*> RopeElements;
  130. for (int i = 0; i < 14; i++)
  131. {
  132. PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
  133. vec3(0.f, 15.f, -20.f) +
  134. vec3(0.f, 0.f, 2.f * (float)i), 1);
  135. RopeElements << new_physobj;
  136. m_physobj_list << new_physobj;
  137. Ticker::Ref(new_physobj);
  138. if (RopeElements.Count() > 1)
  139. {
  140. EasyConstraint* new_constraint = new EasyConstraint();
  141. vec3 A2B = .5f * (RopeElements[i]->GetPhysic()->GetTransform().v3.xyz -
  142. RopeElements[i - 1]->GetPhysic()->GetTransform().v3.xyz);
  143. new_constraint->SetPhysObjA(RopeElements[i - 1]->GetPhysic(), lol::mat4::translate(A2B));
  144. new_constraint->SetPhysObjB(RopeElements[i]->GetPhysic(), lol::mat4::translate(-A2B));
  145. new_constraint->InitConstraintToPoint2Point();
  146. new_constraint->DisableCollisionBetweenObjs(true);
  147. new_constraint->AddToSimulation(m_simulation);
  148. m_constraint_list << new_constraint;
  149. }
  150. }
  151. }
  152. #if 0
  153. //init Physics
  154. {
  155. m_bt_ccd_mode = USE_CCD;
  156. //collision configuration contains default setup for memory, collision setup
  157. m_bt_collision_config = new btDefaultCollisionConfiguration();
  158. //use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
  159. m_bt_dispatcher = new btCollisionDispatcher(m_bt_collision_config);
  160. m_bt_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,
  161. BOX_SHAPE_PROXYTYPE,
  162. m_bt_collision_config->getCollisionAlgorithmCreateFunc(CONVEX_SHAPE_PROXYTYPE,
  163. CONVEX_SHAPE_PROXYTYPE));
  164. m_bt_broadphase = new btDbvtBroadphase();
  165. ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
  166. m_bt_solver = new btSequentialImpulseConstraintSolver;
  167. m_bt_world = new btDiscreteDynamicsWorld(m_bt_dispatcher, m_bt_broadphase, m_bt_solver, m_bt_collision_config);
  168. //m_bt_world->setDebugDrawer(&sDebugDrawer);
  169. m_bt_world->getSolverInfo().m_splitImpulse = true;
  170. m_bt_world->getSolverInfo().m_numIterations = 20;
  171. m_bt_world->getDispatchInfo().m_useContinuous = (m_bt_ccd_mode == USE_CCD);
  172. m_bt_world->setGravity(btVector3(0,-10,0));
  173. ///create a few basic rigid bodies
  174. btBoxShape* box = new btBoxShape(btVector3(btScalar(110.),btScalar(1.),btScalar(110.)));
  175. btCollisionShape* groundShape = box;
  176. m_bt_collision_shapes << groundShape;
  177. m_ground_mesh.Compile("[sc#ddd afcb220 2 220 -1]");
  178. //m_bt_collision_shapes << new btCylinderShape(btVector3(.5f,.5f,.5f));
  179. btTransform groundTransform;
  180. groundTransform.setIdentity();
  181. //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
  182. {
  183. btScalar mass(0.);
  184. //rigidbody is dynamic if and only if mass is non zero, otherwise static
  185. bool isDynamic = (mass != 0.f);
  186. btVector3 localInertia(0,0,0);
  187. if (isDynamic)
  188. groundShape->calculateLocalInertia(mass,localInertia);
  189. //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
  190. btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
  191. btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
  192. btRigidBody* body = new btRigidBody(rbInfo);
  193. //add the body to the dynamics world
  194. m_bt_world->addRigidBody(body);
  195. }
  196. //Adding Shapes
  197. {
  198. //create a few dynamic rigidbodies
  199. // Re-using the same collision is better for memory usage and performance
  200. btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1));
  201. m_rigid_mesh[0].Compile("[sc#add afcb2 2 2 -.1]");
  202. m_rigid_mesh[1].Compile("[sc#dad afcb2 2 2 -.1]");
  203. m_rigid_mesh[2].Compile("[sc#dda afcb2 2 2 -.1]");
  204. m_rigid_mesh[3].Compile("[sc#daa afcb2 2 2 -.1]");
  205. m_rigid_mesh[4].Compile("[sc#ada afcb2 2 2 -.1]");
  206. m_rigid_mesh[5].Compile("[sc#aad afcb2 2 2 -.1]");
  207. m_bt_collision_shapes << colShape;
  208. m_bt_dynamic_shapes << colShape;
  209. /// Create Dynamic Objects
  210. btTransform startTransform;
  211. startTransform.setIdentity();
  212. btScalar mass(1.f);
  213. //rigidbody is dynamic if and only if mass is non zero, otherwise static
  214. bool isDynamic = (mass != 0.f);
  215. btVector3 localInertia(0,0,0);
  216. if (isDynamic)
  217. colShape->calculateLocalInertia(mass,localInertia);
  218. int i;
  219. for (i=0;i<gNumObjects;i++)
  220. {
  221. btCollisionShape* shape = colShape;
  222. btTransform trans;
  223. trans.setIdentity();
  224. //stack them
  225. int colsize = 10;
  226. int row = int(((float)i*CUBE_HALF_EXTENTS*2.0f)/((float)colsize*2.0f*CUBE_HALF_EXTENTS));
  227. int row2 = row;
  228. int col = (i)%(colsize)-colsize/2;
  229. if (col>3)
  230. {
  231. col=11;
  232. row2 |=1;
  233. }
  234. btVector3 pos(((row+col+row2) % 4)*CUBE_HALF_EXTENTS,
  235. 20.0f + row*8*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT,
  236. col*8*CUBE_HALF_EXTENTS + 2 * (row2%2)*CUBE_HALF_EXTENTS);
  237. trans.setOrigin(pos);
  238. float mass = 1.f;
  239. btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
  240. //rigidbody is dynamic if and only if mass is non zero, otherwise static
  241. bool isDynamic = (mass != 0.f);
  242. btVector3 localInertia(0,0,0);
  243. if (isDynamic)
  244. shape->calculateLocalInertia(mass,localInertia);
  245. //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
  246. btDefaultMotionState* myMotionState = new btDefaultMotionState(trans);
  247. btRigidBody::btRigidBodyConstructionInfo cInfo(mass,myMotionState,shape,localInertia);
  248. btRigidBody* body = new btRigidBody(cInfo);
  249. body->setContactProcessingThreshold(BT_LARGE_FLOAT);
  250. m_bt_world->addRigidBody(body);
  251. ///when using m_ccdMode
  252. if (m_bt_ccd_mode == USE_CCD)
  253. {
  254. body->setCcdMotionThreshold(CUBE_HALF_EXTENTS);
  255. body->setCcdSweptSphereRadius(0.9*CUBE_HALF_EXTENTS);
  256. }
  257. }
  258. }
  259. }
  260. #endif
  261. }
  262. void BtPhysTest::TickGame(float seconds)
  263. {
  264. WorldEntity::TickGame(seconds);
  265. if (Input::GetButtonState(27 /*SDLK_ESCAPE*/))
  266. Ticker::Shutdown();
  267. vec3 GroundBarycenter = vec3(.0f);
  268. vec3 PhysObjBarycenter = vec3(.0f);
  269. float factor = .0f;
  270. if (USE_WALL)
  271. {
  272. for (int i = 0; i < m_ground_list.Count(); i++)
  273. {
  274. PhysicsObject* PhysObj = m_ground_list[i];
  275. mat4 GroundMat = PhysObj->GetTransform();
  276. GroundBarycenter += GroundMat.v3.xyz;
  277. factor += 1.f;
  278. }
  279. GroundBarycenter /= factor;
  280. for (int i = 0; i < m_ground_list.Count(); i++)
  281. {
  282. PhysicsObject* PhysObj = m_ground_list[i];
  283. mat4 GroundMat = PhysObj->GetTransform();
  284. vec3 CenterToGround = GroundMat.v3.xyz - GroundBarycenter;
  285. vec3 CenterToCam = m_camera->m_position - GroundBarycenter;
  286. if (dot(normalize(CenterToCam - CenterToGround),
  287. normalize(CenterToGround)) > 0.f)
  288. PhysObj->SetRender(false);
  289. else
  290. PhysObj->SetRender(true);
  291. }
  292. }
  293. if (USE_ROTATION)
  294. {
  295. for (int i = 0; i < m_ground_list.Count(); i++)
  296. {
  297. PhysicsObject* PhysObj = m_ground_list[i];
  298. mat4 GroundMat = PhysObj->GetTransform();
  299. mat4 CenterMx = mat4::translate(GroundBarycenter);
  300. GroundMat = inverse(CenterMx) * GroundMat;
  301. GroundMat = CenterMx *
  302. mat4(quat::fromeuler_xyz(vec3(.0f, 20.f, 20.0f) * seconds))
  303. * GroundMat;
  304. PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
  305. }
  306. }
  307. if (USE_PLATFORM)
  308. {
  309. for (int i = 0; i < m_platform_list.Count(); i++)
  310. {
  311. PhysicsObject* PhysObj = m_platform_list[i];
  312. mat4 GroundMat = PhysObj->GetTransform();
  313. if (i == 0)
  314. {
  315. GroundMat = GroundMat * mat4(quat::fromeuler_xyz(vec3(20.f, .0f, .0f) * seconds));
  316. PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
  317. }
  318. else
  319. {
  320. GroundMat = GroundMat * mat4::translate(vec3(.0f, .0f, 10.0f) * seconds);
  321. if (GroundMat.v3.z > 40.0f)
  322. GroundMat = GroundMat * mat4::translate(vec3(.0f, .0f, -80.0f));
  323. PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
  324. }
  325. }
  326. }
  327. if (USE_CHARACTER)
  328. {
  329. for (int i = 0; i < m_character_list.Count(); i++)
  330. {
  331. PhysicsObject* PhysObj = m_character_list[i];
  332. EasyCharacterController* Character = (EasyCharacterController*)PhysObj->GetCharacter();
  333. int HMovement = Input::GetButtonState(275 /*SDLK_RIGHT*/) - Input::GetButtonState(276 /*SDLK_LEFT*/);
  334. int VMovement = Input::GetButtonState(273 /*SDLK_UP*/) - Input::GetButtonState(274 /*SDLK_DOWN*/);
  335. int RMovement = Input::GetButtonState(280 /*SDLK_PAGEUP*/) - Input::GetButtonState(281 /*SDLK_PAGEDOWN*/);
  336. Character->SetMovementForFrame(vec3((float)VMovement * seconds * 4.f, (float)RMovement * seconds * 10.f, (float)HMovement * seconds * 4.f));
  337. }
  338. }
  339. if (USE_CHARACTER)
  340. {
  341. PhysObjBarycenter = vec3(.0f);
  342. factor = .0f;
  343. for (int i = 0; i < m_character_list.Count(); i++)
  344. {
  345. PhysicsObject* PhysObj = m_character_list[i];
  346. mat4 GroundMat = PhysObj->GetTransform();
  347. PhysObjBarycenter += GroundMat.v3.xyz;
  348. factor += 1.f;
  349. }
  350. PhysObjBarycenter /= factor;
  351. m_camera->SetTarget(m_camera->GetTarget() + (seconds / (seconds + 0.18f)) * (PhysObjBarycenter - m_camera->GetTarget()));
  352. vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 20.0f, .0f);
  353. m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 5.0f);
  354. }
  355. else
  356. {
  357. PhysObjBarycenter = vec3(.0f);
  358. for (int i = 0; i < m_physobj_list.Count(); i++)
  359. {
  360. PhysicsObject* PhysObj = m_physobj_list[i];
  361. mat4 GroundMat = PhysObj->GetTransform();
  362. PhysObjBarycenter += GroundMat.v3.xyz;
  363. factor += 1.f;
  364. }
  365. PhysObjBarycenter /= factor;
  366. m_camera->SetTarget(PhysObjBarycenter);
  367. m_camera->SetPosition(GroundBarycenter + normalize(GroundBarycenter - PhysObjBarycenter) * 60.0f);
  368. }
  369. #if 0
  370. ///step the simulation
  371. if (m_bt_world)
  372. {
  373. //int steps = (int)(seconds / 0.005f);
  374. //for (int i = 0; i < steps; i++)
  375. m_bt_world->stepSimulation(seconds /*/ steps*/);
  376. //optional but useful: debug drawing
  377. //m_bt_world->debugDrawWorld();
  378. }
  379. #endif
  380. }
  381. void BtPhysTest::TickDraw(float seconds)
  382. {
  383. WorldEntity::TickDraw(seconds);
  384. if (!m_ready)
  385. {
  386. #if 0
  387. m_ground_mesh.MeshConvert();
  388. m_rigid_mesh[0].MeshConvert();
  389. m_rigid_mesh[1].MeshConvert();
  390. m_rigid_mesh[2].MeshConvert();
  391. m_rigid_mesh[3].MeshConvert();
  392. m_rigid_mesh[4].MeshConvert();
  393. m_rigid_mesh[5].MeshConvert();
  394. #endif
  395. /* FIXME: this object never cleans up */
  396. m_ready = true;
  397. }
  398. //Video::SetClearColor(vec4(0.0f, 0.0f, 0.12f, 1.0f));
  399. #if 0
  400. vec3 BarycenterLocation = vec3(.0f);
  401. float BarycenterFactor = 0.0f;
  402. for(int i=0;i<gNumObjects;i++)
  403. {
  404. mat4 m(1.0f);
  405. btMatrix3x3 rot; rot.setIdentity();
  406. btCollisionObject* colObj = m_bt_world->getCollisionObjectArray()[i];
  407. btRigidBody* body = btRigidBody::upcast(colObj);
  408. if(body && body->getMotionState())
  409. {
  410. btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState();
  411. myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(&m[0][0]);
  412. rot = myMotionState->m_graphicsWorldTrans.getBasis();
  413. }
  414. else
  415. {
  416. colObj->getWorldTransform().getOpenGLMatrix(&m[0][0]);
  417. rot = colObj->getWorldTransform().getBasis();
  418. }
  419. if (i > 0)
  420. {
  421. BarycenterLocation += m.v3.xyz;
  422. BarycenterFactor += 1.0f;
  423. }
  424. if (i == 0)
  425. m_ground_mesh.Render(m);
  426. else
  427. m_rigid_mesh[i % 6].Render(m);
  428. }
  429. if (BarycenterFactor > .0f)
  430. {
  431. BarycenterLocation /= BarycenterFactor;
  432. m_camera->SetTarget(BarycenterLocation);
  433. m_camera->SetPosition(BarycenterLocation + vec3(-20.0f, 8.0f, .0f));
  434. }
  435. #endif
  436. }
  437. BtPhysTest::~BtPhysTest()
  438. {
  439. Ticker::Unref(m_camera);
  440. while (m_constraint_list.Count())
  441. {
  442. EasyConstraint* CurPop = m_constraint_list.Last();
  443. m_constraint_list.Pop();
  444. CurPop->RemoveFromSimulation(m_simulation);
  445. delete CurPop;
  446. }
  447. while (m_ground_list.Count())
  448. {
  449. PhysicsObject* CurPop = m_ground_list.Last();
  450. m_ground_list.Pop();
  451. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  452. Ticker::Unref(CurPop);
  453. }
  454. while (m_character_list.Count())
  455. {
  456. PhysicsObject* CurPop = m_character_list.Last();
  457. m_character_list.Pop();
  458. CurPop->GetCharacter()->RemoveFromSimulation(m_simulation);
  459. Ticker::Unref(CurPop);
  460. }
  461. while (m_platform_list.Count())
  462. {
  463. PhysicsObject* CurPop = m_platform_list.Last();
  464. m_platform_list.Pop();
  465. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  466. Ticker::Unref(CurPop);
  467. }
  468. while (m_physobj_list.Count())
  469. {
  470. PhysicsObject* CurPop = m_physobj_list.Last();
  471. m_physobj_list.Pop();
  472. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  473. Ticker::Unref(CurPop);
  474. }
  475. Ticker::Unref(m_simulation);
  476. #if 0
  477. //Exit Physics
  478. {
  479. //cleanup in the reverse order of creation/initialization
  480. //remove the rigidbodies from the dynamics world and delete them
  481. for (int i = m_bt_world->getNumCollisionObjects() - 1; i >= 0 ;i--)
  482. {
  483. btCollisionObject* obj = m_bt_world->getCollisionObjectArray()[i];
  484. btRigidBody* body = btRigidBody::upcast(obj);
  485. if (body && body->getMotionState())
  486. delete body->getMotionState();
  487. m_bt_world->removeCollisionObject(obj);
  488. delete obj;
  489. }
  490. //delete collision shapes
  491. for (int j = 0; j < m_bt_collision_shapes.Count(); j++)
  492. {
  493. btCollisionShape* shape = m_bt_collision_shapes[j];
  494. delete shape;
  495. }
  496. m_bt_collision_shapes.Empty();
  497. delete m_bt_world;
  498. delete m_bt_solver;
  499. delete m_bt_broadphase;
  500. delete m_bt_dispatcher;
  501. delete m_bt_collision_config;
  502. }
  503. #endif
  504. }
  505. int main(int argc, char **argv)
  506. {
  507. Application app("BtPhysTest", ivec2(1280, 720), 60.0f);
  508. #if defined _MSC_VER && !defined _XBOX
  509. _chdir("..");
  510. #elif defined _WIN32 && !defined _XBOX
  511. _chdir("../..");
  512. #endif
  513. new BtPhysTest(argc > 1);
  514. app.ShowPointer(false);
  515. app.Run();
  516. return EXIT_SUCCESS;
  517. }