From 7b09710392d35fb55b52031d447a542d99fc6b4b Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 19 Aug 2014 17:10:03 -0400 Subject: Modularize the libdimension codebase. --- libdimension/dimension/model/camera.h | 66 +++++++++++++ libdimension/dimension/model/cameras.h | 34 +++++++ libdimension/dimension/model/csg.h | 59 ++++++++++++ libdimension/dimension/model/finish.h | 141 +++++++++++++++++++++++++++ libdimension/dimension/model/finishes.h | 51 ++++++++++ libdimension/dimension/model/interior.h | 44 +++++++++ libdimension/dimension/model/light.h | 76 +++++++++++++++ libdimension/dimension/model/lights.h | 33 +++++++ libdimension/dimension/model/object.h | 165 ++++++++++++++++++++++++++++++++ libdimension/dimension/model/objects.h | 103 ++++++++++++++++++++ libdimension/dimension/model/pigment.h | 86 +++++++++++++++++ libdimension/dimension/model/pigments.h | 66 +++++++++++++ libdimension/dimension/model/scene.h | 95 ++++++++++++++++++ libdimension/dimension/model/texture.h | 57 +++++++++++ 14 files changed, 1076 insertions(+) create mode 100644 libdimension/dimension/model/camera.h create mode 100644 libdimension/dimension/model/cameras.h create mode 100644 libdimension/dimension/model/csg.h create mode 100644 libdimension/dimension/model/finish.h create mode 100644 libdimension/dimension/model/finishes.h create mode 100644 libdimension/dimension/model/interior.h create mode 100644 libdimension/dimension/model/light.h create mode 100644 libdimension/dimension/model/lights.h create mode 100644 libdimension/dimension/model/object.h create mode 100644 libdimension/dimension/model/objects.h create mode 100644 libdimension/dimension/model/pigment.h create mode 100644 libdimension/dimension/model/pigments.h create mode 100644 libdimension/dimension/model/scene.h create mode 100644 libdimension/dimension/model/texture.h (limited to 'libdimension/dimension/model') 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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @file + * Lights. + */ + +#include + +/* 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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @file + * Objects. + */ + +#include + +/* 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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @file + * Pre-defined objects. + */ + +#include + +/** + * 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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @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 * + * * + * 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 * + * . * + *************************************************************************/ + +/** + * @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); -- cgit v1.2.3