ray-tracer-challenge/test/test_world.c
2024-08-09 15:24:02 -05:00

201 lines
5.5 KiB
C

#include <stdbool.h>
#include <stdio.h>
#include "world.h"
#include "runner.h"
static bool world_test_0(const char ** scenario)
{
*scenario = "Creating a world";
struct world w = world();
return
w.object_count == 0 &&
tuple_equal(w.light.intensity, tuple(0.0f, 0.0f, 0.0f, 0.0f));
}
static bool world_test_1(const char ** scenario)
{
*scenario = "The default world";
struct light light = point_light(point(-10.0f, 10.0f, -10.0f), color(1.0f, 1.0f, 1.0f));
struct sphere s1 = sphere();
s1.material.color = color(0.8f, 1.0f, 0.6f);
s1.material.diffuse = 0.7f;
s1.material.specular = 0.2f;
struct sphere s2 = sphere();
s2.transform = scaling(0.5f, 0.5f, 0.5f);
struct world w = world_default();
return
tuple_equal(w.light.position, light.position) &&
tuple_equal(w.light.intensity, light.intensity) &&
w.object_count == 2 &&
tuple_equal(w.objects[0].material.color, s1.material.color) &&
float_equal(w.objects[0].material.diffuse, s1.material.diffuse) &&
float_equal(w.objects[0].material.specular, s1.material.specular) &&
mat4x4_equal(&w.objects[1].transform, &s2.transform);
}
static bool world_test_2(const char ** scenario)
{
*scenario = "Intersect a world with a ray";
struct world w = world_default();
struct ray r = ray(point(0.0f, 0.0f, -5.0f), vector(0.0f, 0.0f, 1.0f));
struct intersections xs;
world_intersect(&w, r, &xs);
return
xs.count == 4 &&
float_equal(xs.i[0].t, 4.0f) &&
float_equal(xs.i[1].t, 4.5f) &&
float_equal(xs.i[2].t, 5.5f) &&
float_equal(xs.i[3].t, 6.0f);
}
static bool world_test_3(const char ** scenario)
{
*scenario = "Shading an intersection";
struct world w = world_default();
struct ray r = ray(point(0.0f, 0.0f, -5.0f), vector(0.0f, 0.0f, 1.0f));
struct sphere * shape = &w.objects[0];
struct intersection i = intersection(4.0f, shape);
struct computations comps = prepare_computations(i, r);
struct tuple c = world_shade_hit(&w, &comps);
return tuple_equal(c, color(0.38066, 0.47583, 0.2855));
}
static bool world_test_4(const char ** scenario)
{
*scenario = "Shading an intersection from the inside";
struct world w = world_default();
w.light = point_light(point(0.0f, 0.25f, 0.0f), color(1.0f, 1.0f, 1.0f));
struct ray r = ray(point(0.0f, 0.0f, 0.0f), vector(0.0f, 0.0f, 1.0f));
struct sphere * shape = &w.objects[1];
struct intersection i = intersection(0.5f, shape);
struct computations comps = prepare_computations(i, r);
struct tuple c = world_shade_hit(&w, &comps);
return tuple_equal(c, color(0.90498, 0.90498, 0.90498));
}
static bool world_test_5(const char ** scenario)
{
*scenario = "The color when a ray misses";
struct world w = world_default();
struct ray r = ray(point(0.0f, 0.0f, -5.0f), vector(0.0f, 1.0f, 0.0f));
struct tuple c = world_color_at(&w, r);
return tuple_equal(c, color(0.0f, 0.0f, 0.0f));
}
static bool world_test_6(const char ** scenario)
{
*scenario = "The color when a ray hits";
struct world w = world_default();
struct ray r = ray(point(0.0f, 0.0f, -5.0f), vector(0.0f, 0.0f, 1.0f));
struct tuple c = world_color_at(&w, r);
return tuple_equal(c, color(0.38066f, 0.47583f, 0.2855f));
}
static bool world_test_7(const char ** scenario)
{
*scenario = "The color with an intersection behind the ray";
struct world w = world_default();
struct sphere * outer = &w.objects[0];
outer->material.ambient = 1.0f;
struct sphere * inner = &w.objects[1];
inner->material.ambient = 1.0f;
struct ray r = ray(point(0.0f, 0.0f, 0.75f), vector(0.0f, 0.0f, -1.0f));
struct tuple c = world_color_at(&w, r);
return tuple_equal(c, inner->material.color);
}
static bool world_test_8(const char ** scenario)
{
*scenario = "There is no shadow when nothing is collinear with point and light";
struct world w = world_default();
struct tuple p = point(0.0f, 10.0f, 0.0f);
return world_is_shadowed(&w, p) == false;
}
static bool world_test_9(const char ** scenario)
{
*scenario = "The shadow when an object is between the point and the light";
struct world w = world_default();
struct tuple p = point(10.0f, -10.0f, 10.0f);
return world_is_shadowed(&w, p) == true;
}
static bool world_test_10(const char ** scenario)
{
*scenario = "There is no shadow when an object is behind the light";
struct world w = world_default();
struct tuple p = point(-20.0f, 20.0f, -20.0f);
return world_is_shadowed(&w, p) == false;
}
static bool world_test_11(const char ** scenario)
{
*scenario = "There is not shadow when an object is behind the point";
struct world w = world_default();
struct tuple p = point(-2.0f, 2.0f, -2.0f);
return world_is_shadowed(&w, p) == false;
}
static bool world_test_12(const char ** scenario)
{
*scenario = "shade_hit() is given an intersection in shadow";
struct world w = world();
w.light = point_light(point(0.0f, 0.0f, -10.0f), color(1.0f, 1.0f, 1.0f));
struct sphere s1 = sphere();
w.objects[0] = s1;
struct sphere s2 = sphere();
s2.transform = translation(0.0f, 0.0f, 10.0f);
w.objects[1] = s2;
w.object_count = 2;
struct ray r = ray(point(0.0f, 0.0f, 5.0f), vector(0.0f, 0.0f, 1.0f));
struct intersection i = intersection(4.0f, &s2);
struct computations comps = prepare_computations(i, r);
struct tuple c = world_shade_hit(&w, &comps);
return tuple_equal(c, color(0.1f, 0.1f, 0.1f));
}
test_t world_tests[] = {
world_test_0,
world_test_1,
world_test_2,
world_test_3,
world_test_4,
world_test_5,
world_test_6,
world_test_7,
world_test_8,
world_test_9,
world_test_10,
world_test_11,
world_test_12,
};
RUNNER(world_tests)