17#ifndef RESONANCE_AUDIO_BASE_MISC_MATH_H_
18#define RESONANCE_AUDIO_BASE_MISC_MATH_H_
20#ifndef _USE_MATH_DEFINES
21#define _USE_MATH_DEFINES
31#include "base/integral_types.h"
33#include "base/constants_and_types.h"
34#include "base/logging.h"
42 template <
typename Arg1,
typename... Args>
44 :
Matrix(arg1, std::forward<Args>(args)...) {}
51 return std::abs(this->x() - other.x()) > kEpsilonFloat ||
52 std::abs(this->y() - other.y()) > kEpsilonFloat ||
53 std::abs(this->z() - other.z()) > kEpsilonFloat;
61 template <
typename Arg1,
typename... Args>
63 :
Quaternion(arg1, std::forward<Args>(args)...) {}
69 float AngularDifferenceRad(
const WorldRotation& other)
const {
91inline void ConvertAudioFromWorldPosition(
const WorldPosition& world_position,
93 DCHECK(audio_position);
94 (*audio_position)(0) = -world_position[2];
95 (*audio_position)(1) = -world_position[0];
96 (*audio_position)(2) = world_position[1];
109inline void ConvertWorldFromAudioPosition(
const AudioPosition& audio_position,
110 AudioPosition* world_position) {
111 DCHECK(world_position);
112 (*world_position)(0) = -audio_position[1];
113 (*world_position)(1) = audio_position[2];
114 (*world_position)(2) = -audio_position[0];
127inline void ConvertAudioFromWorldRotation(
const WorldRotation& world_rotation,
128 AudioRotation* audio_rotation) {
129 DCHECK(audio_rotation);
130 audio_rotation->w() = world_rotation.w();
131 audio_rotation->x() = -world_rotation.x();
132 audio_rotation->y() = world_rotation.y();
133 audio_rotation->z() = -world_rotation.z();
143inline void GetRelativeDirection(
const WorldPosition& from_position,
144 const WorldRotation& from_rotation,
145 const WorldPosition& to_position,
146 WorldPosition* relative_direction) {
147 DCHECK(relative_direction);
148 *relative_direction =
149 from_rotation.conjugate() * (to_position - from_position);
158inline void GetClosestPositionInAabb(
const WorldPosition& relative_position,
159 const WorldPosition& aabb_dimensions,
160 WorldPosition* closest_position) {
161 DCHECK(closest_position);
162 const WorldPosition aabb_offset = 0.5f * aabb_dimensions;
163 (*closest_position)[0] =
164 std::min(std::max(relative_position[0], -aabb_offset[0]), aabb_offset[0]);
165 (*closest_position)[1] =
166 std::min(std::max(relative_position[1], -aabb_offset[1]), aabb_offset[1]);
167 (*closest_position)[2] =
168 std::min(std::max(relative_position[2], -aabb_offset[2]), aabb_offset[2]);
177inline bool IsPositionInAabb(
const WorldPosition& position,
178 const WorldPosition& aabb_center,
179 const WorldPosition& aabb_dimensions) {
180 return std::abs(position[0] - aabb_center[0]) <= 0.5f * aabb_dimensions[0] &&
181 std::abs(position[1] - aabb_center[1]) <= 0.5f * aabb_dimensions[1] &&
182 std::abs(position[2] - aabb_center[2]) <= 0.5f * aabb_dimensions[2];
193inline bool DoesIntegerMultiplicationOverflow(T a, T b, T x) {
196 return a == 0 ? false : (x / a != b);
206inline bool DoesIntegerAdditionOverflow(T a, T b) {
216inline bool DoesIntSafelyConvertToSizeT(
int i,
size_t* x) {
220 *x =
static_cast<size_t>(i);
229inline bool DoesSizeTSafelyConvertToInt(
size_t i,
int* x) {
230 if (i >
static_cast<size_t>(std::numeric_limits<int>::max())) {
233 *x =
static_cast<int>(i);
243inline int FindGcd(
int a,
int b) {
260inline size_t NextPowTwo(
size_t input) {
262 DCHECK_LT(
static_cast<uint64_t>(input),
263 static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()));
265 number |= number >> 1;
266 number |= number >> 2;
267 number |= number >> 4;
268 number |= number >> 8;
269 number |= number >> 16;
271 return static_cast<size_t>(number);
275inline float Factorial(
int x) {
276 if (x < 0)
return 0.0f;
278 for (; x > 0; --x) result *=
static_cast<float>(x);
286inline float DoubleFactorial(
int x) {
287 if (x < 0)
return 0.0f;
289 for (; x > 0; x -= 2) result *=
static_cast<float>(x);
299template <
typename Iterator>
300inline bool EqualSafe(
const Iterator& lhs_begin,
const Iterator& lhs_end,
301 const Iterator& rhs_begin,
const Iterator& rhs_end) {
302 auto lhs_itr = lhs_begin;
303 auto rhs_itr = rhs_begin;
304 while (lhs_itr != lhs_end && rhs_itr != rhs_end) {
305 if (*lhs_itr != *rhs_itr) {
311 return lhs_itr == lhs_end && rhs_itr == rhs_end;
318inline float FastReciprocalSqrt(
float input) {
319 const float kThreeHalfs = 1.5f;
320 const uint32_t kMagicNumber = 0x5f3759df;
324 integer = kMagicNumber - (integer >> 1);
325 float approximation = *
reinterpret_cast<float*
>(&integer);
326 const float half_input = input * 0.5f;
328 return approximation *
329 (kThreeHalfs - (half_input * approximation * approximation));
345bool LinearLeastSquareFitting(
const std::vector<float>& x_array,
346 const std::vector<float>& y_array,
float* slope,
347 float* intercept,
float* r_squared);
367static inline T IntegerPow(T base,
int exp) {
369 T result =
static_cast<T
>(1);
Represents a 3D rotation as a rotation angle around an arbitrary 3D axis.
Definition AngleAxis.h:50
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 Quaternion< Scalar > inverse() const
Definition Quaternion.h:720
The quaternion class used to represent 3D orientations and rotations.
Definition Quaternion.h:274
EIGEN_DEVICE_FUNC Quaternion()
Definition Quaternion.h:288
Definition misc_math.h:38
Definition misc_math.h:57
AngleAxis< float > AngleAxisf
Definition AngleAxis.h:157
GLM_FUNC_QUALIFIER vec< L, T, Q > exp(vec< L, T, Q > const &x)
Definition func_exponential.inl:80
uint64 uint64_t
Definition fwd.hpp:145
uint32 uint32_t
Definition fwd.hpp:131