Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

BtPhysTest.cpp 8.6 KiB

před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
před 12 roky
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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. #if USE_SDL && defined __APPLE__
  28. # include <SDL_main.h>
  29. #endif
  30. #include <bullet/btBulletDynamicsCommon.h>
  31. #include <bullet/btBulletCollisionCommon.h>
  32. #include "core.h"
  33. #include "loldebug.h"
  34. using namespace lol;
  35. #include "BtPhysTest.h"
  36. #define CUBE_HALF_EXTENTS .5f
  37. #define EXTRA_HEIGHT 1.f
  38. int gNumObjects = 64;
  39. BtPhysTest::BtPhysTest(bool editor)
  40. {
  41. /* Create a camera that matches the settings of XNA BtPhysTest */
  42. m_camera = new Camera(vec3(0.f, 600.f, 0.f),
  43. vec3(0.f, 0.f, 0.f),
  44. vec3(0, 1, 0));
  45. m_camera->SetRotation(quat::fromeuler_xyz(0.f, 0.f, 0.f));
  46. m_camera->SetPerspective(90.f, 1280.f, 960.f, .1f, 1000.f);
  47. //m_camera->SetOrtho(1280.f / 6, 960.f / 6, -1000.f, 1000.f);
  48. Ticker::Ref(m_camera);
  49. m_ready = false;
  50. //init Physics
  51. {
  52. m_bt_ccd_mode = USE_CCD;
  53. //collision configuration contains default setup for memory, collision setup
  54. m_bt_collision_config = new btDefaultCollisionConfiguration();
  55. //use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
  56. m_bt_dispatcher = new btCollisionDispatcher(m_bt_collision_config);
  57. m_bt_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,m_bt_collision_config->getCollisionAlgorithmCreateFunc(CONVEX_SHAPE_PROXYTYPE,CONVEX_SHAPE_PROXYTYPE));
  58. m_bt_broadphase = new btDbvtBroadphase();
  59. ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
  60. m_bt_solver = new btSequentialImpulseConstraintSolver;
  61. m_bt_world = new btDiscreteDynamicsWorld(m_bt_dispatcher, m_bt_broadphase, m_bt_solver, m_bt_collision_config);
  62. //m_bt_world->setDebugDrawer(&sDebugDrawer);
  63. m_bt_world->getSolverInfo().m_splitImpulse = true;
  64. m_bt_world->getSolverInfo().m_numIterations = 20;
  65. m_bt_world->getDispatchInfo().m_useContinuous = (m_bt_ccd_mode == USE_CCD);
  66. m_bt_world->setGravity(btVector3(0,-10,0));
  67. ///create a few basic rigid bodies
  68. btBoxShape* box = new btBoxShape(btVector3(btScalar(110.),btScalar(1.),btScalar(110.)));
  69. btCollisionShape* groundShape = box;
  70. m_bt_collision_shapes << groundShape;
  71. m_ground_mesh.Compile("[sc#ddd afcb110 1 110 -1]");
  72. //m_bt_collision_shapes << new btCylinderShape(btVector3(.5f,.5f,.5f));
  73. btTransform groundTransform;
  74. groundTransform.setIdentity();
  75. //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
  76. {
  77. btScalar mass(0.);
  78. //rigidbody is dynamic if and only if mass is non zero, otherwise static
  79. bool isDynamic = (mass != 0.f);
  80. btVector3 localInertia(0,0,0);
  81. if (isDynamic)
  82. groundShape->calculateLocalInertia(mass,localInertia);
  83. //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
  84. btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
  85. btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
  86. btRigidBody* body = new btRigidBody(rbInfo);
  87. //add the body to the dynamics world
  88. m_bt_world->addRigidBody(body);
  89. }
  90. //Adding Shapes
  91. {
  92. //create a few dynamic rigidbodies
  93. // Re-using the same collision is better for memory usage and performance
  94. btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1));
  95. m_rigid_mesh.Compile("[sc#ada afcb2 2 2 -.1]");
  96. m_bt_collision_shapes << colShape;
  97. m_bt_dynamic_shapes << colShape;
  98. /// Create Dynamic Objects
  99. btTransform startTransform;
  100. startTransform.setIdentity();
  101. btScalar mass(1.f);
  102. //rigidbody is dynamic if and only if mass is non zero, otherwise static
  103. bool isDynamic = (mass != 0.f);
  104. btVector3 localInertia(0,0,0);
  105. if (isDynamic)
  106. colShape->calculateLocalInertia(mass,localInertia);
  107. int i;
  108. for (i=0;i<gNumObjects;i++)
  109. {
  110. btCollisionShape* shape = colShape;
  111. btTransform trans;
  112. trans.setIdentity();
  113. //stack them
  114. int colsize = 10;
  115. int row = (i*CUBE_HALF_EXTENTS*2)/(colsize*2*CUBE_HALF_EXTENTS);
  116. int row2 = row;
  117. int col = (i)%(colsize)-colsize/2;
  118. if (col>3)
  119. {
  120. col=11;
  121. row2 |=1;
  122. }
  123. btVector3 pos(col*2*CUBE_HALF_EXTENTS + (row2%2)*CUBE_HALF_EXTENTS, 20.0f +
  124. row*2*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT,0);
  125. trans.setOrigin(pos);
  126. float mass = 1.f;
  127. btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
  128. //rigidbody is dynamic if and only if mass is non zero, otherwise static
  129. bool isDynamic = (mass != 0.f);
  130. btVector3 localInertia(0,0,0);
  131. if (isDynamic)
  132. shape->calculateLocalInertia(mass,localInertia);
  133. //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
  134. btDefaultMotionState* myMotionState = new btDefaultMotionState(trans);
  135. btRigidBody::btRigidBodyConstructionInfo cInfo(mass,myMotionState,shape,localInertia);
  136. btRigidBody* body = new btRigidBody(cInfo);
  137. body->setContactProcessingThreshold(BT_LARGE_FLOAT);
  138. m_bt_world->addRigidBody(body);
  139. ///when using m_ccdMode
  140. if (m_bt_ccd_mode == USE_CCD)
  141. {
  142. body->setCcdMotionThreshold(CUBE_HALF_EXTENTS);
  143. body->setCcdSweptSphereRadius(0.9*CUBE_HALF_EXTENTS);
  144. }
  145. }
  146. }
  147. }
  148. }
  149. void BtPhysTest::TickGame(float seconds)
  150. {
  151. WorldEntity::TickGame(seconds);
  152. if (Input::GetButtonState(27 /*SDLK_ESCAPE*/))
  153. Ticker::Shutdown();
  154. ///step the simulation
  155. if (m_bt_world)
  156. {
  157. m_bt_world->stepSimulation(seconds);
  158. //optional but useful: debug drawing
  159. //m_bt_world->debugDrawWorld();
  160. }
  161. }
  162. void BtPhysTest::TickDraw(float seconds)
  163. {
  164. WorldEntity::TickDraw(seconds);
  165. if (!m_ready)
  166. {
  167. m_ground_mesh.MeshConvert();
  168. m_rigid_mesh.MeshConvert();
  169. /* FIXME: this object never cleans up */
  170. m_ready = true;
  171. }
  172. Video::SetClearColor(vec4(0.0f, 0.0f, 0.12f, 1.0f));
  173. vec3 BarycenterLocation = vec3(.0f);
  174. float BarycenterFactor = 0.0f;
  175. for(int i=0;i<gNumObjects;i++)
  176. {
  177. mat4 m(1.0f);
  178. btMatrix3x3 rot; rot.setIdentity();
  179. btCollisionObject* colObj = m_bt_world->getCollisionObjectArray()[i];
  180. btRigidBody* body = btRigidBody::upcast(colObj);
  181. if(body && body->getMotionState())
  182. {
  183. btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState();
  184. myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(&m[0][0]);
  185. rot = myMotionState->m_graphicsWorldTrans.getBasis();
  186. }
  187. else
  188. {
  189. colObj->getWorldTransform().getOpenGLMatrix(&m[0][0]);
  190. rot = colObj->getWorldTransform().getBasis();
  191. }
  192. if (i > 0)
  193. {
  194. BarycenterLocation += m.v3.xyz;
  195. BarycenterFactor += 1.0f;
  196. }
  197. if (i == 0)
  198. m_ground_mesh.Render(m);
  199. else
  200. m_rigid_mesh.Render(m);
  201. }
  202. if (BarycenterFactor > .0f)
  203. {
  204. BarycenterLocation /= BarycenterFactor;
  205. m_camera->SetTarget(BarycenterLocation);
  206. m_camera->SetPosition(BarycenterLocation + vec3(-20.0f, 5.0f, .0f));
  207. }
  208. }
  209. BtPhysTest::~BtPhysTest()
  210. {
  211. Ticker::Unref(m_camera);
  212. //Exit Physics
  213. {
  214. //cleanup in the reverse order of creation/initialization
  215. //remove the rigidbodies from the dynamics world and delete them
  216. for (int i = m_bt_world->getNumCollisionObjects() - 1; i >= 0 ;i--)
  217. {
  218. btCollisionObject* obj = m_bt_world->getCollisionObjectArray()[i];
  219. btRigidBody* body = btRigidBody::upcast(obj);
  220. if (body && body->getMotionState())
  221. delete body->getMotionState();
  222. m_bt_world->removeCollisionObject(obj);
  223. delete obj;
  224. }
  225. //delete collision shapes
  226. for (int j = 0; j < m_bt_collision_shapes.Count(); j++)
  227. {
  228. btCollisionShape* shape = m_bt_collision_shapes[j];
  229. delete shape;
  230. }
  231. m_bt_collision_shapes.Empty();
  232. delete m_bt_world;
  233. delete m_bt_solver;
  234. delete m_bt_broadphase;
  235. delete m_bt_dispatcher;
  236. delete m_bt_collision_config;
  237. }
  238. }
  239. int main(int argc, char **argv)
  240. {
  241. Application app("BtPhysTest", ivec2(800, 600), 60.0f);
  242. #if defined _MSC_VER && !defined _XBOX
  243. _chdir("..");
  244. #elif defined _WIN32 && !defined _XBOX
  245. _chdir("../..");
  246. #endif
  247. new BtPhysTest(argc > 1);
  248. app.ShowPointer(false);
  249. app.Run();
  250. return EXIT_SUCCESS;
  251. }