#pragma once #include "lights.h" #include "spheres.h" #include "transformations.h" #include "intersections_shapes.h" #include "rays.h" #include "materials.h" #define WORLD_MAX_OBJECTS 128 struct world { struct light light; int object_count; struct shape objects[WORLD_MAX_OBJECTS]; }; inline static struct world world() { return (struct world){ .light = (struct light){{{{0}}}}, .object_count = 0, }; } inline static struct world world_default() { struct shape s1 = sphere(); s1.material.color = color(0.8f, 1.0f, 0.6f); s1.material.diffuse = 0.7f; s1.material.specular = 0.2f; struct shape s2 = sphere(); s2.transform = scaling(0.5f, 0.5f, 0.5f); return (struct world){ .light = point_light(point(-10.0f, 10.0f, -10.0f), color(1.0f, 1.0f, 1.0f)), .object_count = 2, .objects = { s1, s2 } }; } inline static void world_intersect(struct world * world, struct ray ray, struct intersections * intersections) { intersections->count = 0; for (int i = 0; i < world->object_count; i++) { intersect(&world->objects[i], ray, intersections); } intersections_sort(intersections); } inline static bool world_is_shadowed(struct world * world, struct tuple point) { struct tuple v = tuple_sub(world->light.position, point); float distance = tuple_magnitude(v); struct tuple direction = tuple_normalize(v); struct ray r = ray(point, direction); struct intersections xs; world_intersect(world, r, &xs); struct intersection * h = hit(&xs); if (h != NULL && h->t < distance) { return true; } else { return false; } } inline static struct tuple world_shade_hit(struct world * world, struct computations * computations) { bool is_shadowed = world_is_shadowed(world, computations->over_point); struct tuple color = lighting(computations->object->material, world->light, computations->point, computations->eyev, computations->normalv, is_shadowed); return color; } inline static struct tuple world_color_at(struct world * world, struct ray ray) { struct intersections xs; world_intersect(world, ray, &xs); struct intersection * i = hit(&xs); if (i != NULL) { struct computations computations = prepare_computations(*i, ray); struct tuple color = world_shade_hit(world, &computations); return color; } else { return color(0.0f, 0.0f, 0.0f); } }