2024-08-11 19:36:48 -05:00

96 lines
2.5 KiB
C

#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);
}
}