diff --git a/HandmadeMath.h b/HandmadeMath.h index 792257d..e428b2e 100644 --- a/HandmadeMath.h +++ b/HandmadeMath.h @@ -4,6 +4,8 @@ This is a single header file with a bunch of useful functions for game and graphics math operations. + All angles are in radians. + ============================================================================= You MUST @@ -544,6 +546,16 @@ HMM_INLINE float HMM_PowerF(float Base, float Exponent) * Utility functions */ +COVERAGE(HMM_ToDegrees, 1) +HMM_INLINE float HMM_ToDegrees(float Radians) +{ + ASSERT_COVERED(HMM_ToDegrees); + + float Result = Radians * (180.0f / HMM_PI32); + + return (Result); +} + COVERAGE(HMM_ToRadians, 1) HMM_INLINE float HMM_ToRadians(float Degrees) { @@ -1404,7 +1416,7 @@ HMM_INLINE hmm_mat4 HMM_Orthographic(float Left, float Right, float Bottom, floa } COVERAGE(HMM_Perspective, 1) -HMM_INLINE hmm_mat4 HMM_Perspective(float FOV, float AspectRatio, float Near, float Far) +HMM_INLINE hmm_mat4 HMM_Perspective(float FOVRadians, float AspectRatio, float Near, float Far) { ASSERT_COVERED(HMM_Perspective); @@ -1412,7 +1424,7 @@ HMM_INLINE hmm_mat4 HMM_Perspective(float FOV, float AspectRatio, float Near, fl // See https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml - float Cotangent = 1.0f / HMM_TanF(FOV * (HMM_PI32 / 360.0f)); + float Cotangent = 1.0f / HMM_TanF(FOVRadians / 2.0f); Result.Elements[0][0] = Cotangent / AspectRatio; Result.Elements[1][1] = Cotangent; @@ -1438,7 +1450,7 @@ HMM_INLINE hmm_mat4 HMM_Translate(hmm_vec3 Translation) return (Result); } -HMM_EXTERN hmm_mat4 HMM_Rotate(float Angle, hmm_vec3 Axis); +HMM_EXTERN hmm_mat4 HMM_Rotate(float AngleRadians, hmm_vec3 Axis); COVERAGE(HMM_Scale, 1) HMM_INLINE hmm_mat4 HMM_Scale(hmm_vec3 Scale) @@ -1675,7 +1687,7 @@ HMM_INLINE hmm_quaternion HMM_NLerp(hmm_quaternion Left, float Time, hmm_quatern HMM_EXTERN hmm_quaternion HMM_Slerp(hmm_quaternion Left, float Time, hmm_quaternion Right); HMM_EXTERN hmm_mat4 HMM_QuaternionToMat4(hmm_quaternion Left); HMM_EXTERN hmm_quaternion HMM_Mat4ToQuaternion(hmm_mat4 Left); -HMM_EXTERN hmm_quaternion HMM_QuaternionFromAxisAngle(hmm_vec3 Axis, float AngleOfRotation); +HMM_EXTERN hmm_quaternion HMM_QuaternionFromAxisAngle(hmm_vec3 Axis, float AngleOfRotationRadians); #ifdef __cplusplus } @@ -2978,7 +2990,7 @@ hmm_mat4 HMM_DivideMat4f(hmm_mat4 Matrix, float Scalar) #endif COVERAGE(HMM_Rotate, 1) -hmm_mat4 HMM_Rotate(float Angle, hmm_vec3 Axis) +hmm_mat4 HMM_Rotate(float AngleRadians, hmm_vec3 Axis) { ASSERT_COVERED(HMM_Rotate); @@ -2986,8 +2998,8 @@ hmm_mat4 HMM_Rotate(float Angle, hmm_vec3 Axis) Axis = HMM_NormalizeVec3(Axis); - float SinTheta = HMM_SinF(HMM_ToRadians(Angle)); - float CosTheta = HMM_CosF(HMM_ToRadians(Angle)); + float SinTheta = HMM_SinF(AngleRadians); + float CosTheta = HMM_CosF(AngleRadians); float CosValue = 1.0f - CosTheta; Result.Elements[0][0] = (Axis.X * Axis.X * CosValue) + CosTheta; @@ -3205,17 +3217,17 @@ hmm_quaternion HMM_Mat4ToQuaternion(hmm_mat4 M) } COVERAGE(HMM_QuaternionFromAxisAngle, 1) -hmm_quaternion HMM_QuaternionFromAxisAngle(hmm_vec3 Axis, float AngleOfRotation) +hmm_quaternion HMM_QuaternionFromAxisAngle(hmm_vec3 Axis, float AngleOfRotationRadians) { ASSERT_COVERED(HMM_QuaternionFromAxisAngle); hmm_quaternion Result; hmm_vec3 AxisNormalized = HMM_NormalizeVec3(Axis); - float SineOfRotation = HMM_SinF(AngleOfRotation / 2.0f); + float SineOfRotation = HMM_SinF(AngleOfRotationRadians / 2.0f); Result.XYZ = HMM_MultiplyVec3f(AxisNormalized, SineOfRotation); - Result.W = HMM_CosF(AngleOfRotation / 2.0f); + Result.W = HMM_CosF(AngleOfRotationRadians / 2.0f); return (Result); } diff --git a/test/categories/Projection.h b/test/categories/Projection.h index 828ce98..456ead9 100644 --- a/test/categories/Projection.h +++ b/test/categories/Projection.h @@ -15,7 +15,7 @@ TEST(Projection, Orthographic) TEST(Projection, Perspective) { - hmm_mat4 projection = HMM_Perspective(90.0f, 2.0f, 5.0f, 15.0f); + hmm_mat4 projection = HMM_Perspective(HMM_ToRadians(90.0f), 2.0f, 5.0f, 15.0f); { hmm_vec3 original = HMM_Vec3(5.0f, 5.0f, -15.0f); diff --git a/test/categories/QuaternionOps.h b/test/categories/QuaternionOps.h index a373106..3cd937c 100644 --- a/test/categories/QuaternionOps.h +++ b/test/categories/QuaternionOps.h @@ -111,7 +111,7 @@ TEST(QuaternionOps, Mat4ToQuat) // Rotate 90 degrees on the X axis { - hmm_mat4 m = HMM_Rotate(90, HMM_Vec3(1, 0, 0)); + hmm_mat4 m = HMM_Rotate(HMM_ToRadians(90.0f), HMM_Vec3(1, 0, 0)); hmm_quaternion result = HMM_Mat4ToQuaternion(m); float cosf = 0.707107f; // cos(90/2 degrees) @@ -125,7 +125,7 @@ TEST(QuaternionOps, Mat4ToQuat) // Rotate 90 degrees on the Y axis (axis not normalized, just for fun) { - hmm_mat4 m = HMM_Rotate(90, HMM_Vec3(0, 2, 0)); + hmm_mat4 m = HMM_Rotate(HMM_ToRadians(90.0f), HMM_Vec3(0, 2, 0)); hmm_quaternion result = HMM_Mat4ToQuaternion(m); float cosf = 0.707107f; // cos(90/2 degrees) @@ -139,7 +139,7 @@ TEST(QuaternionOps, Mat4ToQuat) // Rotate 90 degrees on the Z axis { - hmm_mat4 m = HMM_Rotate(90, HMM_Vec3(0, 0, 1)); + hmm_mat4 m = HMM_Rotate(HMM_ToRadians(90.0f), HMM_Vec3(0, 0, 1)); hmm_quaternion result = HMM_Mat4ToQuaternion(m); float cosf = 0.707107f; // cos(90/2 degrees) @@ -153,7 +153,7 @@ TEST(QuaternionOps, Mat4ToQuat) // Rotate 45 degrees on the X axis (this hits case 4) { - hmm_mat4 m = HMM_Rotate(45, HMM_Vec3(1, 0, 0)); + hmm_mat4 m = HMM_Rotate(HMM_ToRadians(45.0f), HMM_Vec3(1, 0, 0)); hmm_quaternion result = HMM_Mat4ToQuaternion(m); float cosf = 0.9238795325f; // cos(90/2 degrees) diff --git a/test/categories/ScalarMath.h b/test/categories/ScalarMath.h index d5350fe..bc2b7e3 100644 --- a/test/categories/ScalarMath.h +++ b/test/categories/ScalarMath.h @@ -36,6 +36,13 @@ TEST(ScalarMath, Trigonometry) // checking that things work by default. } +TEST(ScalarMath, ToDegrees) +{ + EXPECT_FLOAT_EQ(HMM_ToDegrees(0.0f), 0.0f); + EXPECT_FLOAT_EQ(HMM_ToDegrees(HMM_PI32), 180.0f); + EXPECT_FLOAT_EQ(HMM_ToDegrees(-HMM_PI32), -180.0f); +} + TEST(ScalarMath, ToRadians) { EXPECT_FLOAT_EQ(HMM_ToRadians(0.0f), 0.0f); diff --git a/test/categories/Transformation.h b/test/categories/Transformation.h index 19ce7f2..6e89cd8 100644 --- a/test/categories/Transformation.h +++ b/test/categories/Transformation.h @@ -17,21 +17,23 @@ TEST(Transformations, Rotate) { hmm_vec3 original = HMM_Vec3(1.0f, 1.0f, 1.0f); - hmm_mat4 rotateX = HMM_Rotate(90, HMM_Vec3(1, 0, 0)); + float angle = HMM_ToRadians(90.0f); + + hmm_mat4 rotateX = HMM_Rotate(angle, HMM_Vec3(1, 0, 0)); hmm_vec4 rotatedX = HMM_MultiplyMat4ByVec4(rotateX, HMM_Vec4v(original, 1)); EXPECT_FLOAT_EQ(rotatedX.X, 1.0f); EXPECT_FLOAT_EQ(rotatedX.Y, -1.0f); EXPECT_FLOAT_EQ(rotatedX.Z, 1.0f); EXPECT_FLOAT_EQ(rotatedX.W, 1.0f); - hmm_mat4 rotateY = HMM_Rotate(90, HMM_Vec3(0, 1, 0)); + hmm_mat4 rotateY = HMM_Rotate(angle, HMM_Vec3(0, 1, 0)); hmm_vec4 rotatedY = HMM_MultiplyMat4ByVec4(rotateY, HMM_Vec4v(original, 1)); EXPECT_FLOAT_EQ(rotatedY.X, 1.0f); EXPECT_FLOAT_EQ(rotatedY.Y, 1.0f); EXPECT_FLOAT_EQ(rotatedY.Z, -1.0f); EXPECT_FLOAT_EQ(rotatedY.W, 1.0f); - hmm_mat4 rotateZ = HMM_Rotate(90, HMM_Vec3(0, 0, 1)); + hmm_mat4 rotateZ = HMM_Rotate(angle, HMM_Vec3(0, 0, 1)); hmm_vec4 rotatedZ = HMM_MultiplyMat4ByVec4(rotateZ, HMM_Vec4v(original, 1)); EXPECT_FLOAT_EQ(rotatedZ.X, -1.0f); EXPECT_FLOAT_EQ(rotatedZ.Y, 1.0f);