Skip to content

Commit dbfa09f

Browse files
committed
impl: Added math files from SAR to handle Valve Vectors and Matrices
1 parent 1d82e41 commit dbfa09f

File tree

2 files changed

+715
-0
lines changed

2 files changed

+715
-0
lines changed

src/utils/math.cpp

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
/*******************************************************************
2+
* @file math.cpp
3+
* @brief Vector, Matrix, and other math related functions.
4+
* @author SAR Team
5+
*********************************************************************/
6+
7+
#include "math.hpp"
8+
9+
#include <cmath>
10+
#include <cfloat>
11+
#include <random>
12+
13+
#include "loggingsystem.hpp"
14+
15+
float Math::AngleNormalize(float angle)
16+
{
17+
angle = fmodf(angle, 360.0f);
18+
if (angle > 180)
19+
angle -= 360;
20+
21+
if (angle < -180)
22+
angle += 360;
23+
24+
return angle;
25+
}
26+
27+
float Math::VectorNormalize(Vector& vec)
28+
{
29+
const auto radius = sqrtf(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
30+
const auto iRadius = 1.f / (radius + FLT_EPSILON);
31+
32+
vec.x *= iRadius;
33+
vec.y *= iRadius;
34+
vec.z *= iRadius;
35+
36+
return radius;
37+
}
38+
39+
void Math::AngleVectors(const QAngle& angles, Vector* forward)
40+
{
41+
float sp, sy, cp, cy;
42+
43+
Math::SinCos(DEG_2RAD(angles.y), &sy, &cy);
44+
Math::SinCos(DEG_2RAD(angles.x), &sp, &cp);
45+
46+
forward->x = cp * cy;
47+
forward->y = cp * sy;
48+
forward->z = -sp;
49+
}
50+
51+
void Math::AngleVectors(const QAngle& angles, Vector* forward, Vector* right, Vector* up)
52+
{
53+
float sr, sp, sy, cr, cp, cy;
54+
55+
Math::SinCos(DEG_2RAD(angles.y), &sy, &cy);
56+
Math::SinCos(DEG_2RAD(angles.x), &sp, &cp);
57+
Math::SinCos(DEG_2RAD(angles.z), &sr, &cr);
58+
59+
if (forward)
60+
{
61+
forward->x = cp * cy;
62+
forward->y = cp * sy;
63+
forward->z = -sp;
64+
}
65+
66+
if (right)
67+
{
68+
right->x = -1 * sr * sp * cy + -1 * cr * -sy;
69+
right->y = -1 * sr * sp * sy + -1 * cr * cy;
70+
right->z = -1 * sr * cp;
71+
}
72+
73+
if (up)
74+
{
75+
up->x = cr * sp * cy + -sr * -sy;
76+
up->y = cr * sp * sy + -sr * cy;
77+
up->z = cr * cp;
78+
}
79+
}
80+
81+
Matrix Math::AngleMatrix(const QAngle& angles)
82+
{
83+
float fsPitch, fcPitch;
84+
float fsYaw, fcYaw;
85+
float fsRoll, fcRoll;
86+
87+
Math::SinCos(DEG_2RAD(angles.x), &fsPitch, &fcPitch);
88+
Math::SinCos(DEG_2RAD(angles.y), &fsYaw, &fcYaw);
89+
Math::SinCos(DEG_2RAD(angles.z), &fsRoll, &fcRoll);
90+
91+
const double sPitch = fsPitch;
92+
const double cPitch = fcPitch;
93+
const double sYaw = fsYaw;
94+
const double cYaw = fcYaw;
95+
const double sRoll = fsRoll;
96+
const double cRoll = fcRoll;
97+
98+
Matrix rot{3, 3, 0};
99+
rot(0, 0) = cYaw * cPitch;
100+
rot(0, 1) = cYaw * sPitch * sRoll - sYaw * cRoll;
101+
rot(0, 2) = cYaw * sPitch * cRoll + sYaw * sRoll;
102+
rot(1, 0) = sYaw * cPitch;
103+
rot(1, 1) = sYaw * sPitch * sRoll + cYaw * cRoll;
104+
rot(1, 2) = sYaw * sPitch * cRoll - cYaw * sRoll;
105+
rot(2, 0) = -sPitch;
106+
rot(2, 1) = cPitch * sRoll;
107+
rot(2, 2) = cPitch * cRoll;
108+
109+
return rot;
110+
}
111+
112+
void Math::VectorAngles(const Vector& forward, Vector& pseudoup, QAngle* angles)
113+
{
114+
if (!angles)
115+
return;
116+
117+
const Vector left = pseudoup.Cross(forward).Normalize();
118+
119+
if (float xyDist = forward.Length2D(); xyDist > 0.001f)
120+
{
121+
angles->y = RAD_2DEG(atan2f(forward.y, forward.x));
122+
angles->x = RAD_2DEG(atan2f(-forward.z, xyDist));
123+
const float upZ = (left.y * forward.x) - (left.x * forward.y);
124+
angles->z = RAD_2DEG(atan2f(left.z, upZ));
125+
}
126+
else
127+
{
128+
angles->y = RAD_2DEG(atan2f(-left.x, left.y));
129+
angles->x = RAD_2DEG(atan2f(-forward.z, xyDist));
130+
angles->z = 0;
131+
}
132+
}
133+
134+
float Math::RandomNumber(const float& min, const float& max)
135+
{
136+
std::random_device rd;
137+
std::mt19937 mt(rd());
138+
std::uniform_real_distribution<float> dist_pitch(min, std::nextafter(max, FLT_MAX));
139+
140+
return dist_pitch(mt);
141+
}
142+
143+
int Math::RandomNumber(const int& min, const int& max)
144+
{
145+
std::random_device rd;
146+
std::mt19937 mt(rd());
147+
std::uniform_int_distribution<int> dist_pitch(min, max);
148+
149+
return dist_pitch(mt);
150+
}
151+
152+
153+
Matrix::Matrix(const int rows, const int cols, const double init)
154+
: rows(rows)
155+
, cols(cols)
156+
{
157+
this->mat.resize(rows);
158+
for (auto& it : this->mat)
159+
it.resize(cols, init);
160+
}
161+
162+
Matrix& Matrix::operator=(const Matrix& rhs)
163+
{
164+
if (&rhs == this)
165+
return *this;
166+
167+
const auto newRows = rhs.rows;
168+
auto newCols = rhs.cols;
169+
170+
this->mat.resize(newRows);
171+
for (auto& it : this->mat)
172+
it.resize(newCols);
173+
174+
for (int i = 0; i < newRows; i++)
175+
for (int j = 0; j < newCols; j++)
176+
mat[i][j] = rhs(i, j);
177+
178+
this->rows = newRows;
179+
this->cols = newCols;
180+
181+
return *this;
182+
}
183+
184+
Matrix Matrix::operator+(const Matrix& rhs) const
185+
{
186+
Matrix result(this->rows, this->cols, 0);
187+
188+
for (int i = 0; i < this->rows; i++)
189+
for (int j = 0; j < this->cols; j++)
190+
result(i, j) = this->mat[i][j] + rhs(i, j);
191+
192+
return result;
193+
}
194+
195+
Matrix& Matrix::operator+=(const Matrix& rhs)
196+
{
197+
const auto newRows = rhs.rows;
198+
const auto newCols = rhs.cols;
199+
200+
for (int i = 0; i < newRows; i++)
201+
for (int j = 0; j < newCols; j++)
202+
this->mat[i][j] += rhs(i, j);
203+
204+
return *this;
205+
}
206+
207+
Matrix Matrix::operator*(const Matrix& rhs) const
208+
{
209+
if (this->cols != rhs.rows)
210+
{
211+
Log(INFO, true, "Matrix Error: rows != cols");
212+
return {1, 1, 0};
213+
}
214+
215+
Matrix result(this->rows, rhs.cols, 0);
216+
217+
for (int i = 0; i < this->rows; i++)
218+
{
219+
for (int j = 0; j < rhs.cols; j++)
220+
{
221+
int sum = 0;
222+
for (int k = 0; k < this->rows; k++)
223+
{
224+
sum += this->mat[i][k] * rhs(k, j);
225+
}
226+
result(i, j) += sum;
227+
}
228+
}
229+
230+
return result;
231+
}
232+
233+
Matrix& Matrix::operator*=(const Matrix& rhs)
234+
{
235+
const Matrix result = (*this) * rhs;
236+
(*this) = result;
237+
return *this;
238+
}
239+
240+
Vector Matrix::operator*(const Vector& rhs) const
241+
{
242+
if (this->cols != 3)
243+
{
244+
Log(INFO, true, "Matrix Error: rows != cols");
245+
return {0, 0, 0};
246+
}
247+
248+
Vector result(0, 0, 0);
249+
250+
for (int i = 0; i < this->rows; i++)
251+
{
252+
for (int j = 0; j < 3; j++)
253+
{
254+
result[i] += this->mat[i][j] * rhs[j];
255+
}
256+
}
257+
258+
return result;
259+
}
260+
261+
inline Vector Matrix::operator*=(const Vector& rhs) const
262+
{
263+
return (*this) * rhs;
264+
}
265+
266+
void Matrix::Transpose()
267+
{
268+
Matrix result(this->rows, this->cols, 0);
269+
270+
for (int i = 0; i < this->rows; i++)
271+
{
272+
for (int j = 0; j < this->cols; j++)
273+
{
274+
result(i, j) = this( j, i );
275+
}
276+
}
277+
278+
*this = result;
279+
}
280+
281+
void Matrix::Print() const
282+
{
283+
for (int i = 0; i < this->rows; i++)
284+
{
285+
for (int j = 0; j < this->cols; j++)
286+
{
287+
Log(INFO, false, "%d ", this->mat[i][j]);
288+
}
289+
Log(INFO, false, "\n");
290+
}
291+
}

0 commit comments

Comments
 (0)