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 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. //
  2. // BtPhysTest
  3. //
  4. // Copyright: (c) 2009-2013 Benjamin "Touky" Huet <huet.benjamin@gmail.com>
  5. // (c) 2012-2013 Sam Hocevar <sam@hocevar.net>
  6. //
  7. #if defined HAVE_CONFIG_H
  8. # include "config.h"
  9. #endif
  10. #if defined _XBOX
  11. # define _USE_MATH_DEFINES /* for M_PI */
  12. # include <xtl.h>
  13. # undef near /* Fuck Microsoft */
  14. # undef far /* Fuck Microsoft again */
  15. #elif defined _WIN32
  16. # define _USE_MATH_DEFINES /* for M_PI */
  17. # define WIN32_LEAN_AND_MEAN
  18. # include <windows.h>
  19. # undef near /* Fuck Microsoft */
  20. # undef far /* Fuck Microsoft again */
  21. #else
  22. # include <cmath>
  23. #endif
  24. #include "core.h"
  25. #include "loldebug.h"
  26. using namespace lol;
  27. #ifndef HAVE_PHYS_USE_BULLET
  28. #define HAVE_PHYS_USE_BULLET
  29. #endif /* HAVE_PHYS_USE_BULLET */
  30. #include "physics/lolphysics.h"
  31. #include "physics/easyphysics.h"
  32. #include "physicobject.h"
  33. #include "btphystest.h"
  34. using namespace lol::phys;
  35. #define CUBE_HALF_EXTENTS .5f
  36. #define EXTRA_HEIGHT 1.f
  37. int gNumObjects = 64;
  38. #define USE_WALL 1
  39. #define USE_PLATFORM 1
  40. #define USE_ROPE 0
  41. #define USE_BODIES 1
  42. #define USE_ROTATION 0
  43. #define USE_CHARACTER 1
  44. #define USE_STAIRS 1
  45. #define IPT_MOVE_FORWARD "Move_Forward"
  46. #define IPT_MOVE_BACKWARD "Move_Backward"
  47. #define IPT_MOVE_LEFT "Move_Left"
  48. #define IPT_MOVE_RIGHT "Move_Right"
  49. #define IPT_MOVE_UP "Move_Up"
  50. #define IPT_MOVE_DOWN "Move_Down"
  51. #define IPT_MOVE_JUMP "Move_Jump"
  52. BtPhysTest::BtPhysTest(bool editor)
  53. {
  54. m_loop_value = .0f;
  55. /* Create a camera that matches the settings of XNA BtPhysTest */
  56. m_camera = new Camera(vec3(0.f, 600.f, 0.f),
  57. vec3(0.f, 0.f, 0.f),
  58. vec3(0, 1, 0));
  59. m_camera->SetRotation(quat::fromeuler_xyz(0.f, 0.f, 0.f));
  60. m_camera->SetPerspective(45.f, 1280.f, 960.f, .1f, 1000.f);
  61. //m_camera->SetOrtho(1280.f / 6, 960.f / 6, -1000.f, 1000.f);
  62. Ticker::Ref(m_camera);
  63. m_ready = false;
  64. m_simulation = new Simulation();
  65. m_simulation->SetWorldLimit(vec3(-1000.0f, -1000.0f, -1000.0f), vec3(1000.0f, 1000.0f, 1000.0f));
  66. m_simulation->Init();
  67. vec3 NewGravity = vec3(.0f, -10.0f, .0f);
  68. m_simulation->SetGravity(NewGravity);
  69. m_simulation->SetContinuousDetection(true);
  70. m_simulation->SetTimestep(1.f / 120.f);
  71. Ticker::Ref(m_simulation);
  72. /* Add a white directional light */
  73. m_light1 = new Light();
  74. m_light1->SetPosition(vec4(0.2f, 0.2f, 0.f, 0.f));
  75. m_light1->SetColor(vec4(0.5f, 0.5f, 0.5f, 1.f));
  76. Ticker::Ref(m_light1);
  77. /* Add an orangeish point light */
  78. m_light2 = new Light();
  79. m_light2->SetPosition(vec4(-15.f, 15.f, 15.f, 1.f));
  80. m_light2->SetColor(vec4(0.4f, 0.3f, 0.2f, 1.f));
  81. Ticker::Ref(m_light2);
  82. float offset = 29.5f;
  83. vec3 pos_offset = vec3(.0f, 30.f, .0f);
  84. if (USE_STAIRS)
  85. {
  86. vec3 new_offset = vec3(1.0f, .125f, .0f);
  87. quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
  88. vec3 NewPosition = pos_offset + vec3(5.0f, -29.f, 15.0f);
  89. {
  90. NewRotation = quat::fromeuler_xyz(0.f, 0.f, 30.f);
  91. NewPosition += vec3(4.0f, .0f, -4.0f);
  92. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
  93. Ticker::Ref(NewPhyobj);
  94. m_stairs_list << NewPhyobj;
  95. }
  96. {
  97. NewRotation = quat::fromeuler_xyz(0.f, 0.f, 40.f);
  98. NewPosition += vec3(4.0f, .0f, -4.0f);
  99. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
  100. Ticker::Ref(NewPhyobj);
  101. m_stairs_list << NewPhyobj;
  102. }
  103. NewPosition = pos_offset + vec3(5.0f, -29.5f, 15.0f);
  104. NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
  105. for (int i=0; i < 15; i++)
  106. {
  107. NewPosition += new_offset;
  108. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
  109. Ticker::Ref(NewPhyobj);
  110. m_stairs_list << NewPhyobj;
  111. }
  112. }
  113. if (USE_WALL)
  114. {
  115. for (int i=0; i < 6; i++)
  116. {
  117. vec3 NewPosition = vec3(.0f);
  118. quat NewRotation = quat(1.f);
  119. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation);
  120. int idx = i/2;
  121. NewPosition = pos_offset;
  122. NewPosition[idx] += offset;
  123. offset *= -1.f;
  124. if (idx != 1)
  125. {
  126. vec3 NewAxis = vec3(.0f);
  127. NewAxis[2 - idx] = 1;
  128. NewRotation = quat::rotate(90.f, NewAxis);
  129. }
  130. NewPhyobj->SetTransform(NewPosition, NewRotation);
  131. Ticker::Ref(NewPhyobj);
  132. m_ground_list << NewPhyobj;
  133. }
  134. }
  135. PhysicsObject* BasePhyobj = NULL;
  136. if (USE_PLATFORM)
  137. {
  138. quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
  139. vec3 NewPosition = pos_offset + vec3(5.0f, -25.0f, -15.0f);
  140. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  141. m_platform_list << NewPhyobj;
  142. Ticker::Ref(NewPhyobj);
  143. NewPosition = pos_offset + vec3(-15.0f, -25.0f, 5.0f);
  144. NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  145. BasePhyobj = NewPhyobj;
  146. m_platform_list << NewPhyobj;
  147. Ticker::Ref(NewPhyobj);
  148. NewRotation = quat::fromeuler_xyz(0.f, 0.f, 90.f);
  149. NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f);
  150. NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  151. NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, true);
  152. m_platform_list << NewPhyobj;
  153. Ticker::Ref(NewPhyobj);
  154. //NewPosition += vec3(-0.0f, .0f, .0f);
  155. //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  156. //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, false);
  157. //m_platform_list << NewPhyobj;
  158. //Ticker::Ref(NewPhyobj);
  159. //NewPosition += vec3(-2.0f, .0f, .0f);
  160. //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  161. //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), false, false);
  162. //m_platform_list << NewPhyobj;
  163. //Ticker::Ref(NewPhyobj);
  164. }
  165. if (USE_CHARACTER)
  166. {
  167. quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
  168. vec3 NewPosition = pos_offset + vec3(-5.0f, -10.0f, 15.0f);
  169. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2);
  170. m_character_list << NewPhyobj;
  171. Ticker::Ref(NewPhyobj);
  172. Input::LinkActionToKey(IPT_MOVE_FORWARD, Key::Up);
  173. Input::LinkActionToKey(IPT_MOVE_BACKWARD, Key::Down);
  174. Input::LinkActionToKey(IPT_MOVE_LEFT, Key::Left);
  175. Input::LinkActionToKey(IPT_MOVE_RIGHT, Key::Right);
  176. Input::LinkActionToKey(IPT_MOVE_JUMP, Key::Space);
  177. Input::LinkActionToKey(IPT_MOVE_UP, Key::PageUp);
  178. Input::LinkActionToKey(IPT_MOVE_DOWN, Key::PageDown);
  179. //NewPhyobj->GetCharacter()->AttachTo(BasePhyobj->GetPhysic(), true, true);
  180. }
  181. if (USE_BODIES)
  182. {
  183. for (int x=0; x < 6; x++)
  184. {
  185. for (int y=0; y < 6; y++)
  186. {
  187. for (int z=0; z < 5; z++)
  188. {
  189. PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
  190. vec3(-20.f, 15.f, -20.f) +
  191. vec3(8.f * (float)x, 8.f * (float)y, 8.f * (float)z));
  192. m_physobj_list << new_physobj;
  193. Ticker::Ref(new_physobj);
  194. }
  195. }
  196. }
  197. }
  198. if (USE_ROPE)
  199. {
  200. Array<PhysicsObject*> RopeElements;
  201. for (int i = 0; i < 14; i++)
  202. {
  203. PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
  204. vec3(0.f, 15.f, -20.f) +
  205. vec3(0.f, 0.f, 2.f * (float)i), 1);
  206. RopeElements << new_physobj;
  207. m_physobj_list << new_physobj;
  208. Ticker::Ref(new_physobj);
  209. if (RopeElements.Count() > 1)
  210. {
  211. EasyConstraint* new_constraint = new EasyConstraint();
  212. vec3 A2B = .5f * (RopeElements[i]->GetPhysic()->GetTransform().v3.xyz -
  213. RopeElements[i - 1]->GetPhysic()->GetTransform().v3.xyz);
  214. new_constraint->SetPhysObjA(RopeElements[i - 1]->GetPhysic(), lol::mat4::translate(A2B));
  215. new_constraint->SetPhysObjB(RopeElements[i]->GetPhysic(), lol::mat4::translate(-A2B));
  216. new_constraint->InitConstraintToPoint2Point();
  217. new_constraint->DisableCollisionBetweenObjs(true);
  218. new_constraint->AddToSimulation(m_simulation);
  219. m_constraint_list << new_constraint;
  220. }
  221. }
  222. }
  223. }
  224. void BtPhysTest::TickGame(float seconds)
  225. {
  226. WorldEntity::TickGame(seconds);
  227. if (Input::WasReleased(Key::Escape))
  228. Ticker::Shutdown();
  229. m_loop_value += seconds;
  230. if (m_loop_value > M_PI * 2.0f)
  231. m_loop_value -= M_PI * 2.0f;
  232. vec3 GroundBarycenter = vec3(.0f);
  233. vec3 PhysObjBarycenter = vec3(.0f);
  234. float factor = .0f;
  235. if (USE_WALL)
  236. {
  237. for (int i = 0; i < m_ground_list.Count(); i++)
  238. {
  239. PhysicsObject* PhysObj = m_ground_list[i];
  240. mat4 GroundMat = PhysObj->GetTransform();
  241. GroundBarycenter += GroundMat.v3.xyz;
  242. factor += 1.f;
  243. }
  244. GroundBarycenter /= factor;
  245. for (int i = 0; i < m_ground_list.Count(); i++)
  246. {
  247. PhysicsObject* PhysObj = m_ground_list[i];
  248. mat4 GroundMat = PhysObj->GetTransform();
  249. vec3 CenterToGround = GroundMat.v3.xyz - GroundBarycenter;
  250. vec3 CenterToCam = m_camera->m_position - GroundBarycenter;
  251. if (dot(normalize(CenterToCam - CenterToGround),
  252. normalize(CenterToGround)) > 0.f)
  253. PhysObj->SetRender(false);
  254. else
  255. PhysObj->SetRender(true);
  256. }
  257. }
  258. if (USE_ROTATION)
  259. {
  260. for (int i = 0; i < m_ground_list.Count(); i++)
  261. {
  262. PhysicsObject* PhysObj = m_ground_list[i];
  263. mat4 GroundMat = PhysObj->GetTransform();
  264. mat4 CenterMx = mat4::translate(GroundBarycenter);
  265. GroundMat = inverse(CenterMx) * GroundMat;
  266. GroundMat = CenterMx *
  267. mat4(quat::fromeuler_xyz(vec3(.0f, 20.f, 20.0f) * seconds))
  268. * GroundMat;
  269. PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
  270. }
  271. }
  272. if (USE_PLATFORM)
  273. {
  274. for (int i = 0; i < m_platform_list.Count(); i++)
  275. {
  276. PhysicsObject* PhysObj = m_platform_list[i];
  277. mat4 GroundMat = PhysObj->GetTransform();
  278. if (i == 0)
  279. {
  280. GroundMat = GroundMat * mat4(quat::fromeuler_xyz(vec3(20.f, .0f, .0f) * seconds));
  281. PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
  282. }
  283. else if (i == 1)
  284. {
  285. GroundMat =
  286. mat4::translate(vec3(-15.0f, 5.0f, lol::cos(m_loop_value) * 8.f)) *
  287. mat4(quat::fromeuler_xyz(vec3(.0f, lol::cos(m_loop_value) * 20.f, .0f)));
  288. PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
  289. }
  290. }
  291. }
  292. if (USE_CHARACTER)
  293. {
  294. for (int i = 0; i < m_character_list.Count(); i++)
  295. {
  296. PhysicsObject* PhysObj = m_character_list[i];
  297. EasyCharacterController* Character = (EasyCharacterController*)PhysObj->GetCharacter();
  298. mat4 CtlrMx = Character->GetTransform();
  299. int HMovement = Input::GetStatus(IPT_MOVE_RIGHT) - Input::GetStatus(IPT_MOVE_LEFT);
  300. int VMovement = Input::GetStatus(IPT_MOVE_FORWARD) - Input::GetStatus(IPT_MOVE_BACKWARD);
  301. int RMovement = Input::GetStatus(IPT_MOVE_UP) - Input::GetStatus(IPT_MOVE_DOWN);
  302. vec3 CharMove = vec3((float)VMovement * seconds * 4.f, (float)RMovement * seconds * 10.f, (float)HMovement * seconds * 4.f);
  303. if (Input::WasReleased(IPT_MOVE_JUMP))
  304. Character->Jump();
  305. Character->SetMovementForFrame(CharMove);
  306. RayCastResult HitResult;
  307. if (m_simulation->RayHits(HitResult, ERT_Closest, Character->GetTransform().v3.xyz, (Character->GetTransform().v3.xyz + vec3(.0f, -1.f, .0f)), Character))
  308. Character->AttachTo(HitResult.m_collider_list[0], true, true);
  309. else
  310. Character->AttachTo(NULL);
  311. }
  312. }
  313. if (USE_CHARACTER)
  314. {
  315. PhysObjBarycenter = vec3(.0f);
  316. factor = .0f;
  317. for (int i = 0; i < m_character_list.Count(); i++)
  318. {
  319. PhysicsObject* PhysObj = m_character_list[i];
  320. mat4 GroundMat = PhysObj->GetTransform();
  321. PhysObjBarycenter += GroundMat.v3.xyz;
  322. factor += 1.f;
  323. }
  324. PhysObjBarycenter /= factor;
  325. m_camera->SetTarget(m_camera->GetTarget() + (seconds / (seconds + 0.18f)) * (PhysObjBarycenter - m_camera->GetTarget()));
  326. vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 5.0f, .0f);
  327. m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 20.0f);
  328. }
  329. else
  330. {
  331. PhysObjBarycenter = vec3(.0f);
  332. for (int i = 0; i < m_physobj_list.Count(); i++)
  333. {
  334. PhysicsObject* PhysObj = m_physobj_list[i];
  335. mat4 GroundMat = PhysObj->GetTransform();
  336. PhysObjBarycenter += GroundMat.v3.xyz;
  337. factor += 1.f;
  338. }
  339. PhysObjBarycenter /= factor;
  340. m_camera->SetTarget(PhysObjBarycenter);
  341. m_camera->SetPosition(GroundBarycenter + normalize(GroundBarycenter - PhysObjBarycenter) * 60.0f);
  342. }
  343. }
  344. void BtPhysTest::TickDraw(float seconds)
  345. {
  346. WorldEntity::TickDraw(seconds);
  347. if (!m_ready)
  348. {
  349. /* FIXME: this object never cleans up */
  350. m_ready = true;
  351. }
  352. //Video::SetClearColor(vec4(0.0f, 0.0f, 0.12f, 1.0f));
  353. }
  354. BtPhysTest::~BtPhysTest()
  355. {
  356. Ticker::Unref(m_camera);
  357. Ticker::Unref(m_light1);
  358. Ticker::Unref(m_light2);
  359. while (m_constraint_list.Count())
  360. {
  361. EasyConstraint* CurPop = m_constraint_list.Last();
  362. m_constraint_list.Pop();
  363. CurPop->RemoveFromSimulation(m_simulation);
  364. delete CurPop;
  365. }
  366. while (m_ground_list.Count())
  367. {
  368. PhysicsObject* CurPop = m_ground_list.Last();
  369. m_ground_list.Pop();
  370. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  371. Ticker::Unref(CurPop);
  372. }
  373. while (m_stairs_list.Count())
  374. {
  375. PhysicsObject* CurPop = m_stairs_list.Last();
  376. m_stairs_list.Pop();
  377. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  378. Ticker::Unref(CurPop);
  379. }
  380. while (m_character_list.Count())
  381. {
  382. PhysicsObject* CurPop = m_character_list.Last();
  383. m_character_list.Pop();
  384. CurPop->GetCharacter()->RemoveFromSimulation(m_simulation);
  385. Ticker::Unref(CurPop);
  386. }
  387. while (m_platform_list.Count())
  388. {
  389. PhysicsObject* CurPop = m_platform_list.Last();
  390. m_platform_list.Pop();
  391. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  392. Ticker::Unref(CurPop);
  393. }
  394. while (m_physobj_list.Count())
  395. {
  396. PhysicsObject* CurPop = m_physobj_list.Last();
  397. m_physobj_list.Pop();
  398. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  399. Ticker::Unref(CurPop);
  400. }
  401. Ticker::Unref(m_simulation);
  402. }
  403. int main(int argc, char **argv)
  404. {
  405. System::Init(argc, argv);
  406. Application app("BtPhysTest", ivec2(1280, 720), 60.0f);
  407. new BtPhysTest(argc > 1);
  408. app.ShowPointer(false);
  409. app.Run();
  410. return EXIT_SUCCESS;
  411. }