summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libdimension/camera.c29
-rw-r--r--libdimension/dimension/camera.h16
-rw-r--r--libdimension/dimension/object.h8
-rw-r--r--libdimension/scene.c4
-rw-r--r--libdimension/sphere.c4
-rw-r--r--tests/raytrace.c4
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;