Wayverb
box.h
1 #pragma once
2 
3 #include "core/conversions.h"
4 #include "core/scene_data.h"
5 
6 #include "utilities/range.h"
7 
8 #include "glm/glm.hpp"
9 
10 #include <experimental/optional>
11 
12 namespace wayverb {
13 namespace core {
14 namespace geo {
15 
16 struct triangle_vec3;
17 class ray;
18 
19 using box = util::range<glm::vec3>;
20 
21 enum class wall { nx, px, ny, py, nz, pz };
22 enum class direction { x, y, z };
23 
24 bool overlaps(const box& b, const triangle_vec3& t);
25 
26 std::experimental::optional<std::pair<float, float>> intersection_distances(
27  const box& b, const ray& ray);
28 
32 std::experimental::optional<float> intersects(const box& b, const ray& ray);
33 
36 bool intersects(const box& b, const ray& ray, float t0, float t1);
37 
38 template <typename Surface>
39 auto get_scene_data(const box& b, Surface s) {
40  return make_scene_data(
41  util::aligned::vector<triangle>{{0, 0, 1, 5},
42  {0, 0, 5, 4},
43  {0, 1, 0, 3},
44  {0, 0, 2, 3},
45  {0, 2, 0, 6},
46  {0, 0, 4, 6},
47  {0, 5, 1, 7},
48  {0, 1, 3, 7},
49  {0, 3, 2, 7},
50  {0, 2, 6, 7},
51  {0, 4, 5, 7},
52  {0, 6, 4, 7}},
53  util::aligned::vector<cl_float3>{
54  {{b.get_min().x, b.get_min().y, b.get_min().z}},
55  {{b.get_max().x, b.get_min().y, b.get_min().z}},
56  {{b.get_min().x, b.get_max().y, b.get_min().z}},
57  {{b.get_max().x, b.get_max().y, b.get_min().z}},
58  {{b.get_min().x, b.get_min().y, b.get_max().z}},
59  {{b.get_max().x, b.get_min().y, b.get_max().z}},
60  {{b.get_min().x, b.get_max().y, b.get_max().z}},
61  {{b.get_max().x, b.get_max().y, b.get_max().z}}},
62  util::aligned::vector<Surface>{std::move(s)});
63 }
64 
65 constexpr glm::vec3 mirror_on_axis(const glm::vec3& v,
66  const glm::vec3& pt,
67  direction d) {
68  switch (d) {
69  case direction::x: return glm::vec3(2 * pt.x - v.x, v.y, v.z);
70  case direction::y: return glm::vec3(v.x, 2 * pt.y - v.y, v.z);
71  case direction::z: return glm::vec3(v.x, v.y, 2 * pt.z - v.z);
72  }
73 }
74 
75 constexpr glm::vec3 mirror(const box& b, const glm::vec3& v, wall w) {
76  switch (w) {
77  case wall::nx: return mirror_on_axis(v, b.get_min(), direction::x);
78  case wall::px: return mirror_on_axis(v, b.get_max(), direction::x);
79  case wall::ny: return mirror_on_axis(v, b.get_min(), direction::y);
80  case wall::py: return mirror_on_axis(v, b.get_max(), direction::y);
81  case wall::nz: return mirror_on_axis(v, b.get_min(), direction::z);
82  case wall::pz: return mirror_on_axis(v, b.get_max(), direction::z);
83  }
84 }
85 
86 template <typename T>
87 geo::box compute_aabb(const T* b, const T* e);
88 
89 template <typename T>
90 geo::box compute_aabb(T&& t) {
91  return compute_aabb(t.data(), t.data() + t.size());
92 }
93 
94 glm::vec3 mirror_inside(const box& b, const glm::vec3& v, direction d);
95 box mirror(const box& b, wall w);
96 
97 } // namespace geo
98 
99 inline auto inside(const geo::box& a, const glm::vec3& b) {
100  return glm::all(glm::lessThan(a.get_min(), b)) &&
101  glm::all(glm::lessThan(b, a.get_max()));
102 }
103 
104 } // namespace core
105 } // namespace wayverb
Definition: traits.cpp:2
Definition: range.h:12
Definition: capsule_base.h:9