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