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

267 lines
6.3 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. #ifndef ANTKEEPER_SCENE_OBJECT_HPP
  20. #define ANTKEEPER_SCENE_OBJECT_HPP
  21. #include "animation/tween.hpp"
  22. #include "geom/bounding-volume.hpp"
  23. #include "math/vector-type.hpp"
  24. #include "math/quaternion-type.hpp"
  25. #include "math/transform-type.hpp"
  26. #include "renderer/context.hpp"
  27. #include "renderer/queue.hpp"
  28. #include <atomic>
  29. #include <cstddef>
  30. namespace scene {
  31. /**
  32. * Internal base class for scene objects.
  33. */
  34. class object_base
  35. {
  36. public:
  37. typedef math::vector<float, 3> vector_type;
  38. typedef math::quaternion<float> quaternion_type;
  39. typedef math::transform<float> transform_type;
  40. typedef geom::bounding_volume<float> bounding_volume_type;
  41. /// Returns the type ID for this scene object type.
  42. virtual const std::size_t get_object_type_id() const = 0;
  43. /**
  44. * Creates a scene object base.
  45. */
  46. object_base();
  47. /**
  48. * Destroys a scene object base.
  49. */
  50. virtual ~object_base() = default;
  51. /**
  52. * Adds a render operation describing this object to a render queue.
  53. *
  54. * @param ctx Render context.
  55. * @param queue Render queue.
  56. *
  57. * @see render::context
  58. * @see render::operation
  59. */
  60. virtual void render(const render::context& ctx, render::queue& queue) const;
  61. /**
  62. * Updates all tweens in the scene object.
  63. */
  64. virtual void update_tweens();
  65. /**
  66. * Activates or deactivates the scene object.
  67. */
  68. void set_active(bool active);
  69. /**
  70. *
  71. */
  72. void look_at(const vector_type& position, const vector_type& target, const vector_type& up);
  73. /**
  74. * Sets the scene object's transform.
  75. */
  76. void set_transform(const transform_type& transform);
  77. /**
  78. * Sets the scene object's translation.
  79. */
  80. void set_translation(const vector_type& translation);
  81. /**
  82. * Sets the scene object's rotation.
  83. */
  84. void set_rotation(const quaternion_type& rotation);
  85. /**
  86. * Sets the scene object's scale.
  87. */
  88. void set_scale(const vector_type& scale);
  89. /**
  90. * Sets a culling mask for the object, which will be used for view-frustum culling instead of the object's bounds.
  91. */
  92. void set_culling_mask(const bounding_volume_type* culling_mask);
  93. /// Returns whether the scene object is active.
  94. bool is_active() const;
  95. /**
  96. * Returns the transform.
  97. */
  98. const transform_type& get_transform() const;
  99. /**
  100. * Returns the transform's translation vector.
  101. */
  102. const vector_type& get_translation() const;
  103. /**
  104. * Returns the transform's rotation quaternion.
  105. */
  106. const quaternion_type& get_rotation() const;
  107. /**
  108. * Returns the transform's scale vector.
  109. */
  110. const vector_type& get_scale() const;
  111. /**
  112. * Returns the transform tween.
  113. */
  114. const tween<transform_type>& get_transform_tween() const;
  115. tween<transform_type>& get_transform_tween();
  116. /**
  117. * Returns the local-space (untransformed) bounds of the object.
  118. */
  119. virtual const bounding_volume_type& get_local_bounds() const = 0;
  120. /**
  121. * Returns the world-space (transformed) bounds of the object.
  122. */
  123. virtual const bounding_volume_type& get_world_bounds() const = 0;
  124. /**
  125. * Returns the culling mask of the object.
  126. */
  127. const bounding_volume_type* get_culling_mask() const;
  128. protected:
  129. static std::size_t next_object_type_id();
  130. private:
  131. /// Interpolates between two transforms.
  132. static transform_type interpolate_transforms(const transform_type& x, const transform_type& y, float a);
  133. /**
  134. * Called every time the scene object's tranform is changed.
  135. */
  136. virtual void transformed();
  137. bool active;
  138. tween<transform_type> transform;
  139. const bounding_volume_type* culling_mask;
  140. };
  141. inline void object_base::set_active(bool active)
  142. {
  143. this->active = active;
  144. }
  145. inline void object_base::set_transform(const transform_type& transform)
  146. {
  147. this->transform[1] = transform;
  148. transformed();
  149. }
  150. inline void object_base::set_translation(const vector_type& translation)
  151. {
  152. transform[1].translation = translation;
  153. transformed();
  154. }
  155. inline void object_base::set_rotation(const quaternion_type& rotation)
  156. {
  157. transform[1].rotation = rotation;
  158. transformed();
  159. }
  160. inline void object_base::set_scale(const vector_type& scale)
  161. {
  162. transform[1].scale = scale;
  163. transformed();
  164. }
  165. inline bool object_base::is_active() const
  166. {
  167. return active;
  168. }
  169. inline const typename object_base::transform_type& object_base::get_transform() const
  170. {
  171. return transform[1];
  172. }
  173. inline const typename object_base::vector_type& object_base::get_translation() const
  174. {
  175. return get_transform().translation;
  176. }
  177. inline const typename object_base::quaternion_type& object_base::get_rotation() const
  178. {
  179. return get_transform().rotation;
  180. }
  181. inline const typename object_base::vector_type& object_base::get_scale() const
  182. {
  183. return get_transform().scale;
  184. }
  185. inline const tween<typename object_base::transform_type>& object_base::get_transform_tween() const
  186. {
  187. return transform;
  188. }
  189. inline tween<typename object_base::transform_type>& object_base::get_transform_tween()
  190. {
  191. return transform;
  192. }
  193. inline const typename object_base::bounding_volume_type* object_base::get_culling_mask() const
  194. {
  195. return culling_mask;
  196. }
  197. /**
  198. * Abstract base class for lights, cameras, model instances, and other scene objects.
  199. *
  200. * @tparam T This should be the same class that's inheriting from the scene object, in order to give it a valid type-specific ID.
  201. */
  202. template <class T>
  203. class object: public object_base
  204. {
  205. public:
  206. /// Unique type ID for this scene object type.
  207. static const std::atomic<std::size_t> object_type_id;
  208. virtual const std::size_t get_object_type_id() const final;
  209. };
  210. template <typename T>
  211. const std::atomic<std::size_t> object<T>::object_type_id{object_base::next_object_type_id()};
  212. template <typename T>
  213. inline const std::size_t object<T>::get_object_type_id() const
  214. {
  215. return object_type_id;
  216. }
  217. } // namespace scene
  218. #endif // ANTKEEPER_SCENE_OBJECT_HPP