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

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