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

262 lines
6.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. #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 bounds of the object.
  118. */
  119. virtual const bounding_volume_type& get_bounds() const = 0;
  120. /**
  121. * Returns the culling mask of the object.
  122. */
  123. const bounding_volume_type* get_culling_mask() const;
  124. protected:
  125. static std::size_t next_object_type_id();
  126. private:
  127. /// Interpolates between two transforms.
  128. static transform_type interpolate_transforms(const transform_type& x, const transform_type& y, float a);
  129. /**
  130. * Called every time the scene object's tranform is changed.
  131. */
  132. virtual void transformed();
  133. bool active;
  134. tween<transform_type> transform;
  135. const bounding_volume_type* culling_mask;
  136. };
  137. inline void object_base::set_active(bool active)
  138. {
  139. this->active = active;
  140. }
  141. inline void object_base::set_transform(const transform_type& transform)
  142. {
  143. this->transform[1] = transform;
  144. transformed();
  145. }
  146. inline void object_base::set_translation(const vector_type& translation)
  147. {
  148. transform[1].translation = translation;
  149. transformed();
  150. }
  151. inline void object_base::set_rotation(const quaternion_type& rotation)
  152. {
  153. transform[1].rotation = rotation;
  154. transformed();
  155. }
  156. inline void object_base::set_scale(const vector_type& scale)
  157. {
  158. transform[1].scale = scale;
  159. transformed();
  160. }
  161. inline bool object_base::is_active() const
  162. {
  163. return active;
  164. }
  165. inline const typename object_base::transform_type& object_base::get_transform() const
  166. {
  167. return transform[1];
  168. }
  169. inline const typename object_base::vector_type& object_base::get_translation() const
  170. {
  171. return get_transform().translation;
  172. }
  173. inline const typename object_base::quaternion_type& object_base::get_rotation() const
  174. {
  175. return get_transform().rotation;
  176. }
  177. inline const typename object_base::vector_type& object_base::get_scale() const
  178. {
  179. return get_transform().scale;
  180. }
  181. inline const tween<typename object_base::transform_type>& object_base::get_transform_tween() const
  182. {
  183. return transform;
  184. }
  185. inline tween<typename object_base::transform_type>& object_base::get_transform_tween()
  186. {
  187. return transform;
  188. }
  189. inline const typename object_base::bounding_volume_type* object_base::get_culling_mask() const
  190. {
  191. return culling_mask;
  192. }
  193. /**
  194. * Abstract base class for lights, cameras, model instances, and other scene objects.
  195. *
  196. * @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.
  197. */
  198. template <class T>
  199. class object: public object_base
  200. {
  201. public:
  202. /// Unique type ID for this scene object type.
  203. static const std::atomic<std::size_t> object_type_id;
  204. virtual const std::size_t get_object_type_id() const final;
  205. };
  206. template <typename T>
  207. const std::atomic<std::size_t> object<T>::object_type_id{object_base::next_object_type_id()};
  208. template <typename T>
  209. inline const std::size_t object<T>::get_object_type_id() const
  210. {
  211. return object_type_id;
  212. }
  213. } // namespace scene
  214. #endif // ANTKEEPER_SCENE_OBJECT_HPP