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.

meshviewer.cpp 29 KiB

11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
11 vuotta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. //
  2. // Lol Engine - EasyMesh tutorial
  3. //
  4. // Copyright: (c) 2011-2013 Sam Hocevar <sam@hocevar.net>
  5. // (c) 2012-2013 Benjamin "Touky" Huet <huet.benjamin@gmail.com>
  6. // This program is free software; you can redistribute it and/or
  7. // modify it under the terms of the Do What The Fuck You Want To
  8. // Public License, Version 2, as published by Sam Hocevar. See
  9. // http://www.wtfpl.net/ for more details.
  10. //
  11. #if defined HAVE_CONFIG_H
  12. # include "config.h"
  13. #endif
  14. #include <cfloat> /* for FLT_MAX */
  15. #include "core.h"
  16. #include "scenesetup.h"
  17. using namespace std;
  18. using namespace lol;
  19. static int const TEXTURE_WIDTH = 256;
  20. #define R_M 1.f
  21. #define DEFAULT_WIDTH (1200.f * R_M)
  22. #define DEFAULT_HEIGHT (400.f * R_M)
  23. #define WIDTH ((float)Video::GetSize().x)
  24. #define HEIGHT ((float)Video::GetSize().y)
  25. #define SCREEN_W (10.f / WIDTH)
  26. #define SCREEN_LIMIT 1.4f
  27. #define RATIO_HW (HEIGHT / WIDTH)
  28. #define RATIO_WH (WIDTH / HEIGHT)
  29. #define RESET_TIMER .2f
  30. #define ROT_SPEED vec2(50.f)
  31. #define ROT_CLAMP 89.f
  32. #define POS_SPEED vec2(1.2f)
  33. #define POS_CLAMP 1.f
  34. #define FOV_SPEED 20.f
  35. #define FOV_CLAMP 120.f
  36. #define ZOM_SPEED 3.f
  37. #define ZOM_CLAMP 20.f
  38. #define HST_SPEED .5f
  39. #define HST_CLAMP 1.f
  40. #define WITH_TEXTURE 0
  41. #define NO_NACL_EM (!__native_client__ && !EMSCRIPTEN)
  42. #define NACL_EM (__native_client__ || EMSCRIPTEN)
  43. #define HAS_KBOARD (m_input_usage & (1<<IPT_MV_KBOARD))
  44. #define HAS_MOUSE (m_input_usage & (1<<IPT_MV_MOUSE))
  45. LOLFX_RESOURCE_DECLARE(shinyfur);
  46. LOLFX_RESOURCE_DECLARE(shinymvtexture);
  47. enum
  48. {
  49. IPT_MV_KBOARD = 0,
  50. IPT_MV_MOUSE,
  51. INPUT_MAX
  52. };
  53. enum MVKeyboardList
  54. {
  55. KEY_CAM_RESET = 0,
  56. KEY_CAM_POS,
  57. KEY_CAM_FOV,
  58. KEY_CAM_UP,
  59. KEY_CAM_DOWN,
  60. KEY_CAM_LEFT,
  61. KEY_CAM_RIGHT,
  62. KEY_MESH_NEXT,
  63. KEY_MESH_PREV,
  64. KEY_F1,
  65. KEY_F2,
  66. KEY_F3,
  67. KEY_F4,
  68. KEY_F5,
  69. KEY_ESC,
  70. KEY_MAX
  71. };
  72. enum MVMouseKeyList
  73. {
  74. MSE_CAM_ROT = KEY_MAX,
  75. MSE_CAM_POS,
  76. MSE_CAM_FOV,
  77. MSE_MAX
  78. };
  79. enum MVMouseAxisList
  80. {
  81. MSEX_CAM_Y = 0,
  82. MSEX_CAM_X,
  83. MSEX_MAX
  84. };
  85. #define MAX_KEYS MSE_MAX
  86. #define MAX_AXIS MSEX_MAX
  87. #define ALL_FEATURES 1
  88. #define NO_SC_SETUP 0
  89. enum GizmoType
  90. {
  91. GZ_Editor = 0,
  92. GZ_LightPos,
  93. GZ_LightDir,
  94. GZ_MAX
  95. };
  96. struct LightData
  97. {
  98. LightData(vec3 pos, vec4 col)
  99. {
  100. m_pos = pos;
  101. m_col = col;
  102. }
  103. vec3 m_pos;
  104. vec4 m_col;
  105. };
  106. class MeshViewer : public WorldEntity
  107. {
  108. public:
  109. MeshViewer(char const *file_name = "data/mesh-buffer.txt")
  110. : m_file_name(file_name)
  111. {
  112. m_init = false;
  113. m_first_tick = false;
  114. // Message Service
  115. MessageService::Setup();
  116. m_ssetup = nullptr;
  117. m_camera = nullptr;
  118. m_controller = nullptr;
  119. //Compile ref meshes
  120. m_gizmos << new EasyMesh();
  121. m_gizmos.Last()->Compile("[sc#0f0 ac 3 .5 .4 0 ty .25 [ad 3 .4 sy -1] ty .5 ac 3 1 .1 ty .5 dup[rz 90 ry 90 scv#00f dup[ry 90 scv#f00]]][sc#fff ab .1]");
  122. m_gizmos << new EasyMesh();
  123. m_gizmos.Last()->Compile("[sc#666 acap 1 .5 .5 ty -.5 sc#fff asph 2 1]");
  124. m_gizmos << new EasyMesh();
  125. m_gizmos.Last()->Compile("[sc#fff ac 3 .5 .4 0 ty .25 [ad 3 .4 sy -1] ty .5 ac 3 1 .1 ty .5 [ad 3 .1 sy -1] ty 1 rz 90 ry 90]");
  126. // Mesh Setup
  127. m_render_max = vec2(-.9f, 4.1f);
  128. m_mesh_id = 0;
  129. m_mesh_id1 = 0.f;
  130. m_default_texture = nullptr;
  131. m_texture_shader = nullptr;
  132. m_texture = nullptr;
  133. //Camera Setup
  134. m_reset_timer = -1.f;
  135. m_fov = -100.f;
  136. m_fov_mesh = 0.f;
  137. m_fov_speed = 0.f;
  138. m_zoom = -100.f;
  139. m_zoom_mesh = 0.f;
  140. m_zoom_speed = 0.f;
  141. m_rot = vec2(45.f);
  142. m_rot_mesh = vec2::zero;
  143. m_rot_speed = vec2::zero;
  144. m_pos = vec2::zero;
  145. m_pos_mesh = vec2::zero;
  146. m_pos_speed = vec2::zero;
  147. m_screen_offset = vec2::zero;
  148. m_hist_scale = vec2(.13f, .03f);
  149. m_hist_scale_mesh = vec2(.0f);
  150. m_hist_scale_speed = vec2(.0f);
  151. m_mat_prev = mat4(quat::fromeuler_xyz(vec3::zero));
  152. m_mat = mat4(quat::fromeuler_xyz(vec3(m_rot_mesh, .0f)));
  153. //stream update
  154. m_stream_update_time = 2.0f;
  155. m_stream_update_timer = 1.0f;
  156. }
  157. ~MeshViewer()
  158. {
  159. if (m_camera)
  160. g_scene->PopCamera(m_camera);
  161. if (m_ssetup)
  162. delete(m_ssetup);
  163. MessageService::Destroy();
  164. m_controller = nullptr;
  165. m_camera = nullptr;
  166. m_ssetup = nullptr;
  167. }
  168. #if NO_NACL_EM
  169. bool KeyReleased(MVKeyboardList index) { return (HAS_KBOARD && m_controller->GetKey(index).IsReleased()); }
  170. bool KeyPressed(MVKeyboardList index) { return (HAS_KBOARD && m_controller->GetKey(index).IsPressed()); }
  171. bool KeyDown(MVKeyboardList index) { return (HAS_KBOARD && m_controller->GetKey(index).IsDown()); }
  172. bool KeyReleased(MVMouseKeyList index) { return (HAS_MOUSE && m_controller->GetKey(index).IsReleased()); }
  173. bool KeyPressed(MVMouseKeyList index) { return (HAS_MOUSE && m_controller->GetKey(index).IsPressed()); }
  174. bool KeyDown(MVMouseKeyList index) { return (HAS_MOUSE && m_controller->GetKey(index).IsDown()); }
  175. float AxisValue(MVMouseAxisList index) { return (HAS_MOUSE)?(m_controller->GetAxis(index).GetValue()):(0.f); }
  176. #endif //NO_NACL_EM
  177. void Init()
  178. {
  179. m_init = true;
  180. m_input_usage = 0;
  181. #if NO_NACL_EM
  182. /* Register an input controller for the keyboard */
  183. m_controller = new Controller("Default", MAX_KEYS, MAX_AXIS);
  184. if (InputDevice::Get("Mouse"))
  185. {
  186. m_input_usage |= (1<<IPT_MV_MOUSE);
  187. m_controller->GetKey(MSE_CAM_ROT).Bind("Mouse", "Left");
  188. m_controller->GetKey(MSE_CAM_POS).Bind("Mouse", "Right");
  189. m_controller->GetKey(MSE_CAM_FOV).Bind("Mouse", "Middle");
  190. m_controller->GetAxis(MSEX_CAM_Y).Bind("Mouse", "Y");
  191. m_controller->GetAxis(MSEX_CAM_X).Bind("Mouse", "X");
  192. }
  193. if (InputDevice::Get("Keyboard"))
  194. {
  195. m_input_usage |= (1<<IPT_MV_KBOARD);
  196. //Camera keyboard rotation
  197. m_controller->GetKey(KEY_CAM_UP ).Bind("Keyboard", "Up");
  198. m_controller->GetKey(KEY_CAM_DOWN ).Bind("Keyboard", "Down");
  199. m_controller->GetKey(KEY_CAM_LEFT ).Bind("Keyboard", "Left");
  200. m_controller->GetKey(KEY_CAM_RIGHT).Bind("Keyboard", "Right");
  201. //Camera keyboard position switch
  202. m_controller->GetKey(KEY_CAM_POS ).Bind("Keyboard", "LeftShift");
  203. m_controller->GetKey(KEY_CAM_FOV ).Bind("Keyboard", "LeftCtrl");
  204. //Camera unzoom switch
  205. m_controller->GetKey(KEY_CAM_RESET).Bind("Keyboard", "Space");
  206. //Mesh change
  207. m_controller->GetKey(KEY_MESH_NEXT).Bind("Keyboard", "PageUp");
  208. m_controller->GetKey(KEY_MESH_PREV).Bind("Keyboard", "PageDown");
  209. //Base setup
  210. m_controller->GetKey(KEY_F1).Bind("Keyboard", "F1");
  211. m_controller->GetKey(KEY_F2).Bind("Keyboard", "F2");
  212. m_controller->GetKey(KEY_F3).Bind("Keyboard", "F3");
  213. m_controller->GetKey(KEY_F4).Bind("Keyboard", "F4");
  214. m_controller->GetKey(KEY_F5).Bind("Keyboard", "F5");
  215. m_controller->GetKey(KEY_ESC).Bind("Keyboard", "Escape");
  216. }
  217. #endif //NO_NACL_EM
  218. m_camera = new Camera();
  219. m_camera->SetView(vec3(0.f, 0.f, 10.f), vec3::zero, vec3::axis_y);
  220. m_camera->SetProjection(0.f, .0001f, 2000.f, WIDTH * SCREEN_W, RATIO_HW);
  221. m_camera->UseShift(true);
  222. g_scene->PushCamera(m_camera);
  223. //Lights setup
  224. m_ssetup = new SceneSetup();
  225. #if NO_SC_SETUP
  226. m_ssetup->m_lights << new Light();
  227. m_ssetup->m_lights.Last()->SetPosition(vec4(4.f, -1.f, -4.f, 0.f));
  228. m_ssetup->m_lights.Last()->SetColor(vec4(.0f, .2f, .5f, 1.f));
  229. Ticker::Ref(m_ssetup->m_lights.Last());
  230. m_ssetup->m_lights << new Light();
  231. m_ssetup->m_lights.Last()->SetPosition(vec4(8.f, 2.f, 6.f, 0.f));
  232. m_ssetup->m_lights.Last()->SetColor(vec4(1.f));
  233. Ticker::Ref(m_ssetup->m_lights.Last());
  234. EasyMesh* em = new EasyMesh();
  235. if (em->Compile("sc#fff ab 1"))
  236. {
  237. if (m_mesh_id == m_meshes.Count() - 1)
  238. m_mesh_id++;
  239. m_meshes.Push(em);
  240. }
  241. #else
  242. m_ssetup->Compile("addlight 0.0 position (4 -1 -4) color (.0 .2 .5 1) "
  243. "addlight 0.0 position (8 2 6) color #ffff "
  244. "showgizmo true ");
  245. m_ssetup->Startup();
  246. #endif //NO_SC_SETUP
  247. for (int i = 0; i < m_ssetup->m_lights.Count(); ++i)
  248. {
  249. m_light_datas << LightData(m_ssetup->m_lights[i]->GetPosition().xyz, m_ssetup->m_lights[i]->GetColor());
  250. m_ssetup->m_lights[i]->SetPosition(vec4(vec3::zero, m_ssetup->m_lights[i]->GetPosition().w));
  251. m_ssetup->m_lights[i]->SetColor(vec4::zero);
  252. }
  253. }
  254. virtual void TickGame(float seconds)
  255. {
  256. WorldEntity::TickGame(seconds);
  257. if (!m_init && g_scene)
  258. {
  259. Init();
  260. return;
  261. }
  262. if (!m_init)
  263. return;
  264. m_first_tick = true;
  265. //TODO : This should probably be "standard LoL behaviour"
  266. #if NO_NACL_EM
  267. {
  268. //Shutdown logic
  269. if (KeyReleased(KEY_ESC))
  270. Ticker::Shutdown();
  271. }
  272. #endif //NO_NACL_EM
  273. //Compute render mesh count
  274. float a_j = lol::abs(m_render_max[1]);
  275. float i_m = m_hist_scale_mesh.x;
  276. float i_trans = a_j - ((a_j * a_j * i_m * i_m + a_j * i_m) * .5f);
  277. m_render_max[1] = a_j * ((RATIO_WH * 1.f) / ((i_trans != 0.f)?(i_trans):(RATIO_WH))) - RATIO_HW * .3f;
  278. //Mesh Change
  279. #if NO_NACL_EM
  280. m_mesh_id = clamp(m_mesh_id + ((int)KeyPressed(KEY_MESH_PREV) - (int)KeyPressed(KEY_MESH_NEXT)), 0, m_meshes.Count() - 1);
  281. #endif //NO_NACL_EM
  282. m_mesh_id1 = damp(m_mesh_id1, (float)m_mesh_id, .2f, seconds);
  283. #if ALL_FEATURES
  284. //Update light position & damping
  285. for (int i = 0; i < m_ssetup->m_lights.Count(); ++i)
  286. {
  287. vec3 pos = (m_mat * inverse(m_mat_prev) * vec4(m_ssetup->m_lights[i]->GetPosition().xyz, 1.f)).xyz;
  288. vec3 tgt = (m_mat * vec4(m_light_datas[i].m_pos, 1.f)).xyz;
  289. vec3 new_pos = damp(pos, tgt, .3f, seconds);
  290. vec4 new_col = damp(m_ssetup->m_lights[i]->GetColor(), m_light_datas[i].m_col, .3f, seconds);
  291. m_ssetup->m_lights[i]->SetPosition(vec4(new_pos, m_ssetup->m_lights[i]->GetPosition().w));
  292. m_ssetup->m_lights[i]->SetColor(new_col);
  293. }
  294. //Camera update
  295. bool is_pos = false;
  296. bool is_fov = false;
  297. bool is_hsc = false;
  298. vec2 tmpv = vec2::zero;
  299. #if NO_NACL_EM
  300. is_pos = KeyDown(KEY_CAM_POS) || KeyDown(MSE_CAM_POS);
  301. is_fov = KeyDown(KEY_CAM_FOV) || KeyDown(MSE_CAM_FOV);
  302. if (KeyDown(MSE_CAM_ROT) || KeyDown(MSE_CAM_POS) || KeyDown(MSE_CAM_FOV))
  303. {
  304. tmpv += vec2(AxisValue(MSEX_CAM_Y), AxisValue(MSEX_CAM_X));
  305. if (KeyDown(MSE_CAM_ROT))
  306. tmpv *= 6.f;
  307. if (KeyDown(MSE_CAM_POS))
  308. tmpv *= vec2(1.f, -1.f) * 3.f;
  309. if (KeyDown(MSE_CAM_FOV))
  310. tmpv = vec2(tmpv.y * 4.f, tmpv.x * 6.f);
  311. }
  312. tmpv += vec2((float)KeyDown(KEY_CAM_UP ) - (float)KeyDown(KEY_CAM_DOWN),
  313. (float)KeyDown(KEY_CAM_RIGHT) - (float)KeyDown(KEY_CAM_LEFT));
  314. #endif //NO_NACL_EM
  315. //Base data
  316. vec2 rot = (!is_pos && !is_fov)?(tmpv):(vec2(.0f)); rot = vec2(rot.x, rot.y);
  317. vec2 pos = ( is_pos && !is_fov)?(tmpv):(vec2(.0f)); pos = -vec2(pos.y, pos.x);
  318. vec2 fov = (!is_pos && is_fov )?(tmpv):(vec2(.0f)); fov = vec2(-fov.x, fov.y);
  319. vec2 hsc = (is_hsc)?(vec2(0.f)):(vec2(0.f));
  320. //speed
  321. m_rot_speed = damp(m_rot_speed, rot * ROT_SPEED, .2f, seconds);
  322. float pos_factor = 1.f / (1.f + m_zoom_mesh * .5f);
  323. m_pos_speed = damp(m_pos_speed, pos * POS_SPEED * pos_factor, .2f, seconds);
  324. float fov_factor = 1.f + lol::pow((m_fov_mesh / FOV_CLAMP) * 1.f, 2.f);
  325. m_fov_speed = damp(m_fov_speed, fov.x * FOV_SPEED * fov_factor, .2f, seconds);
  326. float zom_factor = 1.f + lol::pow((m_zoom_mesh / ZOM_CLAMP) * 1.f, 2.f);
  327. m_zoom_speed = damp(m_zoom_speed, fov.y * ZOM_SPEED * zom_factor, .2f, seconds);
  328. m_hist_scale_speed = damp(m_hist_scale_speed, hsc * HST_SPEED, .2f, seconds);
  329. m_rot += m_rot_speed * seconds;
  330. #if NO_NACL_EM
  331. if (m_reset_timer >= 0.f)
  332. m_reset_timer -= seconds;
  333. if (KeyPressed(KEY_CAM_RESET))
  334. {
  335. if (m_reset_timer >= 0.f)
  336. {
  337. m_pos = vec2(0.f);
  338. m_zoom = -100.f;
  339. }
  340. else
  341. m_reset_timer = RESET_TIMER;
  342. }
  343. //Transform update
  344. if (!KeyDown(KEY_CAM_RESET))
  345. {
  346. m_pos += m_pos_speed * seconds;
  347. m_fov += m_fov_speed * seconds;
  348. m_zoom += m_zoom_speed * seconds;
  349. m_hist_scale += m_hist_scale_speed * seconds;
  350. }
  351. #endif //NO_NACL_EM
  352. //clamp
  353. vec2 rot_mesh = vec2(SmoothClamp(m_rot.x, -ROT_CLAMP, ROT_CLAMP, ROT_CLAMP * .1f), m_rot.y);
  354. vec2 pos_mesh = vec2(SmoothClamp(m_pos.x, -POS_CLAMP, POS_CLAMP, POS_CLAMP * .1f),
  355. SmoothClamp(m_pos.y, -POS_CLAMP, POS_CLAMP, POS_CLAMP * .1f));
  356. float fov_mesh = SmoothClamp(m_fov, 0.f, FOV_CLAMP, FOV_CLAMP * .1f);
  357. float zoom_mesh = SmoothClamp(m_zoom, 0.f, ZOM_CLAMP, ZOM_CLAMP * .1f);
  358. vec2 hist_scale_mesh = vec2(SmoothClamp(m_hist_scale.x, 0.f, HST_CLAMP, HST_CLAMP * .1f),
  359. SmoothClamp(m_hist_scale.y, 0.f, HST_CLAMP, HST_CLAMP * .1f));
  360. #if NO_NACL_EM
  361. if (KeyDown(KEY_CAM_RESET) && m_reset_timer < 0.f)
  362. {
  363. pos_mesh = vec2::zero;
  364. zoom_mesh = 0.f;
  365. }
  366. #endif //NO_NACL_EM
  367. m_rot_mesh = vec2(damp(m_rot_mesh.x, rot_mesh.x, .2f, seconds), damp(m_rot_mesh.y, rot_mesh.y, .2f, seconds));
  368. m_pos_mesh = vec2(damp(m_pos_mesh.x, pos_mesh.x, .2f, seconds), damp(m_pos_mesh.y, pos_mesh.y, .2f, seconds));
  369. m_fov_mesh = damp(m_fov_mesh, fov_mesh, .2f, seconds);
  370. m_zoom_mesh = damp(m_zoom_mesh, zoom_mesh, .2f, seconds);
  371. m_hist_scale_mesh = damp(m_hist_scale_mesh, hist_scale_mesh, .2f, seconds);
  372. //Mesh mat calculation
  373. m_mat_prev = m_mat;
  374. m_mat = mat4(quat::fromeuler_xyz(vec3(m_rot_mesh, .0f)));
  375. //Target List Setup
  376. Array<vec3> target_list;
  377. if (m_meshes.Count() && m_mesh_id >= 0)
  378. for (int i = 0; i < m_meshes[m_mesh_id]->GetVertexCount(); i++)
  379. target_list << (m_mat * mat4::translate(m_meshes[m_mesh_id]->GetVertexLocation(i))).v3.xyz;
  380. //--
  381. //Update mesh screen location - Get the Min/Max needed
  382. //--
  383. vec2 cam_center(0.f);
  384. float cam_factor = .0f;
  385. vec3 local_min_max[2] = { vec3(FLT_MAX), vec3(-FLT_MAX) };
  386. vec2 screen_min_max[2] = { vec2(FLT_MAX), vec2(-FLT_MAX) };
  387. mat4 world_cam = m_camera->GetView();
  388. mat4 cam_screen = m_camera->GetProjection();
  389. //target on-screen computation
  390. for (int i = 0; i < target_list.Count(); i++)
  391. {
  392. vec3 obj_loc = target_list[i];
  393. {
  394. //Debug::DrawBox(obj_loc - vec3(4.f), obj_loc + vec3(4.f), vec4(1.f, 0.f, 0.f, 1.f));
  395. mat4 target_mx = mat4::translate(obj_loc);
  396. vec3 vpos;
  397. //Get location in cam coordinates
  398. target_mx = world_cam * target_mx;
  399. vpos = target_mx.v3.xyz;
  400. local_min_max[0] = min(vpos.xyz, local_min_max[0]);
  401. local_min_max[1] = max(vpos.xyz, local_min_max[1]);
  402. //Get location in screen coordinates
  403. target_mx = cam_screen * target_mx;
  404. vpos = (target_mx.v3 / target_mx.v3.w).xyz;
  405. screen_min_max[0] = min(screen_min_max[0], vpos.xy * vec2(RATIO_WH, 1.f));
  406. screen_min_max[1] = max(screen_min_max[1], vpos.xy * vec2(RATIO_WH, 1.f));
  407. //Build Barycenter
  408. cam_center += vpos.xy;
  409. cam_factor += 1.f;
  410. }
  411. }
  412. float screen_ratio = max(max(lol::abs(local_min_max[0].x), lol::abs(local_min_max[0].y)),
  413. max(lol::abs(local_min_max[1].x), lol::abs(local_min_max[1].y)));
  414. float scale_ratio = max(max(lol::abs(screen_min_max[0].x), lol::abs(screen_min_max[0].y)),
  415. max(lol::abs(screen_min_max[1].x), lol::abs(screen_min_max[1].y)));
  416. vec2 screen_offset = vec2(0.f, -(screen_min_max[1].y + screen_min_max[0].y) * .5f);
  417. m_screen_offset = damp(m_screen_offset, screen_offset, .9f, seconds);
  418. float z_pos = (inverse(world_cam) * mat4::translate(vec3(0.f, 0.f, max(local_min_max[0].z, local_min_max[1].z)))).v3.z;
  419. if (cam_factor > 0.f)
  420. {
  421. vec2 new_screen_scale = m_camera->GetScreenScale();
  422. m_camera->SetScreenScale(max(vec2(0.001f), new_screen_scale * ((1.0f + m_zoom_mesh) / (scale_ratio * SCREEN_LIMIT))));
  423. m_camera->SetPosition(vec3(vec2::zero, damp(m_camera->m_position.z, z_pos + screen_ratio * 2.f, .1f, seconds)), true);
  424. m_camera->SetFov(m_fov_mesh);
  425. m_camera->SetScreenInfos(damp(m_camera->GetScreenSize(), max(1.f, screen_ratio), 1.2f, seconds));
  426. }
  427. //--
  428. //Message Service
  429. //--
  430. String mesh("");
  431. int u = 1;
  432. while (u-- > 0 && MessageService::FetchFirst(MessageBucket::AppIn, mesh))
  433. {
  434. int o = 1;
  435. while (o-- > 0)
  436. {
  437. SceneSetup* new_ssetup = new SceneSetup();
  438. if (new_ssetup->Compile(mesh.C()) && new_ssetup->m_lights.Count())
  439. {
  440. //Store current light datas, in World
  441. Array<LightData> light_datas;
  442. for (int i = 0; i < m_ssetup->m_lights.Count(); ++i)
  443. light_datas << LightData(m_ssetup->m_lights[i]->GetPosition().xyz, m_ssetup->m_lights[i]->GetColor());
  444. if (m_ssetup)
  445. delete(m_ssetup);
  446. m_ssetup = new_ssetup;
  447. m_ssetup->Startup();
  448. //Restore all light datas so blend can occur
  449. mat4 light_mat = m_mat * inverse(mat4(quat::fromeuler_xyz(vec3::zero)));
  450. for (int i = 0; i < m_ssetup->m_lights.Count(); ++i)
  451. {
  452. //Store local dst in current m_ld
  453. LightData ltmp = LightData(m_ssetup->m_lights[i]->GetPosition().xyz, m_ssetup->m_lights[i]->GetColor());
  454. if (i < m_light_datas.Count())
  455. m_light_datas[i] = ltmp;
  456. else
  457. m_light_datas << ltmp;
  458. vec3 loc = vec3::zero;
  459. vec4 col = vec4::zero;
  460. if (i < light_datas.Count())
  461. {
  462. loc = light_datas[i].m_pos;
  463. col = light_datas[i].m_col;
  464. }
  465. //Restore old light datas in new lights
  466. m_ssetup->m_lights[i]->SetPosition(vec4(loc, m_ssetup->m_lights[i]->GetPosition().w));
  467. m_ssetup->m_lights[i]->SetColor(col);
  468. }
  469. }
  470. else
  471. {
  472. m_ssetup->m_custom_cmd += new_ssetup->m_custom_cmd;
  473. delete(new_ssetup);
  474. }
  475. }
  476. }
  477. //Check the custom cmd even if we don't have new messages.
  478. int o = 1;
  479. while (o-- > 0)
  480. {
  481. for (int i = 0; m_ssetup && i < m_ssetup->m_custom_cmd.Count(); ++i)
  482. {
  483. if (m_ssetup->m_custom_cmd[i].m1 == "setmesh")
  484. {
  485. //Create a new mesh
  486. EasyMesh* em = new EasyMesh();
  487. if (em->Compile(m_ssetup->m_custom_cmd[i].m2.C()))
  488. {
  489. if (m_mesh_id == m_meshes.Count() - 1)
  490. m_mesh_id++;
  491. m_meshes.Push(em);
  492. }
  493. else
  494. delete(em);
  495. }
  496. }
  497. }
  498. m_ssetup->m_custom_cmd.Empty();
  499. #endif //ALL_FEATURES
  500. #if NACL_EM
  501. /*
  502. if (m_stream_update_time > .0f)
  503. {
  504. m_stream_update_time = -1.f;
  505. MessageService::Send(MessageBucket::AppIn,
  506. " addlight 0.0 position (4 -1 -4) color (.0 .2 .5 1) \
  507. addlight 0.0 position (8 2 6) color #ffff \
  508. custom setmesh \"[sc#f8f ab 1]\"");
  509. // MessageService::Send(MessageBucket::AppIn, "[sc#f8f ab 1]");
  510. // MessageService::Send(MessageBucket::AppIn, "[sc#f8f ab 1 splt 4 twy 90]");
  511. // MessageService::Send(MessageBucket::AppIn, "[sc#8ff afcb 1 1 1 0]");
  512. // MessageService::Send(MessageBucket::AppIn, "[sc#ff8 afcb 1 1 1 0]");
  513. }
  514. */
  515. #elif WIN32
  516. //--
  517. //File management
  518. //--
  519. m_stream_update_time += seconds;
  520. if (m_stream_update_time > m_stream_update_timer)
  521. {
  522. m_stream_update_time = 0.f;
  523. File f;
  524. f.Open(m_file_name.C(), FileAccess::Read);
  525. String cmd = f.ReadString();
  526. f.Close();
  527. if (cmd.Count()
  528. && (!m_cmdlist.Count() || cmd != m_cmdlist.Last()))
  529. {
  530. m_cmdlist << cmd;
  531. MessageService::Send(MessageBucket::AppIn, cmd);
  532. }
  533. }
  534. #endif //WINDOWS
  535. }
  536. virtual void TickDraw(float seconds)
  537. {
  538. WorldEntity::TickDraw(seconds);
  539. if (!m_init || !m_first_tick)
  540. return;
  541. //TODO : This should probably be "standard LoL behaviour"
  542. #if NO_NACL_EM
  543. {
  544. if (KeyReleased(KEY_F1))
  545. Video::SetDebugRenderMode(DebugRenderMode::Default);
  546. if (KeyReleased(KEY_F2))
  547. Video::SetDebugRenderMode(DebugRenderMode::Wireframe);
  548. if (KeyReleased(KEY_F3))
  549. Video::SetDebugRenderMode(DebugRenderMode::Lighting);
  550. if (KeyReleased(KEY_F4))
  551. Video::SetDebugRenderMode(DebugRenderMode::Normal);
  552. if (KeyReleased(KEY_F5))
  553. Video::SetDebugRenderMode(DebugRenderMode::UV);
  554. }
  555. #endif //NO_NACL_EM
  556. #if NO_NACL_EM && WITH_TEXTURE
  557. if (!m_default_texture)
  558. {
  559. m_texture_shader = Shader::Create(LOLFX_RESOURCE_NAME(shinymvtexture));
  560. m_texture_uni = m_texture_shader->GetUniformLocation("u_Texture");
  561. m_default_texture = Tiler::Register("data/test-texture.png", ivec2::zero, ivec2(0,1));
  562. }
  563. else if (m_texture && m_default_texture)
  564. m_texture_shader->SetUniform(m_texture_uni, m_default_texture->GetTexture(), 0);
  565. #endif //NO_NACL_EM
  566. g_renderer->SetClearColor(m_ssetup->m_clear_color);
  567. for (int i = 0; i < m_gizmos.Count(); ++i)
  568. {
  569. if (m_gizmos[i]->GetMeshState() == MeshRender::NeedConvert)
  570. m_gizmos[i]->MeshConvert();
  571. else
  572. break;
  573. }
  574. vec3 x = vec3(1.f,0.f,0.f);
  575. vec3 y = vec3(0.f,1.f,0.f);
  576. mat4 save_proj = m_camera->GetProjection();
  577. //Y object Offset
  578. mat4 mat_obj_offset = mat4::translate(x * m_screen_offset.x + y * m_screen_offset.y) *
  579. //Mesh Pos Offset
  580. mat4::translate((x * m_pos_mesh.x * RATIO_HW + y * m_pos_mesh.y) * 2.f * (1.f + .5f * m_zoom_mesh / SCREEN_LIMIT));
  581. //Align right meshes
  582. mat4 mat_align = mat4::translate(x - x * RATIO_HW);
  583. mat4 mat_gizmo = mat_obj_offset * mat_align * save_proj;
  584. for (int i = 0; i < m_meshes.Count(); i++)
  585. {
  586. {
  587. if (m_meshes[i]->GetMeshState() == MeshRender::NeedConvert)
  588. {
  589. #if WITH_TEXTURE
  590. m_meshes[i]->MeshConvert(new DefaultShaderData(((1 << VertexUsage::Position) | (1 << VertexUsage::Normal) |
  591. (1 << VertexUsage::Color) | (1 << VertexUsage::TexCoord)),
  592. m_texture_shader, true));
  593. #else
  594. m_meshes[i]->MeshConvert();
  595. #endif //WITH_TEXTURE
  596. }
  597. #if ALL_FEATURES
  598. float j = -(float)(m_meshes.Count() - (i + 1)) + (-m_mesh_id1 + (float)(m_meshes.Count() - 1));
  599. if (m_mesh_id1 - m_render_max[0] > (float)i && m_mesh_id1 - m_render_max[1] < (float)i &&
  600. m_meshes[i]->GetMeshState() > MeshRender::NeedConvert)
  601. {
  602. float a_j = lol::abs(j);
  603. float i_trans = (a_j * a_j * m_hist_scale_mesh.x + a_j * m_hist_scale_mesh.x) * .5f;
  604. float i_scale = clamp(1.f - (m_hist_scale_mesh.y * (m_mesh_id1 - (float)i)), 0.f, 1.f);
  605. //Mesh count offset
  606. mat4 mat_count_offset = mat4::translate(x * RATIO_HW * 2.f * (j + i_trans));
  607. //Mesh count scale
  608. mat4 mat_count_scale = mat4::scale(vec3(vec2(i_scale), 1.f));
  609. //Camera projection
  610. mat4 new_proj = mat_obj_offset * mat_count_offset * mat_align * mat_count_scale * save_proj;
  611. m_camera->SetProjection(new_proj);
  612. //#if NO_NACL_EM
  613. m_meshes[i]->Render(m_mat);
  614. //#endif //NO_NACL_EM
  615. g_renderer->Clear(ClearMask::Depth);
  616. }
  617. m_camera->SetProjection(save_proj);
  618. #else
  619. m_meshes[i]->Render(m_mat);
  620. #endif //ALL_FEATURES
  621. }
  622. }
  623. if (m_ssetup)
  624. {
  625. m_camera->SetProjection(mat_gizmo);
  626. if (m_ssetup->m_show_gizmo)
  627. m_gizmos[GZ_Editor]->Render(m_mat);
  628. if (m_ssetup->m_show_lights)
  629. {
  630. for (int k = 0; k < m_ssetup->m_lights.Count(); ++k)
  631. {
  632. Light* ltmp = m_ssetup->m_lights[k];
  633. mat4 world = mat4::translate(ltmp->GetPosition().xyz);
  634. mat4 local = mat4::translate((inverse(m_mat) * world).v3.xyz);
  635. //dir light
  636. if (ltmp->GetPosition().w == 0.f)
  637. {
  638. m_gizmos[GZ_LightPos]->Render(m_mat * inverse(local));
  639. m_gizmos[GZ_LightDir]->Render(inverse(world) * inverse(mat4::lookat(vec3::zero, -ltmp->GetPosition().xyz, vec3::axis_y)));
  640. }
  641. else //point light
  642. {
  643. m_gizmos[GZ_LightPos]->Render(m_mat * local);
  644. }
  645. }
  646. }
  647. m_camera->SetProjection(save_proj);
  648. }
  649. }
  650. private:
  651. SceneSetup* m_ssetup;
  652. Array<LightData> m_light_datas;
  653. Controller* m_controller;
  654. short m_input_usage;
  655. mat4 m_mat;
  656. mat4 m_mat_prev;
  657. bool m_init;
  658. bool m_first_tick;
  659. //Camera Setup
  660. Camera * m_camera;
  661. float m_reset_timer;
  662. float m_fov;
  663. float m_fov_mesh;
  664. float m_fov_speed;
  665. float m_zoom;
  666. float m_zoom_mesh;
  667. float m_zoom_speed;
  668. vec2 m_rot;
  669. vec2 m_rot_mesh;
  670. vec2 m_rot_speed;
  671. vec2 m_pos;
  672. vec2 m_pos_mesh;
  673. vec2 m_pos_speed;
  674. vec2 m_hist_scale;
  675. vec2 m_hist_scale_mesh;
  676. vec2 m_hist_scale_speed;
  677. vec2 m_screen_offset;
  678. //Mesh infos
  679. vec2 m_render_max;
  680. int m_mesh_id;
  681. float m_mesh_id1;
  682. Array<EasyMesh*> m_meshes;
  683. Array<EasyMesh*> m_gizmos;
  684. //File data
  685. String m_file_name;
  686. Array<String> m_cmdlist;
  687. float m_stream_update_time;
  688. float m_stream_update_timer;
  689. //misc datas
  690. Shader * m_texture_shader;
  691. TileSet * m_default_texture;
  692. Texture * m_texture;
  693. ShaderUniform m_texture_uni;
  694. };
  695. //The basic main :
  696. int main(int argc, char **argv)
  697. {
  698. System::Init(argc, argv);
  699. Application app("MeshViewer", ivec2((int)DEFAULT_WIDTH, (int)DEFAULT_HEIGHT), 60.0f);
  700. if (argc > 1)
  701. new MeshViewer(argv[1]);
  702. else
  703. new MeshViewer();
  704. app.Run();
  705. return EXIT_SUCCESS;
  706. }