💿🐜 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.

197 lines
5.6 KiB

  1. /*
  2. * Copyright (C) 2021 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 "entity/commands.hpp"
  20. #include "entity/components/model.hpp"
  21. #include "entity/components/transform.hpp"
  22. #include "entity/components/copy-transform.hpp"
  23. #include "entity/components/snap.hpp"
  24. #include "entity/components/parent.hpp"
  25. #include "entity/components/celestial-body.hpp"
  26. #include "entity/components/terrain.hpp"
  27. #include "entity/components/name.hpp"
  28. #include <limits>
  29. namespace entity {
  30. namespace command {
  31. void translate(entity::registry& registry, entity::id eid, const float3& translation)
  32. {
  33. if (registry.has<component::transform>(eid))
  34. {
  35. component::transform& transform = registry.get<component::transform>(eid);
  36. transform.local.translation += translation;
  37. }
  38. }
  39. void move_to(entity::registry& registry, entity::id eid, const float3& position)
  40. {
  41. if (registry.has<component::transform>(eid))
  42. {
  43. component::transform& transform = registry.get<component::transform>(eid);
  44. transform.local.translation = position;
  45. }
  46. }
  47. void warp_to(entity::registry& registry, entity::id eid, const float3& position)
  48. {
  49. if (registry.has<component::transform>(eid))
  50. {
  51. component::transform& transform = registry.get<component::transform>(eid);
  52. transform.local.translation = position;
  53. transform.warp = true;
  54. }
  55. }
  56. void set_scale(entity::registry& registry, entity::id eid, const float3& scale)
  57. {
  58. if (registry.has<component::transform>(eid))
  59. {
  60. component::transform& transform = registry.get<component::transform>(eid);
  61. transform.local.scale = scale;
  62. }
  63. }
  64. void set_transform(entity::registry& registry, entity::id eid, const math::transform<float>& transform, bool warp)
  65. {
  66. if (registry.has<component::transform>(eid))
  67. {
  68. component::transform& component = registry.get<component::transform>(eid);
  69. component.local = transform;
  70. component.warp = warp;
  71. }
  72. }
  73. void place(entity::registry& registry, entity::id eid, entity::id celestial_body_id, double altitude, double latitude, double longitude)
  74. {
  75. if (registry.has<component::transform>(eid))
  76. {
  77. double x = 0.0;
  78. double y = altitude;
  79. double z = 0.0;
  80. if (registry.has<component::celestial_body>(celestial_body_id))
  81. {
  82. const component::celestial_body& celestial_body = registry.get<component::celestial_body>(celestial_body_id);
  83. x = longitude * math::two_pi<double> * celestial_body.radius;
  84. z = -latitude * math::two_pi<double> * celestial_body.radius;
  85. if (registry.has<component::terrain>(celestial_body_id))
  86. {
  87. const component::terrain& terrain = registry.get<component::terrain>(celestial_body_id);
  88. if (terrain.elevation != nullptr)
  89. {
  90. y += terrain.elevation(latitude, longitude);
  91. }
  92. }
  93. }
  94. component::transform& transform = registry.get<component::transform>(eid);
  95. transform.local.translation = math::type_cast<float>(double3{x, y, z});
  96. transform.warp = true;
  97. }
  98. }
  99. void assign_render_layers(entity::registry& registry, entity::id eid, unsigned int layers)
  100. {
  101. if (registry.has<component::model>(eid))
  102. {
  103. component::model model = registry.get<component::model>(eid);
  104. model.layers = layers;
  105. registry.replace<component::model>(eid, model);
  106. // Apply to child layers
  107. registry.view<component::parent>().each(
  108. [&](entity::id eid, auto& component)
  109. {
  110. if (component.parent == eid)
  111. assign_render_layers(registry, eid, layers);
  112. });
  113. }
  114. }
  115. void bind_transform(entity::registry& registry, entity::id source, entity::id target)
  116. {
  117. component::copy_transform copy_transform = {target};
  118. registry.assign_or_replace<component::copy_transform>(source, copy_transform);
  119. }
  120. math::transform<float> get_local_transform(entity::registry& registry, entity::id eid)
  121. {
  122. if (registry.has<component::transform>(eid))
  123. {
  124. const component::transform& component = registry.get<component::transform>(eid);
  125. return component.local;
  126. }
  127. return math::identity_transform<float>;
  128. }
  129. math::transform<float> get_world_transform(entity::registry& registry, entity::id eid)
  130. {
  131. if (registry.has<component::transform>(eid))
  132. {
  133. const component::transform& component = registry.get<component::transform>(eid);
  134. return component.world;
  135. }
  136. return math::identity_transform<float>;
  137. }
  138. void parent(entity::registry& registry, entity::id child, entity::id parent)
  139. {
  140. component::parent component;
  141. component.parent = parent;
  142. registry.assign_or_replace<component::parent>(child, component);
  143. }
  144. void rename(entity::registry& registry, entity::id eid, const std::string& name)
  145. {
  146. registry.assign_or_replace<component::name>(eid, name);
  147. }
  148. entity::id find(entity::registry& registry, const std::string& name)
  149. {
  150. auto view = registry.view<component::name>();
  151. for (auto eid: view)
  152. {
  153. if (view.get(eid).id == name)
  154. return eid;
  155. }
  156. return entt::null;
  157. }
  158. entity::id create(entity::registry& registry)
  159. {
  160. return registry.create();
  161. }
  162. entity::id create(entity::registry& registry, const std::string& name)
  163. {
  164. auto eid = registry.create();
  165. rename(registry, eid, name);
  166. return eid;
  167. }
  168. } // namespace command
  169. } // namespace entity