diff --git a/source/include/object.h b/source/include/object.h index d08e570..6f71cce 100644 --- a/source/include/object.h +++ b/source/include/object.h @@ -12,13 +12,24 @@ class Object; #include +#include +#include #include /* Base class for all object that can be presented in the world */ class Object { public: + Matrix transformMatrix; + Matrix inverseTransform; + +public: + Object(); + virtual Intersect intersect(Ray r); + void setTransform(Matrix transform); + Ray transform(Ray r) { return Ray(this->transformMatrix * r.origin, this->transformMatrix * r.direction); }; + Ray invTransform(Ray r) { return Ray(this->inverseTransform * r.origin, this->inverseTransform * r.direction); }; }; #endif //DORAYME_OBJECT_H diff --git a/source/objects/object.cpp b/source/objects/object.cpp index 9ecf9b1..b944a76 100644 --- a/source/objects/object.cpp +++ b/source/objects/object.cpp @@ -9,9 +9,23 @@ #include #include +#include +#include #include +Object::Object() +{ + this->transformMatrix = Matrix4().identity(); + this->inverseTransform = this->transformMatrix.inverse(); +} + Intersect Object::intersect(Ray r) { return Intersect(); -}; \ No newline at end of file +}; + +void Object::setTransform(Matrix transform) +{ + this->transformMatrix = transform; + this->inverseTransform = transform.inverse(); +} diff --git a/source/objects/sphere.cpp b/source/objects/sphere.cpp index 394d340..3c3b620 100644 --- a/source/objects/sphere.cpp +++ b/source/objects/sphere.cpp @@ -17,10 +17,13 @@ Intersect Sphere::intersect(Ray r) { Intersect ret; double a, b, c, discriminant; - Tuple sphere_to_ray = r.origin - Point(0, 0, 0); - a = r.direction.dot(r.direction); - b = 2 * r.direction.dot(sphere_to_ray); + Ray transRay = this->invTransform(r); + + Tuple sphere_to_ray = transRay.origin - Point(0, 0, 0); + + a = transRay.direction.dot(transRay.direction); + b = 2 * transRay.direction.dot(sphere_to_ray); c = sphere_to_ray.dot(sphere_to_ray) - 1; discriminant = b * b - 4 * a * c; diff --git a/tests/ray_test.cpp b/tests/ray_test.cpp index 1a9d0d7..3bd2dd8 100644 --- a/tests/ray_test.cpp +++ b/tests/ray_test.cpp @@ -7,6 +7,8 @@ * */ #include +#include +#include #include @@ -29,4 +31,34 @@ TEST(RayTest, Computing_a_point_from_a_distance) ASSERT_EQ(r.position(1), Point(3, 3, 4)); ASSERT_EQ(r.position(-1), Point(1, 3, 4)); ASSERT_EQ(r.position(2.5), Point(4.5, 3, 4)); +} + +TEST(RayTest, Translating_a_ray) +{ + Ray r = Ray(Point(1, 2, 3), Vector(0, 1, 0)); + + Matrix m = translation(3, 4, 5); + Object o = Object(); + + o.setTransform(m); + + Ray r2 = o.transform(r); + + ASSERT_EQ(r2.origin, Point(4, 6, 8)); + ASSERT_EQ(r2.direction, Vector(0, 1, 0)); +} + +TEST(RayTest, Scaling_a_ray) +{ + Ray r = Ray(Point(1, 2, 3), Vector(0, 1, 0)); + + Matrix m = scaling(2, 3, 4); + Object o = Object(); + + o.setTransform(m); + + Ray r2 = o.transform(r); + + ASSERT_EQ(r2.origin, Point(2, 6, 12)); + ASSERT_EQ(r2.direction, Vector(0, 3, 0)); } \ No newline at end of file diff --git a/tests/sphere_test.cpp b/tests/sphere_test.cpp index 0cacc38..9988e73 100644 --- a/tests/sphere_test.cpp +++ b/tests/sphere_test.cpp @@ -8,6 +8,7 @@ */ #include #include +#include #include @@ -62,4 +63,46 @@ TEST(SphereTest, A_sphere_is_behind_a_ray) ASSERT_EQ(xs.count(), 2); ASSERT_EQ(xs[0].t, -6.0); ASSERT_EQ(xs[1].t, -4.0); +} + +TEST(SphereTest, A_sphere_default_transformation) +{ + Sphere s = Sphere(); + ASSERT_EQ(s.transformMatrix, Matrix4().identity()); +} + +TEST(SphereTest, Changing_a_sphere_transformation) +{ + Sphere s = Sphere(); + Matrix t = translation(2, 3, 4); + + s.setTransform(t); + + ASSERT_EQ(s.transformMatrix, t); +} + +TEST(SphereTest, Intersecting_a_scaled_sphere_with_a_ray) +{ + Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1)); + Sphere s = Sphere(); + + s.setTransform(scaling(2, 2, 2)); + + Intersect xs = s.intersect(r); + + ASSERT_EQ(xs.count(), 2); + ASSERT_EQ(xs[0].t, 3.0); + ASSERT_EQ(xs[1].t, 7.0); +} + +TEST(SphereTest, Intersecting_a_translated_sphere_with_a_ray) +{ + Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1)); + Sphere s = Sphere(); + + s.setTransform(translation(5, 0, 0)); + + Intersect xs = s.intersect(r); + + ASSERT_EQ(xs.count(), 0); } \ No newline at end of file