Skip to content

Commit

Permalink
[#5] Add triangulated mesh hittable and sample scene that showcases it
Browse files Browse the repository at this point in the history
  • Loading branch information
Morozov-5F committed Nov 16, 2021
1 parent 72cd455 commit f6dc18b
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 33 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ add_executable(ray_tracing_one_week rt_camera.c rt_colour.c rt_aabb.c rt_perlin.
# Hittables
hittables/rt_hittable.c hittables/rt_sphere.c hittables/rt_hittable_list.c main.c hittables/rt_moving_sphere.c
hittables/rt_bvh.c hittables/rt_aa_rect.c hittables/rt_box.c hittables/rt_instance.c hittables/rt_const_medium.c
hittables/rt_triangle.c hittables/rt_triangle_mesh.c
# Textures
textures/rt_texture.c textures/rt_texture_solid_colour.c textures/rt_texture_checker_pattern.c
textures/rt_texture_noise.c textures/rt_texture_image.c
Expand All @@ -39,7 +40,7 @@ add_executable(ray_tracing_one_week rt_camera.c rt_colour.c rt_aabb.c rt_perlin.
# Random number generation
random/rt_random.c random/rt_random.h
# Threading
${THREADING_IMPLEMENTATION} threads/rt_thread_pool.c hittables/rt_triangle.c hittables/rt_triangle.h)
${THREADING_IMPLEMENTATION} threads/rt_thread_pool.c)

target_compile_options(ray_tracing_one_week PRIVATE $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
-Wall -Wextra -Winline>
Expand Down
3 changes: 3 additions & 0 deletions hittables/rt_hittable.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,7 @@ rt_hittable_t *rt_moving_sphere_new(point3_t center_start, point3_t center_end,
// Triangle
rt_hittable_t *rt_triangle_new(point3_t a, point3_t b, point3_t c, rt_material_t *material);

// Mesh composed of triangles
rt_hittable_t *rt_triangle_mesh_new(const point3_t *vertices, size_t vertices_count, const size_t *triangles, size_t triangles_count, rt_material_t *material);

#endif // RAY_TRACING_ONE_WEEK_RT_HITTABLE_H
1 change: 1 addition & 0 deletions hittables/rt_hittable_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ typedef enum rt_hittable_type_e
RT_HITTABLE_TYPE_INSTANCE,
RT_HITTABLE_CONSTANT_MEDIUM,
RT_HITTABLE_TYPE_TRIANGLE,
RT_HITTABLE_TYPE_MESH,
} rt_hittable_type_t;

typedef bool (*rt_hittable_hit_fn)(const rt_hittable_t *hittable, const ray_t *ray, double t_min, double t_max,
Expand Down
2 changes: 1 addition & 1 deletion hittables/rt_triangle.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
#include <assert.h>
#include <float.h>
#include "rt_triangle.h"
#include "rt_hittable.h"
#include "rt_hittable_shared.h"

typedef struct rt_triangle_s
Expand Down
12 changes: 0 additions & 12 deletions hittables/rt_triangle.h

This file was deleted.

108 changes: 108 additions & 0 deletions hittables/rt_triangle_mesh.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/**
* Copyright (c) 2021, Evgeniy Morozov
* All rights reserved.
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <assert.h>
#include "rt_weekend.h"
#include "rt_hittable.h"
#include "rt_hittable_shared.h"
#include "rt_hittable_list.h"

typedef struct rt_mesh_s
{
rt_hittable_t base;

rt_hittable_list_t *triangles;
vec3_t min, max;
} rt_mesh_t;

static rt_mesh_t rt_mesh_init(const point3_t *vertices, size_t vertices_count, const size_t *triangles, size_t triangles_count, rt_material_t *material);
static bool rt_mesh_hit(const rt_hittable_t *hittable, const ray_t *ray, double t_min, double t_max,
rt_hit_record_t *record);
static bool rt_mesh_bb(const rt_hittable_t *hittable, double time0, double time1, rt_aabb_t *out_bb);
static void rt_mesh_delete(rt_hittable_t *hittable);

rt_hittable_t *rt_triangle_mesh_new(const point3_t *vertices, size_t vertices_count, const size_t *triangles, size_t triangles_count, rt_material_t *material)
{
rt_mesh_t *mesh = (rt_mesh_t *)calloc(1, sizeof(rt_mesh_t));
assert(NULL != mesh);

*mesh = rt_mesh_init(vertices, vertices_count, triangles, triangles_count, material);
return (rt_hittable_t *)mesh;
}

static rt_mesh_t rt_mesh_init(const point3_t *vertices, size_t vertices_count, const size_t *triangles, size_t triangles_count,
rt_material_t *material)
{
assert(NULL != vertices);

rt_mesh_t result = {
.triangles = rt_hittable_list_init(triangles_count),
.min = vec3(0, 0, 0),
.max = vec3(0, 0, 0),
};
assert(NULL != triangles);

for (size_t i = 0; i < triangles_count; ++i)
{
assert(triangles[3 * i] < vertices_count);
point3_t a = vertices[triangles[3 * i]];

assert(triangles[3 * i + 1] < vertices_count);
point3_t b = vertices[triangles[3 * i + 1]];

assert(triangles[3 * i + 2] < vertices_count);
point3_t c = vertices[triangles[3 * i + 2]];

result.min.x = fmin(result.min.x, fmin(a.x, fmin(b.x, c.x)));
result.min.y = fmin(result.min.y, fmin(a.y, fmin(b.y, c.y)));
result.min.z = fmin(result.min.z, fmin(a.z, fmin(b.z, c.z)));

result.max.x = fmax(result.max.x, fmax(a.x, fmax(b.x, c.x)));
result.max.y = fmax(result.max.y, fmax(a.y, fmax(b.y, c.y)));
result.max.z = fmax(result.max.z, fmax(a.z, fmax(b.z, c.z)));

rt_hittable_list_add(result.triangles, rt_triangle_new(a, b, c, rt_material_claim(material)));
}

rt_material_delete(material);

rt_hittable_init(&result.base, RT_HITTABLE_TYPE_MESH, rt_mesh_hit, rt_mesh_bb, rt_mesh_delete);
return result;
}

static bool rt_mesh_hit(const rt_hittable_t *hittable, const ray_t *ray, double t_min, double t_max,
rt_hit_record_t *record)
{
assert(NULL != hittable);
assert(RT_HITTABLE_TYPE_MESH == hittable->type);

const rt_mesh_t *mesh = (const rt_mesh_t *)hittable;
return rt_hittable_list_hit_test(mesh->triangles, ray, t_min, t_max, record);
}

static bool rt_mesh_bb(const rt_hittable_t *hittable, double time0, double time1, rt_aabb_t *out_bb)
{
assert(NULL != hittable);
assert(RT_HITTABLE_TYPE_MESH == hittable->type);

const rt_mesh_t *mesh = (const rt_mesh_t *)hittable;
*out_bb = rt_aabb(mesh->min, mesh->max);

return true;
}

static void rt_mesh_delete(rt_hittable_t *hittable)
{
if (NULL == hittable)
{
return;
}
assert(RT_HITTABLE_TYPE_MESH == hittable->type);

const rt_mesh_t *mesh = (const rt_mesh_t *)hittable;
rt_hittable_list_deinit(mesh->triangles);
}

Binary file added images/mesh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion main.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ int main(int argc, char const *argv[])
return EXIT_FAILURE;

case RT_SCENE_TRIANGLE_TEST:
look_from = point3(0, 0, 20);
look_from = point3(0, 2, 20);
look_at = point3(0, 0, 0);
vertical_fov = 20.0;

Expand Down
32 changes: 14 additions & 18 deletions scenes/rt_scenes.c

Large diffs are not rendered by default.

0 comments on commit f6dc18b

Please sign in to comment.