RavEngine
Loading...
Searching...
No Matches
proxy_room_estimator.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_PROXY_ROOM_ESTIMATOR_H_
18#define RESONANCE_AUDIO_GEOMETRICAL_ACOUSTICS_PROXY_ROOM_ESTIMATOR_H_
19
20#include <array>
21#include <utility>
22#include <vector>
23
24#include "Eigen/Core"
25#include "api/resonance_audio_api.h"
26#include "base/constants_and_types.h"
27#include "base/misc_math.h"
28#include "geometrical_acoustics/path.h"
29#include "platforms/common/room_properties.h"
30
31namespace vraudio {
32
33// A class that estimates a "proxy room" from traced sound propagation paths.
34// A proxy room is used to model dynamic early reflections as if they are
35// reflected from a box-shaped room, even though the real scene geometry is
36// arbitrarily complex. This is to complement the pre-computed late reverb
37// effects, and it takes the same input (i.e., the ray tracing results) as the
38// reverb pre-computation. The proxy room is estimated from the first order
39// ray paths (i.e., those from the source to the first hit points), and the
40// estimation has two stages:
41// 1. Fitting the geometry (currently only as an axis-aligned cube).
42// 2. Fitting the surface materials on the six walls.
44 public:
45 ProxyRoomEstimator() = default;
46
47 // ProxyRoomEstimator is neither copyable nor movable.
49 ProxyRoomEstimator& operator=(const ProxyRoomEstimator&) = delete;
50
51 // Collects hit point data from traced ray paths, batch-by-batch.
52 //
53 // @param paths_batch A batch of ray paths.
54 void CollectHitPointData(const std::vector<Path>& paths_batch);
55
56 // Estimates a cube-shaped proxy room from collected hit points. Hit points
57 // are sorted according to their traveled distance. In order to make the
58 // estimation more robust, we discard "outlier" hit points, i.e., those whose
59 // traveled distances are too large or too small.
60 //
61 // @param outlier_portion What portion of the hit points are considered as
62 // outliers. For example, a value of 0.1 means that the hit points whose
63 // distances are in the top 10% and bottom 10% are considered as outliers
64 // and discarded. The value must be in the range of [0, 0.5].
65 // @param room_properties Room properties of the estimated axis-aligned cube-
66 // shaped room, each wall having an estimated surface material.
67 // @return True if the estimation is successful.
68 bool EstimateCubicProxyRoom(float outlier_portion,
69 RoomProperties* room_properties);
70
71 private:
72 class CoefficientsVector : public Eigen::Matrix<float, kNumReverbOctaveBands,
73 1, Eigen::DontAlign> {
74 public:
75 // Inherits all constructors with 1-or-more arguments. Necessary because
76 // MSVC12 doesn't support inheriting constructors.
77 template <typename Arg1, typename... Args>
78 CoefficientsVector(const Arg1& arg1, Args&&... args)
79 : Matrix(arg1, std::forward<Args>(args)...) {}
80
81 // Constructs a zero vector.
82 CoefficientsVector() { setZero(); }
83 };
84
85 // A struct to contain data necessary for estimating a proxy room.
86 struct HitPointData {
87 // Origin of the ray that creates this hit point.
88 WorldPosition origin;
89
90 // Direction of the ray that creates this hit point.
91 WorldPosition direction;
92
93 // Ray parameter t corresponding to the hit point. If the ray escaped the
94 // scene and did not hit anything, then |t_far| takes the value of
95 // |AcousticRay::kInfinity|. Escaped rays are still useful in estimating
96 // surface materials, because they can be considered completely absorbed
97 // and should increase the effective absorption coefficients.
98 float t_far;
99
100 // Absorption coefficients of the surface of the hit point across the
101 // frequency bands.
102 std::array<float, kNumReverbOctaveBands> absorption_coefficients;
103 };
104
105 // Collects one hit point from one traced ray path.
106 //
107 // @param path Traced ray path.
108 // @return Collected hit point.
109 HitPointData CollectHitPointDataFromPath(const Path& path);
110
111 // Estimates the geometry of the cube.
112 //
113 // @param outlier_portion Portion of all hit points to be discarded. See
114 // EstimateCube() above.
115 // @param position Output center position of the estimated cube.
116 // @param dimensions Output dimensions of the estimated cube.
117 // @return True if the estimation is successful.
118 bool EstimateCubeGeometry(float outlier_portion, float* position,
119 float* dimensions, float* rotation);
120
121 // Groups hit points by which walls they lie on in an assumed axis-aligned
122 // room.
123 //
124 // @param room_position Center position of the assumed axis-aligned room.
125 // @param room_dimensions Dimensions of the assumed axis-aligned room.
126 // @return An array of six elements, each being a vector of hit points
127 // on one of the six walls.
128 std::array<std::vector<HitPointData>, kNumRoomSurfaces> GroupHitPointsByWalls(
129 const WorldPosition& room_position, const WorldPosition& room_dimensions);
130
131 // Compute the hit point positions and distances (measured along the normal
132 // direction of the walls that they hit) from hit points on walls.
133 //
134 // @param hit_points_on_walls Hit points on walls.
135 // @return A vector of {hit point position, distance} pairs.
136 std::vector<std::pair<WorldPosition, float>>
137 ComputeDistancesAndPositionsFromHitPoints(
138 const std::array<std::vector<HitPointData>, kNumRoomSurfaces>&
139 hit_points_on_walls);
140
141 // Estimates the surface materials on the six walls of the proxy room.
142 //
143 // @param room_position Center position of the estimated proxy room.
144 // @param room_dimensions Dimensions of the estimated proxy room.
145 // @param material_names Names of the estimated surface materials.
146 void EstimateSurfaceMaterials(const WorldPosition& room_position,
147 const WorldPosition& room_dimensions,
148 MaterialName* material_names);
149
150 // Collected hit points.
151 std::vector<HitPointData> hit_points_;
152};
153
154} // namespace vraudio
155
156#endif // RESONANCE_AUDIO_GEOMETRICAL_ACOUSTICS_PROXY_ROOM_ESTIMATOR_H_
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:180
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Matrix()
Default constructor.
Definition Matrix.h:259
EIGEN_DEVICE_FUNC Derived & setZero(Index size)
Definition CwiseNullaryOp.h:562
Definition proxy_room_estimator.h:43
Definition misc_math.h:38
Definition path.h:30
Definition room_properties.h:70