💿🐜 Antkeeper source code https://antkeeper.com
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.

199 lines
5.9 KiB

  1. /*
  2. * Copyright (C) 2020 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "ui-system.hpp"
  20. #include "input/control.hpp"
  21. #include "resources/resource-manager.hpp"
  22. ui_system::ui_system(::resource_manager* resource_manager):
  23. resource_manager(resource_manager),
  24. tool_menu_control(nullptr),
  25. camera(nullptr),
  26. scene(nullptr)
  27. {
  28. // Setup lighting
  29. indirect_light.set_intensity(0.25f);
  30. indirect_light.update_tweens();
  31. direct_light.look_at({-0.1f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f});
  32. direct_light.set_intensity(1.0f);
  33. direct_light.update_tweens();
  34. // Setup modal background
  35. modal_bg_material.set_shader_program(resource_manager->load<shader_program>("ui-element-untextured.glsl"));
  36. modal_bg_material.set_flags(1);
  37. modal_bg_material.add_property<float4>("tint")->set_value({0, 0, 0, 0.25f});
  38. modal_bg.set_material(&modal_bg_material);
  39. modal_bg.set_translation({0, 0, -10.0f});
  40. // Setup tool selector background
  41. tool_selector_bg.set_material(resource_manager->load<material>("tool-selector.mtl"));
  42. tool_selector_bg.set_translation({0, 0, -4.0f});
  43. tool_selector_bg.set_scale({270, 270, 270});
  44. // Setup tool selector ant
  45. tool_selector_ant.set_model(resource_manager->load<model>("worker-ant.obj"));
  46. tool_selector_ant.set_scale({350, 350, 350});
  47. tool_selector_ant.set_rotation(math::angle_axis(math::radians(180.0f), {0, 0, 1}) * math::angle_axis(math::radians(90.0f), {1, 0, 0}));
  48. tool_selector_ant.update_tweens();
  49. // Setup energy symbol
  50. energy_symbol.set_model(resource_manager->load<model>("energy.obj"));
  51. energy_symbol.set_scale({30, 30, 30});
  52. energy_symbol.update_tweens();
  53. energy_symbol.set_active(false);
  54. // Setup scene
  55. //scene.add_object(&camera);
  56. //scene.add_object(&indirect_light);
  57. //scene.add_object(&direct_light);
  58. //scene.add_object(&energy_symbol);
  59. }
  60. void ui_system::update(float dt)
  61. {}
  62. void ui_system::set_viewport(const float4& viewport)
  63. {
  64. this->viewport = viewport;
  65. // Calculate viewport center
  66. viewport_center[0] = (viewport[2] - viewport[0]) * 0.5f;
  67. viewport_center[1] = (viewport[3] - viewport[1]) * 0.5f;
  68. energy_symbol.set_translation({viewport[2] * 0.25f, 0.0f, 0.0f});
  69. energy_symbol.update_tweens();
  70. // Resize modal BG
  71. modal_bg.set_scale({viewport[2] * 0.5f, viewport[3] * 0.5f, 1.0f});
  72. modal_bg.update_tweens();
  73. update_projection();
  74. }
  75. void ui_system::set_tool_menu_control(control* control)
  76. {
  77. tool_menu_control = control;
  78. tool_menu_control->set_activated_callback(std::bind(&ui_system::open_tool_menu, this));
  79. tool_menu_control->set_deactivated_callback(std::bind(&ui_system::close_tool_menu, this));
  80. }
  81. void ui_system::set_camera(::camera* camera)
  82. {
  83. this->camera = camera;
  84. if (camera)
  85. {
  86. camera->look_at({0.0f, 0.0f, 500.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f});
  87. update_projection();
  88. }
  89. }
  90. void ui_system::set_scene(::scene* scene)
  91. {
  92. this->scene = scene;
  93. }
  94. void ui_system::handle_event(const mouse_moved_event& event)
  95. {
  96. if (tool_menu_control->is_active())
  97. {
  98. tool_selection_vector.x += event.dx;
  99. tool_selection_vector.y += event.dy;
  100. float max_length = 200.0f;
  101. float selection_threshold = 20.0f;
  102. int sector_count = 6;
  103. float sector_angle = math::two_pi<float> / static_cast<float>(sector_count);
  104. float length_squared = math::length_squared(tool_selection_vector);
  105. // Select tool if length of selection vector within threshold
  106. if (length_squared >= selection_threshold * selection_threshold)
  107. {
  108. // Limit length of tool selection vector
  109. if (length_squared > max_length * max_length)
  110. {
  111. tool_selection_vector = (tool_selection_vector / std::sqrt(length_squared)) * max_length;
  112. }
  113. float2 selection_direction = tool_selection_vector / std::sqrt(length_squared);
  114. float selection_angle = std::atan2(-selection_direction.y, selection_direction.x) - math::radians(90.0f);
  115. selection_angle = (selection_angle >= 0.0f ? selection_angle : (math::two_pi<float> + selection_angle));
  116. int sector = static_cast<int>((selection_angle + sector_angle * 0.5f) / sector_angle) % sector_count;
  117. float rotation_angle = static_cast<float>(sector) * sector_angle;
  118. tool_selector_bg.set_rotation(math::angle_axis(rotation_angle, {0, 0, 1}));
  119. tool_selector_bg.update_tweens();
  120. tool_selector_ant.set_rotation(math::angle_axis(rotation_angle + math::radians(180.0f), {0, 0, 1}) * math::angle_axis(math::radians(90.0f), {1, 0, 0}));
  121. }
  122. }
  123. mouse_position[0] = event.x;
  124. mouse_position[1] = event.y;
  125. }
  126. void ui_system::update_projection()
  127. {
  128. if (camera)
  129. {
  130. float clip_left = -viewport[2] * 0.5f;
  131. float clip_right = viewport[2] * 0.5f;
  132. float clip_top = -viewport[3] * 0.5f;
  133. float clip_bottom = viewport[3] * 0.5f;
  134. float clip_near = 0.0f;
  135. float clip_far = 1000.0f;
  136. camera->set_orthographic(clip_left, clip_right, clip_top, clip_bottom, clip_near, clip_far);
  137. }
  138. }
  139. void ui_system::open_tool_menu()
  140. {
  141. if (scene)
  142. {
  143. scene->add_object(&modal_bg);
  144. scene->add_object(&tool_selector_bg);
  145. scene->add_object(&tool_selector_ant);
  146. }
  147. tool_selection_vector = {0, 0};
  148. }
  149. void ui_system::close_tool_menu()
  150. {
  151. if (scene)
  152. {
  153. scene->remove_object(&modal_bg);
  154. scene->remove_object(&tool_selector_bg);
  155. scene->remove_object(&tool_selector_ant);
  156. }
  157. }
  158. void ui_system::open_elevator_menu()
  159. {
  160. }
  161. void ui_system::close_elevator_menu()
  162. {
  163. }