mirror of
https://github.com/HandmadeMath/HandmadeMath.git
synced 2025-12-28 07:34:32 +00:00
Make everything use radians (#107)
* Make everything use radians (and provide an escape hatch) * Fix tests * Add tests for forcing degrees * Add degrees tests for windows * Remove coverage macro; just always use radians * Update forward declarations and clean up tests * Tell the user that angles are in radians
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user