Add Matrix::LookAt (flutter/engine#37361)
This commit is contained in:
@@ -424,6 +424,52 @@ TEST(GeometryTest, MatrixIsAligned) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(GeometryTest, MatrixLookAt) {
|
||||
{
|
||||
auto m = Matrix::MakeLookAt(Vector3(0, 0, -1), Vector3(0, 0, 1),
|
||||
Vector3(0, 1, 0));
|
||||
auto expected = Matrix{
|
||||
1, 0, 0, 0, //
|
||||
0, 1, 0, 0, //
|
||||
0, 0, 1, 0, //
|
||||
0, 0, 1, 1, //
|
||||
};
|
||||
ASSERT_MATRIX_NEAR(m, expected);
|
||||
}
|
||||
|
||||
// Sideways tilt.
|
||||
{
|
||||
auto m = Matrix::MakeLookAt(Vector3(0, 0, -1), Vector3(0, 0, 1),
|
||||
Vector3(1, 1, 0).Normalize());
|
||||
|
||||
// clang-format off
|
||||
auto expected = Matrix{
|
||||
k1OverSqrt2, k1OverSqrt2, 0, 0,
|
||||
-k1OverSqrt2, k1OverSqrt2, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 1, 1,
|
||||
};
|
||||
// clang-format on
|
||||
ASSERT_MATRIX_NEAR(m, expected);
|
||||
}
|
||||
|
||||
// Half way between +x and -y, yaw 90
|
||||
{
|
||||
auto m =
|
||||
Matrix::MakeLookAt(Vector3(), Vector3(10, -10, 0), Vector3(0, 0, -1));
|
||||
|
||||
// clang-format off
|
||||
auto expected = Matrix{
|
||||
-k1OverSqrt2, 0, k1OverSqrt2, 0,
|
||||
-k1OverSqrt2, 0, -k1OverSqrt2, 0,
|
||||
0, -1, 0, 0,
|
||||
0, 0, 0, 1,
|
||||
};
|
||||
// clang-format on
|
||||
ASSERT_MATRIX_NEAR(m, expected);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(GeometryTest, QuaternionLerp) {
|
||||
auto q1 = Quaternion{{0.0, 0.0, 1.0}, 0.0};
|
||||
auto q2 = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
|
||||
|
||||
@@ -435,6 +435,23 @@ struct Matrix {
|
||||
return MakePerspective(fov_y, static_cast<Scalar>(size.width) / size.height,
|
||||
z_near, z_far);
|
||||
}
|
||||
|
||||
static constexpr Matrix MakeLookAt(Vector3 position,
|
||||
Vector3 target,
|
||||
Vector3 up) {
|
||||
Vector3 forward = (target - position).Normalize();
|
||||
Vector3 right = up.Cross(forward);
|
||||
up = forward.Cross(right);
|
||||
|
||||
// clang-format off
|
||||
return {
|
||||
right.x, up.x, forward.x, 0.0f,
|
||||
right.y, up.y, forward.y, 0.0f,
|
||||
right.z, up.z, forward.z, 0.0f,
|
||||
-right.Dot(position), -up.Dot(position), -forward.Dot(position), 1.0f
|
||||
};
|
||||
// clang-format on
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(struct Matrix) == sizeof(Scalar) * 16,
|
||||
|
||||
Reference in New Issue
Block a user