summaryrefslogtreecommitdiffstats
path: root/libdimension/dimension/model
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2014-08-19 17:10:03 -0400
committerTavian Barnes <tavianator@tavianator.com>2015-10-25 11:03:56 -0400
commit7b09710392d35fb55b52031d447a542d99fc6b4b (patch)
tree270eb927ee8c52ceeb99926ebf4843704775a610 /libdimension/dimension/model
parent200c86b91ea7063d35be3bffc11c5da53c054653 (diff)
downloaddimension-7b09710392d35fb55b52031d447a542d99fc6b4b.tar.xz
Modularize the libdimension codebase.
Diffstat (limited to 'libdimension/dimension/model')
-rw-r--r--libdimension/dimension/model/camera.h66
-rw-r--r--libdimension/dimension/model/cameras.h34
-rw-r--r--libdimension/dimension/model/csg.h59
-rw-r--r--libdimension/dimension/model/finish.h141
-rw-r--r--libdimension/dimension/model/finishes.h51
-rw-r--r--libdimension/dimension/model/interior.h44
-rw-r--r--libdimension/dimension/model/light.h76
-rw-r--r--libdimension/dimension/model/lights.h33
-rw-r--r--libdimension/dimension/model/object.h165
-rw-r--r--libdimension/dimension/model/objects.h103
-rw-r--r--libdimension/dimension/model/pigment.h86
-rw-r--r--libdimension/dimension/model/pigments.h66
-rw-r--r--libdimension/dimension/model/scene.h95
-rw-r--r--libdimension/dimension/model/texture.h57
14 files changed, 1076 insertions, 0 deletions
diff --git a/libdimension/dimension/model/camera.h b/libdimension/dimension/model/camera.h
new file mode 100644
index 0000000..37f80b9
--- /dev/null
+++ b/libdimension/dimension/model/camera.h
@@ -0,0 +1,66 @@
+/*************************************************************************
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Cameras.
+ */
+
+/* Forward-declare dmnsn_camera */
+typedef struct dmnsn_camera dmnsn_camera;
+
+/**
+ * Camera ray callback.
+ * @param[in] camera The camera itself.
+ * @param[in] x The x coordinate of the pixel (in [0, 1]).
+ * @param[in] y The y coordinate of the pixel (in [0, 1]).
+ * @return The ray through (\p x, \p y).
+ */
+typedef dmnsn_ray dmnsn_camera_ray_fn(const dmnsn_camera *camera, double x, double y);
+
+/** A camera. */
+struct dmnsn_camera {
+ /* Callback functions */
+ dmnsn_camera_ray_fn *ray_fn; /**< Camera ray callback. */
+
+ dmnsn_matrix trans; /**< Transformation matrix. */
+};
+
+/**
+ * Create a dummy camera.
+ * @param[in] pool The memory pool to allocate from.
+ * @return The allocated camera.
+ */
+dmnsn_camera *dmnsn_new_camera(dmnsn_pool *pool);
+
+/**
+ * Initialize a dmnsn_camera field.
+ * @param[out] camera The camera to initialize.
+ */
+void dmnsn_init_camera(dmnsn_camera *camera);
+
+/**
+ * Invoke the camera ray callback, then correctly transform the ray.
+ * @param[in] camera The camera itself.
+ * @param[in] x The x coordinate of the pixel (in [0, 1]).
+ * @param[in] y The y coordinate of the pixel (in [0, 1]).
+ * @return The ray through (\p x, \p y).
+ */
+dmnsn_ray dmnsn_camera_ray(const dmnsn_camera *camera, double x, double y);
diff --git a/libdimension/dimension/model/cameras.h b/libdimension/dimension/model/cameras.h
new file mode 100644
index 0000000..9ef2646
--- /dev/null
+++ b/libdimension/dimension/model/cameras.h
@@ -0,0 +1,34 @@
+/*************************************************************************
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Pre-defined camera types.
+ */
+
+/**
+ * A perspective camera. The camera is located at the origin, looking at
+ * (0, 0, 1). The feild of view is the section of the plane z = 1 from
+ * (-0.5, -0.5) to (0.5, 0.5). Rays are transformed by the camera's
+ * transformation matrix.
+ * @param[in] pool The memory pool to allocate from.
+ * @return A perspective camera.
+ */
+dmnsn_camera *dmnsn_new_perspective_camera(dmnsn_pool *pool);
diff --git a/libdimension/dimension/model/csg.h b/libdimension/dimension/model/csg.h
new file mode 100644
index 0000000..b2ce83f
--- /dev/null
+++ b/libdimension/dimension/model/csg.h
@@ -0,0 +1,59 @@
+/*************************************************************************
+ * Copyright (C) 2010-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Constructive solid geometry
+ */
+
+/**
+ * CSG union.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] objects The objects from which to compose the union.
+ * @return A union of the objects in \p objects.
+ */
+dmnsn_object *dmnsn_new_csg_union(dmnsn_pool *pool, dmnsn_array *objects);
+
+/**
+ * CSG intersection.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in,out] A The first object.
+ * @param[in,out] B The second object.
+ * @return The intersection of \p A and \p B.
+ */
+dmnsn_object *dmnsn_new_csg_intersection(dmnsn_pool *pool, dmnsn_object *A, dmnsn_object *B);
+
+/**
+ * CSG intersection.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in,out] A The outer object.
+ * @param[in,out] B The inner object.
+ * @return The difference between \p A and \p B.
+ */
+dmnsn_object *dmnsn_new_csg_difference(dmnsn_pool *pool, dmnsn_object *A, dmnsn_object *B);
+
+/**
+ * CSG Merge.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in,out] A The first object.
+ * @param[in,out] B The second object.
+ * @return The merge of \p A and \p B.
+ */
+dmnsn_object *dmnsn_new_csg_merge(dmnsn_pool *pool, dmnsn_object *A, dmnsn_object *B);
diff --git a/libdimension/dimension/model/finish.h b/libdimension/dimension/model/finish.h
new file mode 100644
index 0000000..d975877
--- /dev/null
+++ b/libdimension/dimension/model/finish.h
@@ -0,0 +1,141 @@
+/*************************************************************************
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Object finishes.
+ */
+
+/* Ambient component */
+
+/** Ambient finish component. */
+typedef struct dmnsn_ambient {
+ dmnsn_color ambient; /**< Ambient light. */
+} dmnsn_ambient;
+
+/** Allocate an ambient component. */
+dmnsn_ambient *dmnsn_new_ambient(dmnsn_pool *pool, dmnsn_color ambient);
+
+/* Diffuse component */
+
+typedef struct dmnsn_diffuse dmnsn_diffuse;
+
+/**
+ * Diffuse reflection callback.
+ * @param[in] diffuse The diffuse object itself.
+ * @param[in] light The color of the light illuminating the object.
+ * @param[in] color The pigment of the object.
+ * @param[in] ray The direction of the light source.
+ * @param[in] normal The normal vector of the surface.
+ * @return The diffuse reflection component of the object's color.
+ */
+typedef dmnsn_color dmnsn_diffuse_fn(const dmnsn_diffuse *diffuse,
+ dmnsn_color light, dmnsn_color color,
+ dmnsn_vector ray, dmnsn_vector normal);
+
+/** Diffuse finish component. */
+struct dmnsn_diffuse {
+ dmnsn_diffuse_fn *diffuse_fn; /**< Diffuse callback. */
+};
+
+/** Allocate a dummy diffuse component. */
+dmnsn_diffuse *dmnsn_new_diffuse(dmnsn_pool *pool);
+/** Initialize a dmnsn_diffuse field. */
+void dmnsn_init_diffuse(dmnsn_diffuse *diffuse);
+
+/* Specular component */
+
+typedef struct dmnsn_specular dmnsn_specular;
+
+/**
+ * Specular highlight callback.
+ * @param[in] specular The specular object itself.
+ * @param[in] light The color of the light illuminating the object.
+ * @param[in] color The pigment of the object.
+ * @param[in] ray The direction of the light source.
+ * @param[in] normal The normal vector of the surface.
+ * @param[in] viewer The direction of the viewer.
+ * @return The specular reflection component of the object's color.
+ */
+typedef dmnsn_color dmnsn_specular_fn(const dmnsn_specular *specular,
+ dmnsn_color light, dmnsn_color color,
+ dmnsn_vector ray, dmnsn_vector normal,
+ dmnsn_vector viewer);
+
+/** Specular finish component. */
+struct dmnsn_specular {
+ dmnsn_specular_fn *specular_fn; /**< Specular callback. */
+};
+
+/** Allocate a dummy specular component. */
+dmnsn_specular *dmnsn_new_specular(dmnsn_pool *pool);
+/** Initialize a dmnsn_specular field. */
+void dmnsn_init_specular(dmnsn_specular *specular);
+
+/* Reflection component */
+
+typedef struct dmnsn_reflection dmnsn_reflection;
+
+/**
+ * Reflected light callback.
+ * @param[in] reflection The reflection object itself.
+ * @param[in] reflect The color of the reflected ray.
+ * @param[in] color The pigment of the object.
+ * @param[in] ray The direction of the reflected ray.
+ * @param[in] normal The normal vector of the surface.
+ * @return The contribution of the reflected ray to the object's color.
+ */
+typedef dmnsn_color dmnsn_reflection_fn(const dmnsn_reflection *reflection,
+ dmnsn_color reflect, dmnsn_color color,
+ dmnsn_vector ray, dmnsn_vector normal);
+
+/** The reflection component. */
+struct dmnsn_reflection {
+ dmnsn_reflection_fn *reflection_fn; /**< Reflection callback. */
+};
+
+/** Allocate a dummy reflection component. */
+dmnsn_reflection *dmnsn_new_reflection(dmnsn_pool *pool);
+/** Initialize a dmnsn_reflection field. */
+void dmnsn_init_reflection(dmnsn_reflection *reflection);
+
+/* Entire finishes */
+
+/** A finish. */
+typedef struct dmnsn_finish {
+ dmnsn_ambient *ambient; /**< Ambient component. */
+ dmnsn_diffuse *diffuse; /**< Diffuse component. */
+ dmnsn_specular *specular; /**< Specular component. */
+ dmnsn_reflection *reflection; /**< Reflection component. */
+} dmnsn_finish;
+
+/**
+ * Create a new blank finish.
+ * @return The new finish.
+ */
+dmnsn_finish dmnsn_new_finish(void);
+
+/**
+ * Fill missing finish properties from a default finish.
+ * @param[in] default_finish The default finish.
+ * @param[in,out] finish The finish to fill.
+ */
+void dmnsn_finish_cascade(const dmnsn_finish *default_finish,
+ dmnsn_finish *finish);
diff --git a/libdimension/dimension/model/finishes.h b/libdimension/dimension/model/finishes.h
new file mode 100644
index 0000000..e1f7b44
--- /dev/null
+++ b/libdimension/dimension/model/finishes.h
@@ -0,0 +1,51 @@
+/*************************************************************************
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Pre-defined finishes.
+ */
+
+/**
+ * Regular diffuse finish.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] diffuse The diffuse reflection coefficient.
+ * @return A diffuse finish component.
+ */
+dmnsn_diffuse *dmnsn_new_lambertian(dmnsn_pool *pool, double diffuse);
+
+/**
+ * A phong specular highlight.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] specular The specular reflection coefficient.
+ * @param[in] exp The exponent (roughly the highlight size).
+ * @return A phong specular finish component.
+ */
+dmnsn_specular *dmnsn_new_phong(dmnsn_pool *pool, double specular, double exp);
+
+/**
+ * Specular (mirror) reflection.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] min Reflection at paralell angles.
+ * @param[in] max Reflection at perpendicular angles (often == \p min).
+ * @param[in] falloff Degree of exponential falloff (usually 1).
+ * @return A reflective finish component.
+ */
+dmnsn_reflection *dmnsn_new_basic_reflection(dmnsn_pool *pool, dmnsn_color min, dmnsn_color max, double falloff);
diff --git a/libdimension/dimension/model/interior.h b/libdimension/dimension/model/interior.h
new file mode 100644
index 0000000..0ff697d
--- /dev/null
+++ b/libdimension/dimension/model/interior.h
@@ -0,0 +1,44 @@
+/*************************************************************************
+ * Copyright (C) 2010-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Object interiors.
+ */
+
+/** An interior. */
+typedef struct dmnsn_interior {
+ double ior; /**< Refractive index. */
+} dmnsn_interior;
+
+/**
+ * Create an interior object.
+ * @param[in] pool The memory pool to allocate from.
+ * @return The new interior.
+ */
+dmnsn_interior *dmnsn_new_interior(dmnsn_pool *pool);
+
+/**
+ * Fill missing interior properties from a default interior.
+ * @param[in] default_interior The default interior.
+ * @param[in,out] interiorp A pointer to the interior to fill.
+ */
+void dmnsn_interior_cascade(dmnsn_interior *default_interior,
+ dmnsn_interior **interiorp);
diff --git a/libdimension/dimension/model/light.h b/libdimension/dimension/model/light.h
new file mode 100644
index 0000000..218611d
--- /dev/null
+++ b/libdimension/dimension/model/light.h
@@ -0,0 +1,76 @@
+/*************************************************************************
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Lights.
+ */
+
+#include <stdbool.h>
+
+/* Forward-declar dmnsn_light */
+typedef struct dmnsn_light dmnsn_light;
+
+/**
+ * Light direction callback.
+ * @param[in] light The light itself.
+ * @param[in] v The point to illuminate.
+ * @return The direction of light rays pointing from \p v
+ */
+typedef dmnsn_vector dmnsn_light_direction_fn(const dmnsn_light *light,
+ dmnsn_vector v);
+
+/**
+ * Light illumination callback.
+ * @param[in] light The light itself.
+ * @param[in] v The point to illuminate.
+ * @return The color of the light at \p v.
+ */
+typedef dmnsn_color dmnsn_light_illumination_fn(const dmnsn_light *light,
+ dmnsn_vector v);
+
+/**
+ * Light shadow callback.
+ * @param[in] light The light itself.
+ * @param[in] t The line index of the closest shadow ray intersection.
+ * @return Whether the point is in shadow.
+ */
+typedef bool dmnsn_light_shadow_fn(const dmnsn_light *light, double t);
+
+/** A light. */
+struct dmnsn_light {
+ /* Callbacks */
+ dmnsn_light_direction_fn *direction_fn; /**< Direction callback. */
+ dmnsn_light_illumination_fn *illumination_fn; /**< Illumination callback. */
+ dmnsn_light_shadow_fn *shadow_fn; /**< Shadow callback. */
+};
+
+/**
+ * Create a dummy light.
+ * @param[in] pool The memory pool to allocate from.
+ * @return The allocated light.
+ */
+dmnsn_light *dmnsn_new_light(dmnsn_pool *pool);
+
+/**
+ * Initialize a dmnsn_light field.
+ * @param[out] light The light to initialize.
+ */
+void dmnsn_init_light(dmnsn_light *light);
diff --git a/libdimension/dimension/model/lights.h b/libdimension/dimension/model/lights.h
new file mode 100644
index 0000000..e7de4cc
--- /dev/null
+++ b/libdimension/dimension/model/lights.h
@@ -0,0 +1,33 @@
+/*************************************************************************
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Pre-defined light types.
+ */
+
+/**
+ * A point light.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] x0 The origin of the light.
+ * @param[in] color The color of the light.
+ * @return A point light.
+ */
+dmnsn_light *dmnsn_new_point_light(dmnsn_pool *pool, dmnsn_vector x0, dmnsn_color color);
diff --git a/libdimension/dimension/model/object.h b/libdimension/dimension/model/object.h
new file mode 100644
index 0000000..287d838
--- /dev/null
+++ b/libdimension/dimension/model/object.h
@@ -0,0 +1,165 @@
+/*************************************************************************
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Objects.
+ */
+
+#include <stdbool.h>
+
+/* Forward-declare dmnsn_object */
+typedef struct dmnsn_object dmnsn_object;
+
+/** A type to represent a ray-object intersection. */
+typedef struct dmnsn_intersection {
+ dmnsn_ray ray; /**< The ray that intersected. */
+ double t; /**< The ray index that intersected. */
+
+ /** The surface normal at the intersection point. */
+ dmnsn_vector normal;
+
+ /** The object of intersection. */
+ const dmnsn_object *object;
+} dmnsn_intersection;
+
+/**
+ * Ray-object intersection callback.
+ * @param[in] object The object to test.
+ * @param[in] ray The ray to test.
+ * @param[out] intersection Where to store the intersection details of the
+ * closest (if any) intersection.
+ * @return Whether \p ray intersected \p object.
+ */
+typedef bool dmnsn_object_intersection_fn(const dmnsn_object *object, dmnsn_ray ray, dmnsn_intersection *intersection);
+
+/**
+ * Object inside callback.
+ * @param[in] object The object to test.
+ * @param[in] point The point to test.
+ * @return Whether \p point is inside \p object.
+ */
+typedef bool dmnsn_object_inside_fn(const dmnsn_object *object, dmnsn_vector point);
+
+/**
+ * Object bounding callback.
+ * @param[in,out] object The object to bound.
+ * @param[in,out] trans The effective transformation for the object.
+ * @return A world-coordinate bounding box computed for the object.
+ */
+typedef dmnsn_aabb dmnsn_object_bounding_fn(const dmnsn_object *object, dmnsn_matrix trans);
+
+/**
+ * Object precomputation callback.
+ * @param[in,out] object The object to precompute.
+ */
+typedef void dmnsn_object_precompute_fn(dmnsn_object *object);
+
+/** Object callbacks. */
+typedef struct dmnsn_object_vtable {
+ dmnsn_object_intersection_fn *intersection_fn; /**< Intersection callback. */
+ dmnsn_object_inside_fn *inside_fn; /**< Inside callback. */
+ dmnsn_object_bounding_fn *bounding_fn; /**< Bounding callback. */
+ dmnsn_object_precompute_fn *precompute_fn; /**< Precomputation callback. */
+} dmnsn_object_vtable;
+
+/** An object. */
+struct dmnsn_object {
+ const dmnsn_object_vtable *vtable; /**< Callbacks. */
+
+ dmnsn_texture *texture; /**< Surface properties. */
+ dmnsn_interior *interior; /**< Interior properties. */
+
+ dmnsn_matrix trans; /**< Transformation matrix. */
+ dmnsn_matrix intrinsic_trans; /**< Transformations intrinsic to the object. */
+
+ dmnsn_array *children; /**< Child objects. */
+ bool split_children; /**< Whether the child objects can be split. */
+
+ /* Precomputed values */
+ bool precomputed; /**< @internal Whether the object is precomputed yet. */
+ dmnsn_matrix trans_inv; /**< Inverse of the transformation matrix. */
+ dmnsn_matrix pigment_trans; /**< Inverse transformation for the texture. */
+ dmnsn_aabb aabb; /**< Bounding box in world coordinates. */
+};
+
+/**
+ * Allocate a dummy object.
+ * @param[in] pool The memory pool to allocate from.
+ * @return The allocated object.
+ */
+dmnsn_object *dmnsn_new_object(dmnsn_pool *pool);
+
+/**
+ * Initialize a dmnsn_object field.
+ * @param[out] object The object to initialize.
+ */
+void dmnsn_init_object(dmnsn_object *object);
+
+/**
+ * Precompute values for an object and its children.
+ * @param[in,out] object The object to precompute.
+ */
+void dmnsn_object_precompute(dmnsn_object *object);
+
+/**
+ * Appropriately transform a ray, then test for an intersection.
+ * @param[in] object The object to test.
+ * @param[in] ray The ray to test.
+ * @param[out] intersection Where to store the intersection details.
+ * @return Whether there was an intersection.
+ */
+DMNSN_INLINE bool
+dmnsn_object_intersection(const dmnsn_object *object, dmnsn_ray ray,
+ dmnsn_intersection *intersection)
+{
+ dmnsn_ray ray_trans = dmnsn_transform_ray(object->trans_inv, ray);
+ intersection->object = NULL;
+ if (object->vtable->intersection_fn(object, ray_trans, intersection)) {
+ /* Get us back into world coordinates */
+ intersection->ray = ray;
+ intersection->normal = dmnsn_vector_normalized(
+ dmnsn_transform_normal(object->trans_inv, intersection->normal)
+ );
+ if (!intersection->object) {
+ intersection->object = object;
+ }
+
+ dmnsn_assert(!dmnsn_isnan(intersection->t), "Intersection point is NaN.");
+ dmnsn_assert(!dmnsn_vector_isnan(intersection->normal), "Intersection normal is NaN.");
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Appropriately transform a point, then test for containment.
+ * @param[in] object The object to test.
+ * @param[in] point The point to test.
+ * @return Whether \p point was inside \p object.
+ */
+DMNSN_INLINE bool
+dmnsn_object_inside(const dmnsn_object *object, dmnsn_vector point)
+{
+ point = dmnsn_transform_point(object->trans_inv, point);
+ return object->vtable->inside_fn(object, point);
+}
diff --git a/libdimension/dimension/model/objects.h b/libdimension/dimension/model/objects.h
new file mode 100644
index 0000000..2865d82
--- /dev/null
+++ b/libdimension/dimension/model/objects.h
@@ -0,0 +1,103 @@
+/*************************************************************************
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Pre-defined objects.
+ */
+
+#include <stdbool.h>
+
+/**
+ * A flat triangle.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] vertices The corners of the triangle.
+ * @return A triangle.
+ */
+dmnsn_object *dmnsn_new_triangle(dmnsn_pool *pool, dmnsn_vector vertices[3]);
+
+/**
+ * A triangle, with normals interpolated between the points.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] vertices The corners of the triangle.
+ * @param[in] normals The normals at each corner.
+ * @return A smooth triangle.
+ */
+dmnsn_object *dmnsn_new_smooth_triangle(dmnsn_pool *pool, dmnsn_vector vertices[3], dmnsn_vector normals[3]);
+
+/**
+ * A triangle fan.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] vertices The vertices of the fan, starting in the center.
+ * @param[in] nvertices The number of vertices.
+ * @return A triangle fan.
+ */
+dmnsn_object *dmnsn_new_triangle_fan(dmnsn_pool *pool, dmnsn_vector vertices[], size_t nvertices);
+
+/**
+ * A smooth triangle fan.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] vertices The vertices of the fan, starting in the center.
+ * @param[in] normals The normal vector for each vertex.
+ * @param[in] nvertices The number of vertices.
+ * @return A triangle fan.
+ */
+dmnsn_object *dmnsn_new_smooth_triangle_fan(dmnsn_pool *pool, dmnsn_vector vertices[], dmnsn_vector normals[], size_t nvertices);
+
+/**
+ * A plane.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] normal The normal vector of the plane.
+ * @return A plane through the origin, with the given normal.
+ */
+dmnsn_object *dmnsn_new_plane(dmnsn_pool *pool, dmnsn_vector normal);
+
+/**
+ * A sphere.
+ * @param[in] pool The memory pool to allocate from.
+ * @return A sphere of radius 1, centered at the origin.
+ */
+dmnsn_object *dmnsn_new_sphere(dmnsn_pool *pool);
+
+/**
+ * A cube.
+ * @param[in] pool The memory pool to allocate from.
+ * @return An axis-aligned cube, from (-1, -1, -1) to (1, 1, 1).
+ */
+dmnsn_object *dmnsn_new_cube(dmnsn_pool *pool);
+
+/**
+ * A cylinder/cone.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] r1 The bottom radius.
+ * @param[in] r2 The top radius.
+ * @param[in] open Whether to render caps.
+ * @return A cone slice, from r = \p r1 at y = -1, to r = \p r2 at y = 1
+ */
+dmnsn_object *dmnsn_new_cone(dmnsn_pool *pool, double r1, double r2, bool open);
+
+/**
+ * A torus.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] major The major radius.
+ * @param[in] minor The minor radius.
+ * @return A torus, centered at the origin and lying in the x-z plane.
+ */
+dmnsn_object *dmnsn_new_torus(dmnsn_pool *pool, double major, double minor);
diff --git a/libdimension/dimension/model/pigment.h b/libdimension/dimension/model/pigment.h
new file mode 100644
index 0000000..14d8bae
--- /dev/null
+++ b/libdimension/dimension/model/pigment.h
@@ -0,0 +1,86 @@
+/*************************************************************************
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Object pigments.
+ */
+
+/* Forward-declare dmnsn_pigment */
+typedef struct dmnsn_pigment dmnsn_pigment;
+
+/**
+ * Pigment callback.
+ * @param[in] pigment The pigment itself.
+ * @param[in] v The point to color.
+ * @return The color of the pigment at \p v.
+ */
+typedef dmnsn_tcolor dmnsn_pigment_fn(const dmnsn_pigment *pigment,
+ dmnsn_vector v);
+
+/**
+ * Pigment initializer callback.
+ * @param[in,out] pigment The pigment to initialize.
+ */
+typedef void dmnsn_pigment_initialize_fn(dmnsn_pigment *pigment);
+
+/** A pigment. */
+struct dmnsn_pigment {
+ dmnsn_pigment_fn *pigment_fn; /**< The pigment callback. */
+ dmnsn_pigment_initialize_fn *initialize_fn; /**< The initializer callback. */
+
+ dmnsn_matrix trans; /**< Transformation matrix. */
+ dmnsn_matrix trans_inv; /**< The inverse of the transformation matrix. */
+
+ /** Quick color -- used for low-quality renders. */
+ dmnsn_tcolor quick_color;
+
+ bool initialized; /** @internal Whether the pigment is initialized. */
+};
+
+/**
+ * Allocate a new dummy pigment.
+ * @param[in] pool The memory pool to allocate from.
+ * @return The allocated pigment.
+ */
+dmnsn_pigment *dmnsn_new_pigment(dmnsn_pool *pool);
+
+/**
+ * Initialize a dmnsn_pigment field.
+ * @param[out] pigment The pigment to initialize.
+ */
+void dmnsn_init_pigment(dmnsn_pigment *pigment);
+
+/**
+ * Initialize a pigment. Pigments should not be used before being initialized,
+ * but should not be modified after being initialized. Pigments are generally
+ * initialized for you.
+ * @param[in,out] pigment The pigment to initialize.
+ */
+void dmnsn_pigment_initialize(dmnsn_pigment *pigment);
+
+/**
+ * Evaluate the color of a pigment at a point.
+ * @param[in] pigment The pigment to evaluate.
+ * @param[in] v The point to color.
+ * @return The color at \p v.
+ */
+dmnsn_tcolor dmnsn_pigment_evaluate(const dmnsn_pigment *pigment,
+ dmnsn_vector v);
diff --git a/libdimension/dimension/model/pigments.h b/libdimension/dimension/model/pigments.h
new file mode 100644
index 0000000..100016d
--- /dev/null
+++ b/libdimension/dimension/model/pigments.h
@@ -0,0 +1,66 @@
+/*************************************************************************
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Pre-defined pigments.
+ */
+
+/**
+ * A solid color.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] color The color of the pigment.
+ * @return A pigment with the color \p color everywhere.
+ */
+dmnsn_pigment *dmnsn_new_solid_pigment(dmnsn_pool *pool, dmnsn_tcolor color);
+
+/**
+ * An image map. The image (regardless of its real dimensions) is projected
+ * on the x-y plane in tesselating unit squares.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in] canvas The canvas holding the image.
+ * @return An image-mapped pigment.
+ */
+dmnsn_pigment *dmnsn_new_canvas_pigment(dmnsn_pool *pool, dmnsn_canvas *canvas);
+
+/**
+ * Pigment map flags.
+ */
+typedef enum dmnsn_pigment_map_flags {
+ DMNSN_PIGMENT_MAP_REGULAR, /**< Calculate linear color gradients. */
+ DMNSN_PIGMENT_MAP_SRGB /**< Calculate sRGB color gradients. */
+} dmnsn_pigment_map_flags;
+
+/**
+ * Construct a pigment map.
+ * @param[in] pool The memory pool to allocate from.
+ * @return An empty pigment map.
+ */
+dmnsn_map *dmnsn_new_pigment_map(dmnsn_pool *pool);
+
+/**
+ * A pigment-mapped pigment.
+ * @param[in] pool The memory pool to allocate from.
+ * @param[in,out] pattern The pattern of the pigment.
+ * @param[in,out] map The pigment map to apply to the pattern.
+ * @param[in] flags Gradient flags
+ * @return A pigment mapping the pattern to other pigments.
+ */
+dmnsn_pigment *dmnsn_new_pigment_map_pigment(dmnsn_pool *pool, dmnsn_pattern *pattern, dmnsn_map *map, dmnsn_pigment_map_flags flags);
diff --git a/libdimension/dimension/model/scene.h b/libdimension/dimension/model/scene.h
new file mode 100644
index 0000000..dd0c1ba
--- /dev/null
+++ b/libdimension/dimension/model/scene.h
@@ -0,0 +1,95 @@
+/*************************************************************************
+ * Copyright (C) 2010-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Entire scenes.
+ */
+
+/** Render quality flags. */
+enum {
+ DMNSN_RENDER_NONE = 0, /**< Render nothing. */
+ DMNSN_RENDER_PIGMENT = 1 << 0, /**< Render pigments. */
+ DMNSN_RENDER_LIGHTS = 1 << 1, /**< Render lights and shadows. */
+ DMNSN_RENDER_FINISH = 1 << 2, /**< Render object finishes. */
+ DMNSN_RENDER_TRANSPARENCY = 1 << 3, /**< Render transparency/refraction. */
+ DMNSN_RENDER_REFLECTION = 1 << 4, /**< Render specular reflection. */
+ DMNSN_RENDER_FULL = ~DMNSN_RENDER_NONE /**< Render everything. */
+};
+
+/** Render quality. */
+typedef unsigned int dmnsn_quality;
+
+/** An entire scene. */
+typedef struct dmnsn_scene {
+ /* World attributes */
+ dmnsn_pigment *background; /**< Background pigment. */
+ dmnsn_texture *default_texture; /**< Default object texture. */
+ dmnsn_interior *default_interior; /**< Default object interior. */
+
+ /** Canvas. */
+ dmnsn_canvas *canvas;
+
+ /* Support for rendering image subregions. */
+ size_t region_x; /**< The x position of the canvas in the broader image. */
+ size_t region_y; /**< The y position of the canvas in the broader image. */
+ size_t outer_width; /**< Width of the broader image. */
+ size_t outer_height; /**< Height of the broader image. */
+
+ /** Objects. */
+ dmnsn_array *objects;
+
+ /** Lights. */
+ dmnsn_array *lights;
+
+ /** Camera. */
+ dmnsn_camera *camera;
+
+ /** Render quality. */
+ dmnsn_quality quality;
+
+ /** Recursion limit. */
+ unsigned int reclimit;
+
+ /** Adaptive depth control bailout. */
+ double adc_bailout;
+
+ /** Number of parallel threads. */
+ unsigned int nthreads;
+
+ /** Timers. */
+ dmnsn_timer bounding_timer;
+ dmnsn_timer render_timer;
+
+ bool initialized; /**< @internal Whether the scene is initialized. */
+} dmnsn_scene;
+
+/**
+ * Create a scene.
+ * @param[in] pool The memory pool to allocate from.
+ * @return A new empty scene.
+ */
+dmnsn_scene *dmnsn_new_scene(dmnsn_pool *pool);
+
+/**
+ * Initialize a scene.
+ * @param[in,out] scene The scene to initalize.
+ */
+void dmnsn_scene_initialize(dmnsn_scene *scene);
diff --git a/libdimension/dimension/model/texture.h b/libdimension/dimension/model/texture.h
new file mode 100644
index 0000000..df08a4a
--- /dev/null
+++ b/libdimension/dimension/model/texture.h
@@ -0,0 +1,57 @@
+/*************************************************************************
+ * Copyright (C) 2009-2014 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Library. *
+ * *
+ * The Dimension Library is free software; you can redistribute it and/ *
+ * or modify it under the terms of the GNU Lesser General Public License *
+ * as published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Library is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this program. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+/**
+ * @file
+ * Object textures.
+ */
+
+/** A complete texture. */
+typedef struct {
+ dmnsn_pigment *pigment; /**< Pigment. */
+ dmnsn_finish finish; /**< Finish. */
+
+ dmnsn_matrix trans; /**< Transformation matrix. */
+ dmnsn_matrix trans_inv; /**< The inverse of the transformation matrix. */
+
+ bool initialized; /**< @internal Whether the texture is initialized yet. */
+} dmnsn_texture;
+
+/**
+ * Create a blank texture.
+ * @param[in] pool The memory pool to allocate from.
+ * @return The new texture.
+ */
+dmnsn_texture *dmnsn_new_texture(dmnsn_pool *pool);
+
+/**
+ * Initialize a texture. Textures should not be used before being initialized,
+ * but should not be modified after being initialized. Textures are generally
+ * initialized for you.
+ * @param[in,out] texture The texture to initialize.
+ */
+void dmnsn_texture_initialize(dmnsn_texture *texture);
+
+/**
+ * Fill missing texture properties from a default texture.
+ * @param[in] default_texture The default texture.
+ * @param[in,out] texturep A pointer to the texture to fill.
+ */
+void dmnsn_texture_cascade(dmnsn_texture *default_texture, dmnsn_texture **texturep);