Wayverb
voxel_collection.h
1 #pragma once
2 
3 #include "core/geo/rect.h"
4 #include "core/indexing.h"
5 #include "core/spatial_division/ndim_tree.h"
6 
7 namespace wayverb {
8 namespace core {
9 
10 using voxel = util::aligned::vector<size_t>;
11 
12 namespace detail {
13 
15 
16 template <size_t n>
17 struct voxel_data_trait final {
18  using prev_type = voxel_data_trait<n - 1>;
19  using nested_type = typename prev_type::data_type;
20  using data_type = util::aligned::vector<nested_type>;
21  static data_type get_blank(size_t size) {
22  return data_type(size, prev_type::get_blank(size));
23  }
24 };
25 
26 template <>
27 struct voxel_data_trait<0> final {
28  using data_type = voxel;
29  static data_type get_blank(size_t) { return data_type{}; }
30 };
31 
32 template <size_t n>
33 using voxel_data_t = typename voxel_data_trait<n>::data_type;
34 
36 
37 template <size_t n>
38 inline const voxel& index(const typename voxel_data_trait<n>::data_type& data,
39  indexing::index_t<n> i) {
40  return index<n - 1>(data[indexing::back<n>(i)], indexing::reduce<n>(i));
41 }
42 
43 template <>
44 inline const voxel& index<1>(
45  const typename voxel_data_trait<1>::data_type& data,
46  indexing::index_t<1> i) {
47  return data[i];
48 }
49 
50 template <size_t n>
51 inline voxel& index(typename voxel_data_trait<n>::data_type& data,
52  indexing::index_t<n> i) {
53  return index<n - 1>(data[indexing::back<n>(i)], indexing::reduce<n>(i));
54 }
55 
56 template <>
57 inline voxel& index<1>(typename voxel_data_trait<1>::data_type& data,
58  indexing::index_t<1> i) {
59  return data[i];
60 }
61 
63 
64 template <size_t n>
65 void voxelise(const ndim_tree<n>& tree,
66  const indexing::index_t<n>& position,
67  voxel_data_t<n>& ret) {
68  if (!tree.has_nodes()) {
69  index<n>(ret, position) = tree.get_items();
70  } else {
71  for (size_t i = 0; i != tree.get_nodes().size(); ++i) {
72  const auto relative = indexing::relative_position<n>(i) *
73  static_cast<unsigned>(tree.get_side() / 2);
74  voxelise(tree.get_nodes()[i], position + relative, ret);
75  }
76  }
77 }
78 
79 template <size_t n>
80 voxel_data_t<n> voxelise(const ndim_tree<n>& tree) {
81  auto ret = voxel_data_trait<n>::get_blank(tree.get_side());
82  voxelise(tree, indexing::index_t<n>{0}, ret);
83  return ret;
84 }
85 
87 
88 } // namespace detail
89 
94 template <size_t n>
95 class voxel_collection final {
96 public:
98  using data_type = detail::voxel_data_t<n>;
99 
102  : aabb_{tree.get_aabb()}
103  , data_{detail::voxelise(tree)} {}
104 
105  aabb_type get_aabb() const { return aabb_; }
106  size_t get_side() const { return data_.size(); }
107  const auto& get_voxel(indexing::index_t<n> i) const {
108  return detail::index<n>(data_, i);
109  }
110  auto& get_voxel(indexing::index_t<n> i) {
111  return detail::index<n>(data_, i);
112  }
113 
114 private:
115  aabb_type aabb_;
116  data_type data_;
117 };
118 
120 
121 template <size_t n>
122 auto voxel_dimensions(const voxel_collection<n>& voxels) {
123  return dimensions(voxels.get_aabb()) /
124  static_cast<float>(voxels.get_side());
125 }
126 
127 template <size_t n>
128 auto voxel_aabb(const voxel_collection<n>& voxels, indexing::index_t<n> i) {
129  using vt = detail::range_t<n>;
130  const auto dim = voxel_dimensions(voxels);
131  const auto root = voxels.get_aabb().get_min() + (dim * decltype(dim){i});
132  return vt(root, root + dim);
133 }
134 
136 util::aligned::vector<cl_uint> get_flattened(const voxel_collection<3>& voxels);
137 
144 using traversal_callback =
145  std::function<bool(const geo::ray&, const voxel&, float, float)>;
146 
151 void traverse(const voxel_collection<3>& voxels,
152  const geo::ray& ray,
153  const traversal_callback& fun);
154 
155 } // namespace core
156 } // namespace wayverb
Definition: geometry_structs.h:11
I would do this with a struct, but rays have an invariant:
Definition: geometric.h:19
A generic interface for spatial division algorithms (octree, quadtree)
Definition: ndim_tree.h:38
Definition: voxel_collection.h:95
Definition: traits.cpp:2
Definition: range.h:12
voxel_collection(const ndim_tree< n > &tree)
Construct directly from an existing tree.
Definition: voxel_collection.h:101
Definition: traits.h:46
Definition: capsule_base.h:9
Definition: voxel_collection.h:17