aboutsummaryrefslogtreecommitdiffstats
path: root/gb.hpp
diff options
context:
space:
mode:
authorGravatar gingerBill 2015-09-28 20:31:26 +0100
committerGravatar gingerBill 2015-09-28 20:31:26 +0100
commit519708db13a035c5a6e6f5ff9c0ae9db2972401e (patch)
tree3bd34422d247c4dd3e35b12f3bc37913096af62e /gb.hpp
parentgb.hpp - Hash Table Support (diff)
gb.hpp - Time functions
Diffstat (limited to 'gb.hpp')
-rw-r--r--gb.hpp1246
1 files changed, 765 insertions, 481 deletions
diff --git a/gb.hpp b/gb.hpp
index 2090878..2dbd6ee 100644
--- a/gb.hpp
+++ b/gb.hpp
@@ -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;