mirror of
https://github.com/HandmadeMath/HandmadeMath.git
synced 2025-09-07 02:38:15 +00:00

Some build environments build each source file individually to .o files and then link after the fact. With inlined functions, this tends to just produce empty .o files, undefined symbol errors, and grumpy programmers like me. This change simply adds the option to disable inlining of functions so Handmade Math can function properly as a library unto itself.
1207 lines
24 KiB
C
1207 lines
24 KiB
C
/*
|
|
HandmadeMath.h v0.2b
|
|
|
|
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 "HandmadeMath.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 "HandmadeMath.h"
|
|
|
|
All other files should just #include "HandmadeMath.h" without the #define.
|
|
==========================================================================
|
|
|
|
To disable SSE intrinsics, for You MUST
|
|
|
|
#define HANDMADE_MATH_NO_SSE
|
|
|
|
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
|
|
#define HANDMADE_MATH_NO_SSE
|
|
#include "HandmadeMath.h"
|
|
|
|
or
|
|
|
|
#define HANDMADE_MATH_IMPLEMENTATION
|
|
#define HANDMADE_MATH_NO_SSE
|
|
|
|
==========================================================================
|
|
|
|
To disable inlining functions, you MUST
|
|
|
|
#define HANDMADE_MATH_NO_INLINE
|
|
|
|
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
|
|
#define HANDMADE_MATH_NO_INLINE
|
|
#include "HandmadeMath.h"
|
|
|
|
All other files should just #include "HandmadeMath.h" without the #define.
|
|
|
|
Version History:
|
|
0.2 (*) Updated documentation
|
|
(*) Better C compliance
|
|
(*) Prefix all handmade math functions
|
|
(*) Better operator overloading
|
|
0.2a
|
|
(*) Prefixed Macros
|
|
0.2b
|
|
(*) Disabled warning 4201 on MSVC as it is legal is C11
|
|
(*) Removed the f at the end of HMM_PI to get 64bit precision
|
|
0.3
|
|
() Removed CRT
|
|
0.4
|
|
(*) SSE Optimized HMM_SqrtF
|
|
(*) SSE Optimized HMM_RSqrtF
|
|
() SSE Optimized HMM_SinF
|
|
() SSE Optimized HMM_CosF
|
|
() SSe Optimized HMM_TanF
|
|
|
|
|
|
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@handmade.network && @strangezak)
|
|
|
|
Functionality:
|
|
Matt Mascarenhas (@miblo_)
|
|
Aleph
|
|
FieryDrake (@fierydrake)
|
|
Gingerbill (@TheGingerBill)
|
|
|
|
Fixes:
|
|
Jeroen van Rijn (@J_vanRijn)
|
|
Kiljacken (@Kiljacken)
|
|
Insofaras (@insofaras)
|
|
*/
|
|
|
|
#include <xmmintrin.h>
|
|
|
|
#ifndef HANDMADE_MATH_H
|
|
#define HANDMADE_MATH_H
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(disable:4201)
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
#ifdef HANDMADEMATH_STATIC
|
|
#define HMMDEF static
|
|
#else
|
|
#define HMMDEF extern
|
|
#endif
|
|
|
|
#ifdef HANDMADE_MATH_NO_INLINE
|
|
#define HINLINE
|
|
#elif _MSC_VER && !__INTEL_COMPILER
|
|
#define HINLINE __inline
|
|
#else
|
|
#define HINLINE inline
|
|
#endif
|
|
|
|
#define HMM_PI32 3.14159265359f
|
|
#define HMM_PI 3.14159265358979323846
|
|
|
|
#define HMM_MIN(a, b) (a) > (b) ? (b) : (a)
|
|
#define HMM_MAX(a, b) (a) < (b) ? (b) : (a)
|
|
#define HMN_ABS(a) (a) < 0 ? -(a) : (a)
|
|
#define HMM_MOD(a, m) ((a) % (m)) >= 0 ? ((a) % (m)) : (((a) % (m)) + (m))
|
|
#define HMM_SQUARE(x) ((x) * (x))
|
|
|
|
typedef union hmm_vec2
|
|
{
|
|
struct
|
|
{
|
|
float X, Y;
|
|
};
|
|
|
|
struct
|
|
{
|
|
float U, V;
|
|
};
|
|
|
|
struct
|
|
{
|
|
float Left, Right;
|
|
};
|
|
|
|
float Elements[2];
|
|
} hmm_vec2;
|
|
|
|
typedef union hmm_vec3
|
|
{
|
|
struct
|
|
{
|
|
float X, Y, Z;
|
|
};
|
|
|
|
struct
|
|
{
|
|
float U, V, W;
|
|
};
|
|
|
|
struct
|
|
{
|
|
float R, G, B;
|
|
};
|
|
|
|
struct
|
|
{
|
|
hmm_vec2 XY;
|
|
float Ignored0_;
|
|
};
|
|
|
|
struct
|
|
{
|
|
float Ignored1_;
|
|
hmm_vec2 YZ;
|
|
};
|
|
|
|
struct
|
|
{
|
|
hmm_vec2 UV;
|
|
float Ignored2_;
|
|
};
|
|
|
|
struct
|
|
{
|
|
float Ignored3_;
|
|
hmm_vec2 VW;
|
|
};
|
|
|
|
float Elements[3];
|
|
} hmm_vec3;
|
|
|
|
typedef union hmm_vec4
|
|
{
|
|
struct
|
|
{
|
|
union
|
|
{
|
|
hmm_vec3 XYZ;
|
|
struct
|
|
{
|
|
float X, Y, Z;
|
|
};
|
|
};
|
|
|
|
float W;
|
|
};
|
|
struct
|
|
{
|
|
union
|
|
{
|
|
hmm_vec3 RGB;
|
|
struct
|
|
{
|
|
float R, G, B;
|
|
};
|
|
};
|
|
|
|
float A;
|
|
};
|
|
|
|
struct
|
|
{
|
|
hmm_vec2 XY;
|
|
float Ignored0_;
|
|
float Ignored1_;
|
|
};
|
|
|
|
struct
|
|
{
|
|
float Ignored2_;
|
|
hmm_vec2 YZ;
|
|
float Ignored3_;
|
|
};
|
|
|
|
struct
|
|
{
|
|
float Ignored4_;
|
|
float Ignored5_;
|
|
hmm_vec2 ZW;
|
|
};
|
|
|
|
float Elements[4];
|
|
} hmm_vec4;
|
|
|
|
typedef union hmm_mat4
|
|
{
|
|
float Elements[4][4];
|
|
} hmm_mat4;
|
|
|
|
typedef hmm_vec2 hmm_v2;
|
|
typedef hmm_vec3 hmm_v3;
|
|
typedef hmm_vec4 hmm_v4;
|
|
typedef hmm_mat4 hmm_m4;
|
|
|
|
HMMDEF float HMM_SinF(float Angle);
|
|
HMMDEF float HMM_TanF(float Angle);
|
|
HMMDEF float HMM_CosF(float Angle);
|
|
HMMDEF float HMM_SqrtF(float Angle);
|
|
|
|
HMMDEF float HMM_ToRadians(float Degrees);
|
|
HMMDEF float HMM_Inner(hmm_vec3 A, hmm_vec3 B);
|
|
HMMDEF float HMM_SquareRoot(float Float);
|
|
HMMDEF float HMM_LengthSquareRoot(hmm_vec3 A);
|
|
HMMDEF float HMM_FastInverseSquareRoot(float Number);
|
|
HMMDEF float HMM_Length(hmm_vec3 A);
|
|
HMMDEF float HMM_Power(float Base, int Exponent);
|
|
HMMDEF float HMM_Clamp(float Min, float Value, float Max);
|
|
|
|
HMMDEF hmm_vec3 HMM_Normalize(hmm_vec3 A);
|
|
HMMDEF hmm_vec3 HMM_Cross(hmm_vec3 VecOne, hmm_vec3 VecTwo);
|
|
HMMDEF float HMM_Dot(hmm_vec3 VecOne, hmm_vec3 VecTwo);
|
|
|
|
HMMDEF hmm_vec2 HMM_Vec2i(int X, int Y);
|
|
HMMDEF hmm_vec2 HMM_Vec2(float X, float Y);
|
|
HMMDEF hmm_vec3 HMM_Vec3(float X, float Y, float Z);
|
|
HMMDEF hmm_vec3 HMM_Vec3i(int X, int Y, int Z);
|
|
HMMDEF hmm_vec4 HMM_Vec4(float X, float Y, float Z, float W);
|
|
HMMDEF hmm_vec4 HMM_Vec4i(int X, int Y, int Z, int W);
|
|
|
|
HMMDEF hmm_vec2 HMM_AddVec2(hmm_vec2 Left, hmm_vec2 Right);
|
|
HMMDEF hmm_vec3 HMM_AddVec3(hmm_vec3 Left, hmm_vec3 Right);
|
|
HMMDEF hmm_vec4 HMM_AddVec4(hmm_vec4 Left, hmm_vec4 Right);
|
|
|
|
HMMDEF hmm_vec2 HMM_SubtractVec2(hmm_vec2 Left, hmm_vec2 Right);
|
|
HMMDEF hmm_vec3 HMM_SubtractVec3(hmm_vec3 Left, hmm_vec3 Right);
|
|
HMMDEF hmm_vec4 HMM_SubtractVec4(hmm_vec4 Left, hmm_vec4 Right);
|
|
|
|
HMMDEF hmm_vec2 HMM_MultiplyVec2(hmm_vec2 Left, hmm_vec2 Right);
|
|
HMMDEF hmm_vec3 HMM_MultiplyVec3(hmm_vec3 Left, hmm_vec3 Right);
|
|
HMMDEF hmm_vec4 HMM_MultiplyVec4(hmm_vec4 Left, hmm_vec4 Right);
|
|
|
|
HMMDEF hmm_vec2 HMM_DivideVec2(hmm_vec2 Left, hmm_vec2 Right);
|
|
HMMDEF hmm_vec3 HMM_DivideVec3(hmm_vec3 Left, hmm_vec3 Right);
|
|
HMMDEF hmm_vec4 HMM_DivideVec4(hmm_vec4 Left, hmm_vec4 Right);
|
|
|
|
HMMDEF hmm_mat4 HMM_Mat4(void);
|
|
HMMDEF hmm_mat4 HMM_Mat4d(float Diagonal);
|
|
HMMDEF hmm_mat4 HMM_MultiplyMat4(hmm_mat4 Left, hmm_mat4 Right);
|
|
HMMDEF hmm_vec4 HMM_MultiplyMat4ByVec4(hmm_mat4 Matrix, hmm_vec4 Vector);
|
|
|
|
HMMDEF hmm_mat4 HMM_Orthographic(float Left, float Right, float Bottom, float Top, float Near, float Far);
|
|
HMMDEF hmm_mat4 HMM_Perspective(float FOV, float AspectRatio, float Near, float Far);
|
|
HMMDEF hmm_mat4 HMM_Translate(hmm_vec3 Translation);
|
|
HMMDEF hmm_mat4 HMM_Rotate(float Angle, hmm_vec3 Axis);
|
|
HMMDEF hmm_mat4 HMM_Scale(hmm_vec3 Scale);
|
|
|
|
HMMDEF hmm_mat4 HMM_LookAt(hmm_vec3 Eye, hmm_vec3 Center, hmm_vec3 Up);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#ifdef HANDMADE_MATH_CPP_MODE
|
|
|
|
HMMDEF hmm_vec2 HMM_Add(int X, int Y);
|
|
HMMDEF hmm_vec3 HMM_Add(int X, int Y, int Z);
|
|
HMMDEF hmm_vec4 HMM_Add(int X, int Y, int Z, int W);
|
|
|
|
HMMDEF hmm_vec2 HMM_Subtract(int X, int Y);
|
|
HMMDEF hmm_vec3 HMM_Subtract(int X, int Y, int Z);
|
|
HMMDEF hmm_vec4 HMM_Subtract(int X, int Y, int Z, int W);
|
|
|
|
HMMDEF hmm_vec2 HMM_Multiply(int X, int Y);
|
|
HMMDEF hmm_vec3 HMM_Multiply(int X, int Y, int Z);
|
|
HMMDEF hmm_vec4 HMM_Multiply(int X, int Y, int Z, int W);
|
|
HMMDEF hmm_mat4 HMM_Multiply(hmm_mat4 Left, hmm_mat4 Right);
|
|
HMMDEF hmm_vec4 HMM_Multiply(hmm_mat4 Matrix, hmm_vec4 Vector);
|
|
|
|
HMMDEF hmm_vec2 HMM_Divide(int X, int Y);
|
|
HMMDEF hmm_vec3 HMM_Divide(int X, int Y, int Z);
|
|
HMMDEF hmm_vec4 HMM_Divide(int X, int Y, int Z, int W);
|
|
|
|
HMMDEF hmm_vec2 operator+(hmm_vec2 Left, hmm_vec2 Right);
|
|
HMMDEF hmm_vec3 operator+(hmm_vec3 Left, hmm_vec3 Right);
|
|
HMMDEF hmm_vec4 operator+(hmm_vec4 Left, hmm_vec4 Right);
|
|
|
|
HMMDEF hmm_vec2 operator-(hmm_vec2 Left, hmm_vec2 Right);
|
|
HMMDEF hmm_vec3 operator-(hmm_vec3 Left, hmm_vec3 Right);
|
|
HMMDEF hmm_vec4 operator-(hmm_vec4 Left, hmm_vec4 Right);
|
|
|
|
HMMDEF hmm_vec2 operator*(hmm_vec2 Left, hmm_vec2 Right);
|
|
HMMDEF hmm_vec3 operator*(hmm_vec3 Left, hmm_vec3 Right);
|
|
HMMDEF hmm_vec4 operator*(hmm_vec4 Left, hmm_vec4 Right);
|
|
HMMDEF hmm_mat4 operator*(hmm_mat4 Left, hmm_mat4 Right);
|
|
|
|
HMMDEF hmm_vec3 operator*(hmm_vec3 Left, float Right);
|
|
HMMDEF hmm_vec2 operator*(hmm_vec2 Left, float Right);
|
|
|
|
HMMDEF hmm_vec4 operator*(hmm_mat4 Matrix, hmm_vec4 Vector);
|
|
|
|
HMMDEF hmm_vec2 operator/(hmm_vec2 Left, hmm_vec2 Right);
|
|
HMMDEF hmm_vec3 operator/(hmm_vec3 Left, hmm_vec3 Right);
|
|
HMMDEF hmm_vec4 operator/(hmm_vec4 Left, hmm_vec4 Right);
|
|
|
|
#endif /* HANDMADE_MATH_CPP */
|
|
|
|
#endif /* HANDMADE_MATH_H */
|
|
|
|
#ifdef HANDMADE_MATH_IMPLEMENTATION
|
|
|
|
#include <math.h>
|
|
|
|
// TODO(zak): Replace these functions use of the C STD
|
|
HINLINE float
|
|
HMM_SinF(float Angle)
|
|
{
|
|
float Result = 0;
|
|
|
|
Result = sinf(Angle);
|
|
return(Result);
|
|
}
|
|
|
|
HINLINE float
|
|
HMM_CosF(float Angle)
|
|
{
|
|
float Result = 0;
|
|
|
|
Result = cosf(Angle);
|
|
return(Result);
|
|
}
|
|
|
|
HINLINE float
|
|
HMM_TanF(float Radians)
|
|
{
|
|
float Result = 0;
|
|
|
|
Result = tanf(Radians);
|
|
return(Result);
|
|
}
|
|
|
|
HINLINE float
|
|
HMM_SqrtF(float Value)
|
|
{
|
|
float Result = 0;
|
|
#ifdef HANDMADE_MATH_NO_SSE
|
|
Result = sqrtf(Value);
|
|
#else
|
|
__m128 In = _mm_load_ss(&Value);
|
|
__m128 Out = _mm_sqrt_ss(In);
|
|
_mm_store_ss(&Result, Out);
|
|
#endif
|
|
return(Result);
|
|
}
|
|
|
|
HINLINE float
|
|
HMM_RSqrtF(float Value)
|
|
{
|
|
float Result = 0;
|
|
#ifdef HANDMADE_MATH_NO_SSE
|
|
Result = 1.0f/HMM_SqrtF(Value);
|
|
#else
|
|
__m128 In = _mm_load_ss(&Value);
|
|
__m128 Out = _mm_rsqrt_ss(In);
|
|
_mm_store_ss(&Result, Out);
|
|
#endif
|
|
return(Result);
|
|
}
|
|
|
|
HINLINE float
|
|
HMM_ToRadians(float Degrees)
|
|
{
|
|
float Result = Degrees * (HMM_PI32 / 180.0f);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE float
|
|
HMM_Inner(hmm_vec3 A, hmm_vec3 B)
|
|
{
|
|
float Result = A.X * B.X + A.Y * B.Y + A.Z * B.Z;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE float
|
|
HMM_LengthSquareRoot(hmm_vec3 A)
|
|
{
|
|
float Result = HMM_Inner(A, A);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE float
|
|
HMM_Length(hmm_vec3 A)
|
|
{
|
|
float Result = HMM_SqrtF(HMM_LengthSquareRoot(A));
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE float
|
|
HMM_Power(float Base, int Exponent)
|
|
{
|
|
float Result = 1;
|
|
if(Exponent > 0)
|
|
{
|
|
int i;
|
|
for(i = 0; i < Exponent; ++i)
|
|
{
|
|
Result *= Base;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
for(i = 0; i > Exponent; --i)
|
|
{
|
|
Result /= Base;
|
|
}
|
|
}
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE float
|
|
HMM_Lerp(float A, float Time, float B)
|
|
{
|
|
float Result = (1.0f - Time) * A + Time * B;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE float
|
|
HMM_Clamp(float Min, float Value, float Max)
|
|
{
|
|
float Result = Value;
|
|
|
|
if(Result < Min)
|
|
{
|
|
Result = Min;
|
|
}
|
|
else if(Result > Max)
|
|
{
|
|
Result = Max;
|
|
}
|
|
|
|
return (Result);
|
|
}
|
|
|
|
|
|
HINLINE hmm_vec3
|
|
HMM_Normalize(hmm_vec3 A)
|
|
{
|
|
hmm_vec3 Result = {0};
|
|
|
|
Result.X = A.X * (1.0f / HMM_Length(A));
|
|
Result.Y = A.Y * (1.0f / HMM_Length(A));
|
|
Result.Z = A.Z * (1.0f / HMM_Length(A));
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
HMM_Cross(hmm_vec3 VecOne, hmm_vec3 VecTwo)
|
|
{
|
|
hmm_vec3 Result;
|
|
|
|
Result.X = (VecOne.Y * VecTwo.Z) - (VecOne.Z * VecTwo.Y);
|
|
Result.Y = (VecOne.Z * VecTwo.X) - (VecOne.X * VecTwo.Z);
|
|
Result.Z = (VecOne.X * VecTwo.Y) - (VecOne.Y * VecTwo.X);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE float
|
|
HMM_Dot(hmm_vec3 VecOne, hmm_vec3 VecTwo)
|
|
{
|
|
float Result = 0;
|
|
|
|
Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y) + (VecOne.Z * VecTwo.Z);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec2
|
|
HMM_Vec2(float X, float Y)
|
|
{
|
|
hmm_vec2 Result;
|
|
|
|
Result.X = X;
|
|
Result.Y = Y;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec2
|
|
HMM_Vec2i(int X, int Y)
|
|
{
|
|
hmm_vec2 Result;
|
|
|
|
Result.X = (float)X;
|
|
Result.Y = (float)Y;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
HMM_Vec3(float X, float Y, float Z)
|
|
{
|
|
hmm_vec3 Result;
|
|
|
|
Result.X = X;
|
|
Result.Y = Y;
|
|
Result.Z = Z;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
HMM_Vec3i(int X, int Y, int Z)
|
|
{
|
|
hmm_vec3 Result;
|
|
|
|
Result.X = (float)X;
|
|
Result.Y = (float)Y;
|
|
Result.Z = (float)Z;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
HMM_Vec4(float X, float Y, float Z, float W)
|
|
{
|
|
hmm_vec4 Result;
|
|
|
|
Result.X = X;
|
|
Result.Y = Y;
|
|
Result.Z = Z;
|
|
Result.W = W;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
HMM_Vec4i(int X, int Y, int Z, int W)
|
|
{
|
|
hmm_vec4 Result;
|
|
|
|
Result.X = (float)X;
|
|
Result.Y = (float)Y;
|
|
Result.Z = (float)Z;
|
|
Result.W = (float)W;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec2
|
|
HMM_AddVec2(hmm_vec2 Left, hmm_vec2 Right)
|
|
{
|
|
hmm_vec2 Result;
|
|
|
|
Result.X = Left.X + Right.X;
|
|
Result.Y = Left.Y + Right.Y;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
HMM_AddVec3(hmm_vec3 Left, hmm_vec3 Right)
|
|
{
|
|
hmm_vec3 Result;
|
|
|
|
Result.X = Left.X + Right.X;
|
|
Result.Y = Left.Y + Right.Y;
|
|
Result.Z = Left.Z + Right.Z;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
HMM_AddVec4(hmm_vec4 Left, hmm_vec4 Right)
|
|
{
|
|
hmm_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 hmm_vec2
|
|
HMM_SubtractVec2(hmm_vec2 Left, hmm_vec2 Right)
|
|
{
|
|
hmm_vec2 Result;
|
|
|
|
Result.X = Left.X - Right.X;
|
|
Result.Y = Left.Y - Right.Y;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
HMM_SubtractVec3(hmm_vec3 Left, hmm_vec3 Right)
|
|
{
|
|
hmm_vec3 Result;
|
|
|
|
Result.X = Left.X - Right.X;
|
|
Result.Y = Left.Y - Right.Y;
|
|
Result.Z = Left.Z - Right.Z;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
HMM_SubtractVec4(hmm_vec4 Left, hmm_vec4 Right)
|
|
{
|
|
hmm_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 hmm_vec2
|
|
HMM_MultiplyVec2(hmm_vec2 Left, hmm_vec2 Right)
|
|
{
|
|
hmm_vec2 Result;
|
|
|
|
Result.X = Left.X * Right.X;
|
|
Result.Y = Left.Y * Right.Y;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
HMM_MultiplyVec3(hmm_vec3 Left, hmm_vec3 Right)
|
|
{
|
|
hmm_vec3 Result;
|
|
|
|
Result.X = Left.Z * Right.X;
|
|
Result.Y = Left.Y * Right.Y;
|
|
Result.Z = Left.Z * Right.Z;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
HMM_MultiplyVec4(hmm_vec4 Left, hmm_vec4 Right)
|
|
{
|
|
hmm_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 hmm_vec2
|
|
HMM_DivideVec2(hmm_vec2 Left, hmm_vec2 Right)
|
|
{
|
|
hmm_vec2 Result;
|
|
|
|
Result.X = Left.X / Right.X;
|
|
Result.Y = Left.Y / Right.Y;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
HMM_DivideVec3(hmm_vec3 Left, hmm_vec3 Right)
|
|
{
|
|
hmm_vec3 Result;
|
|
|
|
Result.X = Left.X / Right.X;
|
|
Result.Y = Left.Y / Right.Y;
|
|
Result.Z = Left.Z / Right.Z;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
HMM_DivideVec4(hmm_vec4 Left, hmm_vec4 Right)
|
|
{
|
|
hmm_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 hmm_mat4
|
|
HMM_Mat4()
|
|
{
|
|
hmm_mat4 Result = {0};
|
|
|
|
return (Result);
|
|
}
|
|
|
|
hmm_mat4
|
|
HMM_Mat4d(float Diagonal)
|
|
{
|
|
hmm_mat4 Result;
|
|
|
|
int Rows;
|
|
for(Rows = 0; Rows < 4; ++Rows)
|
|
{
|
|
int Columns;
|
|
for(Columns = 0; Columns < 4; ++Columns)
|
|
{
|
|
Result.Elements[Rows][Columns] = 0.0f;
|
|
}
|
|
}
|
|
|
|
Result.Elements[0][0] = Diagonal;
|
|
Result.Elements[1][1] = Diagonal;
|
|
Result.Elements[2][2] = Diagonal;
|
|
Result.Elements[3][3] = Diagonal;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
hmm_mat4
|
|
HMM_MultiplyMat4(hmm_mat4 Left, hmm_mat4 Right)
|
|
{
|
|
hmm_mat4 Result = HMM_Mat4();
|
|
|
|
int Rows;
|
|
for(Rows = 0; Rows < 4; ++Rows)
|
|
{
|
|
int Columns;
|
|
for(Columns = 0; Columns < 4; ++Columns)
|
|
{
|
|
float Sum = 0;
|
|
int CurrentMatrice;
|
|
for(CurrentMatrice = 0; CurrentMatrice < 4; ++CurrentMatrice)
|
|
{
|
|
Sum += Right.Elements[Rows][CurrentMatrice] * Left.Elements[CurrentMatrice][Columns];
|
|
}
|
|
|
|
Result.Elements[Rows][Columns] = Sum;
|
|
}
|
|
}
|
|
|
|
return (Result);
|
|
}
|
|
|
|
hmm_vec4
|
|
HMM_MultiplyMat4ByVec4(hmm_mat4 Matrix, hmm_vec4 Vector)
|
|
{
|
|
hmm_vec4 Result = HMM_Vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
int Rows, Columns;
|
|
for(Rows = 0; Rows < 4; ++Rows)
|
|
{
|
|
float Sum = 0;
|
|
for(Columns = 0; Columns < 4; ++Columns)
|
|
{
|
|
Sum += Matrix.Elements[Rows][Columns] * Vector.Elements[Columns];
|
|
}
|
|
|
|
Result.Elements[Rows] = Sum;
|
|
}
|
|
|
|
return (Result);
|
|
}
|
|
|
|
hmm_mat4
|
|
HMM_Orthographic(float Left, float Right, float Bottom, float Top, float Near, float Far)
|
|
{
|
|
hmm_mat4 Result = HMM_Mat4d(1.0f);
|
|
|
|
Result.Elements[0][0] = 2.0f / (Right - Left);
|
|
Result.Elements[1][1] = 2.0f / (Top - Bottom);
|
|
Result.Elements[2][2] = 2.0f / (Near - Far);
|
|
|
|
Result.Elements[3][0] = (Left + Right) / (Left - Right);
|
|
Result.Elements[3][1] = (Bottom + Top) / (Bottom - Top);
|
|
Result.Elements[3][2] = (Far + Near) / (Near - Far);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
hmm_mat4
|
|
HMM_Perspective(float FOV, float AspectRatio, float Near, float Far)
|
|
{
|
|
hmm_mat4 Result = HMM_Mat4d(1.0f);
|
|
|
|
float TanThetaOver2 = HMM_TanF(FOV * (HMM_PI32 / 360.0f));
|
|
|
|
Result.Elements[0][0] = 1.0f / TanThetaOver2;
|
|
Result.Elements[1][1] = AspectRatio / TanThetaOver2;
|
|
Result.Elements[2][3] = -1.0f;
|
|
Result.Elements[2][2] = (Near + Far) / (Near - Far);
|
|
Result.Elements[3][2] = (2.0f * Near * Far) / (Near - Far);
|
|
Result.Elements[3][3] = 0.0f;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
hmm_mat4
|
|
HMM_Translate(hmm_vec3 Translation)
|
|
{
|
|
hmm_mat4 Result = HMM_Mat4d(1.0f);
|
|
|
|
Result.Elements[0][3] = Translation.X;
|
|
Result.Elements[1][3] = Translation.Y;
|
|
Result.Elements[2][3] = Translation.Z;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
hmm_mat4
|
|
HMM_Rotate(float Angle, hmm_vec3 Axis)
|
|
{
|
|
hmm_mat4 Result = HMM_Mat4d(1.0f);
|
|
|
|
Axis = HMM_Normalize(Axis);
|
|
|
|
float SinTheta = HMM_SinF(HMM_ToRadians(Angle));
|
|
float CosTheta = HMM_CosF(HMM_ToRadians(Angle));
|
|
float CosValue = 1.0f - CosTheta;
|
|
|
|
Result.Elements[0][0] = (Axis.X * Axis.X * CosValue) + CosTheta;
|
|
Result.Elements[0][1] = (Axis.X * Axis.Y * CosValue) + (Axis.Z * SinTheta);
|
|
Result.Elements[0][2] = (Axis.X * Axis.Z * CosValue) - (Axis.Y * SinTheta);
|
|
|
|
Result.Elements[1][0] = (Axis.Y * Axis.X * CosValue) - (Axis.Z * SinTheta);
|
|
Result.Elements[1][1] = (Axis.Y * Axis.Y * CosValue) + CosTheta;
|
|
Result.Elements[1][2] = (Axis.Y * Axis.Z * CosValue) + (Axis.X * SinTheta);
|
|
|
|
Result.Elements[2][0] = (Axis.Z * Axis.X * CosValue) + (Axis.Y * SinTheta);
|
|
Result.Elements[2][1] = (Axis.Z * Axis.Y * CosValue) - (Axis.X * SinTheta);
|
|
Result.Elements[2][2] = (Axis.Z * Axis.Z * CosValue) + CosTheta;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
hmm_mat4
|
|
HMM_LookAt(hmm_vec3 Eye, hmm_vec3 Center, hmm_vec3 Up)
|
|
{
|
|
hmm_mat4 Result = {0};
|
|
|
|
hmm_vec3 F = HMM_Normalize(HMM_SubtractVec3(Center, Eye));
|
|
hmm_vec3 S = HMM_Normalize(HMM_Cross(F, Up));
|
|
hmm_vec3 U = HMM_Cross(S, F);
|
|
|
|
Result.Elements[0][0] = S.X;
|
|
Result.Elements[0][1] = U.X;
|
|
Result.Elements[0][2] = -F.X;
|
|
|
|
Result.Elements[1][0] = S.Y;
|
|
Result.Elements[1][1] = U.Y;
|
|
Result.Elements[1][2] = -F.Y;
|
|
|
|
Result.Elements[2][0] = S.Z;
|
|
Result.Elements[2][1] = U.Z;
|
|
Result.Elements[2][2] = -F.Z;
|
|
|
|
Result.Elements[3][0] = -HMM_Dot(S, Eye);
|
|
Result.Elements[3][1] = -HMM_Dot(U, Eye);
|
|
Result.Elements[3][2] = HMM_Dot(F, Eye);
|
|
Result.Elements[3][3] = 1.0f;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
hmm_mat4
|
|
HMM_Scale(hmm_vec3 Scale)
|
|
{
|
|
hmm_mat4 Result = HMM_Mat4d(1.0f);
|
|
|
|
Result.Elements[0][0] = Scale.X;
|
|
Result.Elements[1][1] = Scale.Y;
|
|
Result.Elements[2][2] = Scale.Z;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
#ifdef HANDMADE_MATH_CPP_MODE
|
|
|
|
HINLINE hmm_vec2
|
|
Add(hmm_vec2 Left, hmm_vec2 Right)
|
|
{
|
|
hmm_vec2 Result = HMM_AddVec2(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
Add(hmm_vec3 Left, hmm_vec3 Right)
|
|
{
|
|
hmm_vec3 Result = HMM_AddVec3(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HMMDEF HINLINE hmm_vec4
|
|
Add(hmm_vec4 Left, hmm_vec4 Right)
|
|
{
|
|
hmm_vec4 Result = HMM_AddVec4(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec2
|
|
Subtract(hmm_vec2 Left, hmm_vec2 Right)
|
|
{
|
|
hmm_vec2 Result = HMM_SubtractVec2(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
Subtract(hmm_vec3 Left, hmm_vec3 Right)
|
|
{
|
|
hmm_vec3 Result = HMM_SubtractVec3(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
Subtract(hmm_vec4 Left, hmm_vec4 Right)
|
|
{
|
|
hmm_vec4 Result = HMM_SubtractVec4(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec2
|
|
Multiply(hmm_vec2 Left, hmm_vec2 Right)
|
|
{
|
|
hmm_vec2 Result = HMM_MultiplyVec2(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
Multiply(hmm_vec3 Left, hmm_vec3 Right)
|
|
{
|
|
hmm_vec3 Result = HMM_MultiplyVec3(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
Multiply(hmm_vec4 Left, hmm_vec4 Right)
|
|
{
|
|
hmm_vec4 Result = HMM_MultiplyVec4(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_mat4
|
|
Multiply(hmm_mat4 Left, hmm_mat4 Right)
|
|
{
|
|
hmm_mat4 Result = HMM_MultiplyMat4(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
Multiply(hmm_mat4 Matrix, hmm_vec4 Vector)
|
|
{
|
|
hmm_vec4 Result = HMM_MultiplyMat4ByVec4(Matrix, Vector);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec2
|
|
Divide(hmm_vec2 Left, hmm_vec2 Right)
|
|
{
|
|
hmm_vec2 Result = HMM_DivideVec2(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
Divide(hmm_vec3 Left, hmm_vec3 Right)
|
|
{
|
|
hmm_vec3 Result = HMM_DivideVec3(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
Divide(hmm_vec4 Left, hmm_vec4 Right)
|
|
{
|
|
hmm_vec4 Result = HMM_DivideVec4(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec2
|
|
operator+(hmm_vec2 Left, hmm_vec2 Right)
|
|
{
|
|
hmm_vec2 Result = Add(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
operator+(hmm_vec3 Left, hmm_vec3 Right)
|
|
{
|
|
hmm_vec3 Result = Add(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
operator+(hmm_vec4 Left, hmm_vec4 Right)
|
|
{
|
|
hmm_vec4 Result = Add(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec2
|
|
operator-(hmm_vec2 Left, hmm_vec2 Right)
|
|
{
|
|
hmm_vec2 Result = Subtract(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
operator-(hmm_vec3 Left, hmm_vec3 Right)
|
|
{
|
|
hmm_vec3 Result = Subtract(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
operator-(hmm_vec4 Left, hmm_vec4 Right)
|
|
{
|
|
hmm_vec4 Result = Subtract(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec2
|
|
operator*(hmm_vec2 Left, hmm_vec2 Right)
|
|
{
|
|
hmm_vec2 Result = Multiply(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
operator*(hmm_vec3 Left, hmm_vec3 Right)
|
|
{
|
|
hmm_vec3 Result = Multiply(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
operator*(hmm_vec3 Left, float Right)
|
|
{
|
|
hmm_vec3 Result;
|
|
|
|
Result.X = Right * Left.X;
|
|
Result.Y = Right * Left.Y;
|
|
Result.Z = Right * Left.Z;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec2
|
|
operator*(hmm_vec2 Left, float Right)
|
|
{
|
|
hmm_vec2 Result;
|
|
|
|
Result.X = Right * Left.X;
|
|
Result.Y = Right * Left.Y;
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
operator*(hmm_vec4 Left, hmm_vec4 Right)
|
|
{
|
|
hmm_vec4 Result = Multiply(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_mat4
|
|
operator*(hmm_mat4 Left, hmm_mat4 Right)
|
|
{
|
|
hmm_mat4 Result = Multiply(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
operator*(hmm_mat4 Matrix, hmm_vec4 Vector)
|
|
{
|
|
hmm_vec4 Result = Multiply(Matrix, Vector);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec2
|
|
operator/(hmm_vec2 Left, hmm_vec2 Right)
|
|
{
|
|
hmm_vec2 Result = Divide(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec3
|
|
operator/(hmm_vec3 Left, hmm_vec3 Right)
|
|
{
|
|
hmm_vec3 Result = Divide(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
HINLINE hmm_vec4
|
|
operator/(hmm_vec4 Left, hmm_vec4 Right)
|
|
{
|
|
hmm_vec4 Result = Divide(Left, Right);
|
|
|
|
return (Result);
|
|
}
|
|
|
|
#endif /* HANDMADE_MATH_CPP_MODE */
|
|
|
|
#endif /* HANDMADE_MATH_IMPLEMENTATION */ |