diff --git a/HandmadeMath.h b/HandmadeMath.h index 4e1d1ff..ee59212 100644 --- a/HandmadeMath.h +++ b/HandmadeMath.h @@ -233,7 +233,7 @@ extern "C" #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_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)) @@ -387,7 +387,10 @@ typedef hmm_mat4 hmm_m4; HMMDEF float HMM_SinF(float Angle); HMMDEF float HMM_TanF(float Angle); +HMMDEF float HMM_ATanF(float Theta); +HMMDEF float HMM_ATanF2(float Theta, float Theta2); HMMDEF float HMM_CosF(float Angle); +HMMDEF float HMM_ACosF(float Theta); HMMDEF float HMM_ExpF(float Float); HMMDEF float HMM_LogF(float Float); @@ -607,6 +610,15 @@ HMM_SinF(float Angle) return (Result); } +HINLINE float +HMM_ACosF(float Theta) +{ + float Result = 0.0f; + float Theta2 = HMM_SquareRootF((1.0f + Theta) * (1.0f - Theta)); + Result = HMM_ATanF2(Theta2, Theta); + return(Result); +} + HINLINE float HMM_CosF(float Angle) { @@ -625,6 +637,36 @@ HMM_TanF(float Radians) return (Result); } +HINLINE float +HMM_ATanF(float Theta) +{ + float u = Theta*Theta; + float u2 = u*u; + float u3 = u2*u; + float u4 = u3*u; + float f = 1.0f + 0.33288950512027f*u - 0.08467922817644f*u2 + 0.03252232640125f*u3 - 0.00749305860992f*u4; + return Theta / f; +} + +HINLINE float +HMM_ATanF2(float Theta, float Theta2) +{ + if (HMM_ABS(Theta2) > HMM_ABS(Theta)) { + float a = HMM_ATanF(Theta / Theta2); + if (Theta2 > 0.0f) + return a; + else + return Theta > 0.0f ? a + HMM_PI : a - HMM_PI; + } + else { + float a = HMM_ATanF(Theta2 / Theta); + if (Theta2 > 0.0f) + return Theta > 0.0f ? (HMM_PI/2) - a : - (HMM_PI/2) - a; + else + return Theta > 0.0f ? (HMM_PI/2) + a : - (HMM_PI/2) + a; + } +} + HINLINE float HMM_ExpF(float Float) { @@ -1536,14 +1578,42 @@ HMM_DotQuat(hmm_quaternion QuaternionOne, hmm_quaternion QuaternionTwo) return(Result); } -/**HMM_Slerp(hmm_quaternion QuaternionOne, hmm_quaternion QuaternionTwo, float time) +HINLINE hmm_quaternion +HMM_Slerp(hmm_quaternion QuaternionOne, hmm_quaternion QuaternionTwo, float time) { hmm_quaternion Result = {0}; + hmm_quaternion QuaternionLeft = {0}; + hmm_quaternion QuaternionRight = {0}; - float Theta = HMM_DotQuat(QuaternionOne, QuaternionTwo); + float Cos_Theta = HMM_DotQuat(QuaternionOne, QuaternionTwo); + float angle = HMM_ACosF(Cos_Theta); + + float s1 = HMM_SinF(1.0f - time*angle); + float s2 = HMM_SinF(time*angle); + float is = 1.0f / HMM_SinF(angle); + + QuaternionLeft.X = QuaternionTwo.X * s1; + QuaternionLeft.Y = QuaternionTwo.Y * s1; + QuaternionLeft.Z = QuaternionTwo.Z * s1; + QuaternionLeft.W = QuaternionTwo.W * s1; + + QuaternionRight.X = QuaternionTwo.X * s2; + QuaternionRight.Y = QuaternionTwo.Y * s2; + QuaternionRight.Z = QuaternionTwo.Z * s2; + QuaternionRight.W = QuaternionTwo.W * s2; + + Result.X = QuaternionLeft.X + QuaternionRight.X; + Result.Y = QuaternionLeft.Y + QuaternionRight.Y; + Result.Z = QuaternionLeft.Z + QuaternionRight.Z; + Result.W = QuaternionLeft.W + QuaternionRight.W; + + Result.X = Result.X * is; + Result.Y = Result.Y * is; + Result.Z = Result.Z * is; + Result.W = Result.W * is; return(Result); -}**/ +} #ifdef HANDMADE_MATH_CPP_MODE diff --git a/test/.vs/HandmadeMath/v14/.suo b/test/.vs/HandmadeMath/v14/.suo deleted file mode 100644 index 2445682..0000000 Binary files a/test/.vs/HandmadeMath/v14/.suo and /dev/null differ diff --git a/test/HandmadeMath.cpp b/test/HandmadeMath.cpp index a8b7747..769275e 100644 --- a/test/HandmadeMath.cpp +++ b/test/HandmadeMath.cpp @@ -2,90 +2,25 @@ #define HANDMADE_MATH_IMPLEMENTATION #define HANDMADE_MATH_CPP_MODE #define HANDMADE_MATH_NO_INLINE +#define GB_MATH_IMPLEMENTATION #include "../HandmadeMath.h" - -#ifndef gb_abs -#define gb_abs(x) ((x) > 0 ? (x) : -(x)) -#endif - -#define GB_MATH_TAU_OVER_2 3.14159265358979323846264338327950288f -#define GB_MATH_TAU_OVER_4 1.570796326794896619231321691639751442f -#define GB_MATH_TAU_OVER_8 0.785398163397448309615660845819875721f - -static float gb_arctan(float a); -static float gb_arctan2(float y, float x); - -float gb_arccos(float a) { return gb_arctan2(HMM_SquareRootF((1.0f + a) * (1.0 - a)), a); } - -float -gb_arctan(float a) -{ - float u = a*a; - float u2 = u*u; - float u3 = u2*u; - float u4 = u3*u; - float f = 1.0f + 0.33288950512027f*u - 0.08467922817644f*u2 + 0.03252232640125f*u3 - 0.00749305860992f*u4; - return a / f; -} - -float -gb_arctan2(float y, float x) -{ - if (gb_abs(x) > gb_abs(y)) { - float a = gb_arctan(y / x); - if (x > 0.0f) - return a; - else - return y > 0.0f ? a + GB_MATH_TAU_OVER_2 : a - GB_MATH_TAU_OVER_2; - } - else { - float a = gb_arctan(x / y); - if (x > 0.0f) - return y > 0.0f ? GB_MATH_TAU_OVER_4 - a : -GB_MATH_TAU_OVER_4 - a; - else - return y > 0.0f ? GB_MATH_TAU_OVER_4 + a : -GB_MATH_TAU_OVER_4 + a; - } -} +#include "../gb_math.h" int main() { - hmm_quaternion q1 = { 0,1,0 }; - hmm_quaternion q2 = { 0,0,0 }; - hmm_quaternion Result = { 0 }; + hmm_quaternion q1 = { 1,0,0,0 }; + hmm_quaternion q2 = { 0,1,0,0 }; + + gbQuat q3 = { 1,0,0,0 }; + gbQuat q4 = { 0,1,0,0 }; + gbQuat result2 = { 0 }; + float time = 0.5f; - hmm_quaternion x, y, z; - float cos_theta, angle; - float s1, s2, is; + hmm_quaternion Result = HMM_Slerp(q1, q2, time); + gb_quat_slerp(&result2, q3, q4, time); - z = q2; - cos_theta = HMM_DotQuat(q1, q2); - angle = gb_arccos(cos_theta); - - s1 = HMM_SinF(1.0f - time*angle); - s2 = HMM_SinF(time*angle); - is = 1.0f / HMM_SinF(angle); - - x.X = z.X * s1; - x.Y = z.Y * s1; - x.Z = z.Z * s1; - x.W = z.W * s1; - - y.X = z.X * s2; - y.Y = z.Y * s2; - y.Z = z.Z * s2; - y.W = z.W * s2; - - Result.X = x.X + y.X; - Result.Y = x.Y + y.Y; - Result.Z = x.Z + y.Z; - Result.W = x.W + y.W; - - Result.X = Result.X * is; - Result.Y = Result.Y * is; - Result.Z = Result.Z * is; - Result.W = Result.W * is; return 0; } \ No newline at end of file diff --git a/test/build.bat b/test/build.bat deleted file mode 100644 index 5200276..0000000 --- a/test/build.bat +++ /dev/null @@ -1 +0,0 @@ -cl -Zi HandmadeMath.cpp \ No newline at end of file diff --git a/test/vc140.pdb b/test/vc140.pdb deleted file mode 100644 index 7fe4e7b..0000000 Binary files a/test/vc140.pdb and /dev/null differ