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

113 lines
2.9 KiB

  1. /*
  2. * Copyright (C) 2023 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_GEOM_BVH_HPP
  20. #define ANTKEEPER_GEOM_BVH_HPP
  21. #include <engine/geom/primitives/ray.hpp>
  22. #include <engine/geom/bvh/bvh-primitive.hpp>
  23. #include <engine/geom/bvh/bvh-node.hpp>
  24. #include <cstdint>
  25. #include <functional>
  26. #include <span>
  27. #include <vector>
  28. namespace geom {
  29. class brep_mesh;
  30. /**
  31. * Bounding volume hierarchy (BVH).
  32. */
  33. class bvh
  34. {
  35. public:
  36. using visitor_type = std::function<void(std::uint32_t)>;
  37. /**
  38. * Constructs a BVH from a set of primitives.
  39. *
  40. * @param primitives Axis-aligned bounding boxes.
  41. */
  42. explicit bvh(std::span<const bvh_primitive> primitives);
  43. /**
  44. * Constructs a BVH from a B-rep mesh.
  45. *
  46. * @param mesh B-rep mesh from which to build the BVH.
  47. */
  48. explicit bvh(const brep_mesh& mesh);
  49. /// Constructs an empty BVH.
  50. constexpr bvh() noexcept = default;
  51. /**
  52. * Constructs a BVH from a set of primitives.
  53. *
  54. * @param primitives BVH primitives.
  55. */
  56. void build(std::span<const bvh_primitive> primitives);
  57. /**
  58. * Constructs a BVH from a B-rep mesh.
  59. *
  60. * @param mesh B-rep mesh from which to build the BVH.
  61. */
  62. void build(const brep_mesh& mesh);
  63. /**
  64. * Visits the primitive indices of all BVH nodes that intersect a ray.
  65. *
  66. * @param ray Query ray.
  67. * @param f Unary visitor function which operates on a BVH primitive index.
  68. */
  69. inline void visit(const geom::ray<float, 3>& ray, const visitor_type& f) const
  70. {
  71. if (m_node_count)
  72. {
  73. visit(m_nodes.front(), ray, f);
  74. }
  75. }
  76. /// Returns the BVH nodes.
  77. [[nodiscard]] inline constexpr const std::vector<bvh_node>& nodes() const noexcept
  78. {
  79. return m_nodes;
  80. }
  81. private:
  82. void update_bounds(bvh_node& node, const std::span<const bvh_primitive>& primitives);
  83. /**
  84. * Builds the BVH through recursive subdivision.
  85. *
  86. * @param node Current node.
  87. * @param primitives BVH primitives.
  88. */
  89. void subdivide(bvh_node& node, const std::span<const bvh_primitive>& primitives);
  90. void visit(const bvh_node& node, const geom::ray<float, 3>& ray, const visitor_type& f) const;
  91. std::vector<std::uint32_t> m_primitive_indices;
  92. std::vector<bvh_node> m_nodes;
  93. std::uint32_t m_node_count{};
  94. };
  95. } // namespace geom
  96. #endif // ANTKEEPER_GEOM_BVH_HPP