Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. //
  2. // Lol Engine — BtPhys tutorial
  3. //
  4. // Copyright © 2009—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
  5. // © 2012—2015 Sam Hocevar <sam@hocevar.net>
  6. //
  7. // Lol Engine is free software. It comes without any warranty, to
  8. // the extent permitted by applicable law. You can redistribute it
  9. // and/or modify it under the terms of the Do What the Fuck You Want
  10. // to Public License, Version 2, as published by the WTFPL Task Force.
  11. // See http://www.wtfpl.net/ for more details.
  12. //
  13. #if HAVE_CONFIG_H
  14. # include "config.h"
  15. #endif
  16. #include <lol/engine.h>
  17. #include "loldebug.h"
  18. using namespace lol;
  19. #include "physics/lolphysics.h"
  20. #include "physics/easyphysics.h"
  21. #define CAT_MODE 0
  22. #define OBJ_SIZE 2.f
  23. #define NB_SPRITE 4
  24. #define PARTICLE_SIZE 4
  25. #include "physicobject.h"
  26. #include "btphystest.h"
  27. using namespace lol::phys;
  28. #define CUBE_HALF_EXTENTS .5f
  29. #define EXTRA_HEIGHT 1.f
  30. #define BASE_TIME 2.f
  31. #define ZERO_TIME (BASE_TIME + rand(-BASE_TIME * .4f, BASE_TIME * .4f))
  32. #define ZERO_SPEED 3.5f
  33. #define JUMP_HEIGHT 30.f
  34. #define JUMP_STRAFE .5f
  35. #define TARGET_TIMER 10.f + (rand(4.f) - 2.f)
  36. int gNumObjects = 16;
  37. #if CAT_MODE
  38. #define USE_WALL 1
  39. #define USE_BODIES 1
  40. #else
  41. #define USE_WALL 1
  42. #define USE_PLATFORM 0
  43. #define USE_ROPE 0
  44. #define USE_BODIES 1
  45. #define USE_ROTATION 1
  46. #define USE_CHARACTER 0
  47. #define USE_STAIRS 0
  48. #endif
  49. LOLFX_RESOURCE_DECLARE(front_camera_sprite);
  50. BtPhysTest::BtPhysTest(bool editor)
  51. {
  52. m_init_status = 0;
  53. }
  54. void BtPhysTest::InitApp()
  55. {
  56. m_init_status = 1;
  57. m_loop_value = .0f;
  58. #if CAT_MODE
  59. /* cat datas setup */
  60. m_cat_texture = Tiler::Register("data/CatsSheet.png", ivec2::zero, ivec2(0,1));
  61. m_fov_dp = .0f;
  62. m_loc_dp = .0f;
  63. #endif //CAT_MODE
  64. #if 1 //HAS_INPUT
  65. InputProfile& ip = m_profile;
  66. ip.AddBindings<BtPhysTestKeyInput, BtPhysTestKeyInput::KEY_START, BtPhysTestKeyInput::KEY_MAX>(InputProfileType::Keyboard);
  67. m_controller = new Controller("Default");
  68. m_controller->Init(m_profile);
  69. Ticker::Ref(m_controller);
  70. #else
  71. /* Register an input controller for the keyboard */
  72. m_controller = new Controller("Default");
  73. m_controller->SetInputCount(KEY_MAX, 0);
  74. m_controller->GetKey(KEY_MOVE_FORWARD).Bind("Keyboard", "Up");
  75. m_controller->GetKey(KEY_MOVE_BACK).Bind("Keyboard", "Down");
  76. m_controller->GetKey(KEY_MOVE_LEFT).Bind("Keyboard", "Left");
  77. m_controller->GetKey(KEY_MOVE_RIGHT).Bind("Keyboard", "Right");
  78. m_controller->GetKey(KEY_MOVE_JUMP).Bind("Keyboard", "Space");
  79. m_controller->GetKey(KEY_MOVE_UP).Bind("Keyboard", "PageUp");
  80. m_controller->GetKey(KEY_MOVE_DOWN).Bind("Keyboard", "PageDown");
  81. m_controller->GetKey(KEY_QUIT).Bind("Keyboard", "Escape");
  82. #endif
  83. /* Create a camera that matches the settings of XNA BtPhysTest */
  84. m_camera = new Camera();
  85. #if CAT_MODE
  86. m_camera->SetView(vec3(70.f, 50.f, 0.f),
  87. vec3(0.f, 0.f, 0.f),
  88. vec3(0, 1, 0));
  89. m_camera->SetProjection(radians(60.f), .1f, 1000.f, (float)Video::GetSize().x, (float)Video::GetSize().y / (float)Video::GetSize().x);
  90. m_target_timer = TARGET_TIMER;
  91. m_cam_target = -1;
  92. #else
  93. m_camera->SetView(vec3(50.f, 50.f, 0.f),
  94. vec3(0.f, 0.f, 0.f),
  95. vec3(0, 1, 0));
  96. m_camera->SetProjection(radians(45.f), .1f, 1000.f, (float)Video::GetSize().x, (float)Video::GetSize().y / (float)Video::GetSize().x);
  97. #endif
  98. Scene& scene = Scene::GetScene();
  99. scene.PushCamera(m_camera);
  100. m_ready = false;
  101. m_simulation = new Simulation();
  102. m_simulation->SetWorldLimit(vec3(-1000.0f, -1000.0f, -1000.0f), vec3(1000.0f, 1000.0f, 1000.0f));
  103. m_simulation->Init();
  104. vec3 NewGravity = vec3(.0f, -10.0f, .0f);
  105. m_simulation->SetGravity(NewGravity);
  106. m_simulation->SetContinuousDetection(true);
  107. m_simulation->SetTimestep(1.f / 120.f);
  108. Ticker::Ref(m_simulation);
  109. /* Add a white directional light */
  110. m_light1 = new Light();
  111. m_light1->SetPosition(vec3(0.2f, 0.2f, 0.f));
  112. m_light1->SetColor(vec4(0.5f, 0.5f, 0.5f, 1.f));
  113. m_light1->SetType(LightType::Directional);
  114. Ticker::Ref(m_light1);
  115. /* Add an orangeish point light */
  116. m_light2 = new Light();
  117. m_light2->SetPosition(vec3(-15.f, 15.f, 15.f));
  118. m_light2->SetColor(vec4(0.4f, 0.3f, 0.2f, 1.f));
  119. m_light2->SetType(LightType::Point);
  120. Ticker::Ref(m_light2);
  121. float offset = 29.5f;
  122. vec3 pos_offset = vec3(.0f, 30.f, .0f);
  123. #if USE_STAIRS
  124. {
  125. vec3 new_offset = vec3(1.0f, .125f, .0f);
  126. quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
  127. vec3 NewPosition = pos_offset + vec3(5.0f, -29.f, 15.0f);
  128. {
  129. NewRotation = quat::fromeuler_xyz(0.f, 0.f, radians(30.f));
  130. NewPosition += vec3(4.0f, .0f, -4.0f);
  131. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
  132. Ticker::Ref(NewPhyobj);
  133. m_stairs_list << NewPhyobj;
  134. }
  135. {
  136. NewRotation = quat::fromeuler_xyz(0.f, 0.f, radians(40.f));
  137. NewPosition += vec3(4.0f, .0f, -4.0f);
  138. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
  139. Ticker::Ref(NewPhyobj);
  140. m_stairs_list << NewPhyobj;
  141. }
  142. NewPosition = pos_offset + vec3(5.0f, -29.5f, 15.0f);
  143. NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
  144. for (int i=0; i < 15; i++)
  145. {
  146. NewPosition += new_offset;
  147. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
  148. Ticker::Ref(NewPhyobj);
  149. m_stairs_list << NewPhyobj;
  150. }
  151. }
  152. #endif //USE_STAIRS
  153. #if USE_WALL
  154. {
  155. for (int i=0; i < 6; i++)
  156. {
  157. vec3 NewPosition = vec3(.0f);
  158. quat NewRotation = quat(1.f);
  159. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation);
  160. int idx = i/2;
  161. NewPosition = pos_offset;
  162. NewPosition[idx] += offset;
  163. offset *= -1.f;
  164. if (idx != 1)
  165. {
  166. vec3 NewAxis = vec3(.0f);
  167. NewAxis[2 - idx] = 1;
  168. NewRotation = quat::rotate(radians(90.f), NewAxis);
  169. }
  170. NewPhyobj->SetTransform(NewPosition, NewRotation);
  171. Ticker::Ref(NewPhyobj);
  172. m_ground_list << NewPhyobj;
  173. }
  174. }
  175. #endif //USE_WALL
  176. PhysicsObject* BasePhyobj = nullptr;
  177. #if USE_PLATFORM
  178. {
  179. quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
  180. vec3 NewPosition = pos_offset + vec3(5.0f, -25.0f, -15.0f);
  181. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  182. m_platform_list << NewPhyobj;
  183. Ticker::Ref(NewPhyobj);
  184. NewPosition = pos_offset + vec3(-15.0f, -25.0f, 5.0f);
  185. NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  186. BasePhyobj = NewPhyobj;
  187. m_platform_list << NewPhyobj;
  188. Ticker::Ref(NewPhyobj);
  189. NewRotation = quat::fromeuler_xyz(0.f, 0.f, radians(90.f));
  190. NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f);
  191. NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  192. NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, true);
  193. m_platform_list << NewPhyobj;
  194. Ticker::Ref(NewPhyobj);
  195. //NewPosition += vec3(-0.0f, .0f, .0f);
  196. //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  197. //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, false);
  198. //m_platform_list << NewPhyobj;
  199. //Ticker::Ref(NewPhyobj);
  200. //NewPosition += vec3(-2.0f, .0f, .0f);
  201. //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
  202. //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), false, false);
  203. //m_platform_list << NewPhyobj;
  204. //Ticker::Ref(NewPhyobj);
  205. }
  206. #endif //USE_PLATFORM
  207. #if USE_CHARACTER
  208. {
  209. quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
  210. vec3 NewPosition = pos_offset + vec3(-5.0f, -10.0f, 15.0f);
  211. PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2);
  212. m_character_list << NewPhyobj;
  213. Ticker::Ref(NewPhyobj);
  214. //NewPhyobj->GetCharacter()->AttachTo(BasePhyobj->GetPhysic(), true, true);
  215. }
  216. #endif //USE_CHARACTER
  217. #if USE_BODIES
  218. {
  219. for (int x=0; x < 6; x++)
  220. {
  221. for (int y=0; y < 2; y++)
  222. {
  223. for (int z=0; z < 5; z++)
  224. {
  225. PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
  226. vec3(-20.f, 15.f, -20.f) +
  227. #if CAT_MODE
  228. vec3(rand(4.f), rand(2.f), rand(4.f)) -
  229. vec3(2.f , 1.f , 2.f) +
  230. #endif //CAT_MODE
  231. vec3(8.f * (float)x, 8.f * (float)y, 8.f * (float)z));
  232. m_physobj_list.push(new_physobj, ZERO_TIME);
  233. Ticker::Ref(new_physobj);
  234. }
  235. }
  236. }
  237. }
  238. #endif //USE_BODIES
  239. #if USE_ROPE
  240. {
  241. array<PhysicsObject*> RopeElements;
  242. for (int i = 0; i < 14; i++)
  243. {
  244. PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
  245. vec3(0.f, 15.f, -20.f) +
  246. vec3(0.f, 0.f, 2.f * (float)i), 1);
  247. RopeElements << new_physobj;
  248. m_physobj_list.push(new_physobj, ZERO_TIME);
  249. Ticker::Ref(new_physobj);
  250. if (RopeElements.count() > 1)
  251. {
  252. EasyConstraint* new_constraint = new EasyConstraint();
  253. vec3 A2B = .5f * (RopeElements[i]->GetPhysic()->GetTransform()[3].xyz -
  254. RopeElements[i - 1]->GetPhysic()->GetTransform()[3].xyz);
  255. new_constraint->SetPhysObjA(RopeElements[i - 1]->GetPhysic(), lol::mat4::translate(A2B));
  256. new_constraint->SetPhysObjB(RopeElements[i]->GetPhysic(), lol::mat4::translate(-A2B));
  257. new_constraint->InitConstraintToPoint2Point();
  258. new_constraint->DisableCollisionBetweenObjs(true);
  259. new_constraint->AddToSimulation(m_simulation);
  260. m_constraint_list << new_constraint;
  261. }
  262. }
  263. }
  264. #endif //USE_ROPE
  265. }
  266. BtPhysTest::~BtPhysTest()
  267. {
  268. Scene& scene = Scene::GetScene();
  269. scene.PopCamera(m_camera);
  270. Ticker::Unref(m_controller);
  271. Ticker::Unref(m_light1);
  272. Ticker::Unref(m_light2);
  273. #if CAT_MODE
  274. /* cat datas setup */
  275. Shader::Destroy(m_cat_shader);
  276. Tiler::Deregister(m_cat_texture);
  277. #endif //CAT_MODE
  278. while (m_constraint_list.count())
  279. {
  280. EasyConstraint* CurPop = m_constraint_list.last();
  281. m_constraint_list.pop();
  282. CurPop->RemoveFromSimulation(m_simulation);
  283. delete CurPop;
  284. }
  285. array<PhysicsObject*> objects
  286. = m_ground_list
  287. + m_stairs_list
  288. + m_character_list
  289. + m_platform_list;
  290. while (m_physobj_list.count())
  291. {
  292. objects << m_physobj_list.last().m1;
  293. m_physobj_list.pop();
  294. }
  295. m_ground_list.empty();
  296. m_stairs_list.empty();
  297. m_character_list.empty();
  298. m_platform_list.empty();
  299. while (objects.count())
  300. {
  301. PhysicsObject* CurPop = objects.pop();
  302. CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  303. Ticker::Unref(CurPop);
  304. }
  305. //while (m_ground_list.count())
  306. //{
  307. // PhysicsObject* CurPop = m_ground_list.last();
  308. // m_ground_list.pop();
  309. // CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  310. // Ticker::Unref(CurPop);
  311. //}
  312. //while (m_stairs_list.count())
  313. //{
  314. // PhysicsObject* CurPop = m_stairs_list.last();
  315. // m_stairs_list.pop();
  316. // CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  317. // Ticker::Unref(CurPop);
  318. //}
  319. //while (m_character_list.count())
  320. //{
  321. // PhysicsObject* CurPop = m_character_list.last();
  322. // m_character_list.pop();
  323. // CurPop->GetCharacter()->RemoveFromSimulation(m_simulation);
  324. // Ticker::Unref(CurPop);
  325. //}
  326. //while (m_platform_list.count())
  327. //{
  328. // PhysicsObject* CurPop = m_platform_list.last();
  329. // m_platform_list.pop();
  330. // CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  331. // Ticker::Unref(CurPop);
  332. //}
  333. //while (m_physobj_list.count())
  334. //{
  335. // PhysicsObject* CurPop = m_physobj_list.last().m1;
  336. // m_physobj_list.pop();
  337. // CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
  338. // Ticker::Unref(CurPop);
  339. //}
  340. Ticker::Unref(m_simulation);
  341. }
  342. void BtPhysTest::TickGame(float seconds)
  343. {
  344. WorldEntity::TickGame(seconds);
  345. if (!m_init_status)
  346. {
  347. if (Renderer::GetCount())
  348. InitApp();
  349. return;
  350. }
  351. else if (m_init_status == 1)
  352. {
  353. m_init_status++;
  354. return;
  355. }
  356. auto context = Debug::DrawContext::New(Color::white, 1.f);
  357. Debug::DrawGrid(vec3::zero, vec3::axis_x, vec3::axis_y, vec3::axis_z, 10.f);
  358. if (m_controller->WasKeyReleasedThisFrame(BtPhysTestKeyInput::KEY_QUIT))
  359. Ticker::Shutdown();
  360. m_loop_value += seconds;
  361. if (m_loop_value > F_PI * 2.0f)
  362. m_loop_value -= F_PI * 2.0f;
  363. vec3 GroundBarycenter = vec3(.0f);
  364. vec3 PhysObjBarycenter = vec3(.0f);
  365. float factor = .0f;
  366. #if CAT_MODE
  367. #if USE_BODIES
  368. vec3 cam_center(0.f);
  369. float cam_factor = .0f;
  370. vec2 screen_min_max[2] = { vec2(FLT_MAX), vec2(-FLT_MAX) };
  371. Scene& scene = Scene::GetScene();
  372. mat4 world_cam = scene.GetCamera()->GetView();
  373. mat4 cam_screen = scene.GetCamera()->GetProjection();
  374. m_target_timer -= seconds;
  375. if (m_target_timer < .0f)
  376. {
  377. m_target_timer = TARGET_TIMER;
  378. if (m_cam_target == -1)
  379. m_cam_target = rand(m_physobj_list.count());
  380. else
  381. m_cam_target = -1;
  382. }
  383. for (int i = 0; i < m_physobj_list.count(); i++)
  384. {
  385. PhysicsObject* PhysObj = m_physobj_list[i].m1;
  386. float &Timer = m_physobj_list[i].m2;
  387. vec3 obj_loc = PhysObj->GetPhysic()->GetTransform()[3].xyz;
  388. if (m_cam_target == -1 || m_cam_target == i)
  389. {
  390. cam_center += obj_loc;
  391. cam_factor += 1.f;
  392. mat4 LocalPos = mat4::translate(obj_loc);
  393. vec3 vpos;
  394. LocalPos = world_cam * LocalPos;
  395. mat4 LocalPos0 = LocalPos;
  396. int j = 2;
  397. while (j-- > 0)
  398. {
  399. if (j == 1)
  400. LocalPos = mat4::translate(vec3(-4.f)) * LocalPos0;
  401. else
  402. LocalPos = mat4::translate(vec3(4.f)) * LocalPos0;
  403. LocalPos = cam_screen * LocalPos;
  404. vpos = (LocalPos[3] / LocalPos[3].w).xyz;
  405. screen_min_max[0] = min(vpos.xy, screen_min_max[0]);
  406. screen_min_max[1] = max(vpos.xy, screen_min_max[1]);
  407. }
  408. }
  409. //Jump handling
  410. //if (length(PhysObj->GetPhysic()->GetLinearVelocity()) < ZERO_SPEED)
  411. if (lol::abs(PhysObj->GetPhysic()->GetLinearVelocity().y) < ZERO_SPEED)
  412. Timer -= seconds;
  413. if (Timer < .0f)
  414. {
  415. PhysObj->GetPhysic()->AddImpulse(JUMP_HEIGHT *
  416. vec3(JUMP_STRAFE, 1.f, JUMP_STRAFE) *
  417. vec3(rand(-1.f, 1.f), 1.0f, rand(-1.f, 1.f)) *
  418. PhysObj->GetPhysic()->GetMass());
  419. Timer = ZERO_TIME;
  420. }
  421. }
  422. float fov_ratio = max(max(lol::abs(screen_min_max[0].x), lol::abs(screen_min_max[0].y)),
  423. max(lol::abs(screen_min_max[1].x), lol::abs(screen_min_max[1].y)));
  424. vec3 new_target = cam_center / cam_factor;
  425. float fov_dp = .0f;
  426. float loc_dp = .0f;
  427. //ideally fov is on the target
  428. if (lol::abs(fov_ratio - 1.f) < .2f)
  429. fov_dp = ((m_cam_target == -1)?(.7f):(.2f));
  430. else
  431. fov_dp = ((m_cam_target == -1)?(1.7f):(.9f));
  432. //ideally loc is on the target
  433. if (length(new_target - m_camera->GetTarget()) < 6.f)
  434. loc_dp = ((m_cam_target == -1)?(.5f):(.03f));
  435. else
  436. loc_dp = ((m_cam_target == -1)?(.9f):(.5f));
  437. m_fov_dp = damp(m_fov_dp, fov_dp, 0.08f, seconds);
  438. m_loc_dp = damp(m_loc_dp, loc_dp, 0.08f, seconds);
  439. m_camera->SetFov(damp(m_camera->GetFov(), m_camera->GetFov() * fov_ratio * 1.1f, m_fov_dp, seconds));
  440. vec3 tmp = damp(m_camera->GetTarget(), new_target, m_loc_dp, seconds);
  441. m_camera->SetView((mat4::rotate(radians(10.f) * seconds, vec3(.0f, 1.f, .0f)) * vec4(m_camera->GetPosition(), 1.0f)).xyz,
  442. tmp, vec3(0, 1, 0));
  443. #endif //USE_BODIES
  444. #endif //CAT_MODE
  445. #if USE_WALL
  446. {
  447. for (int i = 0; i < m_ground_list.count(); i++)
  448. {
  449. PhysicsObject* PhysObj = m_ground_list[i];
  450. mat4 GroundMat = PhysObj->GetTransform();
  451. GroundBarycenter += GroundMat[3].xyz;
  452. factor += 1.f;
  453. }
  454. GroundBarycenter /= factor;
  455. for (int i = 0; i < m_ground_list.count(); i++)
  456. {
  457. PhysicsObject* PhysObj = m_ground_list[i];
  458. mat4 GroundMat = PhysObj->GetTransform();
  459. vec3 CenterToGround = GroundMat[3].xyz - GroundBarycenter;
  460. vec3 CenterToCam = m_camera->GetPosition() - GroundBarycenter;
  461. if (dot(normalize(CenterToCam - CenterToGround),
  462. normalize(CenterToGround)) > 0.f)
  463. PhysObj->SetRender(false);
  464. else
  465. PhysObj->SetRender(true);
  466. }
  467. }
  468. #endif //USE_WALL
  469. #if USE_ROTATION
  470. {
  471. for (int i = 0; i < m_ground_list.count(); i++)
  472. {
  473. PhysicsObject* PhysObj = m_ground_list[i];
  474. mat4 GroundMat = PhysObj->GetTransform();
  475. mat4 CenterMx = mat4::translate(GroundBarycenter);
  476. GroundMat = inverse(CenterMx) * GroundMat;
  477. GroundMat = CenterMx *
  478. mat4(quat::fromeuler_xyz(vec3(.0f, radians(20.f), radians(20.0f)) * seconds))
  479. * GroundMat;
  480. PhysObj->SetTransform(GroundMat[3].xyz, quat(mat3(GroundMat)));
  481. }
  482. }
  483. #endif //USE_ROTATION
  484. #if USE_PLATFORM
  485. {
  486. for (int i = 0; i < m_platform_list.count(); i++)
  487. {
  488. PhysicsObject* PhysObj = m_platform_list[i];
  489. mat4 GroundMat = PhysObj->GetTransform();
  490. if (i == 0)
  491. {
  492. GroundMat = GroundMat * mat4(quat::fromeuler_xyz(vec3(radians(20.f), .0f, .0f) * seconds));
  493. PhysObj->SetTransform(GroundMat[3].xyz, quat(mat3(GroundMat)));
  494. }
  495. else if (i == 1)
  496. {
  497. GroundMat =
  498. mat4::translate(vec3(-15.0f, 5.0f, lol::cos(m_loop_value) * 8.f)) *
  499. mat4(quat::fromeuler_xyz(vec3(.0f, lol::cos(m_loop_value) * radians(20.f), .0f)));
  500. PhysObj->SetTransform(GroundMat[3].xyz, quat(mat3(GroundMat)));
  501. }
  502. }
  503. }
  504. #endif //USE_PLATFORM
  505. #if USE_CHARACTER
  506. {
  507. for (int i = 0; i < m_character_list.count(); i++)
  508. {
  509. PhysicsObject* PhysObj = m_character_list[i];
  510. EasyCharacterController* Character = (EasyCharacterController*)PhysObj->GetCharacter();
  511. mat4 CtlrMx = Character->GetTransform();
  512. vec3 movement(0.f);
  513. movement.z = (m_controller->IsKeyPressed(KEY_MOVE_RIGHT) ? 1.f : 0.f)
  514. - (m_controller->IsKeyPressed(KEY_MOVE_LEFT) ? 1.f : 0.f);
  515. movement.x = (m_controller->IsKeyPressed(KEY_MOVE_FORWARD) ? 1.f : 0.f)
  516. - (m_controller->IsKeyPressed(KEY_MOVE_BACK) ? 1.f : 0.f);
  517. movement.y = (m_controller->IsKeyPressed(KEY_MOVE_UP) ? 1.f : 0.f)
  518. - (m_controller->IsKeyPressed(KEY_MOVE_DOWN) ? 1.f : 0.f);
  519. vec3 CharMove = movement * seconds * vec3(4.f, 10.f, 4.f);
  520. if (m_controller->WasKeyReleasedThisFrame(KEY_MOVE_JUMP))
  521. Character->Jump();
  522. Character->SetMovementForFrame(CharMove);
  523. RayCastResult HitResult;
  524. if (m_simulation->RayHits(HitResult, ERT_Closest, Character->GetTransform()[3].xyz, (Character->GetTransform()[3].xyz + vec3(.0f, -1.f, .0f)), Character))
  525. Character->AttachTo(HitResult.m_collider_list[0], true, true);
  526. else
  527. Character->AttachTo(nullptr);
  528. }
  529. }
  530. #endif //USE_CHARACTER
  531. #if USE_CHARACTER
  532. {
  533. PhysObjBarycenter = vec3(.0f);
  534. factor = .0f;
  535. for (int i = 0; i < m_character_list.count(); i++)
  536. {
  537. PhysicsObject* PhysObj = m_character_list[i];
  538. mat4 GroundMat = PhysObj->GetTransform();
  539. PhysObjBarycenter += GroundMat[3].xyz;
  540. factor += 1.f;
  541. }
  542. PhysObjBarycenter /= factor;
  543. #if 0
  544. m_camera->SetTarget(m_camera->GetTarget() + (seconds / (seconds + 0.18f)) * (PhysObjBarycenter - m_camera->GetTarget()));
  545. vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 5.0f, .0f);
  546. m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 20.0f);
  547. #endif
  548. }
  549. #else
  550. {
  551. PhysObjBarycenter = vec3(.0f);
  552. for (int i = 0; i < m_physobj_list.count(); i++)
  553. {
  554. PhysicsObject* PhysObj = m_physobj_list[i].m1;
  555. mat4 GroundMat = PhysObj->GetTransform();
  556. PhysObjBarycenter += GroundMat[3].xyz;
  557. factor += 1.f;
  558. }
  559. PhysObjBarycenter /= factor;
  560. #if 0
  561. m_camera->SetTarget(PhysObjBarycenter);
  562. m_camera->SetPosition(GroundBarycenter + normalize(GroundBarycenter - PhysObjBarycenter) * 60.0f);
  563. #endif
  564. }
  565. #endif //USE_CHARACTER
  566. }
  567. void BtPhysTest::TickDraw(float seconds, Scene &scene)
  568. {
  569. WorldEntity::TickDraw(seconds, scene);
  570. if (m_init_status != 2)
  571. return;
  572. if (!m_ready)
  573. {
  574. #if CAT_MODE
  575. /* cat datas setup */
  576. m_cat_shader = Shader::Create(LOLFX_RESOURCE_NAME(front_camera_sprite));
  577. #if USE_BODIES
  578. for (int i = 0; i < m_physobj_list.count(); i++)
  579. {
  580. PhysicsObject* PhysObj = m_physobj_list[i].m1;
  581. m_cat_sdata = new CatShaderData(((1 << VertexUsage::Position) |
  582. (1 << VertexUsage::Color) |
  583. (1 << VertexUsage::TexCoord) |
  584. (1 << VertexUsage::TexCoordExt)),
  585. m_cat_shader);
  586. m_cat_sdata->m_tex_uniform = m_cat_texture->GetTexture()->GetTextureUniform();
  587. m_cat_sdata->m_sprite_flip = ((rand(2) == 1)?(1.f):(0.f)) / (float)(NB_SPRITE * PARTICLE_SIZE);
  588. PhysObj->SetCustomShaderData(m_cat_sdata);
  589. m_cat_sdata = nullptr;
  590. }
  591. #endif //USE_BODIES
  592. #endif //CAT_MODE
  593. /* FIXME: this object never cleans up */
  594. m_ready = true;
  595. }
  596. else
  597. {
  598. #if CAT_MODE
  599. for (int i = 0; i < m_physobj_list.count(); i++)
  600. {
  601. PhysicsObject* PhysObj = m_physobj_list[i].m1;
  602. CatShaderData* ShaderData = (CatShaderData*)PhysObj->GetCustomShaderData();
  603. ShaderData->m_sprite_orientation = damp(ShaderData->m_sprite_orientation,
  604. F_PI_4 * ((ShaderData->m_sprite_flip * 2.f * (float)(NB_SPRITE * PARTICLE_SIZE)) - 1.f) *
  605. clamp(PhysObj->GetPhysic()->GetLinearVelocity().y / 20.0f, -1.f, 1.f),
  606. 0.1f, seconds);
  607. }
  608. #endif //CAT_MODE
  609. }
  610. //Video::SetClearColor(vec4(0.0f, 0.0f, 0.12f, 1.0f));
  611. }
  612. //-----------------------------------------------------------------------------
  613. // CShaderData
  614. //-----------------------------------------------------------------------------
  615. CatShaderData::CatShaderData(uint32_t vert_decl_flags, Shader* shader)
  616. : GpuShaderData(vert_decl_flags, shader, DebugRenderMode::Default)
  617. {
  618. m_sprite_orientation = .0f;
  619. m_sprite_flip = .0f;
  620. SetupDefaultData();
  621. }
  622. //-----------------------------------------------------------------------------
  623. void CatShaderData::SetupDefaultData()
  624. {
  625. AddUniform("u_model_view");
  626. AddUniform("u_normal_mat");
  627. AddUniform("u_proj");
  628. AddUniform("u_texture");
  629. AddUniform("u_sprite_orientation");
  630. AddUniform("u_sprite_flip");
  631. }
  632. //-----------------------------------------------------------------------------
  633. void CatShaderData::SetupShaderDatas(mat4 const &model)
  634. {
  635. Scene& scene = Scene::GetScene();
  636. mat4 proj = scene.GetCamera()->GetProjection();
  637. mat4 view = scene.GetCamera()->GetView();
  638. mat4 modelview = view * model;
  639. mat3 normalmat = transpose(inverse(mat3(view)));
  640. m_shader->SetUniform(*GetUniform("u_model_view"), modelview);
  641. m_shader->SetUniform(*GetUniform("u_normal_mat"), normalmat);
  642. m_shader->SetUniform(*GetUniform("u_proj"), proj);
  643. m_shader->SetUniform(*GetUniform("u_texture"), m_tex_uniform, 0);
  644. m_shader->SetUniform(*GetUniform("u_sprite_orientation"), m_sprite_orientation);
  645. m_shader->SetUniform(*GetUniform("u_sprite_flip"), m_sprite_flip);
  646. }
  647. int main(int argc, char **argv)
  648. {
  649. sys::init(argc, argv);
  650. Application app("BtPhysTest", ivec2(1280, 960), 60.0f);
  651. new BtPhysTest(argc > 1);
  652. app.ShowPointer(false);
  653. app.Run();
  654. return EXIT_SUCCESS;
  655. }