RavEngine
Loading...
Searching...
No Matches
acoustic_ray.h
1/*
2Copyright 2018 Google Inc. All Rights Reserved.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS-IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef RESONANCE_AUDIO_GEOMETRICAL_ACOUSTICS_ACOUSTIC_RAY_H_
18#define RESONANCE_AUDIO_GEOMETRICAL_ACOUSTICS_ACOUSTIC_RAY_H_
19
20#include <array>
21#include <vector>
22
23#include "embree2/rtcore.h"
24#include "embree2/rtcore_ray.h"
25#include "base/constants_and_types.h"
26
27namespace vraudio {
28
29// A class extending Embree's RTCRay (https://embree.github.io/api.html) with
30// data needed for acoustic computations.
31// It exposes useful fields through accessors.
32class RTCORE_ALIGN(16) AcousticRay : public RTCRay {
33 public:
34 enum class RayType {
35 kSpecular,
36 kDiffuse,
37 };
38
39 // A constant used to indicate that the ray extends to infinity, if
40 // ray.t_far() == AcousticRay::kInfinity.
41 static const float kInfinity;
42
43 // Used to offset a ray's origin slightly so that it will not
44 // intersect with the same geometry/primitive that it was generated from
45 // (by reflection, transmission, diffraction, etc.).
46 static const float kRayEpsilon;
47
48 // Default constructor. Constructs a ray whose origin is at (0, 0, 0) and
49 // points in the +x direction.
50 AcousticRay()
51 : energies_(), type_(RayType::kSpecular), prior_distance_(0.0f) {
52 org[0] = 0.0f;
53 org[1] = 0.0f;
54 org[2] = 0.0f;
55 dir[0] = 1.0f;
56 dir[1] = 0.0f;
57 dir[2] = 0.0f;
58 tnear = 0.0f;
59 tfar = kInfinity;
60 Ng[0] = 0.0f;
61 Ng[1] = 0.0f;
62 Ng[2] = 0.0f;
63 geomID = RTC_INVALID_GEOMETRY_ID;
64
65 // Members in RTCRay that we do not use (or whose initial values we do not
66 // care) are not initialized:
67 // align0, align1, align2, time, mask, u, v, primID, instID.
68 }
69
70 // Constructor.
71 //
72 // @param origin Origin of the ray.
73 // @param direction Direction of the ray.
74 // @param t_near Ray parameter corresponding to the start of the ray.
75 // @param t_far Ray parameter corresponding to the end of the ray. Pass in
76 // AcousticRay::kInfinity if there is no end point.
77 // @param energies Ray energies for all frequency bands.
78 // @param ray_type Type of ray.
79 // @param prior_distance Distance traveled before this ray.
80 AcousticRay(const float origin[3], const float direction[3], float t_near,
81 float t_far,
82 const std::array<float, kNumReverbOctaveBands>& energies,
83 RayType ray_type, float prior_distance)
84 : energies_(energies), type_(ray_type), prior_distance_(prior_distance) {
85 org[0] = origin[0];
86 org[1] = origin[1];
87 org[2] = origin[2];
88 dir[0] = direction[0];
89 dir[1] = direction[1];
90 dir[2] = direction[2];
91 tnear = t_near;
92 tfar = t_far;
93 Ng[0] = 0.0f;
94 Ng[1] = 0.0f;
95 Ng[2] = 0.0f;
96 geomID = RTC_INVALID_GEOMETRY_ID;
97
98 // Members in RTCRay that we do not use (or whose initial values we do not
99 // care) are not initialized:
100 // align0, align1, align2, time, mask, u, v, primID, instID.
101 }
102
103 // Ray origin.
104 const float* origin() const { return org; }
105 void set_origin(const float origin[3]) {
106 org[0] = origin[0];
107 org[1] = origin[1];
108 org[2] = origin[2];
109 }
110
111 // Ray direction.
112 const float* direction() const { return dir; }
113 void set_direction(const float direction[3]) {
114 dir[0] = direction[0];
115 dir[1] = direction[1];
116 dir[2] = direction[2];
117 }
118
119 // Ray parameter t corresponding to the start of the ray segment.
120 const float t_near() const { return tnear; }
121 void set_t_near(float t_near) { tnear = t_near; }
122
123 // Ray parameter t corresponding to the end of the ray segment.
124 const float t_far() const { return tfar; }
125 void set_t_far(float t_far) { tfar = t_far; }
126
127 // Functions intersected_*() will only return meaningful results after
128 // Intersect() is called, otherwise they return default values as
129 // described below.
130 //
131 // Not normalized geometry normal at the intersection point.
132 // Default value: Vec3fa(0, 0, 0).
133 const float* intersected_geometry_normal() const { return Ng; }
134 void set_intersected_geometry_normal(
135 const float intersected_geometry_normal[3]) {
136 Ng[0] = intersected_geometry_normal[0];
137 Ng[1] = intersected_geometry_normal[1];
138 Ng[2] = intersected_geometry_normal[2];
139 }
140
141 // Id of the intersected geometry.
142 // Default value: kInvalidGeometryId.
143 const unsigned int intersected_geometry_id() const { return geomID; }
144
145 // Id of the intersected primitive.
146 // Default value: kInvalidPrimitiveId.
147 const unsigned int intersected_primitive_id() const { return primID; }
148
149 // Ray energies for all frequency bands.
150 const std::array<float, kNumReverbOctaveBands>& energies() const {
151 return energies_;
152 }
153 void set_energies(const std::array<float, kNumReverbOctaveBands>& energies) {
154 energies_ = energies;
155 }
156
157 // Ray type.
158 const RayType type() const { return type_; }
159 void set_type(const RayType type) { type_ = type; }
160
161 // Prior distance.
162 const float prior_distance() const { return prior_distance_; }
163 void set_prior_distance(float prior_distance) {
164 prior_distance_ = prior_distance;
165 }
166
167 // Finds the first intersection between this ray and a scene. Some fields
168 // will be filled/mutated, which can be examined by the following functions:
169 // - t_far()
170 // - intersected_geometry_normal()
171 // - intersected_geometry_id()
172 // - intersected_primitive_id()
173 //
174 // @param scene An RTCScene to test the intersection.
175 // @return True if an intersection is found.
176 bool Intersect(RTCScene scene) {
177 rtcIntersect(scene, *this);
178 return geomID != RTC_INVALID_GEOMETRY_ID;
179 }
180
181 private:
182 // Used to determine early-termination of rays. May also be used to model
183 // source strength.
184 std::array<float, kNumReverbOctaveBands> energies_;
185
186 // Ray type.
187 RayType type_ = RayType::kSpecular;
188
189 // Accumulated distance traveled on the same path before this ray starts.
190 float prior_distance_ = 0.0f;
191};
192
193} // namespace vraudio
194
195#endif // RESONANCE_AUDIO_GEOMETRICAL_ACOUSTICS_ACOUSTIC_RAY_H_