Add a bounding volume hierarchy
This commit is contained in:
parent
1034668c66
commit
f23e454358
64
aabb.c
Normal file
64
aabb.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "aabb.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
bool aabb_hit(const AABB *aabb, Ray r, double t_min, double t_max) {
|
||||||
|
/* X */
|
||||||
|
{
|
||||||
|
double inv_d = 1.0 / r.direction.x;
|
||||||
|
double t0 = (aabb->min.x - r.origin.x) * inv_d;
|
||||||
|
double t1 = (aabb->max.x - r.origin.x) * inv_d;
|
||||||
|
if (inv_d < 0.0) {
|
||||||
|
double tmp = t0;
|
||||||
|
t0 = t1;
|
||||||
|
t1 = tmp;
|
||||||
|
}
|
||||||
|
t_min = t0 > t_min ? t0 : t_min;
|
||||||
|
t_max = t1 < t_max ? t1 : t_max;
|
||||||
|
if (t_max <= t_min)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Y */
|
||||||
|
{
|
||||||
|
double inv_d = 1.0 / r.direction.y;
|
||||||
|
double t0 = (aabb->min.y - r.origin.y) * inv_d;
|
||||||
|
double t1 = (aabb->max.y - r.origin.y) * inv_d;
|
||||||
|
if (inv_d < 0.0) {
|
||||||
|
double tmp = t0;
|
||||||
|
t0 = t1;
|
||||||
|
t1 = tmp;
|
||||||
|
}
|
||||||
|
t_min = t0 > t_min ? t0 : t_min;
|
||||||
|
t_max = t1 < t_max ? t1 : t_max;
|
||||||
|
if (t_max <= t_min)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Z */
|
||||||
|
{
|
||||||
|
double inv_d = 1.0 / r.direction.z;
|
||||||
|
double t0 = (aabb->min.z - r.origin.z) * inv_d;
|
||||||
|
double t1 = (aabb->max.z - r.origin.z) * inv_d;
|
||||||
|
if (inv_d < 0.0) {
|
||||||
|
double tmp = t0;
|
||||||
|
t0 = t1;
|
||||||
|
t1 = tmp;
|
||||||
|
}
|
||||||
|
t_min = t0 > t_min ? t0 : t_min;
|
||||||
|
t_max = t1 < t_max ? t1 : t_max;
|
||||||
|
if (t_max <= t_min)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AABB aabb_surrounding_box(const AABB *first, const AABB *second) {
|
||||||
|
return (AABB){
|
||||||
|
.min = {fmin(first->min.x, second->min.x),
|
||||||
|
fmin(first->min.y, second->min.y),
|
||||||
|
fmin(first->min.z, second->min.z)},
|
||||||
|
.max = {fmax(first->max.x, second->max.x),
|
||||||
|
fmax(first->max.y, second->max.y),
|
||||||
|
fmax(first->max.z, second->max.z)},
|
||||||
|
};
|
||||||
|
}
|
||||||
17
aabb.h
Normal file
17
aabb.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef INCLUDED_AABB_H
|
||||||
|
#define INCLUDED_AABB_H
|
||||||
|
|
||||||
|
#include "point3.h"
|
||||||
|
#include "ray.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct AABB {
|
||||||
|
Point3 min;
|
||||||
|
Point3 max;
|
||||||
|
} AABB;
|
||||||
|
|
||||||
|
bool aabb_hit(const AABB *aabb, Ray r, double t_min, double t_max);
|
||||||
|
AABB aabb_surrounding_box(const AABB *first, const AABB *second);
|
||||||
|
|
||||||
|
#endif /* INCLUDED_AABB_H */
|
||||||
160
hittable.c
160
hittable.c
@ -1,6 +1,8 @@
|
|||||||
#include "hittable.h"
|
#include "hittable.h"
|
||||||
|
#include "aabb.h"
|
||||||
#include "arena.h"
|
#include "arena.h"
|
||||||
#include "point3.h"
|
#include "point3.h"
|
||||||
|
#include "utils.h"
|
||||||
#include "vec3.h"
|
#include "vec3.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -25,10 +27,37 @@ bool hittable_hit(const Hittable *hittable, Ray r, double t_min, double t_max,
|
|||||||
case HITTABLE_MOVING_SPHERE:
|
case HITTABLE_MOVING_SPHERE:
|
||||||
return moving_sphere_hit((const MovingSphere *)hittable, r, t_min, t_max,
|
return moving_sphere_hit((const MovingSphere *)hittable, r, t_min, t_max,
|
||||||
record);
|
record);
|
||||||
|
case HITTABLE_BVH_NODE:
|
||||||
|
return bvh_node_hit((const BVHNode *)hittable, r, t_min, t_max, record);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hittable_bounding_box(const Hittable *hittable, double time_start,
|
||||||
|
double time_end, AABB *bounding_box) {
|
||||||
|
switch (hittable->type) {
|
||||||
|
case HITTABLE_LIST:
|
||||||
|
return hittable_list_bounding_box((const HittableList *)hittable,
|
||||||
|
time_start, time_end, bounding_box);
|
||||||
|
case HITTABLE_SPHERE:
|
||||||
|
return sphere_bounding_box((const Sphere *)hittable, time_start, time_end,
|
||||||
|
bounding_box);
|
||||||
|
case HITTABLE_MOVING_SPHERE:
|
||||||
|
return moving_sphere_bounding_box((const MovingSphere *)hittable,
|
||||||
|
time_start, time_end, bounding_box);
|
||||||
|
case HITTABLE_BVH_NODE:
|
||||||
|
return bvh_node_bounding_box((const BVHNode *)hittable, time_start,
|
||||||
|
time_end, bounding_box);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HittableList *hittable_list_create(Arena *arena) {
|
||||||
|
HittableList *list = arena_alloc(arena, sizeof(HittableList));
|
||||||
|
list->type = HITTABLE_LIST;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
static void hittable_list_grow(HittableList *list, size_t n, Arena *arena) {
|
static void hittable_list_grow(HittableList *list, size_t n, Arena *arena) {
|
||||||
if (list->objects) {
|
if (list->objects) {
|
||||||
const Hittable **new_objects =
|
const Hittable **new_objects =
|
||||||
@ -65,6 +94,26 @@ bool hittable_list_hit(const HittableList *list, Ray r, double t_min,
|
|||||||
return hit_anything;
|
return hit_anything;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hittable_list_bounding_box(const HittableList *list, double time_start,
|
||||||
|
double time_end, AABB *bounding_box) {
|
||||||
|
if (list->size == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
AABB temp_box;
|
||||||
|
bool first_box = true;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < list->size; ++i) {
|
||||||
|
if (!hittable_bounding_box(list->objects[i], time_start, time_end,
|
||||||
|
&temp_box))
|
||||||
|
return false;
|
||||||
|
*bounding_box =
|
||||||
|
first_box ? temp_box : aabb_surrounding_box(bounding_box, &temp_box);
|
||||||
|
first_box = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Sphere *sphere_create(Point3 center, double radius, const Material *material,
|
Sphere *sphere_create(Point3 center, double radius, const Material *material,
|
||||||
Arena *arena) {
|
Arena *arena) {
|
||||||
Sphere *sphere = arena_alloc(arena, sizeof(Sphere));
|
Sphere *sphere = arena_alloc(arena, sizeof(Sphere));
|
||||||
@ -102,6 +151,18 @@ bool sphere_hit(const Sphere *sphere, Ray r, double t_min, double t_max,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sphere_bounding_box(const Sphere *sphere, double time_start,
|
||||||
|
double time_end, AABB *bounding_box) {
|
||||||
|
(void)time_start, (void)time_end;
|
||||||
|
*bounding_box = (AABB){
|
||||||
|
.min = point3_add(sphere->center, (Vec3){-sphere->radius, -sphere->radius,
|
||||||
|
-sphere->radius}),
|
||||||
|
.max = point3_add(sphere->center,
|
||||||
|
(Vec3){sphere->radius, sphere->radius, sphere->radius}),
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
MovingSphere *moving_sphere_create(Point3 center_start, Point3 center_end,
|
MovingSphere *moving_sphere_create(Point3 center_start, Point3 center_end,
|
||||||
double start, double end, double radius,
|
double start, double end, double radius,
|
||||||
const Material *material, Arena *arena) {
|
const Material *material, Arena *arena) {
|
||||||
@ -150,3 +211,102 @@ bool moving_sphere_hit(const MovingSphere *sphere, Ray r, double t_min,
|
|||||||
record->material = sphere->material;
|
record->material = sphere->material;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool moving_sphere_bounding_box(const MovingSphere *sphere, double time_start,
|
||||||
|
double time_end, AABB *bounding_box) {
|
||||||
|
AABB box_start = {
|
||||||
|
.min =
|
||||||
|
point3_add(moving_sphere_center(sphere, time_start),
|
||||||
|
(Vec3){-sphere->radius, -sphere->radius, -sphere->radius}),
|
||||||
|
.max = point3_add(moving_sphere_center(sphere, time_start),
|
||||||
|
(Vec3){sphere->radius, sphere->radius, sphere->radius}),
|
||||||
|
};
|
||||||
|
AABB box_end = {
|
||||||
|
.min =
|
||||||
|
point3_add(moving_sphere_center(sphere, time_end),
|
||||||
|
(Vec3){-sphere->radius, -sphere->radius, -sphere->radius}),
|
||||||
|
.max = point3_add(moving_sphere_center(sphere, time_end),
|
||||||
|
(Vec3){sphere->radius, sphere->radius, sphere->radius}),
|
||||||
|
};
|
||||||
|
*bounding_box = aabb_surrounding_box(&box_start, &box_end);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef int BoxCompareFunc(const void *lhs, const void *rhs);
|
||||||
|
|
||||||
|
#define BOX_COMPARATOR(axis) \
|
||||||
|
static int box_##axis##_compare(const void *lhs, const void *rhs) { \
|
||||||
|
AABB lhs_box, rhs_box; \
|
||||||
|
if (!hittable_bounding_box(*(const Hittable **)lhs, 0, 0, &lhs_box) || \
|
||||||
|
!hittable_bounding_box(*(const Hittable **)rhs, 0, 0, &rhs_box)) { \
|
||||||
|
fprintf(stderr, "No bounding-box in BVH node"); \
|
||||||
|
exit(1); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
return lhs_box.min.axis < rhs_box.min.axis; \
|
||||||
|
}
|
||||||
|
BOX_COMPARATOR(x)
|
||||||
|
BOX_COMPARATOR(y)
|
||||||
|
BOX_COMPARATOR(z)
|
||||||
|
#undef BOX_COMPARATOR
|
||||||
|
|
||||||
|
BVHNode *bvh_node_create(const Hittable **objects, size_t start, size_t end,
|
||||||
|
double time_start, double time_end, Arena *arena) {
|
||||||
|
BVHNode *node = arena_alloc(arena, sizeof(BVHNode));
|
||||||
|
node->type = HITTABLE_BVH_NODE;
|
||||||
|
|
||||||
|
int axis = random_int_in_range(0, 2);
|
||||||
|
BoxCompareFunc *comparator = (axis == 0) ? box_x_compare
|
||||||
|
: (axis == 1) ? box_y_compare
|
||||||
|
: box_z_compare;
|
||||||
|
|
||||||
|
size_t object_span = end - start;
|
||||||
|
if (object_span == 1) {
|
||||||
|
node->left = node->right = objects[start];
|
||||||
|
} else if (object_span == 2) {
|
||||||
|
if (comparator(&objects[start], &objects[start + 1])) {
|
||||||
|
node->left = objects[start];
|
||||||
|
node->right = objects[start + 1];
|
||||||
|
} else {
|
||||||
|
node->left = objects[start + 1];
|
||||||
|
node->right = objects[start];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qsort(objects + start, object_span, sizeof(const Hittable *), comparator);
|
||||||
|
size_t mid = start + object_span / 2;
|
||||||
|
node->left = (const Hittable *)bvh_node_create(objects, start, mid,
|
||||||
|
time_start, time_end, arena);
|
||||||
|
node->right = (const Hittable *)bvh_node_create(
|
||||||
|
objects, mid, end, time_start, time_end, arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
AABB left_box, right_box;
|
||||||
|
|
||||||
|
if (!hittable_bounding_box(node->left, time_start, time_end, &left_box) ||
|
||||||
|
!hittable_bounding_box(node->right, time_start, time_end, &right_box)) {
|
||||||
|
fprintf(stderr, "No bounding-box in BVH node");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
node->box = aabb_surrounding_box(&left_box, &right_box);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bvh_node_hit(const BVHNode *node, Ray r, double t_min, double t_max,
|
||||||
|
HitRecord *record) {
|
||||||
|
if (!aabb_hit(&node->box, r, t_min, t_max))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool hit_left = hittable_hit(node->left, r, t_min, t_max, record);
|
||||||
|
bool hit_right =
|
||||||
|
hittable_hit(node->right, r, t_min, hit_left ? record->t : t_max, record);
|
||||||
|
|
||||||
|
return hit_left || hit_right;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bvh_node_bounding_box(const BVHNode *node, double time_start,
|
||||||
|
double time_end, AABB *bounding_box) {
|
||||||
|
(void)time_start, (void)time_end;
|
||||||
|
*bounding_box = node->box;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
25
hittable.h
25
hittable.h
@ -1,6 +1,7 @@
|
|||||||
#ifndef INCLUDED_HITTABLE_H
|
#ifndef INCLUDED_HITTABLE_H
|
||||||
#define INCLUDED_HITTABLE_H
|
#define INCLUDED_HITTABLE_H
|
||||||
|
|
||||||
|
#include "aabb.h"
|
||||||
#include "arena.h"
|
#include "arena.h"
|
||||||
#include "material.h"
|
#include "material.h"
|
||||||
#include "point3.h"
|
#include "point3.h"
|
||||||
@ -24,6 +25,7 @@ typedef enum HittableType {
|
|||||||
HITTABLE_LIST,
|
HITTABLE_LIST,
|
||||||
HITTABLE_SPHERE,
|
HITTABLE_SPHERE,
|
||||||
HITTABLE_MOVING_SPHERE,
|
HITTABLE_MOVING_SPHERE,
|
||||||
|
HITTABLE_BVH_NODE,
|
||||||
} HittableType;
|
} HittableType;
|
||||||
|
|
||||||
typedef struct Hittable {
|
typedef struct Hittable {
|
||||||
@ -32,6 +34,8 @@ typedef struct Hittable {
|
|||||||
|
|
||||||
bool hittable_hit(const Hittable *hittable, Ray r, double t_min, double t_max,
|
bool hittable_hit(const Hittable *hittable, Ray r, double t_min, double t_max,
|
||||||
HitRecord *record);
|
HitRecord *record);
|
||||||
|
bool hittable_bounding_box(const Hittable *hittable, double time_start,
|
||||||
|
double time_end, AABB *bounding_box);
|
||||||
|
|
||||||
typedef struct HittableList {
|
typedef struct HittableList {
|
||||||
HittableType type;
|
HittableType type;
|
||||||
@ -40,10 +44,13 @@ typedef struct HittableList {
|
|||||||
size_t capacity;
|
size_t capacity;
|
||||||
} HittableList;
|
} HittableList;
|
||||||
|
|
||||||
|
HittableList *hittable_list_create(Arena *arena);
|
||||||
void hittable_list_add(HittableList *list, const Hittable *hittable,
|
void hittable_list_add(HittableList *list, const Hittable *hittable,
|
||||||
Arena *arena);
|
Arena *arena);
|
||||||
bool hittable_list_hit(const HittableList *list, Ray r, double t_min,
|
bool hittable_list_hit(const HittableList *list, Ray r, double t_min,
|
||||||
double t_max, HitRecord *record);
|
double t_max, HitRecord *record);
|
||||||
|
bool hittable_list_bounding_box(const HittableList *list, double time_start,
|
||||||
|
double time_end, AABB *bounding_box);
|
||||||
|
|
||||||
typedef struct Sphere {
|
typedef struct Sphere {
|
||||||
HittableType type;
|
HittableType type;
|
||||||
@ -56,6 +63,8 @@ Sphere *sphere_create(Point3 center, double radius, const Material *material,
|
|||||||
Arena *arena);
|
Arena *arena);
|
||||||
bool sphere_hit(const Sphere *sphere, Ray r, double t_min, double t_max,
|
bool sphere_hit(const Sphere *sphere, Ray r, double t_min, double t_max,
|
||||||
HitRecord *record);
|
HitRecord *record);
|
||||||
|
bool sphere_bounding_box(const Sphere *sphere, double time_start,
|
||||||
|
double time_end, AABB *bounding_box);
|
||||||
|
|
||||||
typedef struct MovingSphere {
|
typedef struct MovingSphere {
|
||||||
HittableType type;
|
HittableType type;
|
||||||
@ -71,5 +80,21 @@ MovingSphere *moving_sphere_create(Point3 center_start, Point3 center_end,
|
|||||||
Point3 moving_sphere_center(const MovingSphere *sphere, double t);
|
Point3 moving_sphere_center(const MovingSphere *sphere, double t);
|
||||||
bool moving_sphere_hit(const MovingSphere *sphere, Ray r, double t_min,
|
bool moving_sphere_hit(const MovingSphere *sphere, Ray r, double t_min,
|
||||||
double t_max, HitRecord *record);
|
double t_max, HitRecord *record);
|
||||||
|
bool moving_sphere_bounding_box(const MovingSphere *sphere, double time_start,
|
||||||
|
double time_end, AABB *bounding_box);
|
||||||
|
|
||||||
|
typedef struct BVHNode {
|
||||||
|
HittableType type;
|
||||||
|
const Hittable *left;
|
||||||
|
const Hittable *right;
|
||||||
|
AABB box;
|
||||||
|
} BVHNode;
|
||||||
|
|
||||||
|
BVHNode *bvh_node_create(const Hittable **objects, size_t start, size_t end,
|
||||||
|
double time_start, double time_end, Arena *arena);
|
||||||
|
bool bvh_node_hit(const BVHNode *node, Ray r, double t_min, double t_max,
|
||||||
|
HitRecord *record);
|
||||||
|
bool bvh_node_bounding_box(const BVHNode *node, double time_start,
|
||||||
|
double time_end, AABB *bounding_box);
|
||||||
|
|
||||||
#endif /* INCLUDED_HITTABLE_H */
|
#endif /* INCLUDED_HITTABLE_H */
|
||||||
|
|||||||
23
main.c
23
main.c
@ -35,14 +35,14 @@ static Color ray_color(Ray r, const Hittable *world, int depth) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const Hittable *generate_random_scene(Arena *arena) {
|
static const Hittable *generate_random_scene(Arena *arena) {
|
||||||
static HittableList world = {.type = HITTABLE_LIST};
|
HittableList *world = hittable_list_create(arena);
|
||||||
|
|
||||||
const Lambertian *ground_material =
|
const Lambertian *ground_material =
|
||||||
lambertian_create((Color){0.5, 0.5, 0.5}, arena);
|
lambertian_create((Color){0.5, 0.5, 0.5}, arena);
|
||||||
const Sphere *ground_sphere =
|
const Sphere *ground_sphere =
|
||||||
sphere_create((Point3){0.0, -1000.0, 0.0}, 1000.0,
|
sphere_create((Point3){0.0, -1000.0, 0.0}, 1000.0,
|
||||||
(const Material *)ground_material, arena);
|
(const Material *)ground_material, arena);
|
||||||
hittable_list_add(&world, (const Hittable *)ground_sphere, arena);
|
hittable_list_add(world, (const Hittable *)ground_sphere, arena);
|
||||||
|
|
||||||
const Dielectric *glass = dielectric_create(1.5, arena);
|
const Dielectric *glass = dielectric_create(1.5, arena);
|
||||||
|
|
||||||
@ -61,18 +61,18 @@ static const Hittable *generate_random_scene(Arena *arena) {
|
|||||||
const MovingSphere *sphere =
|
const MovingSphere *sphere =
|
||||||
moving_sphere_create(center, center2, 0.0, 1.0, 0.2,
|
moving_sphere_create(center, center2, 0.0, 1.0, 0.2,
|
||||||
(const Material *)material, arena);
|
(const Material *)material, arena);
|
||||||
hittable_list_add(&world, (const Hittable *)sphere, arena);
|
hittable_list_add(world, (const Hittable *)sphere, arena);
|
||||||
} else if (choose_material < 0.95) {
|
} else if (choose_material < 0.95) {
|
||||||
const Metal *material =
|
const Metal *material =
|
||||||
metal_create(color_random_in_range(0.5, 1),
|
metal_create(color_random_in_range(0.5, 1),
|
||||||
random_double_in_range(0.5, 1.0), arena);
|
random_double_in_range(0.5, 1.0), arena);
|
||||||
const Sphere *sphere =
|
const Sphere *sphere =
|
||||||
sphere_create(center, 0.2, (const Material *)material, arena);
|
sphere_create(center, 0.2, (const Material *)material, arena);
|
||||||
hittable_list_add(&world, (const Hittable *)sphere, arena);
|
hittable_list_add(world, (const Hittable *)sphere, arena);
|
||||||
} else {
|
} else {
|
||||||
const Sphere *sphere =
|
const Sphere *sphere =
|
||||||
sphere_create(center, 0.2, (const Material *)glass, arena);
|
sphere_create(center, 0.2, (const Material *)glass, arena);
|
||||||
hittable_list_add(&world, (const Hittable *)sphere, arena);
|
hittable_list_add(world, (const Hittable *)sphere, arena);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,18 +84,22 @@ static const Hittable *generate_random_scene(Arena *arena) {
|
|||||||
|
|
||||||
const Sphere *sphere1 = sphere_create((Point3){0.0, 1.0, 0.0}, 1.0,
|
const Sphere *sphere1 = sphere_create((Point3){0.0, 1.0, 0.0}, 1.0,
|
||||||
(const Material *)glass, arena);
|
(const Material *)glass, arena);
|
||||||
hittable_list_add(&world, (const Hittable *)sphere1, arena);
|
hittable_list_add(world, (const Hittable *)sphere1, arena);
|
||||||
const Sphere *sphere2 = sphere_create((Point3){-4.0, 1.0, 0.0}, 1.0,
|
const Sphere *sphere2 = sphere_create((Point3){-4.0, 1.0, 0.0}, 1.0,
|
||||||
(const Material *)lambertian, arena);
|
(const Material *)lambertian, arena);
|
||||||
hittable_list_add(&world, (const Hittable *)sphere2, arena);
|
hittable_list_add(world, (const Hittable *)sphere2, arena);
|
||||||
const Sphere *sphere3 = sphere_create((Point3){4.0, 1.0, 0.0}, 1.0,
|
const Sphere *sphere3 = sphere_create((Point3){4.0, 1.0, 0.0}, 1.0,
|
||||||
(const Material *)metal, arena);
|
(const Material *)metal, arena);
|
||||||
hittable_list_add(&world, (const Hittable *)sphere3, arena);
|
hittable_list_add(world, (const Hittable *)sphere3, arena);
|
||||||
|
|
||||||
return (const Hittable *)&world;
|
BVHNode *bvh_root =
|
||||||
|
bvh_node_create(world->objects, 0, world->size, 0.0, 1.0, arena);
|
||||||
|
return (const Hittable *)bvh_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
srand(42);
|
||||||
|
|
||||||
/* Memory management */
|
/* Memory management */
|
||||||
|
|
||||||
const unsigned int buffer_size = 1 * 1024 * 1024;
|
const unsigned int buffer_size = 1 * 1024 * 1024;
|
||||||
@ -152,6 +156,7 @@ int main(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "aabb.c"
|
||||||
#include "arena.c"
|
#include "arena.c"
|
||||||
#include "camera.c"
|
#include "camera.c"
|
||||||
#include "color.c"
|
#include "color.c"
|
||||||
|
|||||||
4
utils.c
4
utils.c
@ -11,6 +11,10 @@ double random_double_in_range(double min, double max) {
|
|||||||
return min + (max - min) * random_double();
|
return min + (max - min) * random_double();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int random_int_in_range(int min, int max) {
|
||||||
|
return (int)(random_double_in_range(min, max + 1));
|
||||||
|
}
|
||||||
|
|
||||||
double clamp(double x, double min, double max) {
|
double clamp(double x, double min, double max) {
|
||||||
if (x < min)
|
if (x < min)
|
||||||
return min;
|
return min;
|
||||||
|
|||||||
1
utils.h
1
utils.h
@ -5,6 +5,7 @@ double degrees_to_radians(double degrees);
|
|||||||
|
|
||||||
double random_double(void);
|
double random_double(void);
|
||||||
double random_double_in_range(double min, double max);
|
double random_double_in_range(double min, double max);
|
||||||
|
int random_int_in_range(int min, int max);
|
||||||
|
|
||||||
double clamp(double x, double min, double max);
|
double clamp(double x, double min, double max);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user