25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

420 lines
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 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(0.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. PhysicsObject* BasePhyobj = NewPhyobj;
  100. m_platform_list << NewPhyobj;
  101. Ticker::Ref(NewPhyobj);
  102. NewRotation = quat::fromeuler_xyz(0.f, 0.f, 90.f);
  103. NewPosition = pos_offset + vec3(-25.0f, -25.0f, 5.0f);
  104. NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  105. NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, true);
  106. m_platform_list << NewPhyobj;
  107. Ticker::Ref(NewPhyobj);
  108. NewPosition += vec3(-0.0f, .0f, .0f);
  109. NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  110. NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, false);
  111. m_platform_list << NewPhyobj;
  112. Ticker::Ref(NewPhyobj);
  113. NewPosition += vec3(-2.0f, .0f, .0f);
  114. NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  115. NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), false, false);
  116. m_platform_list << NewPhyobj;
  117. Ticker::Ref(NewPhyobj);
  118. }
  119. if (USE_CHARACTER)
  120. {
  121. quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
  122. vec3 NewPosition = pos_offset + vec3(-15.0f, 20.0f, .0f);
  123. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2);
  124. m_character_list << NewPhyobj;
  125. Ticker::Ref(NewPhyobj);
  126. }
  127. if (USE_BODIES)
  128. {
  129. for (int x=0; x < 6; x++)
  130. {
  131. for (int y=0; y < 6; y++)
  132. {
  133. for (int z=0; z < 5; z++)
  134. {
  135. PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
  136. vec3(-20.f, 15.f, -20.f) +
  137. vec3(8.f * (float)x, 8.f * (float)y, 8.f * (float)z));
  138. m_physobj_list << new_physobj;
  139. Ticker::Ref(new_physobj);
  140. }
  141. }
  142. }
  143. }
  144. if (USE_ROPE)
  145. {
  146. Array<PhysicsObject*> RopeElements;
  147. for (int i = 0; i < 14; i++)
  148. {
  149. PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
  150. vec3(0.f, 15.f, -20.f) +
  151. vec3(0.f, 0.f, 2.f * (float)i), 1);
  152. RopeElements << new_physobj;
  153. m_physobj_list << new_physobj;
  154. Ticker::Ref(new_physobj);
  155. if (RopeElements.Count() > 1)
  156. {
  157. EasyConstraint* new_constraint = new EasyConstraint();
  158. vec3 A2B = .5f * (RopeElements[i]->GetPhysic()->GetTransform().v3.xyz -
  159. RopeElements[i - 1]->GetPhysic()->GetTransform().v3.xyz);
  160. new_constraint->SetPhysObjA(RopeElements[i - 1]->GetPhysic(), lol::mat4::translate(A2B));
  161. new_constraint->SetPhysObjB(RopeElements[i]->GetPhysic(), lol::mat4::translate(-A2B));
  162. new_constraint->InitConstraintToPoint2Point();
  163. new_constraint->DisableCollisionBetweenObjs(true);
  164. new_constraint->AddToSimulation(m_simulation);
  165. m_constraint_list << new_constraint;
  166. }
  167. }
  168. }
  169. }
  170. void BtPhysTest::TickGame(float seconds)
  171. {
  172. WorldEntity::TickGame(seconds);
  173. if (Input::GetButtonState(27 /*SDLK_ESCAPE*/))
  174. Ticker::Shutdown();
  175. m_loop_value += seconds;
  176. if (m_loop_value > M_PI * 2.0f)
  177. m_loop_value -= M_PI * 2.0f;
  178. vec3 GroundBarycenter = vec3(.0f);
  179. vec3 PhysObjBarycenter = vec3(.0f);
  180. float factor = .0f;
  181. if (USE_WALL)
  182. {
  183. for (int i = 0; i < m_ground_list.Count(); i++)
  184. {
  185. PhysicsObject* PhysObj = m_ground_list[i];
  186. mat4 GroundMat = PhysObj->GetTransform();
  187. GroundBarycenter += GroundMat.v3.xyz;
  188. factor += 1.f;
  189. }
  190. GroundBarycenter /= factor;
  191. for (int i = 0; i < m_ground_list.Count(); i++)
  192. {
  193. PhysicsObject* PhysObj = m_ground_list[i];
  194. mat4 GroundMat = PhysObj->GetTransform();
  195. vec3 CenterToGround = GroundMat.v3.xyz - GroundBarycenter;
  196. vec3 CenterToCam = m_camera->m_position - GroundBarycenter;
  197. if (dot(normalize(CenterToCam - CenterToGround),
  198. normalize(CenterToGround)) > 0.f)
  199. PhysObj->SetRender(false);
  200. else
  201. PhysObj->SetRender(true);
  202. }
  203. }
  204. if (USE_ROTATION)
  205. {
  206. for (int i = 0; i < m_ground_list.Count(); i++)
  207. {
  208. PhysicsObject* PhysObj = m_ground_list[i];
  209. mat4 GroundMat = PhysObj->GetTransform();
  210. mat4 CenterMx = mat4::translate(GroundBarycenter);
  211. GroundMat = inverse(CenterMx) * GroundMat;
  212. GroundMat = CenterMx *
  213. mat4(quat::fromeuler_xyz(vec3(.0f, 20.f, 20.0f) * seconds))
  214. * GroundMat;
  215. PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
  216. }
  217. }
  218. if (USE_PLATFORM)
  219. {
  220. for (int i = 0; i < m_platform_list.Count(); i++)
  221. {
  222. PhysicsObject* PhysObj = m_platform_list[i];
  223. mat4 GroundMat = PhysObj->GetTransform();
  224. if (i == 0)
  225. {
  226. GroundMat = GroundMat * mat4(quat::fromeuler_xyz(vec3(20.f, .0f, .0f) * seconds));
  227. PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
  228. }
  229. else if (i == 1)
  230. {
  231. GroundMat = mat4::translate(vec3(-15.0f, 5.0f, lol::cos(m_loop_value) * 8.f)) *
  232. mat4(quat::fromeuler_xyz(vec3(.0f, lol::cos(m_loop_value) * 20.f, .0f)));
  233. PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
  234. }
  235. }
  236. }
  237. if (USE_CHARACTER)
  238. {
  239. for (int i = 0; i < m_character_list.Count(); i++)
  240. {
  241. PhysicsObject* PhysObj = m_character_list[i];
  242. EasyCharacterController* Character = (EasyCharacterController*)PhysObj->GetCharacter();
  243. int HMovement = Input::GetButtonState(275 /*SDLK_RIGHT*/) - Input::GetButtonState(276 /*SDLK_LEFT*/);
  244. int VMovement = Input::GetButtonState(273 /*SDLK_UP*/) - Input::GetButtonState(274 /*SDLK_DOWN*/);
  245. int RMovement = Input::GetButtonState(280 /*SDLK_PAGEUP*/) - Input::GetButtonState(281 /*SDLK_PAGEDOWN*/);
  246. Character->SetMovementForFrame(vec3((float)VMovement * seconds * 4.f, (float)RMovement * seconds * 10.f, (float)HMovement * seconds * 4.f));
  247. }
  248. }
  249. if (USE_CHARACTER)
  250. {
  251. PhysObjBarycenter = vec3(.0f);
  252. factor = .0f;
  253. for (int i = 0; i < m_character_list.Count(); i++)
  254. {
  255. PhysicsObject* PhysObj = m_character_list[i];
  256. mat4 GroundMat = PhysObj->GetTransform();
  257. PhysObjBarycenter += GroundMat.v3.xyz;
  258. factor += 1.f;
  259. }
  260. PhysObjBarycenter /= factor;
  261. m_camera->SetTarget(m_camera->GetTarget() + (seconds / (seconds + 0.18f)) * (PhysObjBarycenter - m_camera->GetTarget()));
  262. vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 20.0f, .0f);
  263. m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 5.0f);
  264. }
  265. else
  266. {
  267. PhysObjBarycenter = vec3(.0f);
  268. for (int i = 0; i < m_physobj_list.Count(); i++)
  269. {
  270. PhysicsObject* PhysObj = m_physobj_list[i];
  271. mat4 GroundMat = PhysObj->GetTransform();
  272. PhysObjBarycenter += GroundMat.v3.xyz;
  273. factor += 1.f;
  274. }
  275. PhysObjBarycenter /= factor;
  276. m_camera->SetTarget(PhysObjBarycenter);
  277. m_camera->SetPosition(GroundBarycenter + normalize(GroundBarycenter - PhysObjBarycenter) * 60.0f);
  278. }
  279. }
  280. void BtPhysTest::TickDraw(float seconds)
  281. {
  282. WorldEntity::TickDraw(seconds);
  283. if (!m_ready)
  284. {
  285. /* FIXME: this object never cleans up */
  286. m_ready = true;
  287. }
  288. //Video::SetClearColor(vec4(0.0f, 0.0f, 0.12f, 1.0f));
  289. }
  290. BtPhysTest::~BtPhysTest()
  291. {
  292. Ticker::Unref(m_camera);
  293. while (m_constraint_list.Count())
  294. {
  295. EasyConstraint* CurPop = m_constraint_list.Last();
  296. m_constraint_list.Pop();
  297. CurPop->RemoveFromSimulation(m_simulation);
  298. delete CurPop;
  299. }
  300. while (m_ground_list.Count())
  301. {
  302. PhysicsObject* CurPop = m_ground_list.Last();
  303. m_ground_list.Pop();
  304. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  305. Ticker::Unref(CurPop);
  306. }
  307. while (m_character_list.Count())
  308. {
  309. PhysicsObject* CurPop = m_character_list.Last();
  310. m_character_list.Pop();
  311. CurPop->GetCharacter()->RemoveFromSimulation(m_simulation);
  312. Ticker::Unref(CurPop);
  313. }
  314. while (m_platform_list.Count())
  315. {
  316. PhysicsObject* CurPop = m_platform_list.Last();
  317. m_platform_list.Pop();
  318. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  319. Ticker::Unref(CurPop);
  320. }
  321. while (m_physobj_list.Count())
  322. {
  323. PhysicsObject* CurPop = m_physobj_list.Last();
  324. m_physobj_list.Pop();
  325. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  326. Ticker::Unref(CurPop);
  327. }
  328. Ticker::Unref(m_simulation);
  329. }
  330. int main(int argc, char **argv)
  331. {
  332. Application app("BtPhysTest", ivec2(1280, 720), 60.0f);
  333. #if defined _MSC_VER && !defined _XBOX
  334. _chdir("..");
  335. #elif defined _WIN32 && !defined _XBOX
  336. _chdir("../..");
  337. #endif
  338. new BtPhysTest(argc > 1);
  339. app.ShowPointer(false);
  340. app.Run();
  341. return EXIT_SUCCESS;
  342. }