mirror of
https://github.com/HandmadeMath/HandmadeMath.git
synced 2025-12-28 07:34:32 +00:00
Add HMM_RotateV2
This commit is contained in:
@@ -2527,6 +2527,17 @@ static inline HMM_Quat HMM_QFromAxisAngle_LH(HMM_Vec3 Axis, float Angle)
|
||||
return HMM_QFromAxisAngle_RH(Axis, -Angle);
|
||||
}
|
||||
|
||||
COVERAGE(HMM_RotateV2, 1)
|
||||
static inline HMM_Vec2 HMM_RotateV2(HMM_Vec2 V, float Angle)
|
||||
{
|
||||
ASSERT_COVERED(HMM_RotateV2)
|
||||
|
||||
float sinA = HMM_SinF(Angle);
|
||||
float cosA = HMM_CosF(Angle);
|
||||
|
||||
return HMM_V2(V.X * cosA - V.Y * sinA, V.X * sinA + V.Y * cosA);
|
||||
}
|
||||
|
||||
// implementation from
|
||||
// https://blog.molecular-matters.com/2013/05/24/a-faster-quaternion-vector-multiplication/
|
||||
COVERAGE(HMM_RotateV3Q, 1)
|
||||
|
||||
@@ -155,9 +155,9 @@ INITIALIZER(_HMT_COVERCASE_FUNCNAME_INIT(name)) { \
|
||||
if (diff < -FLT_EPSILON || FLT_EPSILON < diff) { \
|
||||
_HMT_CASE_FAIL(); \
|
||||
if ((_msg)[0] == 0) { \
|
||||
printf("Expected %f, got %f", (_expected), actual); \
|
||||
printf("Expected %f, got %f (error: %.9g)", (_expected), actual, diff); \
|
||||
} else { \
|
||||
printf("%s: Expected %f, got %f", (_msg), (_expected), actual); \
|
||||
printf("%s: Expected %f, got %f (error: %.9g)", (_msg), (_expected), actual, diff); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -129,22 +129,22 @@ TEST(InvMatrix, InvGeneral)
|
||||
float Det = HMM_DeterminantM4(Matrix);
|
||||
EXPECT_FLOAT_EQ(Det, -80.0f);
|
||||
|
||||
EXPECT_FLOAT_EQ(Result.Elements[0][0], Expect.Elements[0][0]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[0][1], Expect.Elements[0][1]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[0][2], Expect.Elements[0][2]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[0][3], Expect.Elements[0][3]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[1][0], Expect.Elements[1][0]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[1][1], Expect.Elements[1][1]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[1][2], Expect.Elements[1][2]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[1][3], Expect.Elements[1][3]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[2][0], Expect.Elements[2][0]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[2][1], Expect.Elements[2][1]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[2][2], Expect.Elements[2][2]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[2][3], Expect.Elements[2][3]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[3][0], Expect.Elements[3][0]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[3][1], Expect.Elements[3][1]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[3][2], Expect.Elements[3][2]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[3][3], Expect.Elements[3][3]);
|
||||
EXPECT_NEAR(Result.Elements[0][0], Expect.Elements[0][0], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[0][1], Expect.Elements[0][1], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[0][2], Expect.Elements[0][2], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[0][3], Expect.Elements[0][3], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[1][0], Expect.Elements[1][0], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[1][1], Expect.Elements[1][1], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[1][2], Expect.Elements[1][2], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[1][3], Expect.Elements[1][3], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[2][0], Expect.Elements[2][0], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[2][1], Expect.Elements[2][1], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[2][2], Expect.Elements[2][2], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[2][3], Expect.Elements[2][3], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[3][0], Expect.Elements[3][0], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[3][1], Expect.Elements[3][1], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[3][2], Expect.Elements[3][2], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[3][3], Expect.Elements[3][3], 0.00001f);
|
||||
|
||||
#ifdef __cplusplus
|
||||
Inverse = HMM_InvGeneral(Matrix);
|
||||
@@ -153,22 +153,22 @@ TEST(InvMatrix, InvGeneral)
|
||||
Det = HMM_Determinant(Matrix);
|
||||
EXPECT_FLOAT_EQ(Det, -80.0f);
|
||||
|
||||
EXPECT_FLOAT_EQ(Result.Elements[0][0], Expect.Elements[0][0]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[0][1], Expect.Elements[0][1]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[0][2], Expect.Elements[0][2]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[0][3], Expect.Elements[0][3]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[1][0], Expect.Elements[1][0]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[1][1], Expect.Elements[1][1]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[1][2], Expect.Elements[1][2]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[1][3], Expect.Elements[1][3]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[2][0], Expect.Elements[2][0]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[2][1], Expect.Elements[2][1]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[2][2], Expect.Elements[2][2]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[2][3], Expect.Elements[2][3]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[3][0], Expect.Elements[3][0]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[3][1], Expect.Elements[3][1]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[3][2], Expect.Elements[3][2]);
|
||||
EXPECT_FLOAT_EQ(Result.Elements[3][3], Expect.Elements[3][3]);
|
||||
EXPECT_NEAR(Result.Elements[0][0], Expect.Elements[0][0], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[0][1], Expect.Elements[0][1], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[0][2], Expect.Elements[0][2], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[0][3], Expect.Elements[0][3], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[1][0], Expect.Elements[1][0], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[1][1], Expect.Elements[1][1], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[1][2], Expect.Elements[1][2], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[1][3], Expect.Elements[1][3], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[2][0], Expect.Elements[2][0], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[2][1], Expect.Elements[2][1], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[2][2], Expect.Elements[2][2], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[2][3], Expect.Elements[2][3], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[3][0], Expect.Elements[3][0], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[3][1], Expect.Elements[3][1], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[3][2], Expect.Elements[3][2], 0.00001f);
|
||||
EXPECT_NEAR(Result.Elements[3][3], Expect.Elements[3][3], 0.00001f);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,8 @@ TEST(Transformations, LookAt)
|
||||
{
|
||||
const float abs_error = 0.001f;
|
||||
|
||||
{ HMM_Mat4 result = HMM_LookAt_RH(HMM_V3(1.0f, 0.0f, 0.0f), HMM_V3(0.0f, 2.0f, 1.0f), HMM_V3(2.0f, 1.0f, 1.0f));
|
||||
{
|
||||
HMM_Mat4 result = HMM_LookAt_RH(HMM_V3(1.0f, 0.0f, 0.0f), HMM_V3(0.0f, 2.0f, 1.0f), HMM_V3(2.0f, 1.0f, 1.0f));
|
||||
|
||||
EXPECT_NEAR(result.Elements[0][0], 0.169031f, abs_error);
|
||||
EXPECT_NEAR(result.Elements[0][1], 0.897085f, abs_error);
|
||||
@@ -103,3 +104,30 @@ TEST(Transformations, LookAt)
|
||||
EXPECT_NEAR(result.Elements[3][3], 1.0f, abs_error);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Transformations, RotateV2)
|
||||
{
|
||||
HMM_Vec2 v2 = HMM_V2(1, 2);
|
||||
|
||||
float epsilon = 0.000001f;
|
||||
{
|
||||
HMM_Vec2 res = HMM_RotateV2(v2, HMM_AngleDeg(90));
|
||||
EXPECT_NEAR(res.X, -2.0f, epsilon);
|
||||
EXPECT_NEAR(res.Y, 1.0f, epsilon);
|
||||
}
|
||||
{
|
||||
HMM_Vec2 res = HMM_RotateV2(v2, HMM_AngleDeg(180));
|
||||
EXPECT_NEAR(res.X, -1.0f, epsilon);
|
||||
EXPECT_NEAR(res.Y, -2.0f, epsilon);
|
||||
}
|
||||
{
|
||||
HMM_Vec2 res = HMM_RotateV2(v2, HMM_AngleDeg(270));
|
||||
EXPECT_NEAR(res.X, 2.0f, epsilon);
|
||||
EXPECT_NEAR(res.Y, -1.0f, epsilon);
|
||||
}
|
||||
{
|
||||
HMM_Vec2 res = HMM_RotateV2(v2, HMM_AngleDeg(360));
|
||||
EXPECT_NEAR(res.X, 1.0f, epsilon);
|
||||
EXPECT_NEAR(res.Y, 2.0f, epsilon);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user