#include #include #include "camera.h" #include "transformations.h" #include "runner.h" static bool camera_test_0(const char ** scenario) { *scenario = "Constructing a camera"; float hsize = 160.0f; float vsize = 120.0f; float field_of_view = pi / 2.0f; struct camera c = camera(hsize, vsize, field_of_view); struct mat4x4 identity_matrix = mat4x4_identity(); return float_equal(c.hsize, 160.0f) && float_equal(c.vsize, 120.0f) && float_equal(c.field_of_view, pi / 2.0f) && mat4x4_equal(&c.transform, &identity_matrix); } static bool camera_test_1(const char ** scenario) { *scenario = "The pixel size for a horizontal camera"; struct camera c = camera(200.0f, 125.0f, pi / 2.0f); return float_equal(c.pixel_size, 0.01f); } static bool camera_test_2(const char ** scenario) { *scenario = "The pixel size for a vertical camera"; struct camera c = camera(125.0f, 200.0f, pi / 2.0f); return float_equal(c.pixel_size, 0.01f); } static bool camera_test_3(const char ** scenario) { *scenario = "Constructing a ray through the center of the canvas"; struct camera c = camera(201.0f, 101.0f, pi / 2.0f); struct ray r = camera_ray_for_pixel(&c, 100.0f, 50.0f); return tuple_equal(r.origin, point(0.0f, 0.0f, 0.0f)) && tuple_equal(r.direction, vector(0.0f, 0.0f, -1.0f)); } static bool camera_test_4(const char ** scenario) { *scenario = "Constructing a ray through the corner of the canvas"; struct camera c = camera(201.0f, 101.0f, pi / 2.0f); struct ray r = camera_ray_for_pixel(&c, 0.0f, 0.0f); return tuple_equal(r.origin, point(0.0f, 0.0f, 0.0f)) && tuple_equal(r.direction, vector(0.66519f, 0.33259f, -0.66851f)); } static bool camera_test_5(const char ** scenario) { *scenario = "Constructing a ray when the camera is transformed"; struct camera c = camera(201.0f, 101.0f, pi / 2.0f); struct mat4x4 rotate = rotation_y(pi / 4.0f); struct mat4x4 translate = translation(0.0f, -2.0f, 5.0f); c.transform = mat4x4_mul_m(&rotate, &translate); struct ray r = camera_ray_for_pixel(&c, 100.0f, 50.0f); return tuple_equal(r.origin, point(0.0f, 2.0f, -5.0f)) && tuple_equal(r.direction, vector(0.7071067811865476f, 0.0f, -0.7071067811865476f)); } static bool camera_test_6(const char ** scenario) { *scenario = "Rendering a world with a camera"; struct world w = default_world(); struct camera c = camera(11.0f, 11.0f, pi / 2.0f); struct tuple from = point(0.0f, 0.0f, -5.0f); struct tuple to = point(0.0f, 0.0f, 0.0f); struct tuple up = vector(0.0f, 1.0f, 0.0f); c.transform = view_transform(from, to, up); struct canvas image; camera_render(&c, &w, &image); struct tuple col = canvas_pixel_at(&image, 5, 5); return tuple_equal(col, color(0.38066, 0.47583, 0.2855)); } test_t camera_tests[] = { camera_test_0, camera_test_1, camera_test_2, camera_test_3, camera_test_4, camera_test_5, camera_test_6, }; RUNNER(camera_tests)