mirror of
https://github.com/HandmadeMath/HandmadeMath.git
synced 2026-07-16 04:40:33 +00:00
Finished slerp implementation, next is NLerp
This commit is contained in:
@@ -233,7 +233,7 @@ extern "C"
|
|||||||
|
|
||||||
#define HMM_MIN(a, b) (a) > (b) ? (b) : (a)
|
#define HMM_MIN(a, b) (a) > (b) ? (b) : (a)
|
||||||
#define HMM_MAX(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_MOD(a, m) ((a) % (m)) >= 0 ? ((a) % (m)) : (((a) % (m)) + (m))
|
||||||
#define HMM_SQUARE(x) ((x) * (x))
|
#define HMM_SQUARE(x) ((x) * (x))
|
||||||
|
|
||||||
@@ -387,7 +387,10 @@ typedef hmm_mat4 hmm_m4;
|
|||||||
|
|
||||||
HMMDEF float HMM_SinF(float Angle);
|
HMMDEF float HMM_SinF(float Angle);
|
||||||
HMMDEF float HMM_TanF(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_CosF(float Angle);
|
||||||
|
HMMDEF float HMM_ACosF(float Theta);
|
||||||
HMMDEF float HMM_ExpF(float Float);
|
HMMDEF float HMM_ExpF(float Float);
|
||||||
HMMDEF float HMM_LogF(float Float);
|
HMMDEF float HMM_LogF(float Float);
|
||||||
|
|
||||||
@@ -607,6 +610,15 @@ HMM_SinF(float Angle)
|
|||||||
return (Result);
|
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
|
HINLINE float
|
||||||
HMM_CosF(float Angle)
|
HMM_CosF(float Angle)
|
||||||
{
|
{
|
||||||
@@ -625,6 +637,36 @@ HMM_TanF(float Radians)
|
|||||||
return (Result);
|
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
|
HINLINE float
|
||||||
HMM_ExpF(float Float)
|
HMM_ExpF(float Float)
|
||||||
{
|
{
|
||||||
@@ -1536,14 +1578,42 @@ HMM_DotQuat(hmm_quaternion QuaternionOne, hmm_quaternion QuaternionTwo)
|
|||||||
return(Result);
|
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 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);
|
return(Result);
|
||||||
}**/
|
}
|
||||||
|
|
||||||
#ifdef HANDMADE_MATH_CPP_MODE
|
#ifdef HANDMADE_MATH_CPP_MODE
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -2,90 +2,25 @@
|
|||||||
#define HANDMADE_MATH_IMPLEMENTATION
|
#define HANDMADE_MATH_IMPLEMENTATION
|
||||||
#define HANDMADE_MATH_CPP_MODE
|
#define HANDMADE_MATH_CPP_MODE
|
||||||
#define HANDMADE_MATH_NO_INLINE
|
#define HANDMADE_MATH_NO_INLINE
|
||||||
|
#define GB_MATH_IMPLEMENTATION
|
||||||
#include "../HandmadeMath.h"
|
#include "../HandmadeMath.h"
|
||||||
|
#include "../gb_math.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
hmm_quaternion q1 = { 0,1,0 };
|
hmm_quaternion q1 = { 1,0,0,0 };
|
||||||
hmm_quaternion q2 = { 0,0,0 };
|
hmm_quaternion q2 = { 0,1,0,0 };
|
||||||
hmm_quaternion Result = { 0 };
|
|
||||||
|
gbQuat q3 = { 1,0,0,0 };
|
||||||
|
gbQuat q4 = { 0,1,0,0 };
|
||||||
|
gbQuat result2 = { 0 };
|
||||||
|
|
||||||
float time = 0.5f;
|
float time = 0.5f;
|
||||||
|
|
||||||
hmm_quaternion x, y, z;
|
hmm_quaternion Result = HMM_Slerp(q1, q2, time);
|
||||||
float cos_theta, angle;
|
gb_quat_slerp(&result2, q3, q4, time);
|
||||||
float s1, s2, is;
|
|
||||||
|
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
cl -Zi HandmadeMath.cpp
|
|
||||||
BIN
test/vc140.pdb
BIN
test/vc140.pdb
Binary file not shown.
Reference in New Issue
Block a user