gb.hpp - Angle
This commit is contained in:
parent
915845b0dc
commit
9be05386ac
|
@ -6,7 +6,7 @@ library | latest version | category | languages | description
|
||||||
----------------|----------------|----------|-----------|-------------
|
----------------|----------------|----------|-----------|-------------
|
||||||
**gb_string.h** | 0.93 | strings | C, C++ | A better string library for C & C++
|
**gb_string.h** | 0.93 | strings | C, C++ | A better string library for C & C++
|
||||||
**gb_ini.h** | 0.91 | misc | C, C++ | A simple ini file loader library for C & C++
|
**gb_ini.h** | 0.91 | misc | C, C++ | A simple ini file loader library for C & C++
|
||||||
**gb.hpp** | 0.19 | misc | C++11 | (Experimental) A C++11 helper library without STL geared towards game development
|
**gb.hpp** | 0.20 | misc | C++11 | (Experimental) A C++11 helper library without STL geared towards game development
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
|
|
228
gb.hpp
228
gb.hpp
|
@ -1,8 +1,9 @@
|
||||||
// gb.hpp - v0.19 - public domain C++11 helper library - no warranty implied; use at your own risk
|
// gb.hpp - v0.20 - public domain C++11 helper library - no warranty implied; use at your own risk
|
||||||
// (Experimental) A C++11 helper library without STL geared towards game development
|
// (Experimental) A C++11 helper library without STL geared towards game development
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Version History:
|
Version History:
|
||||||
|
0.20 - Angle
|
||||||
0.19 - Cache friendly Transform and String fixes
|
0.19 - Cache friendly Transform and String fixes
|
||||||
0.18 - Hash_Table bug fixes
|
0.18 - Hash_Table bug fixes
|
||||||
0.17 - Death to OOP
|
0.17 - Death to OOP
|
||||||
|
@ -2063,10 +2064,14 @@ struct Matrix4
|
||||||
inline Vector4& operator[](usize index) { return columns[index]; }
|
inline Vector4& operator[](usize index) { return columns[index]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Angle
|
||||||
|
{
|
||||||
|
f32 radians;
|
||||||
|
};
|
||||||
|
|
||||||
struct Euler_Angles
|
struct Euler_Angles
|
||||||
{
|
{
|
||||||
// NOTE(bill): All angles in radians
|
Angle pitch, yaw, roll;
|
||||||
f32 pitch, yaw, roll;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Transform
|
struct Transform
|
||||||
|
@ -2101,6 +2106,16 @@ struct Plane
|
||||||
f32 distance; // negative distance to origin
|
f32 distance; // negative distance to origin
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace angle
|
||||||
|
{
|
||||||
|
Angle radians(f32 radians);
|
||||||
|
Angle degrees(f32 degrees);
|
||||||
|
|
||||||
|
f32 as_radians(Angle angle);
|
||||||
|
f32 as_degrees(Angle angle);
|
||||||
|
} // namespace angle
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
/// ///
|
/// ///
|
||||||
/// Math Type Op Overloads ///
|
/// Math Type Op Overloads ///
|
||||||
|
@ -2259,6 +2274,27 @@ Matrix4& operator+=(Matrix4& a, const Matrix4& b);
|
||||||
Matrix4& operator-=(Matrix4& a, const Matrix4& b);
|
Matrix4& operator-=(Matrix4& a, const Matrix4& b);
|
||||||
Matrix4& operator*=(Matrix4& a, const Matrix4& b);
|
Matrix4& operator*=(Matrix4& a, const Matrix4& b);
|
||||||
|
|
||||||
|
// Angle Operators
|
||||||
|
bool operator==(Angle a, Angle b);
|
||||||
|
bool operator!=(Angle a, Angle b);
|
||||||
|
|
||||||
|
Angle operator-(Angle a);
|
||||||
|
|
||||||
|
Angle operator+(Angle a, Angle b);
|
||||||
|
Angle operator-(Angle a, Angle b);
|
||||||
|
|
||||||
|
Angle operator*(Angle a, f32 scalar);
|
||||||
|
Angle operator*(f32 scalar, Angle a);
|
||||||
|
|
||||||
|
Angle operator/(Angle a, f32 scalar);
|
||||||
|
|
||||||
|
f32 operator/(Angle a, Angle b);
|
||||||
|
|
||||||
|
Angle& operator+=(Angle& a, Angle b);
|
||||||
|
Angle& operator-=(Angle& a, Angle b);
|
||||||
|
Angle& operator*=(Angle& a, f32 scalar);
|
||||||
|
Angle& operator/=(Angle& a, f32 scalar);
|
||||||
|
|
||||||
// Transform Operators
|
// Transform Operators
|
||||||
// World = Parent * Local
|
// World = Parent * Local
|
||||||
Transform operator*(const Transform& ps, const Transform& ls);
|
Transform operator*(const Transform& ps, const Transform& ls);
|
||||||
|
@ -2305,17 +2341,14 @@ f32 cbrt(f32 x);
|
||||||
f32 fast_inv_sqrt(f32 x);
|
f32 fast_inv_sqrt(f32 x);
|
||||||
|
|
||||||
// Trigonometric
|
// Trigonometric
|
||||||
f32 sin(f32 radians);
|
f32 sin(Angle a);
|
||||||
f32 cos(f32 radians);
|
f32 cos(Angle a);
|
||||||
f32 tan(f32 radians);
|
f32 tan(Angle a);
|
||||||
|
|
||||||
f32 arcsin(f32 x);
|
Angle arcsin(f32 x);
|
||||||
f32 arccos(f32 x);
|
Angle arccos(f32 x);
|
||||||
f32 arctan(f32 x);
|
Angle arctan(f32 x);
|
||||||
f32 arctan2(f32 y, f32 x);
|
Angle arctan2(f32 y, f32 x);
|
||||||
|
|
||||||
f32 radians(f32 degrees);
|
|
||||||
f32 degrees(f32 radians);
|
|
||||||
|
|
||||||
// Hyperbolic
|
// Hyperbolic
|
||||||
f32 sinh(f32 x);
|
f32 sinh(f32 x);
|
||||||
|
@ -2413,8 +2446,8 @@ Complex inverse(const Complex& a);
|
||||||
|
|
||||||
f32 complex_angle(const Complex& a);
|
f32 complex_angle(const Complex& a);
|
||||||
inline f32 complex_argument(const Complex& a) { return complex_angle(a); }
|
inline f32 complex_argument(const Complex& a) { return complex_angle(a); }
|
||||||
Complex magnitude_angle(f32 magnitude, f32 radians);
|
Complex magnitude_angle(f32 magnitude, Angle a);
|
||||||
inline Complex complex_polar(f32 magnitude, f32 radians) { return magnitude_angle(magnitude, radians); }
|
inline Complex complex_polar(f32 magnitude, Angle a) { return magnitude_angle(magnitude, a); }
|
||||||
|
|
||||||
// Quaternion functions
|
// Quaternion functions
|
||||||
f32 dot(const Quaternion& a, const Quaternion& b);
|
f32 dot(const Quaternion& a, const Quaternion& b);
|
||||||
|
@ -2427,13 +2460,13 @@ Quaternion normalize(const Quaternion& a);
|
||||||
Quaternion conjugate(const Quaternion& a);
|
Quaternion conjugate(const Quaternion& a);
|
||||||
Quaternion inverse(const Quaternion& a);
|
Quaternion inverse(const Quaternion& a);
|
||||||
|
|
||||||
f32 quaternion_angle(const Quaternion& a);
|
Angle quaternion_angle(const Quaternion& a);
|
||||||
Vector3 quaternion_axis(const Quaternion& a);
|
Vector3 quaternion_axis(const Quaternion& a);
|
||||||
Quaternion axis_angle(const Vector3& axis, f32 radians);
|
Quaternion axis_angle(const Vector3& axis, Angle a);
|
||||||
|
|
||||||
f32 quaternion_roll(const Quaternion& a);
|
Angle quaternion_roll(const Quaternion& a);
|
||||||
f32 quaternion_pitch(const Quaternion& a);
|
Angle quaternion_pitch(const Quaternion& a);
|
||||||
f32 quaternion_yaw(const Quaternion& a);
|
Angle quaternion_yaw(const Quaternion& a);
|
||||||
|
|
||||||
Euler_Angles quaternion_to_euler_angles(const Quaternion& a);
|
Euler_Angles quaternion_to_euler_angles(const Quaternion& a);
|
||||||
Quaternion euler_angles_to_quaternion(const Euler_Angles& e,
|
Quaternion euler_angles_to_quaternion(const Euler_Angles& e,
|
||||||
|
@ -2476,12 +2509,12 @@ Matrix4 quaternion_to_matrix4(const Quaternion& a);
|
||||||
Quaternion matrix4_to_quaternion(const Matrix4& m);
|
Quaternion matrix4_to_quaternion(const Matrix4& m);
|
||||||
|
|
||||||
Matrix4 translate(const Vector3& v);
|
Matrix4 translate(const Vector3& v);
|
||||||
Matrix4 rotate(const Vector3& v, f32 radians);
|
Matrix4 rotate(const Vector3& v, Angle angle);
|
||||||
Matrix4 scale(const Vector3& v);
|
Matrix4 scale(const Vector3& v);
|
||||||
Matrix4 ortho(f32 left, f32 right, f32 bottom, f32 top);
|
Matrix4 ortho(f32 left, f32 right, f32 bottom, f32 top);
|
||||||
Matrix4 ortho(f32 left, f32 right, f32 bottom, f32 top, f32 z_near, f32 z_far);
|
Matrix4 ortho(f32 left, f32 right, f32 bottom, f32 top, f32 z_near, f32 z_far);
|
||||||
Matrix4 perspective(f32 fovy_radians, f32 aspect, f32 z_near, f32 z_far);
|
Matrix4 perspective(Angle fovy, f32 aspect, f32 z_near, f32 z_far);
|
||||||
Matrix4 infinite_perspective(f32 fovy_radians, f32 aspect, f32 z_near);
|
Matrix4 infinite_perspective(Angle fovy, f32 aspect, f32 z_near);
|
||||||
|
|
||||||
Matrix4
|
Matrix4
|
||||||
look_at_matrix4(const Vector3& eye, const Vector3& center, const Vector3& up = {0, 1, 0});
|
look_at_matrix4(const Vector3& eye, const Vector3& center, const Vector3& up = {0, 1, 0});
|
||||||
|
@ -4968,6 +5001,73 @@ Matrix4& operator*=(Matrix4& a, const Matrix4& b)
|
||||||
return (a = a * b);
|
return (a = a * b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Angle Operators
|
||||||
|
bool operator==(Angle a, Angle b)
|
||||||
|
{
|
||||||
|
return a.radians == b.radians;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(Angle a, Angle b)
|
||||||
|
{
|
||||||
|
return !operator==(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle operator-(Angle a)
|
||||||
|
{
|
||||||
|
return {-a.radians};
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle operator+(Angle a, Angle b)
|
||||||
|
{
|
||||||
|
return {a.radians + b.radians};
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle operator-(Angle a, Angle b)
|
||||||
|
{
|
||||||
|
return {a.radians - b.radians};
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle operator*(Angle a, f32 scalar)
|
||||||
|
{
|
||||||
|
return {a.radians * scalar};
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle operator*(f32 scalar, Angle a)
|
||||||
|
{
|
||||||
|
return {a.radians * scalar};
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle operator/(Angle a, f32 scalar)
|
||||||
|
{
|
||||||
|
return {a.radians / scalar};
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 operator/(Angle a, Angle b)
|
||||||
|
{
|
||||||
|
return a.radians / b.radians;
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle& operator+=(Angle& a, Angle b)
|
||||||
|
{
|
||||||
|
return (a = a + b);
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle& operator-=(Angle& a, Angle b)
|
||||||
|
{
|
||||||
|
return (a = a - b);
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle& operator*=(Angle& a, f32 scalar)
|
||||||
|
{
|
||||||
|
return (a = a * scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
Angle& operator/=(Angle& a, f32 scalar)
|
||||||
|
{
|
||||||
|
return (a = a / scalar);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Transform Operators
|
// Transform Operators
|
||||||
// World = Parent * Local
|
// World = Parent * Local
|
||||||
Transform operator*(const Transform& ps, const Transform& ls)
|
Transform operator*(const Transform& ps, const Transform& ls)
|
||||||
|
@ -5008,7 +5108,32 @@ Transform& operator/=(Transform& ws, const Transform& ps)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace angle
|
||||||
|
{
|
||||||
|
inline Angle
|
||||||
|
radians(f32 r)
|
||||||
|
{
|
||||||
|
return {r};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Angle
|
||||||
|
degrees(f32 d)
|
||||||
|
{
|
||||||
|
return {d * math::TAU / 360.0f};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline f32
|
||||||
|
as_radians(Angle angle)
|
||||||
|
{
|
||||||
|
return angle.radians;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline f32
|
||||||
|
as_degrees(Angle angle)
|
||||||
|
{
|
||||||
|
return angle.radians * 360.0f / math::TAU;
|
||||||
|
}
|
||||||
|
} // namespace angle
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
/// ///
|
/// ///
|
||||||
|
@ -5055,17 +5180,14 @@ fast_inv_sqrt(f32 x)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigonometric
|
// Trigonometric
|
||||||
inline f32 sin(f32 radians) { return ::sinf(radians); }
|
inline f32 sin(Angle a) { return ::sinf(angle::as_radians(a)); }
|
||||||
inline f32 cos(f32 radians) { return ::cosf(radians); }
|
inline f32 cos(Angle a) { return ::cosf(angle::as_radians(a)); }
|
||||||
inline f32 tan(f32 radians) { return ::tanf(radians); }
|
inline f32 tan(Angle a) { return ::tanf(angle::as_radians(a)); }
|
||||||
|
|
||||||
inline f32 arcsin(f32 x) { return ::asinf(x); }
|
inline Angle arcsin(f32 x) { return angle::radians(::asinf(x)); }
|
||||||
inline f32 arccos(f32 x) { return ::acosf(x); }
|
inline Angle arccos(f32 x) { return angle::radians(::acosf(x)); }
|
||||||
inline f32 arctan(f32 x) { return ::atanf(x); }
|
inline Angle arctan(f32 x) { return angle::radians(::atanf(x)); }
|
||||||
inline f32 arctan2(f32 y, f32 x) { return ::atan2f(y, x); }
|
inline Angle arctan2(f32 y, f32 x) { return angle::radians(::atan2f(y, x)); }
|
||||||
|
|
||||||
inline f32 radians(f32 degrees) { return TAU * degrees / 360.0f; }
|
|
||||||
inline f32 degrees(f32 radians) { return 360.0f * radians / TAU; }
|
|
||||||
|
|
||||||
// Hyperbolic
|
// Hyperbolic
|
||||||
inline f32 sinh(f32 x) { return ::sinhf(x); }
|
inline f32 sinh(f32 x) { return ::sinhf(x); }
|
||||||
|
@ -5392,10 +5514,10 @@ complex_angle(const Complex& a)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Complex
|
inline Complex
|
||||||
magnitude_angle(f32 magnitude, f32 radians)
|
magnitude_angle(f32 magnitude, Angle a)
|
||||||
{
|
{
|
||||||
f32 real = magnitude * cos(radians);
|
f32 real = magnitude * math::cos(a);
|
||||||
f32 imag = magnitude * sin(radians);
|
f32 imag = magnitude * math::sin(a);
|
||||||
return {real, imag};
|
return {real, imag};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5449,7 +5571,7 @@ inverse(const Quaternion& a)
|
||||||
return math::conjugate(a) * m;
|
return math::conjugate(a) * m;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline f32
|
inline Angle
|
||||||
quaternion_angle(const Quaternion& a)
|
quaternion_angle(const Quaternion& a)
|
||||||
{
|
{
|
||||||
return 2.0f * math::arccos(a.w);
|
return 2.0f * math::arccos(a.w);
|
||||||
|
@ -5469,33 +5591,33 @@ quaternion_axis(const Quaternion& a)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Quaternion
|
inline Quaternion
|
||||||
axis_angle(const Vector3& axis, f32 radians)
|
axis_angle(const Vector3& axis, Angle angle)
|
||||||
{
|
{
|
||||||
Vector3 a = math::normalize(axis);
|
Vector3 a = math::normalize(axis);
|
||||||
f32 s = math::sin(0.5f * radians);
|
f32 s = math::sin(0.5f * angle);
|
||||||
|
|
||||||
Quaternion q;
|
Quaternion q;
|
||||||
q.xyz = a * s;
|
q.xyz = a * s;
|
||||||
q.w = math::cos(0.5f * radians);
|
q.w = math::cos(0.5f * angle);
|
||||||
|
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline f32
|
inline Angle
|
||||||
quaternion_roll(const Quaternion& a)
|
quaternion_roll(const Quaternion& a)
|
||||||
{
|
{
|
||||||
return math::arctan2(2.0f * a.x * a.y + a.z * a.w,
|
return math::arctan2(2.0f * a.x * a.y + a.z * a.w,
|
||||||
a.x * a.x + a.w * a.w - a.y * a.y - a.z * a.z);
|
a.x * a.x + a.w * a.w - a.y * a.y - a.z * a.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline f32
|
inline Angle
|
||||||
quaternion_pitch(const Quaternion& a)
|
quaternion_pitch(const Quaternion& a)
|
||||||
{
|
{
|
||||||
return math::arctan2(2.0f * a.y * a.z + a.w * a.x,
|
return math::arctan2(2.0f * a.y * a.z + a.w * a.x,
|
||||||
a.w * a.w - a.x * a.x - a.y * a.y + a.z * a.z);
|
a.w * a.w - a.x * a.x - a.y * a.y + a.z * a.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline f32
|
inline Angle
|
||||||
quaternion_yaw(const Quaternion& a)
|
quaternion_yaw(const Quaternion& a)
|
||||||
{
|
{
|
||||||
return math::arcsin(-2.0f * (a.x * a.z - a.w * a.y));
|
return math::arcsin(-2.0f * (a.x * a.z - a.w * a.y));
|
||||||
|
@ -5544,9 +5666,9 @@ slerp(const Quaternion& x, const Quaternion& y, f32 t)
|
||||||
lerp(x.w, y.w, t)};
|
lerp(x.w, y.w, t)};
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 angle = math::arccos(cos_theta);
|
Angle angle = math::arccos(cos_theta);
|
||||||
|
|
||||||
Quaternion result = math::sin(1.0f - (t * angle)) * x + math::sin(t * angle) * z;
|
Quaternion result = math::sin(angle::radians(1.0f) - (t * angle)) * x + math::sin(t * angle) * z;
|
||||||
return result * (1.0f / math::sin(angle));
|
return result * (1.0f / math::sin(angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5921,10 +6043,10 @@ translate(const Vector3& v)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Matrix4
|
inline Matrix4
|
||||||
rotate(const Vector3& v, f32 radians)
|
rotate(const Vector3& v, Angle angle)
|
||||||
{
|
{
|
||||||
const f32 c = math::cos(radians);
|
const f32 c = math::cos(angle);
|
||||||
const f32 s = math::sin(radians);
|
const f32 s = math::sin(angle);
|
||||||
|
|
||||||
const Vector3 axis = math::normalize(v);
|
const Vector3 axis = math::normalize(v);
|
||||||
const Vector3 t = (1.0f - c) * axis;
|
const Vector3 t = (1.0f - c) * axis;
|
||||||
|
@ -5980,12 +6102,12 @@ ortho(f32 left, f32 right, f32 bottom, f32 top, f32 z_near, f32 z_far)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Matrix4
|
inline Matrix4
|
||||||
perspective(f32 fovy_radians, f32 aspect, f32 z_near, f32 z_far)
|
perspective(Angle fovy, f32 aspect, f32 z_near, f32 z_far)
|
||||||
{
|
{
|
||||||
GB_ASSERT(math::abs(aspect) > 0.0f,
|
GB_ASSERT(math::abs(aspect) > 0.0f,
|
||||||
"math::perspective `fovy_radians` is %f", fovy_radians);
|
"math::perspective `fovy` is %f rad", angle::as_radians(fovy));
|
||||||
|
|
||||||
f32 tan_half_fovy = math::tan(0.5f * fovy_radians);
|
f32 tan_half_fovy = math::tan(0.5f * fovy);
|
||||||
|
|
||||||
Matrix4 result = {};
|
Matrix4 result = {};
|
||||||
result[0][0] = 1.0f / (aspect * tan_half_fovy);
|
result[0][0] = 1.0f / (aspect * tan_half_fovy);
|
||||||
|
@ -5998,9 +6120,9 @@ perspective(f32 fovy_radians, f32 aspect, f32 z_near, f32 z_far)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Matrix4
|
inline Matrix4
|
||||||
infinite_perspective(f32 fovy_radians, f32 aspect, f32 z_near)
|
infinite_perspective(Angle fovy, f32 aspect, f32 z_near)
|
||||||
{
|
{
|
||||||
f32 range = math::tan(0.5f * fovy_radians) * z_near;
|
f32 range = math::tan(0.5f * fovy) * z_near;
|
||||||
f32 left = -range * aspect;
|
f32 left = -range * aspect;
|
||||||
f32 right = range * aspect;
|
f32 right = range * aspect;
|
||||||
f32 bottom = -range;
|
f32 bottom = -range;
|
||||||
|
|
Loading…
Reference in New Issue