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 35 KiB

10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
10 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  1. //
  2. // Lol Engine - EasyMesh tutorial
  3. //
  4. // Copyright: (c) 2011-2014 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 HAVE_CONFIG_H
  12. # include "config.h"
  13. #endif
  14. #include <cfloat> /* for FLT_MAX */
  15. #include <lol/engine.h>
  16. #include "scenesetup.h"
  17. using namespace lol;
  18. static int const TEXTURE_WIDTH = 256;
  19. //Basic build defines ---------------------------------------------------------
  20. #define HAS_WEB (__native_client__ || EMSCRIPTEN)
  21. #define HAS_INPUT (_WIN32 && !HAS_WEB)
  22. //Basic config defines --------------------------------------------------------
  23. #define R_M 1.f
  24. #if HAS_WEB
  25. #define DEFAULT_WIDTH (800.f * R_M)
  26. #define DEFAULT_HEIGHT (400.f * R_M)
  27. #else
  28. #define DEFAULT_WIDTH (1200.f * R_M)
  29. #define DEFAULT_HEIGHT (400.f * R_M)
  30. #endif //HAS_WEB
  31. #define WIDTH ((float)Video::GetSize().x)
  32. #define HEIGHT ((float)Video::GetSize().y)
  33. #define SCREEN_W (10.f / WIDTH)
  34. #define RATIO_HW (HEIGHT / WIDTH)
  35. #define RATIO_WH (WIDTH / HEIGHT)
  36. #define SCREEN_LIMIT 1.4f
  37. #define RESET_TIMER .2f
  38. #define ROT_SPEED vec2(50.f)
  39. #define ROT_CLAMP 89.f
  40. #define POS_SPEED vec2(1.2f)
  41. #define POS_CLAMP 1.f
  42. #define FOV_SPEED 20.f
  43. #define FOV_CLAMP 120.f
  44. #define ZOM_SPEED 3.f
  45. #define ZOM_CLAMP 20.f
  46. #define HST_SPEED .5f
  47. #define HST_CLAMP 1.f
  48. #define WITH_TEXTURE 0
  49. #define HAS_KBOARD (m_input_usage & (1<<IPT_MV_KBOARD))
  50. #define HAS_MOUSE (m_input_usage & (1<<IPT_MV_MOUSE))
  51. #include "meshviewer.h"
  52. LOLFX_RESOURCE_DECLARE(shinyfur);
  53. LOLFX_RESOURCE_DECLARE(shinymvtexture);
  54. //TargetCamera ----------------------------------------------------------------
  55. class TargetCamera
  56. {
  57. public:
  58. void EmptyTargets() { m_targets.Empty(); }
  59. void AddTarget(vec3 new_target) { m_targets << new_target; }
  60. //This considers the box usage A to B as top-left to bottom-right
  61. void AddTarget(box3 new_target)
  62. {
  63. vec3 base_off = .5f * (new_target.B - new_target.A);
  64. vec3 base_pos = new_target.A + base_off;
  65. int pass = 0;
  66. while (pass < 3)
  67. {
  68. int mask = 3 - max(0, pass - 1);
  69. while (mask-- > 0)
  70. {
  71. ivec3 A((pass == 1 || (pass == 2 && mask == 1))?(1):(0));
  72. ivec3 B((pass == 2)?(1):(0)); B[mask] = 1;
  73. vec3 offset = vec3(ivec3((int)(!A.x != !B.x), (int)(!A.y != !B.y), (int)(!A.z != !B.z)));
  74. AddTarget(base_pos + offset * base_off * 2.f - base_off);
  75. }
  76. pass++;
  77. }
  78. }
  79. array<vec3> m_targets;
  80. };
  81. //EasyMeshLoadJob -------------------------------------------------------------
  82. bool EasyMeshLoadJob::DoWork()
  83. {
  84. if (m_loader.ExecLuaFile(m_path))
  85. {
  86. array<EasyMeshLuaObject*>& objs = m_loader.GetInstances();
  87. for (EasyMeshLuaObject* obj : objs)
  88. m_meshes << new EasyMeshViewerObject(obj->GetMesh());
  89. }
  90. return !!m_meshes.count();
  91. }
  92. //-----------------------------------------------------------------------------
  93. MeshViewerLoadJob* EasyMeshLoadJob::GetInstance(String const& path)
  94. {
  95. if (Check(path))
  96. return new MeshViewerLoadJob(path);
  97. return nullptr;
  98. }
  99. //-----------------------------------------------------------------------------
  100. void EasyMeshLoadJob::RetrieveResult(class MeshViewer* app)
  101. {
  102. for (EasyMeshViewerObject* mesh : m_meshes)
  103. app->AddViewerObj(mesh);
  104. m_meshes.Empty();
  105. }
  106. //MeshViewer ------------------------------------------------------------------
  107. MeshViewer::MeshViewer(char const *file_name)
  108. : m_file_name(file_name)
  109. { }
  110. //-----------------------------------------------------------------------------
  111. MeshViewer::~MeshViewer()
  112. {
  113. Stop();
  114. }
  115. //-----------------------------------------------------------------------------
  116. void MeshViewer::Start()
  117. {
  118. /** OLD STUFF **/
  119. //Prepare();
  120. //Scene setup
  121. m_setup_loader.ExecLuaFile("meshviewer_init.lua");
  122. //Threads setup
  123. m_entities << (m_file_check = new FileUpdateTester());
  124. m_file_status = m_file_check->RegisterFile(m_file_name);
  125. //m_entities << (m_file_loader = new DefaultThreadManager(1, 1));
  126. //Camera setup
  127. m_camera = new Camera();
  128. m_camera->SetView(vec3(0.f, 0.f, 10.f), vec3::zero, vec3::axis_y);
  129. m_camera->SetProjection(0.f, .0001f, 2000.f, WIDTH * SCREEN_W, RATIO_HW);
  130. m_camera->UseShift(true);
  131. g_scene->PushCamera(m_camera);
  132. #if HAS_INPUT
  133. InputProfile& ip = m_profile;
  134. ip.AddBindings<MeshViewerKeyInput, MeshViewerKeyInput::KBD_BEG, MeshViewerKeyInput::KBD_END>(InputProfileType::Keyboard);
  135. ip.AddBindings<MeshViewerKeyInput, MeshViewerKeyInput::MSE_BEG, MeshViewerKeyInput::MSE_END>(InputProfileType::Keyboard);
  136. m_entities << (m_controller = new Controller("MeshViewer"));
  137. m_controller->Init(m_profile);
  138. #endif //HAS_INPUT
  139. /** ----- Register all entities ----- **/
  140. for (Entity* entity : m_entities) Ticker::Ref(entity);
  141. /** ----- Init is done ----- **/
  142. m_init = true;
  143. /** ----- Start threads ----- **/
  144. m_file_check->Start();
  145. }
  146. //-----------------------------------------------------------------------------
  147. void MeshViewer::Stop()
  148. {
  149. //Destroy core stuff
  150. if (m_camera) g_scene->PopCamera(m_camera);
  151. if (m_ssetup) delete m_ssetup;
  152. m_file_check->UnregisterFile(m_file_status);
  153. //Register all entities
  154. for (Entity* entity : m_entities) Ticker::Unref(entity);
  155. //Delete objs
  156. while (m_objs.count()) delete m_objs.Pop();
  157. //Nullify all
  158. m_ssetup = nullptr;
  159. m_camera = nullptr;
  160. m_controller = nullptr;
  161. m_file_check = nullptr;
  162. m_file_loader = nullptr;
  163. /** ----- Init is needed ----- **/
  164. m_init = false;
  165. }
  166. //-----------------------------------------------------------------------------
  167. MeshViewerLoadJob* MeshViewer::GetLoadJob(String const& path)
  168. {
  169. MeshViewerLoadJob* job = nullptr;
  170. if (job = EasyMeshLoadJob::GetInstance(path)) return job;
  171. return job;
  172. }
  173. //-----------------------------------------------------------------------------
  174. void MeshViewer::TickGame(float seconds)
  175. {
  176. super::TickGame(seconds);
  177. if (!m_init && g_scene) Start();
  178. if (!m_init) return;
  179. m_first_tick = true;
  180. //Check file update
  181. ASSERT(m_file_status);
  182. if (false && m_file_status->HasUpdated())
  183. {
  184. MeshViewerLoadJob* job = GetLoadJob(m_file_name);
  185. if (!job)
  186. m_file_loader->AddJob(job);
  187. }
  188. //Check work done
  189. if (false)
  190. {
  191. array<ThreadJob*> result;
  192. m_file_loader->GetWorkResult(result);
  193. if (result.count())
  194. {
  195. for (ThreadJob* job : result)
  196. {
  197. if (job->GetJobType() == ThreadJobType::WORK_SUCCEEDED)
  198. {
  199. MeshViewerLoadJob* mvjob = static_cast<MeshViewerLoadJob*>(job);
  200. mvjob->RetrieveResult(this);
  201. }
  202. delete job;
  203. }
  204. }
  205. }
  206. /** OLD STUFF **/
  207. //Update(seconds);
  208. }
  209. //-----------------------------------------------------------------------------
  210. void MeshViewer::TickDraw(float seconds, Scene &scene)
  211. {
  212. super::TickDraw(seconds, scene);
  213. /** OLD STUFF **/
  214. //Draw(seconds);
  215. }
  216. //The basic main --------------------------------------------------------------
  217. int main(int argc, char **argv)
  218. {
  219. System::Init(argc, argv);
  220. Application app("MeshViewer", ivec2((int)DEFAULT_WIDTH, (int)DEFAULT_HEIGHT), 60.0f);
  221. if (argc > 1)
  222. new MeshViewer(argv[1]);
  223. else
  224. new MeshViewer();
  225. app.Run();
  226. return EXIT_SUCCESS;
  227. }
  228. //-------------------------------------------------------------------------
  229. //OLD ---------------------------------------------------------------------
  230. //-------------------------------------------------------------------------
  231. #if HAS_INPUT
  232. bool MeshViewer::KeyReleased(MVKeyboardList index) { return (HAS_KBOARD && m_controller->WasKeyReleasedThisFrame(index)); }
  233. bool MeshViewer::KeyPressed(MVKeyboardList index) { return (HAS_KBOARD && m_controller->WasKeyPressedThisFrame(index)); }
  234. bool MeshViewer::KeyDown(MVKeyboardList index) { return (HAS_KBOARD && m_controller->IsKeyPressed(index)); }
  235. bool MeshViewer::KeyReleased(MVMouseKeyList index) { return (HAS_MOUSE && m_controller->WasKeyReleasedThisFrame(index)); }
  236. bool MeshViewer::KeyPressed(MVMouseKeyList index) { return (HAS_MOUSE && m_controller->WasKeyPressedThisFrame(index)); }
  237. bool MeshViewer::KeyDown(MVMouseKeyList index) { return (HAS_MOUSE && m_controller->IsKeyPressed(index)); }
  238. float MeshViewer::AxisValue(MVMouseAxisList index) { return (HAS_MOUSE) ? (m_controller->GetAxisValue(index)) : (0.f); }
  239. #endif //HAS_INPUT
  240. void MeshViewer::Prepare()
  241. {
  242. // Message Service
  243. MessageService::Setup();
  244. //Compile ref meshes
  245. m_gizmos << new EasyMesh();
  246. m_gizmos.Last()->Compile("[sc#0f0 ac 3 .5 .4 0 ty .25 [ad 3 .4 sy -1] ty .5 ac 3 1 .075 ty .5 dup[rz 90 ry 90 scv#00f dup[ry 90 scv#f00]]][sc#fff ab .1]");
  247. m_gizmos << new EasyMesh();
  248. m_gizmos.Last()->Compile("[sc#666 acap 1 .5 .5 ty -.5 sc#fff asph 2 1]");
  249. m_gizmos << new EasyMesh();
  250. 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]");
  251. // Mesh Setup
  252. m_render_max = vec2(-.9f, 4.1f);
  253. m_mesh_render = 0;
  254. m_mesh_id = 0;
  255. m_mesh_id1 = 0.f;
  256. m_default_texture = nullptr;
  257. m_texture_shader = nullptr;
  258. m_texture = nullptr;
  259. //Camera Setup
  260. m_reset_timer = -1.f;
  261. m_fov = -100.f;
  262. m_fov_mesh = 0.f;
  263. m_fov_speed = 0.f;
  264. m_zoom = 0.f;
  265. m_zoom_mesh = 0.f;
  266. m_zoom_speed = 0.f;
  267. m_rot = vec2(/*45.f*/0.f, -45.f);
  268. m_rot_mesh = vec2::zero;
  269. m_rot_speed = vec2::zero;
  270. m_pos = vec2::zero;
  271. m_pos_mesh = vec2::zero;
  272. m_pos_speed = vec2::zero;
  273. m_screen_offset = vec2::zero;
  274. m_hist_scale = vec2(.13f, .03f);
  275. m_hist_scale_mesh = vec2(.0f);
  276. m_hist_scale_speed = vec2(.0f);
  277. m_mat_prev = mat4(quat::fromeuler_xyz(vec3::zero));
  278. m_mat = mat4::translate(vec3(0.f));//mat4(quat::fromeuler_xyz(vec3(m_rot_mesh, .0f)));
  279. m_build_timer = 0.1f;
  280. m_build_time = -1.f;
  281. //stream update
  282. m_stream_update_time = 2.0f;
  283. m_stream_update_timer = 1.0f;
  284. m_init = true;
  285. m_input_usage = 0;
  286. #if HAS_INPUT
  287. /* Register an input controller for the keyboard */
  288. m_controller = new Controller("Default");
  289. m_controller->SetInputCount(MAX_KEYS, MAX_AXIS);
  290. if (InputDevice::Get(g_name_mouse.C()))
  291. {
  292. m_input_usage |= (1 << IPT_MV_MOUSE);
  293. m_controller->GetKey(MSE_CAM_ROT).BindMouse("Left");
  294. m_controller->GetKey(MSE_CAM_POS).BindMouse("Right");
  295. m_controller->GetKey(MSE_CAM_FOV).BindMouse("Middle");
  296. m_controller->GetKey(MSE_FOCUS).BindMouse("InScreen");
  297. m_controller->GetAxis(MSEX_CAM_Y).BindMouse("Y");
  298. m_controller->GetAxis(MSEX_CAM_X).BindMouse("X");
  299. }
  300. if (InputDevice::Get(g_name_keyboard.C()))
  301. {
  302. m_input_usage |= (1 << IPT_MV_KBOARD);
  303. //Camera keyboard rotation
  304. m_controller->GetKey(KEY_CAM_UP).BindKeyboard("Up");
  305. m_controller->GetKey(KEY_CAM_DOWN).BindKeyboard("Down");
  306. m_controller->GetKey(KEY_CAM_LEFT).BindKeyboard("Left");
  307. m_controller->GetKey(KEY_CAM_RIGHT).BindKeyboard("Right");
  308. //Camera keyboard position switch
  309. m_controller->GetKey(KEY_CAM_POS).BindKeyboard("LeftShift");
  310. m_controller->GetKey(KEY_CAM_FOV).BindKeyboard("LeftCtrl");
  311. //Camera unzoom switch
  312. m_controller->GetKey(KEY_CAM_RESET).BindKeyboard("Space");
  313. //Mesh change
  314. m_controller->GetKey(KEY_MESH_NEXT).BindKeyboard("PageUp");
  315. m_controller->GetKey(KEY_MESH_PREV).BindKeyboard("PageDown");
  316. //Base setup
  317. m_controller->GetKey(KEY_F1).BindKeyboard("F1");
  318. m_controller->GetKey(KEY_F2).BindKeyboard("F2");
  319. m_controller->GetKey(KEY_F3).BindKeyboard("F3");
  320. m_controller->GetKey(KEY_F4).BindKeyboard("F4");
  321. m_controller->GetKey(KEY_F5).BindKeyboard("F5");
  322. m_controller->GetKey(KEY_ESC).BindKeyboard("Escape");
  323. }
  324. #endif //HAS_INPUT
  325. m_camera = new Camera();
  326. m_camera->SetView(vec3(0.f, 0.f, 10.f), vec3::zero, vec3::axis_y);
  327. m_camera->SetProjection(0.f, .0001f, 2000.f, WIDTH * SCREEN_W, RATIO_HW);
  328. m_camera->UseShift(true);
  329. g_scene->PushCamera(m_camera);
  330. //Lights setup
  331. m_ssetup = new SceneSetup();
  332. #if NO_SC_SETUP
  333. m_ssetup->m_lights << new Light();
  334. m_ssetup->m_lights.Last()->SetPosition(vec4(4.f, -1.f, -4.f, 0.f));
  335. m_ssetup->m_lights.Last()->SetColor(vec4(.0f, .2f, .5f, 1.f));
  336. Ticker::Ref(m_ssetup->m_lights.Last());
  337. m_ssetup->m_lights << new Light();
  338. m_ssetup->m_lights.Last()->SetPosition(vec4(8.f, 2.f, 6.f, 0.f));
  339. m_ssetup->m_lights.Last()->SetColor(vec4(1.f));
  340. Ticker::Ref(m_ssetup->m_lights.Last());
  341. EasyMesh* em = new EasyMesh();
  342. if (em->Compile("sc#fff ab 1"))
  343. {
  344. if (m_mesh_id == m_meshes.Count() - 1)
  345. m_mesh_id++;
  346. m_meshes.Push(em, nullptr);
  347. }
  348. #else
  349. //TOUKY CHANGE THAT
  350. /*
  351. m_ssetup->Compile("addlight 0.0 position (4 -1 -4) color (.0 .2 .5 1) "
  352. "addlight 0.0 position (8 2 6) color #ffff "
  353. "showgizmo true ");
  354. */
  355. m_ssetup->Startup();
  356. #endif //NO_SC_SETUP
  357. for (int i = 0; i < m_ssetup->m_lights.Count(); ++i)
  358. {
  359. m_light_datas << LightData(m_ssetup->m_lights[i]->GetPosition().xyz, m_ssetup->m_lights[i]->GetColor());
  360. m_ssetup->m_lights[i]->SetPosition(vec3::zero);
  361. m_ssetup->m_lights[i]->SetColor(vec4::zero);
  362. }
  363. }
  364. void MeshViewer::Unprepare()
  365. {
  366. if (m_camera) g_scene->PopCamera(m_camera);
  367. if (m_ssetup) delete m_ssetup;
  368. MessageService::Destroy();
  369. //Register all entities
  370. for (Entity* entity : m_entities)
  371. Ticker::Unref(entity);
  372. m_controller = nullptr;
  373. m_camera = nullptr;
  374. m_ssetup = nullptr;
  375. /** ----- Init is needed ----- **/
  376. m_init = false;
  377. }
  378. void MeshViewer::Update(float seconds)
  379. {
  380. //TODO : This should probably be "standard LoL behaviour"
  381. #if HAS_INPUT
  382. {
  383. //Shutdown logic
  384. if (KeyReleased(KEY_ESC))
  385. Ticker::Shutdown();
  386. }
  387. #endif //HAS_INPUT
  388. //Compute render mesh count
  389. float a_j = lol::abs(m_render_max[1]);
  390. float i_m = m_hist_scale_mesh.x;
  391. float i_trans = a_j - ((a_j * a_j * i_m * i_m + a_j * i_m) * .5f);
  392. m_render_max[1] = a_j * ((RATIO_WH * 1.f) / ((i_trans != 0.f)?(i_trans):(RATIO_WH))) - RATIO_HW * .3f;
  393. //Mesh Change
  394. #if HAS_INPUT
  395. m_mesh_id = clamp(m_mesh_id + ((int)KeyPressed(KEY_MESH_PREV) - (int)KeyPressed(KEY_MESH_NEXT)), 0, (int)m_meshes.Count() - 1);
  396. #endif //HAS_INPUT
  397. m_mesh_id1 = damp(m_mesh_id1, (float)m_mesh_id, .2f, seconds);
  398. #if ALL_FEATURES
  399. //Update light position & damping
  400. for (int i = 0; i < m_ssetup->m_lights.Count(); ++i)
  401. {
  402. vec3 pos = (m_mat * inverse(m_mat_prev) * vec4(m_ssetup->m_lights[i]->GetPosition(), 1.f)).xyz;
  403. vec3 tgt = (m_mat * vec4(m_light_datas[i].m_pos, 1.f)).xyz;
  404. vec3 new_pos = damp(pos, tgt, .3f, seconds);
  405. vec4 new_col = damp(m_ssetup->m_lights[i]->GetColor(), m_light_datas[i].m_col, .3f, seconds);
  406. m_ssetup->m_lights[i]->SetPosition(new_pos);
  407. m_ssetup->m_lights[i]->SetColor(new_col);
  408. }
  409. //Camera update
  410. bool is_pos = false;
  411. bool is_fov = false;
  412. bool is_hsc = false;
  413. vec2 tmpv = vec2::zero;
  414. #if HAS_INPUT
  415. is_pos = KeyDown(KEY_CAM_POS) || KeyDown(MSE_CAM_POS);
  416. is_fov = KeyDown(KEY_CAM_FOV) || KeyDown(MSE_CAM_FOV);
  417. if (KeyDown(MSE_FOCUS) && (KeyDown(MSE_CAM_ROT) || KeyDown(MSE_CAM_POS) || KeyDown(MSE_CAM_FOV)))
  418. {
  419. tmpv += vec2(AxisValue(MSEX_CAM_Y), AxisValue(MSEX_CAM_X));
  420. if (KeyDown(MSE_CAM_ROT))
  421. tmpv *= vec2(1.f, 1.f) * 6.f;
  422. if (KeyDown(MSE_CAM_POS))
  423. tmpv *= vec2(1.f, -1.f) * 3.f;
  424. if (KeyDown(MSE_CAM_FOV))
  425. tmpv = vec2(tmpv.y * 4.f, tmpv.x * 6.f);
  426. }
  427. tmpv += vec2((float)KeyDown(KEY_CAM_UP ) - (float)KeyDown(KEY_CAM_DOWN),
  428. (float)KeyDown(KEY_CAM_RIGHT) - (float)KeyDown(KEY_CAM_LEFT));
  429. #endif //HAS_INPUT
  430. //Base data
  431. vec2 rot = (!is_pos && !is_fov)?(tmpv):(vec2(.0f)); rot = vec2(rot.x, -rot.y);
  432. vec2 pos = ( is_pos && !is_fov)?(tmpv):(vec2(.0f)); pos = -vec2(pos.y, pos.x);
  433. vec2 fov = (!is_pos && is_fov )?(tmpv):(vec2(.0f)); fov = vec2(-fov.x, fov.y);
  434. vec2 hsc = (is_hsc)?(vec2(0.f)):(vec2(0.f));
  435. //speed
  436. m_rot_speed = damp(m_rot_speed, rot * ROT_SPEED, .2f, seconds);
  437. float pos_factor = 1.f / (1.f + m_zoom_mesh * .5f);
  438. m_pos_speed = damp(m_pos_speed, pos * POS_SPEED * pos_factor, .2f, seconds);
  439. float fov_factor = 1.f + lol::pow((m_fov_mesh / FOV_CLAMP) * 1.f, 2.f);
  440. m_fov_speed = damp(m_fov_speed, fov.x * FOV_SPEED * fov_factor, .2f, seconds);
  441. float zom_factor = 1.f + lol::pow((m_zoom_mesh / ZOM_CLAMP) * 1.f, 2.f);
  442. m_zoom_speed = damp(m_zoom_speed, fov.y * ZOM_SPEED * zom_factor, .2f, seconds);
  443. m_hist_scale_speed = damp(m_hist_scale_speed, hsc * HST_SPEED, .2f, seconds);
  444. m_rot += m_rot_speed * seconds;
  445. #if HAS_INPUT
  446. if (m_reset_timer >= 0.f)
  447. m_reset_timer -= seconds;
  448. if (KeyPressed(KEY_CAM_RESET))
  449. {
  450. if (m_reset_timer >= 0.f)
  451. {
  452. m_pos = vec2(0.f);
  453. m_zoom = 0.f;
  454. }
  455. else
  456. m_reset_timer = RESET_TIMER;
  457. }
  458. //Transform update
  459. if (!KeyDown(KEY_CAM_RESET))
  460. {
  461. m_pos += m_pos_speed * seconds;
  462. m_fov += m_fov_speed * seconds;
  463. m_zoom += m_zoom_speed * seconds;
  464. m_hist_scale += m_hist_scale_speed * seconds;
  465. }
  466. #endif //HAS_INPUT
  467. //clamp
  468. vec2 rot_mesh = vec2(SmoothClamp(m_rot.x, -ROT_CLAMP, ROT_CLAMP, ROT_CLAMP * .1f), m_rot.y);
  469. vec2 pos_mesh = vec2(SmoothClamp(m_pos.x, -POS_CLAMP, POS_CLAMP, POS_CLAMP * .1f),
  470. SmoothClamp(m_pos.y, -POS_CLAMP, POS_CLAMP, POS_CLAMP * .1f));
  471. float fov_mesh = SmoothClamp(m_fov, 0.f, FOV_CLAMP, FOV_CLAMP * .1f);
  472. float zoom_mesh = SmoothClamp(m_zoom, -ZOM_CLAMP, ZOM_CLAMP, ZOM_CLAMP * .1f);
  473. vec2 hist_scale_mesh = vec2(SmoothClamp(m_hist_scale.x, 0.f, HST_CLAMP, HST_CLAMP * .1f),
  474. SmoothClamp(m_hist_scale.y, 0.f, HST_CLAMP, HST_CLAMP * .1f));
  475. #if HAS_INPUT
  476. if (KeyDown(KEY_CAM_RESET) && m_reset_timer < 0.f)
  477. {
  478. pos_mesh = vec2::zero;
  479. zoom_mesh = 0.f;
  480. }
  481. #endif //HAS_INPUT
  482. m_rot_mesh = vec2(damp(m_rot_mesh.x, rot_mesh.x, .2f, seconds), damp(m_rot_mesh.y, rot_mesh.y, .2f, seconds));
  483. m_pos_mesh = vec2(damp(m_pos_mesh.x, pos_mesh.x, .2f, seconds), damp(m_pos_mesh.y, pos_mesh.y, .2f, seconds));
  484. m_fov_mesh = damp(m_fov_mesh, fov_mesh, .2f, seconds);
  485. m_zoom_mesh = damp(m_zoom_mesh, zoom_mesh, .2f, seconds);
  486. m_hist_scale_mesh = damp(m_hist_scale_mesh, hist_scale_mesh, .2f, seconds);
  487. //Mesh mat calculation
  488. m_mat_prev = m_mat;
  489. m_mat = mat4::translate(vec3(0.f));
  490. //Target List Setup
  491. TargetCamera tc;
  492. if (m_meshes.Count() && m_mesh_id >= 0)
  493. for (int i = 0; i < m_meshes[m_mesh_id].m1->GetVertexCount(); i++)
  494. tc.AddTarget((m_mat * mat4::translate(m_meshes[m_mesh_id].m1->GetVertexLocation(i)))[3].xyz);
  495. tc.AddTarget(box3(vec3(0.f), vec3(1.f)));
  496. for (int k = 0; k < m_ssetup->m_lights.Count() && m_ssetup->m_show_lights; ++k)
  497. {
  498. vec3 light_pos = m_ssetup->m_lights[k]->GetPosition();
  499. mat4 world_cam = m_camera->GetView();
  500. light_pos = (inverse(world_cam) * vec4((world_cam * vec4(light_pos, 1.0f)).xyz * vec3::axis_z, 1.0f)).xyz;
  501. tc.AddTarget(box3(vec3(-1.f), vec3(1.f)) + light_pos *
  502. ((m_ssetup->m_lights[k]->GetType() == LightType::Directional)?(-1.f):(1.f)));
  503. }
  504. //--
  505. //Update mesh screen location - Get the Min/Max needed
  506. //--
  507. vec2 cam_center(0.f);
  508. float cam_factor = .0f;
  509. vec3 local_min_max[2] = { vec3(FLT_MAX), vec3(-FLT_MAX) };
  510. vec2 screen_min_max[2] = { vec2(FLT_MAX), vec2(-FLT_MAX) };
  511. mat4 world_cam = m_camera->GetView();
  512. mat4 cam_screen = m_camera->GetProjection();
  513. //target on-screen computation
  514. for (int i = 0; i < tc.m_targets.Count(); i++)
  515. {
  516. vec3 obj_loc = tc.m_targets[i];
  517. {
  518. //Debug::DrawBox(obj_loc - vec3(4.f), obj_loc + vec3(4.f), vec4(1.f, 0.f, 0.f, 1.f));
  519. mat4 target_mx = mat4::translate(obj_loc);
  520. vec3 vpos;
  521. //Get location in cam coordinates
  522. target_mx = world_cam * target_mx;
  523. vpos = target_mx[3].xyz;
  524. local_min_max[0] = min(vpos.xyz, local_min_max[0]);
  525. local_min_max[1] = max(vpos.xyz, local_min_max[1]);
  526. //Get location in screen coordinates
  527. target_mx = cam_screen * target_mx;
  528. vpos = (target_mx[3] / target_mx[3].w).xyz;
  529. screen_min_max[0] = min(screen_min_max[0], vpos.xy * vec2(RATIO_WH, 1.f));
  530. screen_min_max[1] = max(screen_min_max[1], vpos.xy * vec2(RATIO_WH, 1.f));
  531. //Build Barycenter
  532. cam_center += vpos.xy;
  533. cam_factor += 1.f;
  534. }
  535. }
  536. float screen_ratio = max(max(lol::abs(screen_min_max[0].x), lol::abs(screen_min_max[0].y)),
  537. max(lol::abs(screen_min_max[1].x), lol::abs(screen_min_max[1].y)));
  538. float z_dist = //m_camera->m_target_distance
  539. length(m_camera->m_position)
  540. + max(local_min_max[0].z, local_min_max[1].z);
  541. vec2 screen_offset = vec2(0.f, -(screen_min_max[1].y + screen_min_max[0].y) * .5f);
  542. m_screen_offset = damp(m_screen_offset, screen_offset, .9f, seconds);
  543. float forced_zoom = m_zoom_mesh;
  544. if (cam_factor > 0.f)
  545. {
  546. vec2 old_sscale = m_camera->GetScreenScale();
  547. float old_ssize = m_camera->GetScreenSize();
  548. float zoom_in = 1.f + lol::max(0.f, forced_zoom);
  549. float zoom_out = 1.f + lol::max(0.f, -forced_zoom);
  550. m_camera->SetScreenScale(max(vec2(0.001f), ((old_sscale * zoom_in) / (screen_ratio * zoom_out * SCREEN_LIMIT))));
  551. m_camera->SetFov(m_fov_mesh);
  552. m_camera->SetScreenInfos(damp(old_ssize, max(1.f, screen_ratio * zoom_out), 1.2f, seconds));
  553. vec3 posz = ((mat4::rotate(m_rot_mesh.y, vec3::axis_y) * mat4::rotate(-m_rot_mesh.x, vec3::axis_x) * vec4::axis_z)).xyz;
  554. vec3 newpos = posz * damp(length(m_camera->m_position), z_dist * 1.2f, .1f, seconds);
  555. m_camera->SetView(newpos, vec3(0.f), vec3::axis_y);
  556. }
  557. //--
  558. //Message Service
  559. //--
  560. String mesh("");
  561. int u = 1;
  562. while (u-- > 0 && MessageService::FetchFirst(MessageBucket::AppIn, mesh))
  563. {
  564. int o = 1;
  565. while (o-- > 0)
  566. {
  567. SceneSetup* new_ssetup = new SceneSetup();
  568. if (false) //new_ssetup->Compile(mesh.C()) && new_ssetup->m_lights.Count())
  569. {
  570. //Store current light datas, in World
  571. array<LightData> light_datas;
  572. for (int i = 0; i < m_ssetup->m_lights.Count(); ++i)
  573. light_datas << LightData(m_ssetup->m_lights[i]->GetPosition(), m_ssetup->m_lights[i]->GetColor());
  574. if (m_ssetup)
  575. delete m_ssetup;
  576. m_ssetup = new_ssetup;
  577. m_ssetup->Startup();
  578. //Restore all light datas so blend can occur
  579. mat4 light_mat = m_mat * inverse(mat4(quat::fromeuler_xyz(vec3::zero)));
  580. for (int i = 0; i < m_ssetup->m_lights.Count(); ++i)
  581. {
  582. //Store local dst in current m_ld
  583. LightData ltmp = LightData(m_ssetup->m_lights[i]->GetPosition(), m_ssetup->m_lights[i]->GetColor());
  584. if (i < m_light_datas.Count())
  585. m_light_datas[i] = ltmp;
  586. else
  587. m_light_datas << ltmp;
  588. vec3 loc = vec3::zero;
  589. vec4 col = vec4::zero;
  590. if (i < light_datas.Count())
  591. {
  592. loc = light_datas[i].m_pos;
  593. col = light_datas[i].m_col;
  594. }
  595. //Restore old light datas in new lights
  596. m_ssetup->m_lights[i]->SetPosition(loc);
  597. m_ssetup->m_lights[i]->SetColor(col);
  598. }
  599. }
  600. else
  601. {
  602. m_ssetup->m_custom_cmd += new_ssetup->m_custom_cmd;
  603. delete new_ssetup;
  604. }
  605. }
  606. }
  607. //Check the custom cmd even if we don't have new messages.
  608. int o = 1;
  609. while (o-- > 0)
  610. {
  611. for (int i = 0; m_ssetup && i < m_ssetup->m_custom_cmd.Count(); ++i)
  612. {
  613. if (m_ssetup->m_custom_cmd[i].m1 == "setmesh")
  614. {
  615. //Create a new mesh
  616. EasyMesh* em = new EasyMesh();
  617. if (em->Compile(m_ssetup->m_custom_cmd[i].m2.C(), false))
  618. {
  619. em->BD()->Cmdi() = 0;
  620. if (m_mesh_id == m_meshes.Count() - 1)
  621. m_mesh_id++;
  622. m_meshes.Push(em, nullptr);
  623. }
  624. else
  625. delete em;
  626. }
  627. }
  628. }
  629. m_ssetup->m_custom_cmd.Empty();
  630. #endif //ALL_FEATURES
  631. #if HAS_WEB
  632. /*
  633. if (m_stream_update_time > .0f)
  634. {
  635. m_stream_update_time = -1.f;
  636. MessageService::Send(MessageBucket::AppIn,
  637. " addlight 0.0 position (4 -1 -4) color (.0 .2 .5 1) \
  638. addlight 0.0 position (8 2 6) color #ffff \
  639. custom setmesh \"[sc#f8f ab 1]\"");
  640. // MessageService::Send(MessageBucket::AppIn, "[sc#f8f ab 1]");
  641. // MessageService::Send(MessageBucket::AppIn, "[sc#f8f ab 1 splt 4 twy 90]");
  642. // MessageService::Send(MessageBucket::AppIn, "[sc#8ff afcb 1 1 1 0]");
  643. // MessageService::Send(MessageBucket::AppIn, "[sc#ff8 afcb 1 1 1 0]");
  644. }
  645. */
  646. #elif defined(_WIN32)
  647. //--
  648. //File management
  649. //--
  650. m_stream_update_time += seconds;
  651. if (m_stream_update_time > m_stream_update_timer)
  652. {
  653. m_stream_update_time = 0.f;
  654. File f;
  655. f.Open(m_file_name.C(), FileAccess::Read);
  656. String cmd = f.ReadString();
  657. f.Close();
  658. if (cmd.Count()
  659. && (!m_cmdlist.Count() || cmd != m_cmdlist.Last()))
  660. {
  661. m_cmdlist << cmd;
  662. MessageService::Send(MessageBucket::AppIn, cmd);
  663. }
  664. }
  665. #endif //WINDOWS
  666. }
  667. void MeshViewer::Draw(float seconds, Scene &scene)
  668. {
  669. if (!m_init || !m_first_tick)
  670. return;
  671. //TODO : This should probably be "standard LoL behaviour"
  672. #if HAS_INPUT
  673. {
  674. if (KeyReleased(KEY_F2))
  675. Video::SetDebugRenderMode((Video::GetDebugRenderMode() + 1) % DebugRenderMode::Max);
  676. else if (KeyReleased(KEY_F1))
  677. Video::SetDebugRenderMode((Video::GetDebugRenderMode() + DebugRenderMode::Max - 1) % DebugRenderMode::Max);
  678. }
  679. #endif //HAS_INPUT
  680. #if !HAS_WEB && WITH_TEXTURE
  681. if (!m_default_texture)
  682. {
  683. m_texture_shader = Shader::Create(LOLFX_RESOURCE_NAME(shinymvtexture));
  684. m_texture_uni = m_texture_shader->GetUniformLocation("u_Texture");
  685. m_default_texture = Tiler::Register("data/test-texture.png", ivec2::zero, ivec2(0,1));
  686. }
  687. else if (m_texture && m_default_texture)
  688. m_texture_shader->SetUniform(m_texture_uni, m_default_texture->GetTexture(), 0);
  689. #endif //!HAS_WEB && WITH_TEXTURE
  690. g_renderer->SetClearColor(m_ssetup->m_clear_color);
  691. for (int i = 0; i < m_gizmos.Count(); ++i)
  692. {
  693. if (m_gizmos[i]->GetMeshState() == MeshRender::NeedConvert)
  694. m_gizmos[i]->MeshConvert();
  695. else
  696. break;
  697. }
  698. if (m_build_timer > .0f)
  699. {
  700. if (m_build_time < .0f)
  701. {
  702. m_build_time = m_build_timer;
  703. for (int i = 0; i < m_meshes.Count(); ++i)
  704. {
  705. if (m_meshes[i].m1 && m_meshes[i].m1->BD()->Cmdi() < m_meshes[i].m1->BD()->CmdStack().GetCmdNb())
  706. {
  707. EasyMesh* tmp = m_meshes[i].m1;
  708. EasyMesh* newtmp = new EasyMesh(*tmp);
  709. int ii = 1;
  710. #if 1
  711. bool stop = false;
  712. while (!stop)
  713. {
  714. int cmdi = newtmp->BD()->Cmdi() + ii;
  715. if (cmdi < newtmp->BD()->CmdStack().GetCmdNb())
  716. {
  717. switch (newtmp->BD()->CmdStack().GetCmd(cmdi))
  718. {
  719. case EasyMeshCmdType::LoopStart:
  720. case EasyMeshCmdType::LoopEnd:
  721. case EasyMeshCmdType::OpenBrace:
  722. case EasyMeshCmdType::CloseBrace:
  723. case EasyMeshCmdType::ScaleWinding:
  724. case EasyMeshCmdType::QuadWeighting:
  725. case EasyMeshCmdType::PostBuildNormal:
  726. case EasyMeshCmdType::PreventVertCleanup:
  727. case EasyMeshCmdType::SetColorA:
  728. case EasyMeshCmdType::SetColorB:
  729. {
  730. ii++;
  731. break;
  732. }
  733. default:
  734. {
  735. stop = true;
  736. break;
  737. }
  738. }
  739. }
  740. else
  741. stop = true;
  742. }
  743. #endif
  744. newtmp->BD()->CmdExecNb() = ii;
  745. newtmp->ExecuteCmdStack(false);
  746. m_meshes[i].m1 = newtmp;
  747. delete tmp;
  748. }
  749. }
  750. }
  751. m_build_time -= seconds;
  752. }
  753. #define NORMAL_USAGE 1
  754. #if NORMAL_USAGE
  755. vec3 x = vec3(1.f,0.f,0.f);
  756. vec3 y = vec3(0.f,1.f,0.f);
  757. mat4 save_proj = m_camera->GetProjection();
  758. //Y object Offset
  759. mat4 mat_obj_offset = mat4::translate(x * m_screen_offset.x + y * m_screen_offset.y) *
  760. //Mesh Pos Offset
  761. mat4::translate((x * m_pos_mesh.x * RATIO_HW + y * m_pos_mesh.y) * 2.f * (1.f + .5f * m_zoom_mesh / SCREEN_LIMIT));
  762. //Align right meshes
  763. mat4 mat_align = mat4::translate(x - x * RATIO_HW);
  764. mat4 mat_gizmo = mat_obj_offset * mat_align * save_proj;
  765. for (int i = 0; i < m_meshes.Count(); i++)
  766. {
  767. {
  768. if (m_meshes[i].m1->GetMeshState() == MeshRender::NeedConvert)
  769. {
  770. #if WITH_TEXTURE
  771. m_meshes[i].m1->MeshConvert(new DefaultShaderData(((1 << VertexUsage::Position) | (1 << VertexUsage::Normal) |
  772. (1 << VertexUsage::Color) | (1 << VertexUsage::TexCoord)),
  773. m_texture_shader, true));
  774. #else
  775. m_meshes[i].m1->MeshConvert();
  776. #endif //WITH_TEXTURE
  777. }
  778. #if ALL_FEATURES
  779. float j = -(float)(m_meshes.Count() - (i + 1)) + (-m_mesh_id1 + (float)(m_meshes.Count() - 1));
  780. if (m_mesh_id1 - m_render_max[0] > (float)i && m_mesh_id1 - m_render_max[1] < (float)i &&
  781. m_meshes[i].m1->GetMeshState() > MeshRender::NeedConvert)
  782. {
  783. float a_j = lol::abs(j);
  784. float i_trans = (a_j * a_j * m_hist_scale_mesh.x + a_j * m_hist_scale_mesh.x) * .5f;
  785. float i_scale = clamp(1.f - (m_hist_scale_mesh.y * (m_mesh_id1 - (float)i)), 0.f, 1.f);
  786. //Mesh count offset
  787. mat4 mat_count_offset = mat4::translate(x * RATIO_HW * 2.f * (j + i_trans));
  788. //Mesh count scale
  789. mat4 mat_count_scale = mat4::scale(vec3(vec2(i_scale), 1.f));
  790. //Camera projection
  791. mat4 new_proj = mat_obj_offset * mat_count_offset * mat_align * mat_count_scale * save_proj;
  792. m_camera->SetProjection(new_proj);
  793. scene.AddPrimitive(*m_meshes[i].m1, m_mat);
  794. g_renderer->Clear(ClearMask::Depth);
  795. }
  796. m_camera->SetProjection(save_proj);
  797. #else
  798. scene.AddPrimitive(*m_meshes[i].m1, m_mat);
  799. #endif //ALL_FEATURES
  800. }
  801. }
  802. //Scene setup update
  803. if (m_ssetup)
  804. {
  805. m_camera->SetProjection(mat_gizmo);
  806. if (m_ssetup->m_show_gizmo)
  807. scene.AddPrimitive(*m_gizmos[GZ_Editor], m_mat);
  808. if (m_ssetup->m_show_lights)
  809. {
  810. for (int k = 0; k < m_ssetup->m_lights.Count(); ++k)
  811. {
  812. Light* ltmp = m_ssetup->m_lights[k];
  813. mat4 world = mat4::translate(ltmp->GetPosition());
  814. mat4 local = mat4::translate((inverse(m_mat) * world)[3].xyz);
  815. //dir light
  816. if (ltmp->GetType() == LightType::Directional)
  817. {
  818. scene.AddPrimitive(*m_gizmos[GZ_LightPos], m_mat * inverse(local));
  819. scene.AddPrimitive(*m_gizmos[GZ_LightDir], inverse(world) * inverse(mat4::lookat(vec3::zero, -ltmp->GetPosition(), vec3::axis_y)));
  820. }
  821. else //point light
  822. {
  823. scene.AddPrimitive(*m_gizmos[GZ_LightPos], m_mat * local);
  824. }
  825. }
  826. }
  827. m_camera->SetProjection(save_proj);
  828. }
  829. #endif //NORMAL_USAGE
  830. #if 0 //Debug normal draw
  831. for (int i = m_meshes.Count() - 1; 0 <= i && i < m_meshes.Count(); i++)
  832. {
  833. for (int j = 0; j < m_meshes[i].m1->m_indices.Count(); j += 3)
  834. {
  835. VertexData v[3] = { m_meshes[i].m1->m_vert[m_meshes[i].m1->m_indices[j ]],
  836. m_meshes[i].m1->m_vert[m_meshes[i].m1->m_indices[j+1]],
  837. m_meshes[i].m1->m_vert[m_meshes[i].m1->m_indices[j+2]]
  838. };
  839. for (int k = 0; k < 3; k++)
  840. Debug::DrawLine((m_mat * mat4::translate(v[k].m_coord))[3].xyz,
  841. (m_mat * mat4::translate(v[(k+1)%3].m_coord))[3].xyz, vec4(vec3((v[k].m_coord.z + 1.f)*.5f),1.f));
  842. }
  843. for (int j = 0; j < m_meshes[i].m1->m_vert.Count(); j++)
  844. {
  845. VertexData &v = m_meshes[i].m1->m_vert[m_meshes[i].m1->m_indices[j]];
  846. Debug::DrawLine((m_mat * mat4::translate(v.m_coord))[3].xyz,
  847. (m_mat * mat4::translate(v.m_coord))[3].xyz +
  848. (m_mat * vec4(v.m_normal * 5.f, 0.f)).xyz, vec4(lol::abs(v.m_normal), 1.f));
  849. }
  850. }
  851. #endif
  852. }