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

166 lines
5.2 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 <limits>
  28. namespace entity {
  29. namespace command {
  30. void translate(entity::registry& registry, entity::id entity_id, const float3& translation)
  31. {
  32. if (registry.has<component::transform>(entity_id))
  33. {
  34. component::transform& transform = registry.get<component::transform>(entity_id);
  35. transform.local.translation += translation;
  36. }
  37. }
  38. void move_to(entity::registry& registry, entity::id entity_id, const float3& position)
  39. {
  40. if (registry.has<component::transform>(entity_id))
  41. {
  42. component::transform& transform = registry.get<component::transform>(entity_id);
  43. transform.local.translation = position;
  44. }
  45. }
  46. void warp_to(entity::registry& registry, entity::id entity_id, const float3& position)
  47. {
  48. if (registry.has<component::transform>(entity_id))
  49. {
  50. component::transform& transform = registry.get<component::transform>(entity_id);
  51. transform.local.translation = position;
  52. transform.warp = true;
  53. }
  54. }
  55. void set_scale(entity::registry& registry, entity::id entity_id, const float3& scale)
  56. {
  57. if (registry.has<component::transform>(entity_id))
  58. {
  59. component::transform& transform = registry.get<component::transform>(entity_id);
  60. transform.local.scale = scale;
  61. }
  62. }
  63. void set_transform(entity::registry& registry, entity::id entity_id, const math::transform<float>& transform, bool warp)
  64. {
  65. if (registry.has<component::transform>(entity_id))
  66. {
  67. component::transform& component = registry.get<component::transform>(entity_id);
  68. component.local = transform;
  69. component.warp = warp;
  70. }
  71. }
  72. void place(entity::registry& registry, entity::id entity_id, entity::id celestial_body_id, double altitude, double latitude, double longitude)
  73. {
  74. if (registry.has<component::transform>(entity_id))
  75. {
  76. double x = 0.0;
  77. double y = altitude;
  78. double z = 0.0;
  79. if (registry.has<component::celestial_body>(celestial_body_id))
  80. {
  81. const component::celestial_body& celestial_body = registry.get<component::celestial_body>(celestial_body_id);
  82. x = longitude * math::two_pi<double> * celestial_body.radius;
  83. z = -latitude * math::two_pi<double> * celestial_body.radius;
  84. if (registry.has<component::terrain>(celestial_body_id))
  85. {
  86. const component::terrain& terrain = registry.get<component::terrain>(celestial_body_id);
  87. if (terrain.elevation != nullptr)
  88. {
  89. y += terrain.elevation(latitude, longitude);
  90. }
  91. }
  92. }
  93. component::transform& transform = registry.get<component::transform>(entity_id);
  94. transform.local.translation = math::type_cast<float>(double3{x, y, z});
  95. transform.warp = true;
  96. }
  97. }
  98. void assign_render_layers(entity::registry& registry, entity::id entity_id, unsigned int layers)
  99. {
  100. if (registry.has<component::model>(entity_id))
  101. {
  102. component::model model = registry.get<component::model>(entity_id);
  103. model.layers = layers;
  104. registry.replace<component::model>(entity_id, model);
  105. // Apply to child layers
  106. registry.view<component::parent>().each(
  107. [&](entity::id entity_id, auto& component)
  108. {
  109. if (component.parent == entity_id)
  110. assign_render_layers(registry, entity_id, layers);
  111. });
  112. }
  113. }
  114. void bind_transform(entity::registry& registry, entity::id source, entity::id target)
  115. {
  116. component::copy_transform copy_transform = {target};
  117. registry.assign_or_replace<component::copy_transform>(source, copy_transform);
  118. }
  119. math::transform<float> get_local_transform(entity::registry& registry, entity::id entity_id)
  120. {
  121. if (registry.has<component::transform>(entity_id))
  122. {
  123. const component::transform& component = registry.get<component::transform>(entity_id);
  124. return component.local;
  125. }
  126. return math::identity_transform<float>;
  127. }
  128. math::transform<float> get_world_transform(entity::registry& registry, entity::id entity_id)
  129. {
  130. if (registry.has<component::transform>(entity_id))
  131. {
  132. const component::transform& component = registry.get<component::transform>(entity_id);
  133. return component.world;
  134. }
  135. return math::identity_transform<float>;
  136. }
  137. void parent(entity::registry& registry, entity::id child, entity::id parent)
  138. {
  139. component::parent component;
  140. component.parent = parent;
  141. registry.assign_or_replace<component::parent>(child, component);
  142. }
  143. } // namespace command
  144. } // namespace entity