/* HandmadeMath.h v0.1 This is a single header file with a bunch of useful functions for basic game math operations. ========================================================================== You MUST #define HANDMADE_MATH_IMPLEMENTATION in EXACTLY one C or C++ file that includes this header, BEFORE the include, like this: #define HANDMADE_MATH_IMPLEMENTATION #include "HandmadeMade.h" All other files should just #include "HandmadeMath.h" without the #define. ========================================================================== For overloaded, and operator overloaded versions of the base C functions. You MUST #define HANDMADE_MATH_CPP_MODE in EXACTLY one C or C++ file that includes this header, BEFORE the include, like this: #define HANDMADE_MATH_IMPLEMENTATION #define HANDMADE_MATH_CPP_MODE #include "HandmadeMade.h" All other files should just #include "HandmadeMath.h" without the #define. ========================================================================== LICENSE This software is in the public domain. Where that dedication is not recognized, you are granted a perpetual, irrevocable license to copy, distribute, and modify this file as you see fit. CREDITS Written by Zakary Strange (zak@strangedev.net) Functionality: Matt Mascarenhas (@miblo_) Fixes: Jeroen van Rijn (@J_vanRijn) */ #ifndef HANDMADE_MATH_H #define HANDMADE_MATH_H #ifdef __cplusplus extern "C" { #endif #ifdef HANDMADEMATH_STATIC #define HMMDEF static #else #define HMMDEF extern #endif #if _MSC_VER && !__INTEL_COMPILER #define HINLINE __inline #else #define HINLINE inline #endif typedef union vec2 { struct { float x, y; }; struct { float u, v; }; struct { float left, right; }; float Elements[2]; } vec2; typedef union vec3 { struct { float x, y, z; }; struct { float u, v, w; }; struct { float r, g, b; }; struct { vec2 xy; float Ignored0_; }; struct { float Ignored1_; vec2 yz; }; struct { vec2 uv; float Ignored2_; }; struct { float Ignored3_; vec2 vw; }; float Elements[3]; } vec3; typedef union vec4 { struct { union { vec3 xyz; struct { float x, y, z; }; }; float w; }; struct { union { vec3 rgb; struct { float r, g, b; }; }; float a; }; struct { vec2 xy; float Ignored0_; float Ignored1_; }; struct { float Ignored2_; vec2 yz; float Ignored3_; }; struct { float Ignored4_; float Ignored5_; vec2 zw; }; float E[4]; } vec4; HMMDEF HINLINE vec2 V2i(int X, int Y); HMMDEF HINLINE vec2 V2(float X, float Y); HMMDEF HINLINE vec3 V3(float X, float Y, float Z); HMMDEF HINLINE vec3 V3i(int X, int Y, int Z); HMMDEF HINLINE vec4 V4(float X, float Y, float Z, float W); HMMDEF HINLINE vec4 V4i(int X, int Y, int Z, int W); HMMDEF HINLINE vec2 AddV2(vec2 Left, vec2 Right); HMMDEF HINLINE vec3 AddV3(vec3 Left, vec3 Right); HMMDEF HINLINE vec4 AddV4(vec4 Left, vec4 Right); HMMDEF HINLINE vec2 SubtractV2(vec2 Left, vec2 Right); HMMDEF HINLINE vec3 SubtractV3(vec3 Left, vec3 Right); HMMDEF HINLINE vec4 SubtractV4(vec4 Left, vec4 Right); HMMDEF HINLINE vec2 MultiplyV2(vec2 Left, vec2 Right); HMMDEF HINLINE vec3 MultiplyV3(vec3 Left, vec3 Right); HMMDEF HINLINE vec4 MultiplyV4(vec4 Left, vec4 Right); HMMDEF HINLINE vec2 DivideV2(vec2 Left, vec2 Right); HMMDEF HINLINE vec3 DivideV3(vec3 Left, vec3 Right); HMMDEF HINLINE vec4 DivideV4(vec4 Left, vec4 Right); HMMDEF HINLINE float Power(float Base, int Exponent); #ifdef __cplusplus } #endif #ifdef HANDMADE_MATH_CPP_MODE HMMDEF HINLINE vec2 Add(int X, int Y); HMMDEF HINLINE vec3 Add(int X, int Y, int Z); HMMDEF HINLINE vec4 Add(int X, int Y, int Z, int W); HMMDEF HINLINE vec2 Subtract(int X, int Y); HMMDEF HINLINE vec3 Subtract(int X, int Y, int Z); HMMDEF HINLINE vec4 Subtract(int X, int Y, int Z, int W); HMMDEF HINLINE vec2 Multiply(int X, int Y); HMMDEF HINLINE vec3 Multiply(int X, int Y, int Z); HMMDEF HINLINE vec4 Multiply(int X, int Y, int Z, int W); HMMDEF HINLINE vec2 Divide(int X, int Y); HMMDEF HINLINE vec3 Divide(int X, int Y, int Z); HMMDEF HINLINE vec4 Divide(int X, int Y, int Z, int W); #endif /* HANDMADE_MATH_CPP */ #endif /* HANDMADE_MATH_H */ #ifdef HANDMADE_MATH_IMPLEMENTATION HINLINE vec2 V2(float X, float Y) { vec2 Result = {0}; Result.x = X; Result.y = Y; return(Result); } HINLINE vec2 V2i(int X, int Y) { vec2 Result = {0}; Result.x = (float)X; Result.y = (float)Y; return(Result); } HINLINE vec3 V3(float X, float Y, float Z) { vec3 Result = {0}; Result.x = X; Result.y = Y; Result.z = Z; return(Result); } HINLINE vec3 V3i(int X, int Y, int Z) { vec3 Result = {0}; Result.x = (float)X; Result.y = (float)Y; Result.z = (float)Z; return(Result); } HINLINE vec4 V4(float X, float Y, float Z, float W) { vec4 Result = {0}; Result.x = X; Result.y = Y; Result.z = Z; Result.w = W; return(Result); } HINLINE vec4 V4i(int X, int Y, int Z, int W) { vec4 Result = {0}; Result.x = (float)X; Result.y = (float)Y; Result.z = (float)Z; Result.w = (float)W; return(Result); } HINLINE vec2 AddV2(vec2 Left, vec2 Right) { vec2 Result; Result.x = Left.x + Right.x; Result.y = Left.y + Right.y; return(Result); } HINLINE vec3 AddV3(vec3 Left, vec3 Right) { vec3 Result; Result.x = Left.x + Right.x; Result.y = Left.y + Right.y; Result.z = Left.z + Right.z; return(Result); } HINLINE vec4 AddV4(vec4 Left, vec4 Right) { vec4 Result; Result.x = Left.x + Right.x; Result.y = Left.y + Right.y; Result.z = Left.z + Right.z; Result.w = Left.w + Right.w; return(Result); } HINLINE vec2 SubtractV2(vec2 Left, vec2 Right) { vec2 Result; Result.x = Left.x - Right.x; Result.y = Left.y - Right.y; return(Result); } HINLINE vec3 SubtractV3(vec3 Left, vec3 Right) { vec3 Result; Result.x = Left.x - Right.x; Result.y = Left.y - Right.y; Result.z = Left.z - Right.z; return(Result); } HINLINE vec4 SubtractV4(vec4 Left, vec4 Right) { vec4 Result; Result.x = Left.x - Right.x; Result.y = Left.y - Right.y; Result.z = Left.z - Right.z; Result.w = Left.w - Right.w; return(Result); } HINLINE vec2 MultiplyV2(vec2 Left, vec2 Right) { vec2 Result; Result.x = Left.x * Right.x; Result.y = Left.y * Right.y; return(Result); } HINLINE vec3 MultiplyV3(vec3 Left, vec3 Right) { vec3 Result; Result.x = Left.x * Right.x; Result.y = Left.y * Right.y; Result.z = Left.z * Right.z; return(Result); } HINLINE vec4 MultiplyV4(vec4 Left, vec4 Right) { vec4 Result; Result.x = Left.x * Right.x; Result.y = Left.y * Right.y; Result.z = Left.z * Right.z; Result.w = Left.w * Right.w; return(Result); } HINLINE vec2 DivideV2(vec2 Left, vec2 Right) { vec2 Result; Result.x = Left.x / Right.x; Result.y = Left.y / Right.y; return(Result); } HINLINE vec3 DivideV3(vec3 Left, vec3 Right) { vec3 Result; Result.x = Left.x / Right.x; Result.y = Left.y / Right.y; Result.z = Left.z / Right.z; return(Result); } HINLINE vec4 DivideV4(vec4 Left, vec4 Right) { vec4 Result; Result.x = Left.x / Right.x; Result.y = Left.y / Right.y; Result.z = Left.z / Right.z; Result.w = Left.w / Right.w; return(Result); } HINLINE float Power(float Base, int Exponent) { float Result = 1; if (Exponent > 0) { for (int i = 0; i < Exponent; ++i) { Result *= Base; } } else { for (int i = 0; i > Exponent; --i) { Result /= Base; } } return (Result); } #ifdef HANDMADE_MATH_CPP_MODE HINLINE vec2 Add(vec2 Left, vec2 Right) { vec2 Result = AddV2(Left, Right); return(Result); } HINLINE vec3 Add(vec3 Left, vec3 Right) { vec3 Result = AddV3(Left, Right); return(Result); } HINLINE vec4 Add(vec4 Left, vec4 Right) { vec4 Result = AddV4(Left, Right); return(Result); } HINLINE vec2 Subtract(vec2 Left, vec2 Right) { vec2 Result = SubtractV2(Left, Right); return(Result); } HINLINE vec3 Subtract(vec3 Left, vec3 Right) { vec3 Result = SubtractV3(Left, Right); return(Result); } HINLINE vec4 Subtract(vec4 Left, vec4 Right) { vec4 Result = SubtractV4(Left, Right); return(Result); } HINLINE vec2 Multiply(vec2 Left, vec2 Right) { vec2 Result = MultiplyV2(Left, Right); } HINLINE vec3 Multiply(vec3 Left, vec3 Right) { vec3 Result = MultiplyV3(Left, Right); return(Result); } HINLINE vec4 Multiply(vec4 Left, vec4 Right) { vec4 Result = MultiplyV4(Left, Right); return(Result); } HINLINE vec2 Divide(vec2 Left, vec2 Right) { vec2 Result = DivideV2(Left, Right); return(Result); } HINLINE vec3 Divide(vec3 Left, vec3 Right) { vec3 Result = DivideV3(Left, Right); return(Result); } HINLINE vec4 Divide(vec4 Left, vec4 Right) { vec4 Result = DivideV4(Left, Right); return(Result); } #endif /* HANDMADE_MATH_CPP_MODE */ #endif /* HANDMADE_MATH_IMPLEMENTATION */