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

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