5 #include "core/callback_accumulator.h" 6 #include "core/geo/box.h" 16 namespace image_source {
21 glm::vec3 image_source_position(
const glm::ivec3& order,
22 const glm::vec3& source,
23 const glm::vec3& dim);
26 constexpr T power(T t,
size_t p) {
27 return p == 0 ? core::unit_constructor_v<T> : t * power(t, p - 1);
31 auto attenuation_factor(
const glm::ivec3& order,
32 const glm::vec3& image_source,
33 const glm::vec3& receiver,
35 const auto diff = image_source - receiver;
36 const auto cos_theta = glm::abs(diff) / glm::length(diff);
38 return power(core::average_wall_impedance_to_pressure_reflectance(
39 impedance, cos_theta.x),
41 power(core::average_wall_impedance_to_pressure_reflectance(
42 impedance, cos_theta.y),
44 power(core::average_wall_impedance_to_pressure_reflectance(
45 impedance, cos_theta.z),
50 auto traverse_images(
const core::geo::box& box,
51 const glm::vec3& source,
52 const glm::vec3& receiver,
55 const auto dim = dimensions(box);
56 const auto shells = glm::ivec3(glm::ceil(glm::vec3(max_distance) / dim));
58 std::cout <<
"shells: " << shells.x <<
", " << shells.y <<
", " << shells.z
61 using impulse_t = impulse<::detail::components_v<T>>;
63 util::aligned::vector<impulse_t> impulses;
64 impulses.reserve(shells.x * shells.y * shells.z * 8);
66 for (
auto i = -shells.x; i != shells.x + 1; ++i) {
67 for (
auto j = -shells.y; j != shells.y + 1; ++j) {
68 for (
auto k = -shells.z; k != shells.z + 1; ++k) {
69 const auto order = glm::ivec3{i, j, k};
70 const auto pos = box.get_min() +
71 image_source_position(order, source, dim);
72 const auto dist = glm::distance(pos, receiver);
74 if (dist < max_distance) {
75 const auto attenuation =
76 attenuation_factor(order, pos, receiver, impedance);
78 impulses.emplace_back(
79 impulse_t{attenuation,
80 core::to_cl_float3{}(pos),
81 glm::distance(pos, receiver)});
90 template <
typename Surface>
91 auto find_impulses(
const core::geo::box& box,
92 const glm::vec3& source,
93 const glm::vec3& receiver,
94 const Surface& surface,
95 double max_distance) {
96 const auto impedance = core::pressure_reflectance_to_average_wall_impedance(
97 core::absorption_to_pressure_reflectance(surface));
99 return traverse_images(box, source, receiver, max_distance, impedance);
Definition: pressure.h:22
Definition: capsule_base.h:9