#include #include #include "rays.h" #include "spheres.h" #include "intersections.h" #include "runner.h" #include "matrices.h" #include "transformations.h" static bool spheres_test_0(const char ** scenario) { *scenario = "A ray intersects a sphere at two points"; struct ray r = ray(point(0.0f, 0.0f, -5.0f), vector(0.0f, 0.0f, 1.0f)); struct sphere s = sphere(); struct intersections2 xs = intersect(&s, r); return xs.count == 2 && float_equal(xs.i[0].t, 4.0f) && float_equal(xs.i[1].t, 6.0f); } static bool spheres_test_1(const char ** scenario) { *scenario = "A ray intersects a sphere at a tangent"; struct ray r = ray(point(0.0f, 1.0f, -5.0f), vector(0.0f, 0.0f, 1.0f)); struct sphere s = sphere(); struct intersections2 xs = intersect(&s, r); return xs.count == 2 && float_equal(xs.i[0].t, 5.0f) && float_equal(xs.i[1].t, 5.0f); } static bool spheres_test_2(const char ** scenario) { *scenario = "A ray misses a sphere"; struct ray r = ray(point(0.0f, 2.0f, -5.0f), vector(0.0f, 0.0f, 1.0f)); struct sphere s = sphere(); struct intersections2 xs = intersect(&s, r); return xs.count == 0; } static bool spheres_test_3(const char ** scenario) { *scenario = "A ray originates in a sphere"; struct ray r = ray(point(0.0f, 0.0f, 0.0f), vector(0.0f, 0.0f, 1.0f)); struct sphere s = sphere(); struct intersections2 xs = intersect(&s, r); return xs.count == 2 && float_equal(xs.i[0].t, -1.0f) && float_equal(xs.i[1].t, 1.0f); } static bool spheres_test_4(const char ** scenario) { *scenario = "A sphere is behind a ray"; struct ray r = ray(point(0.0f, 0.0f, 5.0f), vector(0.0f, 0.0f, 1.0f)); struct sphere s = sphere(); struct intersections2 xs = intersect(&s, r); return xs.count == 2 && float_equal(xs.i[0].t, -6.0f) && float_equal(xs.i[1].t, -4.0f); } static bool spheres_test_5(const char ** scenario) { *scenario = "Intersect sets the object on the intersection"; struct ray r = ray(point(0.0f, 0.0f, -5.0f), vector(0.0f, 0.0f, 1.0f)); struct sphere s = sphere(); struct intersections2 xs = intersect(&s, r); return xs.count == 2 && xs.i[0].object == &s && xs.i[1].object == &s; } static bool spheres_test_6(const char ** scenario) { *scenario = "A sphere's default transformation"; struct sphere s = sphere(); struct mat4x4 identity = mat4x4_identity(); return mat4x4_equal(&s.transform, &identity); } static bool spheres_test_7(const char ** scenario) { *scenario = "Changing a sphere's transformation"; struct sphere s = sphere(); struct mat4x4 t = translation(2.0f, 3.0f, 4.0f); s.transform = t; return mat4x4_equal(&s.transform, &t); } static bool spheres_test_8(const char ** scenario) { *scenario = "Intersecting a scaled sphere with a ray"; struct ray r = ray(point(0.0f, 0.0f, -5.0f), vector(0.0f, 0.0f, 1.0f)); struct sphere s = sphere(); s.transform = scaling(2.0f, 2.0f, 2.0f); struct intersections2 xs = intersect(&s, r); return xs.count == 2 && float_equal(xs.i[0].t, 3.0f) && float_equal(xs.i[1].t, 7.0f); } static bool spheres_test_9(const char ** scenario) { *scenario = "Intersecting a translated sphere with a ray"; struct ray r = ray(point(0.0f, 0.0f, 5.0f), vector(0.0f, 0.0f, 1.0f)); struct sphere s = sphere(); s.transform = translation(5.0f, 0.0f, 0.0f); struct intersections2 xs = intersect(&s, r); return xs.count == 0; } test_t spheres_tests[] = { spheres_test_0, spheres_test_1, spheres_test_2, spheres_test_3, spheres_test_4, spheres_test_5, spheres_test_6, spheres_test_7, spheres_test_8, spheres_test_9, }; RUNNER(spheres_tests);