[ADD] Add View treansform
This commit is contained in:
@@ -397,6 +397,24 @@ Matrix Matrix::shearing(double a_xy, double a_xz, double a_yx, double a_yz, doub
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
Matrix Matrix::view_transform(Tuple a_from, Tuple a_to, Tuple an_up)
|
||||||
|
{
|
||||||
|
Tuple the_forward = (a_to - a_from).normalize();
|
||||||
|
Tuple the_up_normalized = an_up.normalize();
|
||||||
|
Tuple the_left = the_forward.cross(the_up_normalized);
|
||||||
|
Tuple the_true_up = the_left.cross(the_forward);
|
||||||
|
Matrix the_orientation = {
|
||||||
|
{ the_left.x(), the_left.y(), the_left.z(), 0},
|
||||||
|
{ the_true_up.x(), the_true_up.y(), the_true_up.z(), 0},
|
||||||
|
{-the_forward.x(), -the_forward.y(), -the_forward.z(), 0},
|
||||||
|
{ 0, 0, 0, 1}
|
||||||
|
};
|
||||||
|
|
||||||
|
return the_orientation * translation(-a_from.x(), -a_from.y(), -a_from.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
bool Matrix::validate_dimensions(const std::initializer_list<std::initializer_list<double>> &a_values) const
|
bool Matrix::validate_dimensions(const std::initializer_list<std::initializer_list<double>> &a_values) const
|
||||||
{
|
{
|
||||||
for (const auto &the_row : a_values)
|
for (const auto &the_row : a_values)
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ namespace Raytracer
|
|||||||
static Matrix rotation_y(double a_radians);
|
static Matrix rotation_y(double a_radians);
|
||||||
static Matrix rotation_z(double a_radians);
|
static Matrix rotation_z(double a_radians);
|
||||||
static Matrix shearing(double a_xy, double a_xz, double a_yx, double a_yz, double a_zx, double a_zy);
|
static Matrix shearing(double a_xy, double a_xz, double a_yx, double a_yz, double a_zx, double a_zy);
|
||||||
|
static Matrix view_transform(Tuple a_from, Tuple a_to, Tuple an_up);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool validate_dimensions(const std::initializer_list<std::initializer_list<double>> &a_values) const;
|
bool validate_dimensions(const std::initializer_list<std::initializer_list<double>> &a_values) const;
|
||||||
|
|||||||
@@ -390,3 +390,116 @@ SCENARIO("The color with an intersection behind the ray", "[features/world.featu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
SCENARIO("The transformation matrix for the default orientation", "[features/transformations.feature]")
|
||||||
|
{
|
||||||
|
GIVEN("from <- point(0, 0, 0)")
|
||||||
|
{
|
||||||
|
Tuple from = Tuple::Point(0, 0, 0);
|
||||||
|
AND_GIVEN("to <- point(0, 0, -1)")
|
||||||
|
{
|
||||||
|
Tuple to = Tuple::Point(0, 0, -1);
|
||||||
|
AND_GIVEN("up <- vector(0, 1, 0)")
|
||||||
|
{
|
||||||
|
Tuple up = Tuple::Vector(0, 1, 0);
|
||||||
|
WHEN("t <- view_transform(from, to, up)")
|
||||||
|
{
|
||||||
|
Matrix t = Matrix::view_transform(from, to, up);
|
||||||
|
THEN("t = identify_matrix")
|
||||||
|
{
|
||||||
|
REQUIRE(t == Matrix::identity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
SCENARIO("A view transformation matrix looking in positive z direction", "[features/transformations.feature]")
|
||||||
|
{
|
||||||
|
GIVEN("from <- point(0, 0, 0)")
|
||||||
|
{
|
||||||
|
Tuple from = Tuple::Point(0, 0, 0);
|
||||||
|
AND_GIVEN("to <- point(0, 0, 1)")
|
||||||
|
{
|
||||||
|
Tuple to = Tuple::Point(0, 0, 1);
|
||||||
|
AND_GIVEN("up <- vector(0, 1, 0)")
|
||||||
|
{
|
||||||
|
Tuple up = Tuple::Vector(0, 1, 0);
|
||||||
|
WHEN("t <- view_transform(from, to, up)")
|
||||||
|
{
|
||||||
|
Matrix t = Matrix::view_transform(from, to, up);
|
||||||
|
THEN("t = scaling(-1, 1, -1)")
|
||||||
|
{
|
||||||
|
REQUIRE(t == Matrix::scaling(-1, 1, -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
SCENARIO("A view transformation moves the world", "[features/transformations.feature]")
|
||||||
|
{
|
||||||
|
GIVEN("from <- point(0, 0, 8)")
|
||||||
|
{
|
||||||
|
Tuple from = Tuple::Point(0, 0, 8);
|
||||||
|
AND_GIVEN("to <- point(0, 0, 0)")
|
||||||
|
{
|
||||||
|
Tuple to = Tuple::Point(0, 0, 0);
|
||||||
|
AND_GIVEN("up <- vector(0, 1, 0)")
|
||||||
|
{
|
||||||
|
Tuple up = Tuple::Vector(0, 1, 0);
|
||||||
|
WHEN("t <- view_transform(from, to, up)")
|
||||||
|
{
|
||||||
|
Matrix t = Matrix::view_transform(from, to, up);
|
||||||
|
THEN("t = translation(0, 0, -8)")
|
||||||
|
{
|
||||||
|
REQUIRE(t == Matrix::translation(0, 0, -8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
SCENARIO("An arbitrary view transformation", "[features/transformations.feature]")
|
||||||
|
{
|
||||||
|
GIVEN("from <- point(1, 3, 2)")
|
||||||
|
{
|
||||||
|
Tuple from = Tuple::Point(1, 3, 2);
|
||||||
|
AND_GIVEN("to <- point(4, -2, 8)")
|
||||||
|
{
|
||||||
|
Tuple to = Tuple::Point(4, -2, 8);
|
||||||
|
AND_GIVEN("up <- vector(1, 1, 0)")
|
||||||
|
{
|
||||||
|
Tuple up = Tuple::Vector(1, 1, 0);
|
||||||
|
WHEN("t <- view_transform(from, to, up)")
|
||||||
|
{
|
||||||
|
Matrix t = Matrix::view_transform(from, to, up);
|
||||||
|
THEN("t iq the following 4x4 matrix")
|
||||||
|
{
|
||||||
|
// | -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 |
|
||||||
|
REQUIRE(t == Matrix({
|
||||||
|
{-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}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user