1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#ifndef CORE_MATH_ANGLES_HH
#define CORE_MATH_ANGLES_HH 1
#pragma once
#include "core/math/constexpr.hh"
constexpr float A180 = math::radians(180.0f);
constexpr float A360 = math::radians(360.0f);
namespace math
{
float wrap_180(float angle);
float wrap_360(float angle);
} // namespace math
namespace math
{
glm::fvec3 wrap_180(const glm::fvec3& angles);
glm::fvec3 wrap_360(const glm::fvec3& angles);
} // namespace math
namespace math
{
void vectors(const glm::fvec3& angles, glm::fvec3& forward);
void vectors(const glm::fvec3& angles, glm::fvec3* forward, glm::fvec3* right, glm::fvec3* up);
} // namespace math
inline float math::wrap_180(float angle)
{
const auto result = std::fmod(angle + A180, A360);
if(result < 0.0f) {
return result + A180;
}
return result - A180;
}
inline float math::wrap_360(float angle)
{
return std::fmod(std::fmod(angle, A360) + A360, A360);
}
inline glm::fvec3 math::wrap_180(const glm::fvec3& angles)
{
return glm::fvec3 {
math::wrap_180(angles.x),
math::wrap_180(angles.y),
math::wrap_180(angles.z),
};
}
inline glm::fvec3 math::wrap_360(const glm::fvec3& angles)
{
return glm::fvec3 {
math::wrap_360(angles.x),
math::wrap_360(angles.y),
math::wrap_360(angles.z),
};
}
inline void math::vectors(const glm::fvec3& angles, glm::fvec3& forward)
{
const float cosp = std::cos(angles.x);
const float cosy = std::cos(angles.y);
const float sinp = std::sin(angles.x);
const float siny = std::sin(angles.y);
forward.x = cosp * siny * (-1.0f);
forward.y = sinp;
forward.z = cosp * cosy * (-1.0f);
}
inline void math::vectors(const glm::fvec3& angles, glm::fvec3* forward, glm::fvec3* right, glm::fvec3* up)
{
if(!forward && !right && !up) {
// There's no point in figuring out
// direction vectors if nothing is passed
// in the function to store that stuff in
return;
}
const auto pcv = glm::cos(angles);
const auto psv = glm::sin(angles);
const auto ncv = pcv * (-1.0f);
const auto nsv = psv * (-1.0f);
if(forward) {
forward->x = pcv.x * nsv.y;
forward->y = psv.x;
forward->z = pcv.x * ncv.y;
}
if(right) {
right->x = pcv.z * pcv.y;
right->y = psv.z * pcv.y;
right->z = nsv.y;
}
if(up) {
up->x = psv.x * psv.y * pcv.z + ncv.y * psv.z;
up->y = pcv.x * pcv.z;
up->z = nsv.x * ncv.y * pcv.z + psv.y * psv.z;
}
}
#endif // CORE_MATH_ANGLES_HH
|