diff options
| author | 2015-09-28 20:31:26 +0100 | |
|---|---|---|
| committer | 2015-09-28 20:31:26 +0100 | |
| commit | 519708db13a035c5a6e6f5ff9c0ae9db2972401e (patch) | |
| tree | 3bd34422d247c4dd3e35b12f3bc37913096af62e /gb.hpp | |
| parent | gb.hpp - Hash Table Support (diff) | |
gb.hpp - Time functions
Diffstat (limited to 'gb.hpp')
| -rw-r--r-- | gb.hpp | 1246 |
1 files changed, 765 insertions, 481 deletions
@@ -16,6 +16,31 @@ // This library is highly experimental and features may not work as expected. // This also means that many functions are not documented. // +// CONTENT +// +// - Common Macros +// - Assert +// - Types +// - C++11 Move Semantics +// - Defer +// - Memory +// - Functions +// - Allocator +// - Heap_Allocator +// - Arena_Allocator +// - Temporary_Arena_Memory +// - Array +// - Hash_Table +// - Math Types +// - Vector(2,3,4) +// - Quaternion +// - Matrix4 +// - Math Operations +// - Math Functions & Constants +// - Math Type Functions +// +// +// #ifndef GB_INCLUDE_GB_HPP #define GB_INCLUDE_GB_HPP @@ -40,11 +65,11 @@ //////////////////////////////// /// System OS /// //////////////////////////////// -#define WIN32_LEAN_AND_MEAN 1 - #if defined(_WIN32) || defined(_WIN64) #define GB_SYSTEM_WINDOWS #define NOMINMAX +#define VC_EXTRALEAN +#define WIN32_EXTRA_LEAN #elif defined(__APPLE__) && defined(__MACH__) #define GB_SYSTEM_OSX @@ -178,14 +203,14 @@ template <typename T> inline T&& forward(typename Remove_Reference<T>::Type& t) { - return static_cast<T &&>(t); + return static_cast<T&&>(t); } template <typename T> inline T&& forward(typename Remove_Reference<T>::Type&& t) { - return static_cast<T &&>(t); + return static_cast<T&&>(t); } template <typename T> @@ -215,6 +240,7 @@ defer_fn(Fn&& fn) { return Defer<Fn>(forward<Fn>(fn)); } } // namespace impl } // namespace gb +// NOTE(bill): These macros are in the global namespace thus, defer can be treated without a gb:: prefix #define GB_DEFER_1(x, y) x##y #define GB_DEFER_2(x, y) GB_DEFER_1(x, y) #define GB_DEFER_3(x) GB_DEFER_2(GB_DEFER_2(x, __COUNTER__), __LINE__) @@ -242,7 +268,9 @@ void lock_mutex(Mutex& mutex); bool try_lock_mutex(Mutex& mutex); void unlock_mutex(Mutex& mutex); +#ifndef GB_DEFAULT_ALIGNMENT #define GB_DEFAULT_ALIGNMENT 4 +#endif inline void* align_forward(void* ptr, usize align) @@ -484,450 +512,8 @@ template <typename T> void remove_entry_from_hash_table(Hash_Table<T>& h, const template <typename T> void remove_all_from_hash_table(Hash_Table<T>& h, u64 key); //////////////////////////////// -/// Math Types /// -//////////////////////////////// - -struct Vector2 -{ - union - { - struct { f32 x, y; }; - f32 data[2]; - }; - - inline const f32& operator[](usize index) const { return data[index]; } - inline f32& operator[](usize index) { return data[index]; } -}; - -struct Vector3 -{ - union - { - struct { f32 x, y, z; }; - Vector2 xy; - f32 data[3]; - }; - - inline const f32& operator[](usize index) const { return data[index]; } - inline f32& operator[](usize index) { return data[index]; } -}; - -struct Vector4 -{ - union - { - struct { f32 x, y, z, w; }; - struct { Vector2 xy, zw; }; - Vector3 xyz; - f32 data[4]; - }; - - inline const f32& operator[](usize index) const { return data[index]; } - inline f32& operator[](usize index) { return data[index]; } -}; - -struct Quaternion -{ - union - { - struct { f32 x, y, z, w; }; - Vector3 xyz; - f32 data[4]; - }; -}; - - -struct Matrix4 -{ - union - { - struct { Vector4 x, y, z, w; }; - Vector4 column[4]; - f32 data[16]; - }; - - inline const Vector4& operator[](usize index) const { return column[index]; } - inline Vector4& operator[](usize index) { return column[index]; } -}; - - -struct Euler_Angles -{ - // NOTE(bill): All angles in radians - f32 pitch; - f32 yaw; - f32 roll; -}; - -extern const Vector2 VECTOR2_ZERO; -extern const Vector3 VECTOR3_ZERO; -extern const Vector4 VECTOR4_ZERO; -extern const Quaternion QUATERNION_IDENTITY; -extern const Matrix4 MATRIX4_IDENTITY; - -//////////////////////////////// -/// Math Type Op Overloads /// -//////////////////////////////// - -// Vector2 Operators -bool operator==(const Vector2& a, const Vector2& b); -bool operator!=(const Vector2& a, const Vector2& b); - -Vector2 operator-(const Vector2& a); - -Vector2 operator+(const Vector2& a, const Vector2& b); -Vector2 operator-(const Vector2& a, const Vector2& b); - -Vector2 operator*(const Vector2& a, f32 scalar); -Vector2 operator*(f32 scalar, const Vector2& a); - -Vector2 operator/(const Vector2& a, f32 scalar); - -Vector2 operator*(const Vector2& a, const Vector2& b); // Hadamard Product -Vector2 operator/(const Vector2& a, const Vector2& b); // Hadamard Product - -Vector2& operator+=(Vector2& a, const Vector2& b); -Vector2& operator-=(Vector2& a, const Vector2& b); -Vector2& operator*=(Vector2& a, f32 scalar); -Vector2& operator/=(Vector2& a, f32 scalar); - -// Vector3 Operators -bool operator==(const Vector3& a, const Vector3& b); -bool operator!=(const Vector3& a, const Vector3& b); - -Vector3 operator-(const Vector3& a); - -Vector3 operator+(const Vector3& a, const Vector3& b); -Vector3 operator-(const Vector3& a, const Vector3& b); - -Vector3 operator*(const Vector3& a, f32 scalar); -Vector3 operator*(f32 scalar, const Vector3& a); - -Vector3 operator/(const Vector3& a, f32 scalar); - -Vector3 operator*(const Vector3& a, const Vector3& b); // Hadamard Product -Vector3 operator/(const Vector3& a, const Vector3& b); // Hadamard Product - -Vector3& operator+=(Vector3& a, const Vector3& b); -Vector3& operator-=(Vector3& a, const Vector3& b); -Vector3& operator*=(Vector3& a, f32 scalar); -Vector3& operator/=(Vector3& a, f32 scalar); - -// Vector4 Operators -bool operator==(const Vector4& a, const Vector4& b); -bool operator!=(const Vector4& a, const Vector4& b); - -Vector4 operator-(const Vector4& a); - -Vector4 operator+(const Vector4& a, const Vector4& b); -Vector4 operator-(const Vector4& a, const Vector4& b); - -Vector4 operator*(const Vector4& a, f32 scalar); -Vector4 operator*(f32 scalar, const Vector4& a); - -Vector4 operator/(const Vector4& a, f32 scalar); - -Vector4 operator*(const Vector4& a, const Vector4& b); // Hadamard Product -Vector4 operator/(const Vector4& a, const Vector4& b); // Hadamard Product - -Vector4& operator+=(Vector4& a, const Vector4& b); -Vector4& operator-=(Vector4& a, const Vector4& b); -Vector4& operator*=(Vector4& a, f32 scalar); -Vector4& operator/=(Vector4& a, f32 scalar); - -// Quaternion Operators -bool operator==(const Quaternion& a, const Quaternion& b); -bool operator!=(const Quaternion& a, const Quaternion& b); - -Quaternion operator-(const Quaternion& a); - -Quaternion operator+(const Quaternion& a, const Quaternion& b); -Quaternion operator-(const Quaternion& a, const Quaternion& b); - -Quaternion operator*(const Quaternion& a, const Quaternion& b); -Quaternion operator*(const Quaternion& a, f32 s); -Quaternion operator*(f32 s, const Quaternion& a); - -Quaternion operator/(const Quaternion& a, f32 s); - -// Matrix4 Operators -bool operator==(const Matrix4& a, const Matrix4& b); -bool operator!=(const Matrix4& a, const Matrix4& b); - -Matrix4 operator+(const Matrix4& a, const Matrix4& b); -Matrix4 operator-(const Matrix4& a, const Matrix4& b); - -Matrix4 operator*(const Matrix4& a, const Matrix4& b); -Vector4 operator*(const Matrix4& a, const Vector4& v); -Matrix4 operator*(const Matrix4& a, f32 scalar); -Matrix4 operator*(f32 scalar, const Matrix4& a); - -Matrix4 operator/(const Matrix4& a, f32 scalar); - -Matrix4& operator+=(Matrix4& a, const Matrix4& b); -Matrix4& operator-=(Matrix4& a, const Matrix4& b); -Matrix4& operator*=(Matrix4& a, const Matrix4& b); - -////////////////////////////////// -/// Math Functions & Constants /// -////////////////////////////////// - -namespace math -{ -extern const f32 EPSILON; -extern const f32 ZERO; -extern const f32 ONE; -extern const f32 THIRD; -extern const f32 TWO_THIRDS; -extern const f32 E; -extern const f32 PI; -extern const f32 TAU; -extern const f32 SQRT_2; -extern const f32 SQRT_3; - - -// Power -f32 sqrt(f32 x); -f32 pow(f32 x, f32 y); -f32 cbrt(f32 x); -f32 fast_inv_sqrt(f32 x); - -// Trigonometric -f32 sin(f32 radians); -f32 cos(f32 radians); -f32 tan(f32 radians); - -f32 asin(f32 x); -f32 acos(f32 x); -f32 atan(f32 x); -f32 atan2(f32 y, f32 x); - -f32 radians(f32 degrees); -f32 degrees(f32 radians); - -// Hyperbolic -f32 sinh(f32 x); -f32 cosh(f32 x); -f32 tanh(f32 x); - -f32 asinh(f32 x); -f32 acosh(f32 x); -f32 atanh(f32 x); - -// Rounding -f32 ceil(f32 x); -f32 floor(f32 x); -f32 mod(f32 x, f32 y); -f32 truncate(f32 x); -f32 round(f32 x); - -s32 sign(s32 x); -s64 sign(s64 x); -f32 sign(f32 x); - -// Other -f32 abs(f32 x); -s8 abs( s8 x); -s16 abs(s16 x); -s32 abs(s32 x); -s64 abs(s64 x); - -s32 min(s32 a, s32 b); -s64 min(s64 a, s64 b); -f32 min(f32 a, f32 b); - -s32 max(s32 a, s32 b); -s64 max(s64 a, s64 b); -f32 max(f32 a, f32 b); - -s32 clamp(s32 x, s32 min, s32 max); -s64 clamp(s64 x, s64 min, s64 max); -f32 clamp(f32 x, f32 min, f32 max); - -// Vector2 functions -f32 dot(const Vector2& a, const Vector2& b); -f32 cross(const Vector2& a, const Vector2& b); - -f32 magnitude(const Vector2& a); -Vector2 normalize(const Vector2& a); - -Vector2 hadamard_product(const Vector2& a, const Vector2& b); - -// Vector3 functions -f32 dot(const Vector3& a, const Vector3& b); -Vector3 cross(const Vector3& a, const Vector3& b); - -f32 magnitude(const Vector3& a); -Vector3 normalize(const Vector3& a); - -Vector3 hadamard_product(const Vector3& a, const Vector3& b); - -// Vector4 functions -f32 dot(const Vector4& a, const Vector4& b); - -f32 magnitude(const Vector4& a); -Vector4 normalize(const Vector4& a); - -Vector4 hadamard_product(const Vector4& a, const Vector4& b); - -// Quaternion functions -f32 dot(const Quaternion& a, const Quaternion& b); -Quaternion cross(const Quaternion& a, const Quaternion& b); - -f32 magnitude(const Quaternion& a); -Quaternion normalize(const Quaternion& a); - -Quaternion conjugate(const Quaternion& a); -Quaternion inverse(const Quaternion& a); - -Vector3 operator*(const Quaternion& a, const Vector3& v); // Rotate v by a - -f32 quaternion_angle(const Quaternion& a); -Vector3 quaternion_axis(const Quaternion& a); -Quaternion axis_angle(const Vector3& axis, f32 radians); - -f32 quaternion_roll(const Quaternion& a); -f32 quaternion_pitch(const Quaternion& a); -f32 quaternion_yaw(const Quaternion& a); - -Euler_Angles quaternion_to_euler_angles(const Quaternion& a); -Quaternion euler_angles_to_quaternion(const Euler_Angles& e, - const Vector3& x_axis = {1, 0, 0}, - const Vector3& y_axis = {0, 1, 0}, - const Vector3& z_axis = {0, 0, 1}); - -// Matrix4 functions -Matrix4 transpose(const Matrix4& m); -f32 determinant(const Matrix4& m); - -Matrix4 inverse(const Matrix4& m); - -Matrix4 hadamard_product(const Matrix4& a, const Matrix4&b); - -Matrix4 quaternion_to_matrix4(const Quaternion& a); -Quaternion matrix4_to_quaternion(const Matrix4& m); - -Matrix4 translate(const Vector3& v); -Matrix4 rotate(const Vector3& v, f32 radians); -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, f32 z_near, f32 z_far); -Matrix4 perspective(f32 fovy_radians, f32 aspect, f32 z_near, f32 z_far); -Matrix4 infinite_perspective(f32 fovy_radians, f32 aspect, f32 z_near); - -Matrix4 -look_at_matrix4(const Vector3& eye, const Vector3& center, const Vector3& up = {0, 1, 0}); - -Quaternion -look_at_quaternion(const Vector3& eye, const Vector3& center, const Vector3& up = {0, 1, 0}); - - -} // namespace math -} // namespace gb -#endif // GB_INCLUDE_GB_HPP - -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// It's a long way to Tipperary -/// -/// -/// -/// -/// -//////////////////////////////// -/// Implemenation /// -//////////////////////////////// -#ifdef GB_IMPLEMENTATION - -#include <float.h> -#include <math.h> -#include <stdarg.h> - -inline void -gb__assert_handler(bool condition, const char* condition_str, - const char* filename, size_t line, - const char* error_text, ...) -{ - if (condition) - return; - - fprintf(stderr, "ASSERT! %s(%d): %s", filename, line, condition_str); - if (error_text) - { - fprintf(stderr, " - "); - - va_list args; - va_start(args, error_text); - vfprintf(stderr, error_text, args); - va_end(args); - } - fprintf(stderr, "\n"); - - *(int*)0 = 0; // TODO(bill): Use a better way to assert -} - - - -namespace gb -{ -//////////////////////////////// /// Array /// //////////////////////////////// - template <typename T> inline Array<T>::Array(Allocator& a, usize count_) { @@ -1059,10 +645,6 @@ grow_array(Array<T>& a, usize min_allocation) //////////////////////////////// /// Hash Table /// //////////////////////////////// - - - - namespace impl { struct Find_Result @@ -1250,12 +832,8 @@ is_hash_table_full(Hash_Table<T>& h) const f32 maximum_load_coefficient = 0.75f; return h.data.count >= maximum_load_coefficient * h.hashes.count; } - - } // namespace impl - - template <typename T> inline bool hash_table_has(const Hash_Table<T>& h, u64 key) @@ -1413,9 +991,506 @@ remove_all_from_hash_table(Hash_Table<T>& h, u64 key) remove(h, key); } +//////////////////////////////// +/// Time /// +//////////////////////////////// + +struct Time +{ + s64 microseconds; +}; + +Time time_now(); +void time_sleep(Time time); + +Time seconds(f32 s); +Time milliseconds(s32 ms); +Time microseconds(s64 us); +f32 time_as_seconds(Time t); +s32 time_as_milliseconds(Time t); +s64 time_as_microseconds(Time t); + +bool operator==(Time left, Time right); +bool operator!=(Time left, Time right); + +bool operator<(Time left, Time right); +bool operator>(Time left, Time right); + +bool operator<=(Time left, Time right); +bool operator>=(Time left, Time right); + +Time operator-(Time right); + +Time operator+(Time left, Time right); +Time operator-(Time left, Time right); + +Time& operator+=(Time& left, Time right); +Time& operator-=(Time& left, Time right); + +Time operator*(Time left, f32 right); +Time operator*(Time left, s64 right); +Time operator*(f32 left, Time right); +Time operator*(s64 left, Time right); + +Time& operator*=(Time& left, f32 right); +Time& operator*=(Time& left, s64 right); + +Time operator/(Time left, f32 right); +Time operator/(Time left, s64 right); + +Time& operator/=(Time& left, f32 right); +Time& operator/=(Time& left, s64 right); + +f32 operator/(Time left, Time right); + +Time operator%(Time left, Time right); +Time& operator%=(Time& left, Time right); + + +//////////////////////////////// +/// Math Types /// +//////////////////////////////// + +struct Vector2 +{ + union + { + struct { f32 x, y; }; + f32 data[2]; + }; + + inline const f32& operator[](usize index) const { return data[index]; } + inline f32& operator[](usize index) { return data[index]; } +}; + +struct Vector3 +{ + union + { + struct { f32 x, y, z; }; + Vector2 xy; + f32 data[3]; + }; + + inline const f32& operator[](usize index) const { return data[index]; } + inline f32& operator[](usize index) { return data[index]; } +}; + +struct Vector4 +{ + union + { + struct { f32 x, y, z, w; }; + struct { Vector2 xy, zw; }; + Vector3 xyz; + f32 data[4]; + }; + + inline const f32& operator[](usize index) const { return data[index]; } + inline f32& operator[](usize index) { return data[index]; } +}; +struct Quaternion +{ + union + { + struct { f32 x, y, z, w; }; + Vector3 xyz; + f32 data[4]; + }; +}; +struct Matrix4 +{ + union + { + struct { Vector4 x, y, z, w; }; + Vector4 column[4]; + f32 data[16]; + }; + + inline const Vector4& operator[](usize index) const { return column[index]; } + inline Vector4& operator[](usize index) { return column[index]; } +}; + + +struct Euler_Angles +{ + // NOTE(bill): All angles in radians + f32 pitch; + f32 yaw; + f32 roll; +}; + +//////////////////////////////// +/// Math Type Op Overloads /// +//////////////////////////////// + +// Vector2 Operators +bool operator==(const Vector2& a, const Vector2& b); +bool operator!=(const Vector2& a, const Vector2& b); + +Vector2 operator-(const Vector2& a); + +Vector2 operator+(const Vector2& a, const Vector2& b); +Vector2 operator-(const Vector2& a, const Vector2& b); + +Vector2 operator*(const Vector2& a, f32 scalar); +Vector2 operator*(f32 scalar, const Vector2& a); + +Vector2 operator/(const Vector2& a, f32 scalar); + +Vector2 operator*(const Vector2& a, const Vector2& b); // Hadamard Product +Vector2 operator/(const Vector2& a, const Vector2& b); // Hadamard Product + +Vector2& operator+=(Vector2& a, const Vector2& b); +Vector2& operator-=(Vector2& a, const Vector2& b); +Vector2& operator*=(Vector2& a, f32 scalar); +Vector2& operator/=(Vector2& a, f32 scalar); + +// Vector3 Operators +bool operator==(const Vector3& a, const Vector3& b); +bool operator!=(const Vector3& a, const Vector3& b); + +Vector3 operator-(const Vector3& a); + +Vector3 operator+(const Vector3& a, const Vector3& b); +Vector3 operator-(const Vector3& a, const Vector3& b); + +Vector3 operator*(const Vector3& a, f32 scalar); +Vector3 operator*(f32 scalar, const Vector3& a); + +Vector3 operator/(const Vector3& a, f32 scalar); + +Vector3 operator*(const Vector3& a, const Vector3& b); // Hadamard Product +Vector3 operator/(const Vector3& a, const Vector3& b); // Hadamard Product + +Vector3& operator+=(Vector3& a, const Vector3& b); +Vector3& operator-=(Vector3& a, const Vector3& b); +Vector3& operator*=(Vector3& a, f32 scalar); +Vector3& operator/=(Vector3& a, f32 scalar); + +// Vector4 Operators +bool operator==(const Vector4& a, const Vector4& b); +bool operator!=(const Vector4& a, const Vector4& b); + +Vector4 operator-(const Vector4& a); + +Vector4 operator+(const Vector4& a, const Vector4& b); +Vector4 operator-(const Vector4& a, const Vector4& b); + +Vector4 operator*(const Vector4& a, f32 scalar); +Vector4 operator*(f32 scalar, const Vector4& a); + +Vector4 operator/(const Vector4& a, f32 scalar); + +Vector4 operator*(const Vector4& a, const Vector4& b); // Hadamard Product +Vector4 operator/(const Vector4& a, const Vector4& b); // Hadamard Product + +Vector4& operator+=(Vector4& a, const Vector4& b); +Vector4& operator-=(Vector4& a, const Vector4& b); +Vector4& operator*=(Vector4& a, f32 scalar); +Vector4& operator/=(Vector4& a, f32 scalar); + +// Quaternion Operators +bool operator==(const Quaternion& a, const Quaternion& b); +bool operator!=(const Quaternion& a, const Quaternion& b); + +Quaternion operator-(const Quaternion& a); + +Quaternion operator+(const Quaternion& a, const Quaternion& b); +Quaternion operator-(const Quaternion& a, const Quaternion& b); + +Quaternion operator*(const Quaternion& a, const Quaternion& b); +Quaternion operator*(const Quaternion& a, f32 s); +Quaternion operator*(f32 s, const Quaternion& a); + +Quaternion operator/(const Quaternion& a, f32 s); + +// Matrix4 Operators +bool operator==(const Matrix4& a, const Matrix4& b); +bool operator!=(const Matrix4& a, const Matrix4& b); + +Matrix4 operator+(const Matrix4& a, const Matrix4& b); +Matrix4 operator-(const Matrix4& a, const Matrix4& b); + +Matrix4 operator*(const Matrix4& a, const Matrix4& b); +Vector4 operator*(const Matrix4& a, const Vector4& v); +Matrix4 operator*(const Matrix4& a, f32 scalar); +Matrix4 operator*(f32 scalar, const Matrix4& a); + +Matrix4 operator/(const Matrix4& a, f32 scalar); + +Matrix4& operator+=(Matrix4& a, const Matrix4& b); +Matrix4& operator-=(Matrix4& a, const Matrix4& b); +Matrix4& operator*=(Matrix4& a, const Matrix4& b); + +////////////////////////////////// +/// Math Functions & Constants /// +////////////////////////////////// +extern const Vector2 VECTOR2_ZERO; +extern const Vector3 VECTOR3_ZERO; +extern const Vector4 VECTOR4_ZERO; +extern const Quaternion QUATERNION_IDENTITY; +extern const Matrix4 MATRIX4_IDENTITY; + +namespace math +{ +extern const f32 EPSILON; +extern const f32 ZERO; +extern const f32 ONE; +extern const f32 THIRD; +extern const f32 TWO_THIRDS; +extern const f32 E; +extern const f32 PI; +extern const f32 TAU; +extern const f32 SQRT_2; +extern const f32 SQRT_3; + +// Power +f32 sqrt(f32 x); +f32 pow(f32 x, f32 y); +f32 cbrt(f32 x); +f32 fast_inv_sqrt(f32 x); + +// Trigonometric +f32 sin(f32 radians); +f32 cos(f32 radians); +f32 tan(f32 radians); + +f32 asin(f32 x); +f32 acos(f32 x); +f32 atan(f32 x); +f32 atan2(f32 y, f32 x); + +f32 radians(f32 degrees); +f32 degrees(f32 radians); + +// Hyperbolic +f32 sinh(f32 x); +f32 cosh(f32 x); +f32 tanh(f32 x); + +f32 asinh(f32 x); +f32 acosh(f32 x); +f32 atanh(f32 x); + +// Rounding +f32 ceil(f32 x); +f32 floor(f32 x); +f32 mod(f32 x, f32 y); +f32 truncate(f32 x); +f32 round(f32 x); + +s32 sign(s32 x); +s64 sign(s64 x); +f32 sign(f32 x); + +// Other +f32 abs(f32 x); +s8 abs( s8 x); +s16 abs(s16 x); +s32 abs(s32 x); +s64 abs(s64 x); + +s32 min(s32 a, s32 b); +s64 min(s64 a, s64 b); +f32 min(f32 a, f32 b); + +s32 max(s32 a, s32 b); +s64 max(s64 a, s64 b); +f32 max(f32 a, f32 b); + +s32 clamp(s32 x, s32 min, s32 max); +s64 clamp(s64 x, s64 min, s64 max); +f32 clamp(f32 x, f32 min, f32 max); + +// Vector2 functions +f32 dot(const Vector2& a, const Vector2& b); +f32 cross(const Vector2& a, const Vector2& b); + +f32 magnitude(const Vector2& a); +Vector2 normalize(const Vector2& a); + +Vector2 hadamard_product(const Vector2& a, const Vector2& b); + +// Vector3 functions +f32 dot(const Vector3& a, const Vector3& b); +Vector3 cross(const Vector3& a, const Vector3& b); + +f32 magnitude(const Vector3& a); +Vector3 normalize(const Vector3& a); + +Vector3 hadamard_product(const Vector3& a, const Vector3& b); + +// Vector4 functions +f32 dot(const Vector4& a, const Vector4& b); + +f32 magnitude(const Vector4& a); +Vector4 normalize(const Vector4& a); + +Vector4 hadamard_product(const Vector4& a, const Vector4& b); + +// Quaternion functions +f32 dot(const Quaternion& a, const Quaternion& b); +Quaternion cross(const Quaternion& a, const Quaternion& b); + +f32 magnitude(const Quaternion& a); +Quaternion normalize(const Quaternion& a); + +Quaternion conjugate(const Quaternion& a); +Quaternion inverse(const Quaternion& a); + +Vector3 operator*(const Quaternion& a, const Vector3& v); // Rotate v by a + +f32 quaternion_angle(const Quaternion& a); +Vector3 quaternion_axis(const Quaternion& a); +Quaternion axis_angle(const Vector3& axis, f32 radians); + +f32 quaternion_roll(const Quaternion& a); +f32 quaternion_pitch(const Quaternion& a); +f32 quaternion_yaw(const Quaternion& a); + +Euler_Angles quaternion_to_euler_angles(const Quaternion& a); +Quaternion euler_angles_to_quaternion(const Euler_Angles& e, + const Vector3& x_axis = {1, 0, 0}, + const Vector3& y_axis = {0, 1, 0}, + const Vector3& z_axis = {0, 0, 1}); + +// Matrix4 functions +Matrix4 transpose(const Matrix4& m); +f32 determinant(const Matrix4& m); + +Matrix4 inverse(const Matrix4& m); + +Matrix4 hadamard_product(const Matrix4& a, const Matrix4&b); + +Matrix4 quaternion_to_matrix4(const Quaternion& a); +Quaternion matrix4_to_quaternion(const Matrix4& m); + +Matrix4 translate(const Vector3& v); +Matrix4 rotate(const Vector3& v, f32 radians); +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, f32 z_near, f32 z_far); +Matrix4 perspective(f32 fovy_radians, f32 aspect, f32 z_near, f32 z_far); +Matrix4 infinite_perspective(f32 fovy_radians, f32 aspect, f32 z_near); + +Matrix4 +look_at_matrix4(const Vector3& eye, const Vector3& center, const Vector3& up = {0, 1, 0}); + +Quaternion +look_at_quaternion(const Vector3& eye, const Vector3& center, const Vector3& up = {0, 1, 0}); + + +} // namespace math +} // namespace gb +#endif // GB_INCLUDE_GB_HPP + +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// It's a long way to Tipperary +/// +/// +/// +/// +/// +//////////////////////////////// +/// Implemenation /// +//////////////////////////////// +#ifdef GB_IMPLEMENTATION + +#include <float.h> +#include <math.h> +#include <stdarg.h> +#include <time.h> + +#ifdef GB_SYSTEM_WINDOWS +#include <windows.h> +#endif + +inline void +gb__assert_handler(bool condition, const char* condition_str, + const char* filename, size_t line, + const char* error_text, ...) +{ + if (condition) + return; + + fprintf(stderr, "ASSERT! %s(%d): %s", filename, line, condition_str); + if (error_text) + { + fprintf(stderr, " - "); + + va_list args; + va_start(args, error_text); + vfprintf(stderr, error_text, args); + va_end(args); + } + fprintf(stderr, "\n"); + + *(int*)0 = 0; // TODO(bill): Use a better way to assert +} + + + +namespace gb +{ //////////////////////////////// /// Memory /// //////////////////////////////// @@ -1592,9 +1667,216 @@ void Arena_Allocator::check() //////////////////////////////// -/// Math /// +/// Time /// //////////////////////////////// +#ifdef GB_SYSTEM_WINDOWS + +static LARGE_INTEGER +win32_get_frequency() +{ + LARGE_INTEGER f; + QueryPerformanceFrequency(&f); + return f; +} + +Time time_now() +{ + // NOTE(bill): std::chrono does not have a good enough precision in MSVC12 + // and below. This may have been fixed in MSVC14 but unsure as of yet. + + // Force the following code to run on first core + // NOTE(bill): See + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx + HANDLE currentThread = GetCurrentThread(); + DWORD_PTR previousMask = SetThreadAffinityMask(currentThread, 1); + + // Get the frequency of the performance counter + // It is constant across the program's lifetime + static LARGE_INTEGER s_frequency = win32_get_frequency(); + + // Get the current time + LARGE_INTEGER t; + QueryPerformanceCounter(&t); + + // Restore the thread affinity + SetThreadAffinityMask(currentThread, previousMask); + + return microseconds(1000000ll * t.QuadPart / s_frequency.QuadPart); +} + +void time_sleep(Time t) +{ + if (t.microseconds <= 0) + return; + + // Get the supported timer resolutions on this system + TIMECAPS tc; + timeGetDevCaps(&tc, sizeof(TIMECAPS)); + // Set the timer resolution to the minimum for the Sleep call + timeBeginPeriod(tc.wPeriodMin); + + // Wait... + ::Sleep(time_as_milliseconds(t)); + + // Reset the timer resolution back to the system default + timeBeginPeriod(tc.wPeriodMin); +} + +#else +Time time_now() +{ + struct timespec spec; + clock_gettime(CLOCK_REALTIME, &spec); + + return milliseconds((spec.tv_sec * 1000000ll) + (spec.tv_nsec * 1000ll)); +} + +void time_sleep(Time t) +{ + if (t.microseconds <= 0) + return; + + struct timespec spec = {}; + spec.tv_sec = static_cast<s64>(time_as_seconds(t)); + spec.tv_nsec = 1000ll * (time_as_microseconds(t) % 1000000ll); + + nanosleep(&spec, nullptr); +} + +#endif + +Time seconds(f32 s) { return {s * 1000000ll}; } +Time milliseconds(s32 ms) { return {ms * 1000l}; } +Time microseconds(s64 us) { return {us}; } +f32 time_as_seconds(Time t) { return t.microseconds / 1000000.0f; } +s32 time_as_milliseconds(Time t) { return t.microseconds / 1000l; } +s64 time_as_microseconds(Time t) { return t.microseconds; } + +bool operator==(Time left, Time right) +{ + return left.microseconds == right.microseconds; +} + +bool operator!=(Time left, Time right) +{ + return !operator==(left, right); +} + + +bool operator<(Time left, Time right) +{ + return left.microseconds < right.microseconds; +} + +bool operator>(Time left, Time right) +{ + return left.microseconds > right.microseconds; +} + +bool operator<=(Time left, Time right) +{ + return left.microseconds <= right.microseconds; +} + +bool operator>=(Time left, Time right) +{ + return left.microseconds >= right.microseconds; +} + +Time operator-(Time right) +{ + return {-right.microseconds}; +} + +Time operator+(Time left, Time right) +{ + return {left.microseconds + right.microseconds}; +} + +Time operator-(Time left, Time right) +{ + return {left.microseconds - right.microseconds}; +} + +Time& operator+=(Time& left, Time right) +{ + return (left = left + right); +} + +Time& operator-=(Time& left, Time right) +{ + return (left = left - right); +} + +Time operator*(Time left, f32 right) +{ + return seconds(time_as_seconds(left) * right); +} + +Time operator*(Time left, s64 right) +{ + return microseconds(time_as_microseconds(left) * right); +} + +Time operator*(f32 left, Time right) +{ + return seconds(time_as_seconds(right) * left); +} + +Time operator*(s64 left, Time right) +{ + return microseconds(time_as_microseconds(right) * left); +} + +Time& operator*=(Time& left, f32 right) +{ + return (left = left * right); +} + +Time& operator*=(Time& left, s64 right) +{ + return (left = left * right); +} + +Time operator/(Time left, f32 right) +{ + return seconds(time_as_seconds(left) / right); +} + +Time operator/(Time left, s64 right) +{ + return microseconds(time_as_microseconds(left) / right); + +} + +Time& operator/=(Time& left, f32 right) +{ + return (left = left / right); +} + +Time& operator/=(Time& left, s64 right) +{ + return (left = left / right); +} + +f32 operator/(Time left, Time right) +{ + return time_as_seconds(left) / time_as_seconds(right); +} + +Time operator%(Time left, Time right) +{ + return microseconds(time_as_microseconds(left) % time_as_microseconds(right)); +} +Time& operator%=(Time& left, Time right) +{ + return (left = left % right); +} + +//////////////////////////////// +/// Math /// +//////////////////////////////// const Vector2 VECTOR2_ZERO = {0, 0}; const Vector3 VECTOR3_ZERO = {0, 0, 0}; @@ -2039,9 +2321,9 @@ const f32 SQRT_2 = 1.414213562f; const f32 SQRT_3 = 1.732050808f; // Power -inline f32 sqrt(f32 x) { return ::sqrtf(x); } +inline f32 sqrt(f32 x) { return ::sqrtf(x); } inline f32 pow(f32 x, f32 y) { return (f32)::powf(x, y); } -inline f32 cbrt(f32 x) { return (f32)::cbrtf(x); } +inline f32 cbrt(f32 x) { return (f32)::cbrtf(x); } inline f32 fast_inv_sqrt(f32 x) { @@ -2064,9 +2346,9 @@ inline f32 sin(f32 radians) { return ::sinf(radians); } inline f32 cos(f32 radians) { return ::cosf(radians); } inline f32 tan(f32 radians) { return ::tanf(radians); } -inline f32 asin(f32 x) { return ::asinf(x); } -inline f32 acos(f32 x) { return ::acosf(x); } -inline f32 atan(f32 x) { return ::atanf(x); } +inline f32 asin(f32 x) { return ::asinf(x); } +inline f32 acos(f32 x) { return ::acosf(x); } +inline f32 atan(f32 x) { return ::atanf(x); } inline f32 atan2(f32 y, f32 x) { return ::atan2f(y, x); } inline f32 radians(f32 degrees) { return TAU * degrees / 360.0f; } @@ -2082,11 +2364,11 @@ inline f32 acosh(f32 x) { return ::acoshf(x); } inline f32 atanh(f32 x) { return ::atanhf(x); } // Rounding -inline f32 ceil(f32 x) { return ::ceilf(x); } -inline f32 floor(f32 x) { return ::floorf(x); } +inline f32 ceil(f32 x) { return ::ceilf(x); } +inline f32 floor(f32 x) { return ::floorf(x); } inline f32 mod(f32 x, f32 y) { return ::fmodf(x, y); } -inline f32 truncate(f32 x) { return ::truncf(x); } -inline f32 round(f32 x) { return ::roundf(x); } +inline f32 truncate(f32 x) { return ::truncf(x); } +inline f32 round(f32 x) { return ::roundf(x); } inline s32 sign(s32 x) { return x >= 0 ? +1 : -1; } inline s64 sign(s64 x) { return x >= 0 ? +1 : -1; } @@ -2102,7 +2384,7 @@ inline f32 abs(f32 x) inline s8 abs(s8 x) { -u8 i = reinterpret_cast<const u8&>(x); + u8 i = reinterpret_cast<const u8&>(x); i &= 0x7Fu; return reinterpret_cast<const s8&>(i); } @@ -2465,15 +2747,15 @@ Matrix4 quaternion_to_matrix4(const Quaternion& q) f32 wz = a.w * a.z; mat[0][0] = 1.0f - 2.0f * (yy + zz); - mat[0][1] = 2.0f * (xy + wz); - mat[0][2] = 2.0f * (xz - wy); + mat[0][1] = 2.0f * (xy + wz); + mat[0][2] = 2.0f * (xz - wy); - mat[1][0] = 2.0f * (xy - wz); + mat[1][0] = 2.0f * (xy - wz); mat[1][1] = 1.0f - 2.0f * (xx + zz); - mat[1][2] = 2.0f * (yz + wx); + mat[1][2] = 2.0f * (yz + wx); - mat[2][0] = 2.0f * (xz + wy); - mat[2][1] = 2.0f * (yz - wx); + mat[2][0] = 2.0f * (xz + wy); + mat[2][1] = 2.0f * (yz - wx); mat[2][2] = 1.0f - 2.0f * (xx + yy); return mat; @@ -2491,17 +2773,17 @@ Quaternion matrix4_to_quaternion(const Matrix4& m) if (four_x_squared_minus_1 > four_biggest_squared_minus_1) { four_biggest_squared_minus_1 = four_x_squared_minus_1; - biggestIndex = 1; + biggestIndex = 1; } if (four_y_squared_minus_1 > four_biggest_squared_minus_1) { four_biggest_squared_minus_1 = four_y_squared_minus_1; - biggestIndex = 2; + biggestIndex = 2; } if (four_z_squared_minus_1 > four_biggest_squared_minus_1) { four_biggest_squared_minus_1 = four_z_squared_minus_1; - biggestIndex = 3; + biggestIndex = 3; } f32 biggestVal = math::sqrt(four_biggest_squared_minus_1 + 1.0f) * 0.5f; @@ -2571,10 +2853,11 @@ Matrix4 rotate(const Vector3& v, f32 radians) const Vector3 t = (1.0f - c) * axis; Matrix4 rot = MATRIX4_IDENTITY; - rot[0][0] = c + t.x * axis.x; - rot[0][1] = 0 + t.x * axis.y + s * axis.z; - rot[0][2] = 0 + t.x * axis.z - s * axis.y; - rot[0][3] = 0; + + rot[0][0] = c + t.x * axis.x; + rot[0][1] = 0 + t.x * axis.y + s * axis.z; + rot[0][2] = 0 + t.x * axis.z - s * axis.y; + rot[0][3] = 0; rot[1][0] = 0 + t.y * axis.x - s * axis.z; rot[1][1] = c + t.y * axis.y; @@ -2669,9 +2952,10 @@ look_at_matrix4(const Vector3& eye, const Vector3& center, const Vector3& up) const Vector3 u = math::cross(s, f); Matrix4 result = MATRIX4_IDENTITY; - result[0][0] = +s.x; - result[1][0] = +s.y; - result[2][0] = +s.z; + + result[0][0] = +s.x; + result[1][0] = +s.y; + result[2][0] = +s.z; result[0][1] = +u.x; result[1][1] = +u.y; |
