113 lines
2.9 KiB
C
113 lines
2.9 KiB
C
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
|
|
#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 = world_default();
|
|
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)
|