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.
 
 
 

434 regels
11 KiB

  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. }