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

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