diff options
-rw-r--r-- | libdimension/camera.c | 29 | ||||
-rw-r--r-- | libdimension/dimension/camera.h | 16 | ||||
-rw-r--r-- | libdimension/dimension/object.h | 8 | ||||
-rw-r--r-- | libdimension/scene.c | 4 | ||||
-rw-r--r-- | libdimension/sphere.c | 4 | ||||
-rw-r--r-- | tests/raytrace.c | 4 |
6 files changed, 47 insertions, 18 deletions
diff --git a/libdimension/camera.c b/libdimension/camera.c index 2052785..282daaf 100644 --- a/libdimension/camera.c +++ b/libdimension/camera.c @@ -35,32 +35,49 @@ dmnsn_delete_camera(dmnsn_camera *camera) /* Perspective camera */ -static dmnsn_line dmnsn_perspective_camera_ray_fn(const dmnsn_canvas *canvas, +static dmnsn_line dmnsn_perspective_camera_ray_fn(const dmnsn_camera *camera, + const dmnsn_canvas *canvas, unsigned int x, unsigned int y); dmnsn_camera * -dmnsn_new_perspective_camera() +dmnsn_new_perspective_camera(dmnsn_matrix trans) { dmnsn_camera *camera = dmnsn_new_camera(); - camera->ray_fn = &dmnsn_perspective_camera_ray_fn; + if (camera) { + camera->ray_fn = &dmnsn_perspective_camera_ray_fn; + + camera->ptr = malloc(sizeof(dmnsn_matrix)); + if (!camera->ptr) { + dmnsn_delete_camera(camera); + return NULL; + } + *((dmnsn_matrix*)camera->ptr) = trans; + } return camera; } void dmnsn_delete_perspective_camera(dmnsn_camera *camera) { - dmnsn_delete_camera(camera); + if (camera) { + free(camera->ptr); + dmnsn_delete_camera(camera); + } } static dmnsn_line -dmnsn_perspective_camera_ray_fn(const dmnsn_canvas *canvas, +dmnsn_perspective_camera_ray_fn(const dmnsn_camera *camera, + const dmnsn_canvas *canvas, unsigned int x, unsigned int y) { + dmnsn_matrix *trans = (dmnsn_matrix *)camera->ptr; dmnsn_line l; + l.x0 = dmnsn_vector_construct(0.0, 0.0, 0.0); l.n.x = ((double)x)/(canvas->x - 1) - 0.5; l.n.y = ((double)y)/(canvas->y - 1) - 0.5; l.n.z = 1.0; - return l; + + return dmnsn_matrix_line_mul(*trans, l); } diff --git a/libdimension/dimension/camera.h b/libdimension/dimension/camera.h index b1c4ebe..4ea1cbe 100644 --- a/libdimension/dimension/camera.h +++ b/libdimension/dimension/camera.h @@ -25,23 +25,29 @@ * A camera. */ -typedef dmnsn_line dmnsn_camera_ray_fn(const dmnsn_canvas *canvas, +/* Forward-declare dmnsn_camera */ +typedef struct dmnsn_camera dmnsn_camera; + +/* Camera callback types */ +typedef dmnsn_line dmnsn_camera_ray_fn(const dmnsn_camera *camera, + const dmnsn_canvas *canvas, unsigned int x, unsigned int y); -typedef struct { +struct dmnsn_camera { /* Generic pointer for camera info */ void *ptr; /* Callback function */ dmnsn_camera_ray_fn *ray_fn; -} dmnsn_camera; +}; dmnsn_camera *dmnsn_new_camera(); void dmnsn_delete_camera(dmnsn_camera *camera); -/* A perspective camera, at the origin, looking at (0, 0, 1) */ +/* A perspective camera, at the origin, looking at (0, 0, 1). Rays are + transformed by the transformation matrix `trans'. */ -dmnsn_camera *dmnsn_new_perspective_camera(); +dmnsn_camera *dmnsn_new_perspective_camera(dmnsn_matrix trans); void dmnsn_delete_perspective_camera(dmnsn_camera *camera); #endif /* DIMENSION_CAMERA_H */ diff --git a/libdimension/dimension/object.h b/libdimension/dimension/object.h index b9702f4..bd660a0 100644 --- a/libdimension/dimension/object.h +++ b/libdimension/dimension/object.h @@ -25,19 +25,23 @@ * Objects. */ +/* Forward-declare dmnsn_object */ +typedef struct dmnsn_object dmnsn_object; + +/* Object callback types */ typedef dmnsn_array *dmnsn_object_intersections_fn(const dmnsn_object *object, dmnsn_line line); typedef int dmnsn_object_inside_fn(const dmnsn_object *object, dmnsn_vector point); -typedef struct { +struct dmnsn_object { /* Generic pointer for object info */ void *ptr; /* Callback functions */ dmnsn_object_intersections_fn *intersections_fn; dmnsn_object_inside_fn *inside_fn; -} dmnsn_object; +}; dmnsn_object *dmnsn_new_object(); void dmnsn_delete_object(dmnsn_object *object); diff --git a/libdimension/scene.c b/libdimension/scene.c index 780f8c6..4a84823 100644 --- a/libdimension/scene.c +++ b/libdimension/scene.c @@ -50,8 +50,8 @@ dmnsn_raytrace_scene(dmnsn_scene *scene) for (i = 0; i < scene->canvas->x; ++i) { for (j = 0; j < scene->canvas->y; ++j) { - ray = (*scene->camera->ray_fn)(scene->canvas, i, j); - if ((*object->intersections_fn)(ray)->length > 0) { + ray = (*scene->camera->ray_fn)(scene->camera, scene->canvas, i, j); + if ((*object->intersections_fn)(object, ray)->length > 0) { dmnsn_set_pixel(scene->canvas, i, j, dmnsn_color_from_XYZ(dmnsn_whitepoint)); } else { diff --git a/libdimension/sphere.c b/libdimension/sphere.c index 74f414d..2829720 100644 --- a/libdimension/sphere.c +++ b/libdimension/sphere.c @@ -22,9 +22,9 @@ #include <stdlib.h> /* For malloc */ #include <math.h> /* For sqrt */ -static dmnsn_array *dmnsn_sphere_intersections_fn(const dmnsn_sphere *sphere, +static dmnsn_array *dmnsn_sphere_intersections_fn(const dmnsn_object *sphere, dmnsn_line line); -static int dmnsn_sphere_inside_fn(const dmnsn_sphere *sphere, +static int dmnsn_sphere_inside_fn(const dmnsn_object *sphere, dmnsn_vector point); dmnsn_object * diff --git a/tests/raytrace.c b/tests/raytrace.c index 15c5d70..a05770b 100644 --- a/tests/raytrace.c +++ b/tests/raytrace.c @@ -33,7 +33,9 @@ int main() { scene = dmnsn_new_scene(); scene->canvas = dmnsn_new_canvas(768, 480); - scene->camera = dmnsn_new_perspective_camera(); + scene->camera = dmnsn_new_perspective_camera( + dmnsn_translation_matrix(dmnsn_vector_construct(0.0, 0.0, -3.0)) + ); sRGB.R = 0.0; sRGB.G = 0.0; |