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 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  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/Include/LolPhysics.h"
  34. #include "Physics/Include/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 0
  44. #define USE_BODIES 0
  45. #define USE_ROTATION 0
  46. #define USE_CHARACTER 1
  47. BtPhysTest::BtPhysTest(bool editor)
  48. {
  49. m_loop_value = .0f;
  50. /* Create a camera that matches the settings of XNA BtPhysTest */
  51. m_camera = new Camera(vec3(0.f, 600.f, 0.f),
  52. vec3(0.f, 0.f, 0.f),
  53. vec3(0, 1, 0));
  54. m_camera->SetRotation(quat::fromeuler_xyz(0.f, 0.f, 0.f));
  55. m_camera->SetPerspective(45.f, 1280.f, 960.f, .1f, 1000.f);
  56. //m_camera->SetOrtho(1280.f / 6, 960.f / 6, -1000.f, 1000.f);
  57. Ticker::Ref(m_camera);
  58. m_ready = false;
  59. m_simulation = new Simulation();
  60. m_simulation->SetWorldLimit(vec3(-1000.0f, -1000.0f, -1000.0f), vec3(1000.0f, 1000.0f, 1000.0f));
  61. m_simulation->Init();
  62. vec3 NewGravity = vec3(.0f, -10.0f, .0f);
  63. m_simulation->SetGravity(NewGravity);
  64. m_simulation->SetContinuousDetection(true);
  65. m_simulation->SetTimestep(1.f / 120.f);
  66. Ticker::Ref(m_simulation);
  67. float offset = 29.5f;
  68. vec3 pos_offset = vec3(.0f, 30.f, .0f);
  69. if (USE_WALL)
  70. {
  71. for (int i=0; i < 6; i++)
  72. {
  73. vec3 NewPosition = vec3(.0f);
  74. quat NewRotation = quat(1.f);
  75. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation);
  76. int idx = i/2;
  77. NewPosition = pos_offset;
  78. NewPosition[idx] += offset;
  79. offset *= -1.f;
  80. if (idx != 1)
  81. {
  82. vec3 axis = vec3(.0f);
  83. axis[2 - idx] = 1;
  84. NewRotation = quat::rotate(90.f, axis);
  85. }
  86. NewPhyobj->SetTransform(NewPosition, NewRotation);
  87. Ticker::Ref(NewPhyobj);
  88. m_ground_list << NewPhyobj;
  89. }
  90. }
  91. PhysicsObject* BasePhyobj = NULL;
  92. if (USE_PLATFORM)
  93. {
  94. quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
  95. vec3 NewPosition = pos_offset + vec3(5.0f, -25.0f, -15.0f);
  96. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  97. m_platform_list << NewPhyobj;
  98. Ticker::Ref(NewPhyobj);
  99. NewPosition = pos_offset + vec3(-15.0f, -25.0f, 5.0f);
  100. NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  101. BasePhyobj = NewPhyobj;
  102. m_platform_list << NewPhyobj;
  103. Ticker::Ref(NewPhyobj);
  104. NewRotation = quat::fromeuler_xyz(0.f, 0.f, 90.f);
  105. NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f);
  106. NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  107. NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, true);
  108. m_platform_list << NewPhyobj;
  109. Ticker::Ref(NewPhyobj);
  110. //NewPosition += vec3(-0.0f, .0f, .0f);
  111. //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  112. //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, false);
  113. //m_platform_list << NewPhyobj;
  114. //Ticker::Ref(NewPhyobj);
  115. //NewPosition += vec3(-2.0f, .0f, .0f);
  116. //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  117. //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), false, false);
  118. //m_platform_list << NewPhyobj;
  119. //Ticker::Ref(NewPhyobj);
  120. }
  121. if (USE_CHARACTER)
  122. {
  123. quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
  124. vec3 NewPosition = pos_offset + vec3(-15.0f, -10.0f, .0f);
  125. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2);
  126. m_character_list << NewPhyobj;
  127. Ticker::Ref(NewPhyobj);
  128. //NewPhyobj->GetCharacter()->AttachTo(BasePhyobj->GetPhysic(), true, true);
  129. }
  130. if (USE_BODIES)
  131. {
  132. for (int x=0; x < 6; x++)
  133. {
  134. for (int y=0; y < 6; y++)
  135. {
  136. for (int z=0; z < 5; z++)
  137. {
  138. PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
  139. vec3(-20.f, 15.f, -20.f) +
  140. vec3(8.f * (float)x, 8.f * (float)y, 8.f * (float)z));
  141. m_physobj_list << new_physobj;
  142. Ticker::Ref(new_physobj);
  143. }
  144. }
  145. }
  146. }
  147. if (USE_ROPE)
  148. {
  149. Array<PhysicsObject*> RopeElements;
  150. for (int i = 0; i < 14; i++)
  151. {
  152. PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
  153. vec3(0.f, 15.f, -20.f) +
  154. vec3(0.f, 0.f, 2.f * (float)i), 1);
  155. RopeElements << new_physobj;
  156. m_physobj_list << new_physobj;
  157. Ticker::Ref(new_physobj);
  158. if (RopeElements.Count() > 1)
  159. {
  160. EasyConstraint* new_constraint = new EasyConstraint();
  161. vec3 A2B = .5f * (RopeElements[i]->GetPhysic()->GetTransform().v3.xyz -
  162. RopeElements[i - 1]->GetPhysic()->GetTransform().v3.xyz);
  163. new_constraint->SetPhysObjA(RopeElements[i - 1]->GetPhysic(), lol::mat4::translate(A2B));
  164. new_constraint->SetPhysObjB(RopeElements[i]->GetPhysic(), lol::mat4::translate(-A2B));
  165. new_constraint->InitConstraintToPoint2Point();
  166. new_constraint->DisableCollisionBetweenObjs(true);
  167. new_constraint->AddToSimulation(m_simulation);
  168. m_constraint_list << new_constraint;
  169. }
  170. }
  171. }
  172. }
  173. void BtPhysTest::TickGame(float seconds)
  174. {
  175. WorldEntity::TickGame(seconds);
  176. if (Input::GetButtonState(27 /*SDLK_ESCAPE*/))
  177. Ticker::Shutdown();
  178. m_loop_value += seconds;
  179. if (m_loop_value > M_PI * 2.0f)
  180. m_loop_value -= M_PI * 2.0f;
  181. vec3 GroundBarycenter = vec3(.0f);
  182. vec3 PhysObjBarycenter = vec3(.0f);
  183. float factor = .0f;
  184. if (USE_WALL)
  185. {
  186. for (int i = 0; i < m_ground_list.Count(); i++)
  187. {
  188. PhysicsObject* PhysObj = m_ground_list[i];
  189. mat4 GroundMat = PhysObj->GetTransform();
  190. GroundBarycenter += GroundMat.v3.xyz;
  191. factor += 1.f;
  192. }
  193. GroundBarycenter /= factor;
  194. for (int i = 0; i < m_ground_list.Count(); i++)
  195. {
  196. PhysicsObject* PhysObj = m_ground_list[i];
  197. mat4 GroundMat = PhysObj->GetTransform();
  198. vec3 CenterToGround = GroundMat.v3.xyz - GroundBarycenter;
  199. vec3 CenterToCam = m_camera->m_position - GroundBarycenter;
  200. if (dot(normalize(CenterToCam - CenterToGround),
  201. normalize(CenterToGround)) > 0.f)
  202. PhysObj->SetRender(false);
  203. else
  204. PhysObj->SetRender(true);
  205. }
  206. }
  207. if (USE_ROTATION)
  208. {
  209. for (int i = 0; i < m_ground_list.Count(); i++)
  210. {
  211. PhysicsObject* PhysObj = m_ground_list[i];
  212. mat4 GroundMat = PhysObj->GetTransform();
  213. mat4 CenterMx = mat4::translate(GroundBarycenter);
  214. GroundMat = inverse(CenterMx) * GroundMat;
  215. GroundMat = CenterMx *
  216. mat4(quat::fromeuler_xyz(vec3(.0f, 20.f, 20.0f) * seconds))
  217. * GroundMat;
  218. PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
  219. }
  220. }
  221. if (USE_PLATFORM)
  222. {
  223. for (int i = 0; i < m_platform_list.Count(); i++)
  224. {
  225. PhysicsObject* PhysObj = m_platform_list[i];
  226. mat4 GroundMat = PhysObj->GetTransform();
  227. if (i == 0)
  228. {
  229. GroundMat = GroundMat * mat4(quat::fromeuler_xyz(vec3(20.f, .0f, .0f) * seconds));
  230. PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
  231. }
  232. else if (i == 1)
  233. {
  234. GroundMat =
  235. mat4::translate(vec3(-15.0f, 5.0f, lol::cos(m_loop_value) * 8.f)) *
  236. mat4(quat::fromeuler_xyz(vec3(.0f, lol::cos(m_loop_value) * 20.f, .0f)));
  237. PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
  238. }
  239. }
  240. }
  241. if (USE_CHARACTER)
  242. {
  243. for (int i = 0; i < m_character_list.Count(); i++)
  244. {
  245. PhysicsObject* PhysObj = m_character_list[i];
  246. EasyCharacterController* Character = (EasyCharacterController*)PhysObj->GetCharacter();
  247. mat4 CtlrMx = Character->GetTransform();
  248. int HMovement = Input::GetButtonState(275 /*SDLK_RIGHT*/) - Input::GetButtonState(276 /*SDLK_LEFT*/);
  249. int VMovement = Input::GetButtonState(273 /*SDLK_UP*/) - Input::GetButtonState(274 /*SDLK_DOWN*/);
  250. int RMovement = Input::GetButtonState(280 /*SDLK_PAGEUP*/) - Input::GetButtonState(281 /*SDLK_PAGEDOWN*/);
  251. vec3 CharMove = vec3((float)VMovement * seconds * 4.f, (float)RMovement * seconds * 10.f, (float)HMovement * seconds * 4.f);
  252. Character->SetMovementForFrame(CharMove);
  253. RayCastResult HitResult;
  254. if (m_simulation->RayHits(HitResult, ERT_Closest, Character->GetTransform().v3.xyz, (Character->GetTransform().v3.xyz + vec3(.0f, -1.f, .0f)), Character))
  255. Character->AttachTo(HitResult.m_collider_list[0], true, true);
  256. else
  257. Character->AttachTo(NULL);
  258. }
  259. }
  260. if (USE_CHARACTER)
  261. {
  262. PhysObjBarycenter = vec3(.0f);
  263. factor = .0f;
  264. for (int i = 0; i < m_character_list.Count(); i++)
  265. {
  266. PhysicsObject* PhysObj = m_character_list[i];
  267. mat4 GroundMat = PhysObj->GetTransform();
  268. PhysObjBarycenter += GroundMat.v3.xyz;
  269. factor += 1.f;
  270. }
  271. PhysObjBarycenter /= factor;
  272. m_camera->SetTarget(m_camera->GetTarget() + (seconds / (seconds + 0.18f)) * (PhysObjBarycenter - m_camera->GetTarget()));
  273. vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 5.0f, .0f);
  274. m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 20.0f);
  275. }
  276. else
  277. {
  278. PhysObjBarycenter = vec3(.0f);
  279. for (int i = 0; i < m_physobj_list.Count(); i++)
  280. {
  281. PhysicsObject* PhysObj = m_physobj_list[i];
  282. mat4 GroundMat = PhysObj->GetTransform();
  283. PhysObjBarycenter += GroundMat.v3.xyz;
  284. factor += 1.f;
  285. }
  286. PhysObjBarycenter /= factor;
  287. m_camera->SetTarget(PhysObjBarycenter);
  288. m_camera->SetPosition(GroundBarycenter + normalize(GroundBarycenter - PhysObjBarycenter) * 60.0f);
  289. }
  290. }
  291. void BtPhysTest::TickDraw(float seconds)
  292. {
  293. WorldEntity::TickDraw(seconds);
  294. if (!m_ready)
  295. {
  296. /* FIXME: this object never cleans up */
  297. m_ready = true;
  298. }
  299. //Video::SetClearColor(vec4(0.0f, 0.0f, 0.12f, 1.0f));
  300. }
  301. BtPhysTest::~BtPhysTest()
  302. {
  303. Ticker::Unref(m_camera);
  304. while (m_constraint_list.Count())
  305. {
  306. EasyConstraint* CurPop = m_constraint_list.Last();
  307. m_constraint_list.Pop();
  308. CurPop->RemoveFromSimulation(m_simulation);
  309. delete CurPop;
  310. }
  311. while (m_ground_list.Count())
  312. {
  313. PhysicsObject* CurPop = m_ground_list.Last();
  314. m_ground_list.Pop();
  315. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  316. Ticker::Unref(CurPop);
  317. }
  318. while (m_character_list.Count())
  319. {
  320. PhysicsObject* CurPop = m_character_list.Last();
  321. m_character_list.Pop();
  322. CurPop->GetCharacter()->RemoveFromSimulation(m_simulation);
  323. Ticker::Unref(CurPop);
  324. }
  325. while (m_platform_list.Count())
  326. {
  327. PhysicsObject* CurPop = m_platform_list.Last();
  328. m_platform_list.Pop();
  329. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  330. Ticker::Unref(CurPop);
  331. }
  332. while (m_physobj_list.Count())
  333. {
  334. PhysicsObject* CurPop = m_physobj_list.Last();
  335. m_physobj_list.Pop();
  336. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  337. Ticker::Unref(CurPop);
  338. }
  339. Ticker::Unref(m_simulation);
  340. }
  341. int main(int argc, char **argv)
  342. {
  343. Application app("BtPhysTest", ivec2(1280, 720), 60.0f);
  344. #if defined _MSC_VER && !defined _XBOX
  345. _chdir("..");
  346. #elif defined _WIN32 && !defined _XBOX
  347. _chdir("../..");
  348. #endif
  349. new BtPhysTest(argc > 1);
  350. app.ShowPointer(false);
  351. app.Run();
  352. return EXIT_SUCCESS;
  353. }