Add viewTransform transformation
This commit is contained in:
@@ -21,4 +21,6 @@ Matrix rotationZ(double angle);
|
|||||||
|
|
||||||
Matrix shearing(double Xy, double Xx, double Yx, double Yz, double Zx, double Zy);
|
Matrix shearing(double Xy, double Xx, double Yx, double Yz, double Zx, double Zy);
|
||||||
|
|
||||||
|
Matrix viewTransform(Tuple from, Tuple to, Tuple up);
|
||||||
|
|
||||||
#endif /* DORAYME_TRANSFORMATION_H */
|
#endif /* DORAYME_TRANSFORMATION_H */
|
||||||
@@ -81,4 +81,19 @@ Matrix shearing(double Xy, double Xz, double Yx, double Yz, double Zx, double Zy
|
|||||||
ret.set(2, 1, Zy);
|
ret.set(2, 1, Zy);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix viewTransform(Tuple from, Tuple to, Tuple up)
|
||||||
|
{
|
||||||
|
Tuple forward = (to - from).normalise();
|
||||||
|
Tuple left = forward.cross(up.normalise());
|
||||||
|
Tuple true_up = left.cross(forward);
|
||||||
|
|
||||||
|
double orientationValues[] = { left.x, left.y, left.z, 0,
|
||||||
|
true_up.x, true_up.y, true_up.z, 0,
|
||||||
|
-forward.x, -forward.y, -forward.z, 0,
|
||||||
|
0, 0, 0, 1 };
|
||||||
|
Matrix orientation = Matrix4(orientationValues);
|
||||||
|
|
||||||
|
return orientation * translation(-from.x, -from.y, -from.z);
|
||||||
}
|
}
|
||||||
@@ -190,6 +190,61 @@ TEST(TransformationTest, Chained_transformation_must_be_applied_in_reverse_order
|
|||||||
ASSERT_EQ(T * p, Point(15, 0, 7));
|
ASSERT_EQ(T * p, Point(15, 0, 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(TransformationTest, The_transformation_matrix_for_the_default_orientation)
|
||||||
|
{
|
||||||
|
Tuple from = Point(0, 0, 0);
|
||||||
|
Tuple to = Point(0, 0, -1);
|
||||||
|
Tuple up = Vector(0, 1, 0);
|
||||||
|
|
||||||
|
Matrix t = viewTransform(from, to, up);
|
||||||
|
|
||||||
|
ASSERT_EQ(t, Matrix4().identity());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(TransformationTest, A_view_transformation_matrix_looking_in_positive_z_direction)
|
||||||
|
{
|
||||||
|
Tuple from = Point(0, 0, 0);
|
||||||
|
Tuple to = Point(0, 0, 1);
|
||||||
|
Tuple up = Vector(0, 1, 0);
|
||||||
|
|
||||||
|
Matrix t = viewTransform(from, to, up);
|
||||||
|
|
||||||
|
ASSERT_EQ(t, scaling(-1, 1, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TransformationTest, The_view_transformation_move_the_world)
|
||||||
|
{
|
||||||
|
Tuple from = Point(0, 0, 8);
|
||||||
|
Tuple to = Point(0, 0, 0);
|
||||||
|
Tuple up = Vector(0, 1, 0);
|
||||||
|
|
||||||
|
Matrix t = viewTransform(from, to, up);
|
||||||
|
|
||||||
|
ASSERT_EQ(t, translation(0, 0, -8));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TransformationTest, An_arbitrary_view_transformation)
|
||||||
|
{
|
||||||
|
Tuple from = Point(1, 3, 2);
|
||||||
|
Tuple to = Point(4, -2, 8);
|
||||||
|
Tuple up = Vector(1, 1, 0);
|
||||||
|
|
||||||
|
Matrix t = viewTransform(from, to, up);
|
||||||
|
|
||||||
|
double values[] = {-0.50709, 0.50709, 0.67612, -2.36643,
|
||||||
|
0.76772, 0.60609, 0.12122, -2.82843,
|
||||||
|
-0.35857, 0.59761, -0.71714, 0.00000,
|
||||||
|
0.00000, 0.00000, 0.00000, 1.00000};
|
||||||
|
|
||||||
|
/* Temporary lower the precision */
|
||||||
|
set_equal_precision(0.00001);
|
||||||
|
|
||||||
|
ASSERT_EQ(t, Matrix4(values));
|
||||||
|
|
||||||
|
set_equal_precision(FLT_EPSILON);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(TransformationTest, Check_that_deg_to_rad_is_working)
|
TEST(TransformationTest, Check_that_deg_to_rad_is_working)
|
||||||
{
|
{
|
||||||
double angle180 = deg_to_rad(180);
|
double angle180 = deg_to_rad(180);
|
||||||
@@ -199,4 +254,5 @@ TEST(TransformationTest, Check_that_deg_to_rad_is_working)
|
|||||||
ASSERT_EQ(angle180, M_PI);
|
ASSERT_EQ(angle180, M_PI);
|
||||||
ASSERT_EQ(angle90, M_PI / 2.);
|
ASSERT_EQ(angle90, M_PI / 2.);
|
||||||
ASSERT_EQ(angle270, M_PI * 1.5);
|
ASSERT_EQ(angle270, M_PI * 1.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user