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/array.h | 357 -------------------- libdimension/dimension/base.h | 46 +++ libdimension/dimension/base/array.h | 361 ++++++++++++++++++++ libdimension/dimension/base/common.h | 34 ++ libdimension/dimension/base/compiler.h | 139 ++++++++ libdimension/dimension/base/dictionary.h | 87 +++++ libdimension/dimension/base/error.h | 118 +++++++ libdimension/dimension/base/malloc.h | 70 ++++ libdimension/dimension/base/pool.h | 81 +++++ libdimension/dimension/camera.h | 67 ---- libdimension/dimension/cameras.h | 34 -- libdimension/dimension/canvas.h | 114 +------ libdimension/dimension/canvas/canvas.h | 131 ++++++++ libdimension/dimension/canvas/gl.h | 52 +++ libdimension/dimension/canvas/png.h | 75 +++++ libdimension/dimension/color.h | 177 +--------- libdimension/dimension/color/color.h | 198 +++++++++++ libdimension/dimension/color/tcolor.h | 116 +++++++ libdimension/dimension/common.h | 30 -- libdimension/dimension/compiler.h | 135 -------- libdimension/dimension/concurrency.h | 39 +++ libdimension/dimension/concurrency/future.h | 85 +++++ libdimension/dimension/csg.h | 59 ---- libdimension/dimension/dictionary.h | 83 ----- libdimension/dimension/error.h | 117 ------- libdimension/dimension/finish.h | 141 -------- libdimension/dimension/finishes.h | 51 --- libdimension/dimension/future.h | 79 ----- libdimension/dimension/geometry.h | 500 ---------------------------- libdimension/dimension/gl.h | 48 --- libdimension/dimension/interior.h | 44 --- libdimension/dimension/light.h | 76 ----- libdimension/dimension/lights.h | 33 -- libdimension/dimension/malloc.h | 66 ---- libdimension/dimension/map.h | 68 ---- libdimension/dimension/math.h | 82 +---- libdimension/dimension/math/aabb.h | 129 +++++++ libdimension/dimension/math/matrix.h | 193 +++++++++++ libdimension/dimension/math/ray.h | 83 +++++ libdimension/dimension/math/scalar.h | 103 ++++++ libdimension/dimension/math/vector.h | 183 ++++++++++ libdimension/dimension/model.h | 59 ++++ 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 ++++ libdimension/dimension/object.h | 164 --------- libdimension/dimension/objects.h | 103 ------ libdimension/dimension/pattern.h | 50 +-- libdimension/dimension/pattern/map.h | 68 ++++ libdimension/dimension/pattern/pattern.h | 62 ++++ libdimension/dimension/pattern/patterns.h | 48 +++ libdimension/dimension/patterns.h | 48 --- libdimension/dimension/pigment.h | 86 ----- libdimension/dimension/pigments.h | 66 ---- libdimension/dimension/platform.h | 39 +++ libdimension/dimension/platform/timer.h | 58 ++++ libdimension/dimension/png.h | 71 ---- libdimension/dimension/polynomial.h | 85 ----- libdimension/dimension/pool.h | 77 ----- libdimension/dimension/ray_trace.h | 37 -- libdimension/dimension/render.h | 41 +++ libdimension/dimension/render/render.h | 41 +++ libdimension/dimension/scene.h | 95 ------ libdimension/dimension/tcolor.h | 112 ------- libdimension/dimension/texture.h | 57 ---- libdimension/dimension/timer.h | 54 --- 77 files changed, 3874 insertions(+), 3407 deletions(-) delete mode 100644 libdimension/dimension/array.h create mode 100644 libdimension/dimension/base.h create mode 100644 libdimension/dimension/base/array.h create mode 100644 libdimension/dimension/base/common.h create mode 100644 libdimension/dimension/base/compiler.h create mode 100644 libdimension/dimension/base/dictionary.h create mode 100644 libdimension/dimension/base/error.h create mode 100644 libdimension/dimension/base/malloc.h create mode 100644 libdimension/dimension/base/pool.h delete mode 100644 libdimension/dimension/camera.h delete mode 100644 libdimension/dimension/cameras.h create mode 100644 libdimension/dimension/canvas/canvas.h create mode 100644 libdimension/dimension/canvas/gl.h create mode 100644 libdimension/dimension/canvas/png.h create mode 100644 libdimension/dimension/color/color.h create mode 100644 libdimension/dimension/color/tcolor.h delete mode 100644 libdimension/dimension/common.h delete mode 100644 libdimension/dimension/compiler.h create mode 100644 libdimension/dimension/concurrency.h create mode 100644 libdimension/dimension/concurrency/future.h delete mode 100644 libdimension/dimension/csg.h delete mode 100644 libdimension/dimension/dictionary.h delete mode 100644 libdimension/dimension/error.h delete mode 100644 libdimension/dimension/finish.h delete mode 100644 libdimension/dimension/finishes.h delete mode 100644 libdimension/dimension/future.h delete mode 100644 libdimension/dimension/geometry.h delete mode 100644 libdimension/dimension/gl.h delete mode 100644 libdimension/dimension/interior.h delete mode 100644 libdimension/dimension/light.h delete mode 100644 libdimension/dimension/lights.h delete mode 100644 libdimension/dimension/malloc.h delete mode 100644 libdimension/dimension/map.h create mode 100644 libdimension/dimension/math/aabb.h create mode 100644 libdimension/dimension/math/matrix.h create mode 100644 libdimension/dimension/math/ray.h create mode 100644 libdimension/dimension/math/scalar.h create mode 100644 libdimension/dimension/math/vector.h create mode 100644 libdimension/dimension/model.h 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 delete mode 100644 libdimension/dimension/object.h delete mode 100644 libdimension/dimension/objects.h create mode 100644 libdimension/dimension/pattern/map.h create mode 100644 libdimension/dimension/pattern/pattern.h create mode 100644 libdimension/dimension/pattern/patterns.h delete mode 100644 libdimension/dimension/patterns.h delete mode 100644 libdimension/dimension/pigment.h delete mode 100644 libdimension/dimension/pigments.h create mode 100644 libdimension/dimension/platform.h create mode 100644 libdimension/dimension/platform/timer.h delete mode 100644 libdimension/dimension/png.h delete mode 100644 libdimension/dimension/polynomial.h delete mode 100644 libdimension/dimension/pool.h delete mode 100644 libdimension/dimension/ray_trace.h create mode 100644 libdimension/dimension/render.h create mode 100644 libdimension/dimension/render/render.h delete mode 100644 libdimension/dimension/scene.h delete mode 100644 libdimension/dimension/tcolor.h delete mode 100644 libdimension/dimension/texture.h delete mode 100644 libdimension/dimension/timer.h (limited to 'libdimension/dimension') diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h deleted file mode 100644 index 9261a0e..0000000 --- a/libdimension/dimension/array.h +++ /dev/null @@ -1,357 +0,0 @@ -/************************************************************************* - * 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 - * Simple dynamic arrays. - */ - -#include /* For size_t */ -#include /* For qsort() */ -#include /* For memcpy() */ - -/** Dynamic array type. */ -typedef struct dmnsn_array { - void *ptr; /**< @internal The actual memory. */ - size_t obj_size; /**< @internal The size of each object. */ - size_t length; /**< @internal The current size of the array. */ - size_t capacity; /**< @internal The size of the allocated space. */ -} dmnsn_array; - -/** - * @internal - * Initialize a new array. - * @param[out] array The array to initialize. - * @param[in] obj_size The size of the objects to store in the array. - */ -DMNSN_INLINE void -dmnsn_init_array(dmnsn_array *array, size_t obj_size) -{ - array->obj_size = obj_size; - array->length = 0; - array->capacity = 2; /* Start with capacity of 2 */ - - /* Allocate the memory */ - array->ptr = dmnsn_malloc(array->capacity*array->obj_size); -} - -/** - * Allocate an array. - * @param[in] obj_size The size of the objects to store in the array. - * @return An empty array. - */ -DMNSN_INLINE dmnsn_array * -dmnsn_new_array(size_t obj_size) -{ - dmnsn_array *array = DMNSN_MALLOC(dmnsn_array); - dmnsn_init_array(array, obj_size); - return array; -} - -/** - * Allocate an array. - * @param[in] type Type type of element to store in the array. - * @return An empty array. - */ -#define DMNSN_NEW_ARRAY(type) (dmnsn_new_array(sizeof(type))) - -/** - * Delete an array. - * @param[in,out] array The array to delete. - */ -DMNSN_INLINE void -dmnsn_delete_array(dmnsn_array *array) -{ - if (array) { - dmnsn_free(array->ptr); - dmnsn_free(array); - } -} - -/** - * @internal - * Free a pool-allocated array. - * @param[in,out] ptr The array to clean up. - */ -void dmnsn_array_cleanup(void *ptr); - -/** - * Allocate an array from a pool. - * @param[in] pool The memory pool to allocate from. - * @param[in] obj_size The size of the objects to store in the array. - * @return An empty array. - */ -DMNSN_INLINE dmnsn_array * -dmnsn_palloc_array(dmnsn_pool *pool, size_t obj_size) -{ - dmnsn_array *array = DMNSN_PALLOC_TIDY(pool, dmnsn_array, dmnsn_array_cleanup); - dmnsn_init_array(array, obj_size); - return array; -} - -/** - * Allocate an array from a pool. - * @param[in] pool The memory pool to allocate from. - * @param[in] type Type type of element to store in the array. - * @return An empty array. - */ -#define DMNSN_PALLOC_ARRAY(pool, type) (dmnsn_palloc_array(pool, sizeof(type))) - -/** - * Get the size of the array. - * @param[in] array The array in question. - * @return The number of elements in the array. - */ -DMNSN_INLINE size_t -dmnsn_array_size(const dmnsn_array *array) -{ - return array->length; -} - -/** - * Set the size of the array. - * @param[in,out] array The array to resize. - * @param[in] length The new length of the array. - */ -DMNSN_INLINE void -dmnsn_array_resize(dmnsn_array *array, size_t length) -{ - if (length > array->capacity) { - /* Resize if we don't have enough capacity */ - array->capacity = length*2; /* We are greedy */ - array->ptr = dmnsn_realloc(array->ptr, array->obj_size*array->capacity); - } - - array->length = length; -} - -/** - * Copy an array. - * @param[in] array The array to copy. - * @return A copy of the array. - */ -DMNSN_INLINE dmnsn_array * -dmnsn_array_copy(const dmnsn_array *array) -{ - dmnsn_array *copy = dmnsn_new_array(array->obj_size); - dmnsn_array_resize(copy, dmnsn_array_size(array)); - memcpy(copy->ptr, array->ptr, dmnsn_array_size(array)*array->obj_size); - return copy; -} - -/** - * Split an array in half. - * @param[in,out] array The array to split. - * @return The second half of the array. - */ -DMNSN_INLINE dmnsn_array * -dmnsn_array_split(dmnsn_array *array) -{ - dmnsn_array *half = dmnsn_new_array(array->obj_size); - size_t new_size = dmnsn_array_size(array)/2; - size_t old_size = dmnsn_array_size(array) - new_size; - dmnsn_array_resize(half, new_size); - memcpy(half->ptr, (char *)array->ptr + old_size*array->obj_size, - new_size*array->obj_size); - dmnsn_array_resize(array, old_size); - return half; -} - -/** - * Get the i'th element. - * @param[in] array The array to access. - * @param[in] i The index of the element to extract. - * @param[out] obj The location to store the extracted object. - */ -DMNSN_INLINE void -dmnsn_array_get(const dmnsn_array *array, size_t i, void *obj) -{ - dmnsn_assert(i < dmnsn_array_size(array), "Array index out of bounds."); - memcpy(obj, (char *)array->ptr + array->obj_size*i, array->obj_size); -} - -/** - * Set the i'th object, expanding the array if necessary. - * @param[in,out] array The array to modify. - * @param[in] i The index to update. - * @param[in] obj The location of the object to copy into the array. - */ -DMNSN_INLINE void -dmnsn_array_set(dmnsn_array *array, size_t i, const void *obj) -{ - if (i >= dmnsn_array_size(array)) { - /* Resize if i is out of range */ - dmnsn_array_resize(array, i + 1); - } - memcpy((char *)array->ptr + array->obj_size*i, obj, array->obj_size); -} - -/** - * First element. - * @param[in] array The array to index. - * @return The address of the first element of the array. - */ -DMNSN_INLINE void * -dmnsn_array_first(const dmnsn_array *array) -{ - return array->ptr; -} - -/** - * Last element. - * @param[in] array The array to index. - * @return The address of the last element of the array. - */ -DMNSN_INLINE void * -dmnsn_array_last(const dmnsn_array *array) -{ - return (char *)array->ptr + array->obj_size*(array->length - 1); -} - -/** - * Arbitrary element access. - * @param[in] array The array to index. - * @param[in] i The index to access. - * @return The address of the i'th element of the array. - */ -DMNSN_INLINE void * -dmnsn_array_at(const dmnsn_array *array, size_t i) -{ - dmnsn_assert(i < dmnsn_array_size(array), "Array index out of bounds."); - return (char *)array->ptr + array->obj_size*i; -} - -/** - * Push an object to the end of the array. - * @param[in,out] array The array to append to. - * @param[in] obj The location of the object to push. - */ -DMNSN_INLINE void -dmnsn_array_push(dmnsn_array *array, const void *obj) -{ - dmnsn_array_set(array, dmnsn_array_size(array), obj); -} - -/** - * Pop an object from the end of the array. - * @param[in,out] array The array to pop from. - * @param[out] obj The location to store the extracted object. - */ -DMNSN_INLINE void -dmnsn_array_pop(dmnsn_array *array, void *obj) -{ - size_t size = dmnsn_array_size(array); - dmnsn_assert(size > 0, "Array is empty."); - dmnsn_array_get(array, size - 1, obj); /* Copy the object */ - dmnsn_array_resize(array, size - 1); /* Shrink the array */ -} - -/** - * Insert an item into the middle of the array. This is O(n). - * @param[in,out] array The array to insert to. - * @param[in] i The index at which to insert. - * @param[in] obj The object to insert. - */ -DMNSN_INLINE void -dmnsn_array_insert(dmnsn_array *array, size_t i, const void *obj) -{ - size_t size = dmnsn_array_size(array) + 1; - if (i >= size) - size = i + 1; - dmnsn_array_resize(array, size); - - /* Move the elements at and after `i' 1 to the right */ - memmove((char *)array->ptr + array->obj_size*(i + 1), - (char *)array->ptr + array->obj_size*i, - array->obj_size*(size - i - 1)); - /* Insert `obj' at `i' */ - memcpy((char *)array->ptr + array->obj_size*i, obj, array->obj_size); -} - -/** - * Remove an item from the middle of the array. This is O(n). - * @param[in,out] array The array to remove from. - * @param[in] i The index to remove. - */ -DMNSN_INLINE void -dmnsn_array_remove(dmnsn_array *array, size_t i) -{ - size_t size = dmnsn_array_size(array); - dmnsn_assert(i < size, "Array index out of bounds."); - /* Move the array elements after `i' 1 to the left */ - memmove((char *)array->ptr + array->obj_size*i, - (char *)array->ptr + array->obj_size*(i + 1), - array->obj_size*(size - i - 1)); - /* Decrease the size by 1 */ - dmnsn_array_resize(array, size - 1); -} - -/** - * Apply a callback to each element of an array. - * @param[in,out] array The array. - * @param[in] callback The callback to apply to the elements. - */ -DMNSN_INLINE void -dmnsn_array_apply(dmnsn_array *array, dmnsn_callback_fn *callback) -{ - char *i, *last = (char *)dmnsn_array_last(array); - for (i = (char *)dmnsn_array_first(array); i <= last; i += array->obj_size) { - callback((void *)i); - } -} - -/** - * Callback type for array sorting. - * @param[in] a The first element. - * @param[in] b The second element. - * @return A negative value iff a < b, zero iff a == b, and a positive value iff - * a > b. - */ -typedef int dmnsn_array_comparator_fn(const void *a, const void *b); - -/** - * Sort an array. - * @param[in,out] array The array to sort. - * @param[in] comparator The sorting comparator to use. - */ -DMNSN_INLINE void -dmnsn_array_sort(dmnsn_array *array, dmnsn_array_comparator_fn *comparator) -{ - qsort(array->ptr, dmnsn_array_size(array), array->obj_size, comparator); -} - -/* Macros to shorten array iteration */ - -/** - * Iterate over an array. For example, - * @code - * DMNSN_ARRAY_FOREACH (int *, i, array) { - * printf("%d\n", *i); - * } - * @endcode - * - * @param type The (pointer) type to use as an iterator. - * @param i The name of the iterator within the loop body. - * @param[in] array The array to loop over. - */ -#define DMNSN_ARRAY_FOREACH(type, i, array) \ - for (type i = dmnsn_array_first(array); \ - (size_t)(i - (type)dmnsn_array_first(array)) < dmnsn_array_size(array); \ - ++i) diff --git a/libdimension/dimension/base.h b/libdimension/dimension/base.h new file mode 100644 index 0000000..d9f063f --- /dev/null +++ b/libdimension/dimension/base.h @@ -0,0 +1,46 @@ +/************************************************************************* + * Copyright (C) 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 + * Basic functionality: compiler abstractions, error reporting, memory + * management, data structures, etc. + */ + +#ifndef DMNSN_BASE_H +#define DMNSN_BASE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif /* DMNSN_BASE_H */ diff --git a/libdimension/dimension/base/array.h b/libdimension/dimension/base/array.h new file mode 100644 index 0000000..a54d0e5 --- /dev/null +++ b/libdimension/dimension/base/array.h @@ -0,0 +1,361 @@ +/************************************************************************* + * 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 + * Simple dynamic arrays. + */ + +#ifndef DMNSN_BASE_H +#error "Please include instead of this header directly." +#endif + +#include /* For size_t */ +#include /* For qsort() */ +#include /* For memcpy() */ + +/** Dynamic array type. */ +typedef struct dmnsn_array { + void *ptr; /**< @internal The actual memory. */ + size_t obj_size; /**< @internal The size of each object. */ + size_t length; /**< @internal The current size of the array. */ + size_t capacity; /**< @internal The size of the allocated space. */ +} dmnsn_array; + +/** + * @internal + * Initialize a new array. + * @param[out] array The array to initialize. + * @param[in] obj_size The size of the objects to store in the array. + */ +DMNSN_INLINE void +dmnsn_init_array(dmnsn_array *array, size_t obj_size) +{ + array->obj_size = obj_size; + array->length = 0; + array->capacity = 2; /* Start with capacity of 2 */ + + /* Allocate the memory */ + array->ptr = dmnsn_malloc(array->capacity*array->obj_size); +} + +/** + * Allocate an array. + * @param[in] obj_size The size of the objects to store in the array. + * @return An empty array. + */ +DMNSN_INLINE dmnsn_array * +dmnsn_new_array(size_t obj_size) +{ + dmnsn_array *array = DMNSN_MALLOC(dmnsn_array); + dmnsn_init_array(array, obj_size); + return array; +} + +/** + * Allocate an array. + * @param[in] type Type type of element to store in the array. + * @return An empty array. + */ +#define DMNSN_NEW_ARRAY(type) (dmnsn_new_array(sizeof(type))) + +/** + * Delete an array. + * @param[in,out] array The array to delete. + */ +DMNSN_INLINE void +dmnsn_delete_array(dmnsn_array *array) +{ + if (array) { + dmnsn_free(array->ptr); + dmnsn_free(array); + } +} + +/** + * @internal + * Free a pool-allocated array. + * @param[in,out] ptr The array to clean up. + */ +void dmnsn_array_cleanup(void *ptr); + +/** + * Allocate an array from a pool. + * @param[in] pool The memory pool to allocate from. + * @param[in] obj_size The size of the objects to store in the array. + * @return An empty array. + */ +DMNSN_INLINE dmnsn_array * +dmnsn_palloc_array(dmnsn_pool *pool, size_t obj_size) +{ + dmnsn_array *array = DMNSN_PALLOC_TIDY(pool, dmnsn_array, dmnsn_array_cleanup); + dmnsn_init_array(array, obj_size); + return array; +} + +/** + * Allocate an array from a pool. + * @param[in] pool The memory pool to allocate from. + * @param[in] type Type type of element to store in the array. + * @return An empty array. + */ +#define DMNSN_PALLOC_ARRAY(pool, type) (dmnsn_palloc_array(pool, sizeof(type))) + +/** + * Get the size of the array. + * @param[in] array The array in question. + * @return The number of elements in the array. + */ +DMNSN_INLINE size_t +dmnsn_array_size(const dmnsn_array *array) +{ + return array->length; +} + +/** + * Set the size of the array. + * @param[in,out] array The array to resize. + * @param[in] length The new length of the array. + */ +DMNSN_INLINE void +dmnsn_array_resize(dmnsn_array *array, size_t length) +{ + if (length > array->capacity) { + /* Resize if we don't have enough capacity */ + array->capacity = length*2; /* We are greedy */ + array->ptr = dmnsn_realloc(array->ptr, array->obj_size*array->capacity); + } + + array->length = length; +} + +/** + * Copy an array. + * @param[in] array The array to copy. + * @return A copy of the array. + */ +DMNSN_INLINE dmnsn_array * +dmnsn_array_copy(const dmnsn_array *array) +{ + dmnsn_array *copy = dmnsn_new_array(array->obj_size); + dmnsn_array_resize(copy, dmnsn_array_size(array)); + memcpy(copy->ptr, array->ptr, dmnsn_array_size(array)*array->obj_size); + return copy; +} + +/** + * Split an array in half. + * @param[in,out] array The array to split. + * @return The second half of the array. + */ +DMNSN_INLINE dmnsn_array * +dmnsn_array_split(dmnsn_array *array) +{ + dmnsn_array *half = dmnsn_new_array(array->obj_size); + size_t new_size = dmnsn_array_size(array)/2; + size_t old_size = dmnsn_array_size(array) - new_size; + dmnsn_array_resize(half, new_size); + memcpy(half->ptr, (char *)array->ptr + old_size*array->obj_size, + new_size*array->obj_size); + dmnsn_array_resize(array, old_size); + return half; +} + +/** + * Get the i'th element. + * @param[in] array The array to access. + * @param[in] i The index of the element to extract. + * @param[out] obj The location to store the extracted object. + */ +DMNSN_INLINE void +dmnsn_array_get(const dmnsn_array *array, size_t i, void *obj) +{ + dmnsn_assert(i < dmnsn_array_size(array), "Array index out of bounds."); + memcpy(obj, (char *)array->ptr + array->obj_size*i, array->obj_size); +} + +/** + * Set the i'th object, expanding the array if necessary. + * @param[in,out] array The array to modify. + * @param[in] i The index to update. + * @param[in] obj The location of the object to copy into the array. + */ +DMNSN_INLINE void +dmnsn_array_set(dmnsn_array *array, size_t i, const void *obj) +{ + if (i >= dmnsn_array_size(array)) { + /* Resize if i is out of range */ + dmnsn_array_resize(array, i + 1); + } + memcpy((char *)array->ptr + array->obj_size*i, obj, array->obj_size); +} + +/** + * First element. + * @param[in] array The array to index. + * @return The address of the first element of the array. + */ +DMNSN_INLINE void * +dmnsn_array_first(const dmnsn_array *array) +{ + return array->ptr; +} + +/** + * Last element. + * @param[in] array The array to index. + * @return The address of the last element of the array. + */ +DMNSN_INLINE void * +dmnsn_array_last(const dmnsn_array *array) +{ + return (char *)array->ptr + array->obj_size*(array->length - 1); +} + +/** + * Arbitrary element access. + * @param[in] array The array to index. + * @param[in] i The index to access. + * @return The address of the i'th element of the array. + */ +DMNSN_INLINE void * +dmnsn_array_at(const dmnsn_array *array, size_t i) +{ + dmnsn_assert(i < dmnsn_array_size(array), "Array index out of bounds."); + return (char *)array->ptr + array->obj_size*i; +} + +/** + * Push an object to the end of the array. + * @param[in,out] array The array to append to. + * @param[in] obj The location of the object to push. + */ +DMNSN_INLINE void +dmnsn_array_push(dmnsn_array *array, const void *obj) +{ + dmnsn_array_set(array, dmnsn_array_size(array), obj); +} + +/** + * Pop an object from the end of the array. + * @param[in,out] array The array to pop from. + * @param[out] obj The location to store the extracted object. + */ +DMNSN_INLINE void +dmnsn_array_pop(dmnsn_array *array, void *obj) +{ + size_t size = dmnsn_array_size(array); + dmnsn_assert(size > 0, "Array is empty."); + dmnsn_array_get(array, size - 1, obj); /* Copy the object */ + dmnsn_array_resize(array, size - 1); /* Shrink the array */ +} + +/** + * Insert an item into the middle of the array. This is O(n). + * @param[in,out] array The array to insert to. + * @param[in] i The index at which to insert. + * @param[in] obj The object to insert. + */ +DMNSN_INLINE void +dmnsn_array_insert(dmnsn_array *array, size_t i, const void *obj) +{ + size_t size = dmnsn_array_size(array) + 1; + if (i >= size) + size = i + 1; + dmnsn_array_resize(array, size); + + /* Move the elements at and after `i' 1 to the right */ + memmove((char *)array->ptr + array->obj_size*(i + 1), + (char *)array->ptr + array->obj_size*i, + array->obj_size*(size - i - 1)); + /* Insert `obj' at `i' */ + memcpy((char *)array->ptr + array->obj_size*i, obj, array->obj_size); +} + +/** + * Remove an item from the middle of the array. This is O(n). + * @param[in,out] array The array to remove from. + * @param[in] i The index to remove. + */ +DMNSN_INLINE void +dmnsn_array_remove(dmnsn_array *array, size_t i) +{ + size_t size = dmnsn_array_size(array); + dmnsn_assert(i < size, "Array index out of bounds."); + /* Move the array elements after `i' 1 to the left */ + memmove((char *)array->ptr + array->obj_size*i, + (char *)array->ptr + array->obj_size*(i + 1), + array->obj_size*(size - i - 1)); + /* Decrease the size by 1 */ + dmnsn_array_resize(array, size - 1); +} + +/** + * Apply a callback to each element of an array. + * @param[in,out] array The array. + * @param[in] callback The callback to apply to the elements. + */ +DMNSN_INLINE void +dmnsn_array_apply(dmnsn_array *array, dmnsn_callback_fn *callback) +{ + char *i, *last = (char *)dmnsn_array_last(array); + for (i = (char *)dmnsn_array_first(array); i <= last; i += array->obj_size) { + callback((void *)i); + } +} + +/** + * Callback type for array sorting. + * @param[in] a The first element. + * @param[in] b The second element. + * @return A negative value iff a < b, zero iff a == b, and a positive value iff + * a > b. + */ +typedef int dmnsn_array_comparator_fn(const void *a, const void *b); + +/** + * Sort an array. + * @param[in,out] array The array to sort. + * @param[in] comparator The sorting comparator to use. + */ +DMNSN_INLINE void +dmnsn_array_sort(dmnsn_array *array, dmnsn_array_comparator_fn *comparator) +{ + qsort(array->ptr, dmnsn_array_size(array), array->obj_size, comparator); +} + +/* Macros to shorten array iteration */ + +/** + * Iterate over an array. For example, + * @code + * DMNSN_ARRAY_FOREACH (int *, i, array) { + * printf("%d\n", *i); + * } + * @endcode + * + * @param type The (pointer) type to use as an iterator. + * @param i The name of the iterator within the loop body. + * @param[in] array The array to loop over. + */ +#define DMNSN_ARRAY_FOREACH(type, i, array) \ + for (type i = dmnsn_array_first(array); \ + (size_t)(i - (type)dmnsn_array_first(array)) < dmnsn_array_size(array); \ + ++i) diff --git a/libdimension/dimension/base/common.h b/libdimension/dimension/base/common.h new file mode 100644 index 0000000..b947b4a --- /dev/null +++ b/libdimension/dimension/base/common.h @@ -0,0 +1,34 @@ +/************************************************************************* + * Copyright (C) 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 + * Common types and utilities. + */ + +#ifndef DMNSN_BASE_H +#error "Please include instead of this header directly." +#endif + +/** + * Generic callback type. + * @param[in,out] ptr A pointer to an object to act on. + */ +typedef void dmnsn_callback_fn(void *ptr); diff --git a/libdimension/dimension/base/compiler.h b/libdimension/dimension/base/compiler.h new file mode 100644 index 0000000..a83f1b9 --- /dev/null +++ b/libdimension/dimension/base/compiler.h @@ -0,0 +1,139 @@ +/************************************************************************* + * 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 + * Compiler abstractions. + */ + +#ifndef DMNSN_BASE_H +#error "Please include instead of this header directly." +#endif + +/** + * @internal + * @def DMNSN_C_VERSION + * The C version according to \p __STDC_VERSION__ if available, otherwise 0. + */ +#ifdef __STDC_VERSION__ + #define DMNSN_C_VERSION __STDC_VERSION__ +#else + #define DMNSN_C_VERSION 0L +#endif + +/** + * @internal + * @def DMNSN_CXX_VERSION + * The C++ version according to \p __cplusplus if available, otherwise 0. + */ +#ifdef __cplusplus + #define DMNSN_CXX_VERSION __cplusplus +#else + #define DMNSN_CXX_VERSION 0L +#endif + +/** + * @internal + * Whether we're being compiled as C++. + */ +#define DMNSN_CXX (DMNSN_CXX_VERSION > 0) + +/** + * @internal + * Whether C++11 features are supported. + */ +#define DMNSN_CXX11 (DMNSN_CXX_VERSION >= 201103L) + +/** + * @internal + * Whether C99 features are supported. + */ +#define DMNSN_C99 (DMNSN_C_VERSION >= 199901L || DMNSN_CXX11) + +/** + * @internal + * Whether C11 features are supported. + */ +#define DMNSN_C11 (DMNSN_C_VERSION >= 201112L) + +/** + * @internal + * Whether GNU C features are supported. + */ +#define DMNSN_GNUC defined(__GNUC__) + +/** + * @def DMNSN_INLINE + * A portable inline specifier. Expands to the correct method of declaring + * inline functions for the version of C you are using. + */ +#ifndef DMNSN_INLINE + #if DMNSN_CXX + /* C++ inline semantics */ + #define DMNSN_INLINE inline + #elif DMNSN_C99 + /* C99 inline semantics */ + #define DMNSN_INLINE inline + #elif DMNSN_GNUC + /* GCC inline semantics */ + #define DMNSN_INLINE __extension__ extern __inline__ + #else + /* Unknown C - mark functions static and hope the compiler is smart enough + to inline them */ + #define DMNSN_INLINE static + #endif +#endif + +/** + * @def DMNSN_NORETURN + * A portable noreturn attribute. + */ +#if DMNSN_CXX11 + #define DMNSN_NORETURN [[noreturn]] void +#elif DMNSN_C11 + #define DMNSN_NORETURN _Noreturn void +#elif DMNSN_GNUC + #define DMNSN_NORETURN __attribute__((noreturn)) void +#else + #define DMNSN_NORETURN void +#endif + +/** + * @internal + * @def DMNSN_FUNC + * @brief Expands to the name of the current function + */ +#if DMNSN_GNUC + #define DMNSN_FUNC __PRETTY_FUNCTION__ +#elif DMNSN_C99 + #define DMNSN_FUNC __func__ +#else + #define DMNSN_FUNC "" +#endif + +/** + * @internal + * An unreachable statement. + */ +#if DMNSN_GNUC + #define DMNSN_UNREACHABLE() __builtin_unreachable() +#else + #define DMNSN_UNREACHABLE() ((void)0) +#endif diff --git a/libdimension/dimension/base/dictionary.h b/libdimension/dimension/base/dictionary.h new file mode 100644 index 0000000..7360b45 --- /dev/null +++ b/libdimension/dimension/base/dictionary.h @@ -0,0 +1,87 @@ +/************************************************************************* + * Copyright (C) 2010-2011 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 + * Simple associative arrays. + */ + +#ifndef DMNSN_BASE_H +#error "Please include instead of this header directly." +#endif + +/** A string-object associative array. */ +typedef struct dmnsn_dictionary dmnsn_dictionary; + +/** + * Allocate a dictionary. + * @param[in] obj_size The size of the objects to store in the dictionary. + * @return An empty dictionary. + */ +dmnsn_dictionary *dmnsn_new_dictionary(size_t obj_size); + +/** + * Delete a dictionary. + * @param[in,out] dict The dictionary to delete. + */ +void dmnsn_delete_dictionary(dmnsn_dictionary *dict); + +/** + * Find an element in a dictionary. + * @param[in] dict The dictionary to search. + * @param[in] key The key to search for. + * @param[out] obj The location to store the found object. + * @return Whether the element was found. + */ +bool dmnsn_dictionary_get(const dmnsn_dictionary *dict, const char *key, + void *obj); + +/** + * Access an element in a dictionary. + * @param[in] dict The dictionary to search. + * @param[in] key The key to search for. + * @return A pointer to the element if found, otherwise NULL. + */ +void *dmnsn_dictionary_at(const dmnsn_dictionary *dict, const char *key); + +/** + * Insert a (key, value) pair into a dictionary. + * @param[in,out] dict The dictionary to modify. + * @param[in] key The key to insert. + * @param[in] obj The object to insert. + */ +void dmnsn_dictionary_insert(dmnsn_dictionary *dict, const char *key, + const void *obj); + +/** + * Remove a (key, value) pair from a dictionary. + * @param[in,out] dict The dictionary to modify. + * @param[in] key The key to remove. + * @return Whether the key existed in the dictionary. + */ +bool dmnsn_dictionary_remove(dmnsn_dictionary *dict, const char *key); + +/** + * Apply a callback to all elements in a dictionary. + * @param[in,out] dict The dictionary. + * @param[in] callback The callback to apply to the elements. + */ +void dmnsn_dictionary_apply(dmnsn_dictionary *dict, + dmnsn_callback_fn *callback); diff --git a/libdimension/dimension/base/error.h b/libdimension/dimension/base/error.h new file mode 100644 index 0000000..d039081 --- /dev/null +++ b/libdimension/dimension/base/error.h @@ -0,0 +1,118 @@ +/************************************************************************* + * 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 + * Error reporting. + */ + +#ifndef DMNSN_BASE_H +#error "Please include instead of this header directly." +#endif + +#include + +/** + * Report a warning. + * @param[in] str A string to print explaining the warning. + */ +#define dmnsn_warning(str) \ + dmnsn_report_warning(DMNSN_FUNC, __FILE__, __LINE__, str) + +/** + * Report an error. + * @param[in] str A string to print explaining the error. + */ +#define dmnsn_error(str) \ + dmnsn_report_error(DMNSN_FUNC, __FILE__, __LINE__, str) + +/** + * @def dmnsn_assert + * Make an assertion. + * @param[in] expr The expression to assert. + * @param[in] str A string to print if the assertion fails. + */ +#if DMNSN_DEBUG + #define dmnsn_assert(expr, str) \ + do { \ + if (!(expr)) { \ + dmnsn_error((str)); \ + } \ + } while (0) +#else + #define dmnsn_assert(expr, str) ((void)0) +#endif + +/** + * @def dmnsn_unreachable + * Express that a line of code is unreachable. + * @param[in] str A string to print if the line is reached. + */ +#if DMNSN_DEBUG + #define dmnsn_unreachable(str) dmnsn_error((str)) +#else + #define dmnsn_unreachable(str) DMNSN_UNREACHABLE() +#endif + +/** + * @internal + * Called by dmnsn_warning(); don't call directly. + * @param[in] func The name of the function where the error originated. + * @param[in] file The file where the error originated. + * @param[in] line The line number where the error originated. + * @param[in] str A string describing the error. + */ +void dmnsn_report_warning(const char *func, const char *file, unsigned int line, const char *str); + +/** + * @internal + * Called by dmnsn_error(); don't call directly. + * @param[in] func The name of the function where the error originated. + * @param[in] file The file where the error originated. + * @param[in] line The line number where the error originated. + * @param[in] str A string describing the error. + */ +DMNSN_NORETURN dmnsn_report_error(const char *func, const char *file, unsigned int line, const char *str); + +/** + * Treat warnings as errors. + * @param[in] always_die Whether to die on warnings. + */ +void dmnsn_die_on_warnings(bool always_die); + +/** + * Fatal error callback type. This function should never return. + */ +typedef void dmnsn_fatal_error_fn(void); + +/** + * Get the libdimension fatal error handler, thread-safely. The default fatal + * error handler terminates the current thread, or the entire program if the + * current thread is the main thread. + * @return The current fatal error handler. + */ +dmnsn_fatal_error_fn *dmnsn_get_fatal_error_fn(void); + +/** + * Set the libdimension fatal error handler, thread-safely. + * @param[in] fatal The new fatal error handler. This function must never + * return. + */ +void dmnsn_set_fatal_error_fn(dmnsn_fatal_error_fn *fatal); diff --git a/libdimension/dimension/base/malloc.h b/libdimension/dimension/base/malloc.h new file mode 100644 index 0000000..fcc492e --- /dev/null +++ b/libdimension/dimension/base/malloc.h @@ -0,0 +1,70 @@ +/************************************************************************* + * 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 + * Dynamic memory. dmnsn_malloc() and friends behave like their + * non-dmnsn_-prefixed counterparts, but never return NULL. If allocation + * fails, they instead call dmnsn_error(). + */ + +#ifndef DMNSN_BASE_H +#error "Please include instead of this header directly." +#endif + +#include /* For size_t */ + +/** + * Allocate some memory. Always use dmnsn_free() to free this memory, never + * free(). + * @param[in] size The size of the memory block to allocate. + * @return The allocated memory area. + */ +void *dmnsn_malloc(size_t size); + +/** + * Allocate some memory. Always use dmnsn_free() to free this memory, never + * free(). + * @param[in] type The type of the memory block to allocate. + * @return The allocated memory area. + */ +#define DMNSN_MALLOC(type) ((type *)dmnsn_malloc(sizeof(type))) + +/** + * Expand or shrink an allocation created by dmnsn_malloc(). + * @param[in] ptr The block to resize. + * @param[in] size The new size. + * @return The resized memory area. + */ +void *dmnsn_realloc(void *ptr, size_t size); + +/** + * Duplicate a string. + * @param[in] s The string to duplicate. + * @return A string with the same contents as \p s, suitable for release by + * dmnsn_free(). + */ +char *dmnsn_strdup(const char *s); + +/** + * Free memory allocated by dmnsn_malloc() or dmnsn_strdup(). + * @param[in] ptr The memory block to free, or NULL. + */ +void dmnsn_free(void *ptr); diff --git a/libdimension/dimension/base/pool.h b/libdimension/dimension/base/pool.h new file mode 100644 index 0000000..9983f1d --- /dev/null +++ b/libdimension/dimension/base/pool.h @@ -0,0 +1,81 @@ +/************************************************************************* + * Copyright (C) 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 + * Memory pools. Rather than more complicated garbage collection methods like + * reference counting, objects are allocated out of pools which are freed all at + * once once a scene is rendered (for example). + */ + +#ifndef DMNSN_BASE_H +#error "Please include instead of this header directly." +#endif + +#include /* For size_t */ + +/* Forward-declare dmnsn_pool. */ +typedef struct dmnsn_pool dmnsn_pool; + +/** + * Create a new memory pool. + * @return The new pool. + */ +dmnsn_pool *dmnsn_new_pool(void); + +/** + * Allocate some memory from a pool. + * @param[in] pool The memory pool to allocate from. + * @param[in] size The size of the memory block to allocate. + * @return The allocated memory area. + */ +void *dmnsn_palloc(dmnsn_pool *pool, size_t size); + +/** + * Allocate some memory from a pool. + * @param[in] pool The memory pool to allocate from. + * @param[in] size The size of the memory block to allocate. + * @param[in] cleanup_fn A callback to invoke before the memory is freed. + * @return The allocated memory area. + */ +void *dmnsn_palloc_tidy(dmnsn_pool *pool, size_t size, dmnsn_callback_fn *cleanup_fn); + +/** + * Allocate some memory from a pool. + * @param[in] pool The memory pool to allocate from. + * @param[in] type The type of the memory block to allocate. + * @return The allocated memory area. + */ +#define DMNSN_PALLOC(pool, type) ((type *)dmnsn_palloc((pool), sizeof(type))) + +/** + * Allocate some memory from a pool. + * @param[in] pool The memory pool to allocate from. + * @param[in] type The type of the memory block to allocate. + * @param[in] cleanup_fn A callback to invoke before the memory is freed. + * @return The allocated memory area. + */ +#define DMNSN_PALLOC_TIDY(pool, type, cleanup_fn) ((type *)dmnsn_palloc_tidy((pool), sizeof(type), (cleanup_fn))) + +/** + * Free a memory pool and all associated allocations. + * @param[in] pool The memory pool to free. + */ +void dmnsn_delete_pool(dmnsn_pool *pool); diff --git a/libdimension/dimension/camera.h b/libdimension/dimension/camera.h deleted file mode 100644 index 3c6494c..0000000 --- a/libdimension/dimension/camera.h +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************* - * 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_line 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_line dmnsn_camera_ray(const dmnsn_camera *camera, double x, double y); diff --git a/libdimension/dimension/cameras.h b/libdimension/dimension/cameras.h deleted file mode 100644 index 9ef2646..0000000 --- a/libdimension/dimension/cameras.h +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************* - * 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/canvas.h b/libdimension/dimension/canvas.h index e325364..53bbda3 100644 --- a/libdimension/dimension/canvas.h +++ b/libdimension/dimension/canvas.h @@ -1,5 +1,5 @@ /************************************************************************* - * Copyright (C) 2009-2014 Tavian Barnes * + * Copyright (C) 2014 Tavian Barnes * * * * This file is part of The Dimension Library. * * * @@ -20,108 +20,26 @@ /** * @file - * A canvas which is rendered to. + * Using, importing, and exporting canvases. */ -#include +#ifndef DMNSN_CANVAS_H +#define DMNSN_CANVAS_H -/** A canvas, or image. */ -typedef struct dmnsn_canvas { - size_t width; /**< Canvas width. */ - size_t height; /**< Canvas height. */ +#ifdef __cplusplus +extern "C" { +#endif - /** An array of dmnsn_canvas_optimizers. */ - dmnsn_array *optimizers; +#include +#include +#include - /** - * @internal - * Stored in first-quadrant representation (origin is bottom-left). The pixel - * at (a,b) is accessible as pixels[b*width + a]. - */ - dmnsn_tcolor *pixels; -} dmnsn_canvas; +#include +#include +#include -/* Forward-declare dmnsn_canvas_optimizer. */ -typedef struct dmnsn_canvas_optimizer dmnsn_canvas_optimizer; - -/** - * Canvas optimizer callback type. - * @param[in] optimizer The canvas optimizer. - * @param[in] canvas The canvas that was just updated. - * @param[in] x The x-coordinate that was just updated. - * @param[in] y The y-coordinate that was just updated. - */ -typedef void dmnsn_canvas_optimizer_fn(dmnsn_canvas_optimizer *optimizer, const dmnsn_canvas *canvas, size_t x, size_t y); - -/** Canvas optimizer. */ -struct dmnsn_canvas_optimizer { - dmnsn_canvas_optimizer_fn *optimizer_fn; /**< Optimizer callback. */ -}; - -/** - * Allocate a new canvas. - * @param[in] pool The memory pool to allocate from. - * @param[in] width The width of the canvas to allocate (in pixels). - * @param[in] height The height of the canvas to allocate (in pixels). - * @return The allocated canvas. - */ -dmnsn_canvas *dmnsn_new_canvas(dmnsn_pool *pool, size_t width, size_t height); - -/** - * Initialize a dmnsn_canvas_optimizer field - * @param[in] optimizer The optimizer to initialize. - */ -void dmnsn_init_canvas_optimizer(dmnsn_canvas_optimizer *optimizer); - -/** - * Set a canvas optimizer - * @param[in,out] canvas The canvas to optimize. - * @param[in] optimizer The optimizer to use. - */ -void dmnsn_canvas_optimize(dmnsn_canvas *canvas, - const dmnsn_canvas_optimizer *optimizer); - -/** - * Find a canvas optimizer by its callback. - * @param[in] canvas The canvas to check. - * @param[in] optimizer_fn The callback to search for for. - * @return A pointer to the canvas optimizer with the callback \p optimizer_fn, - * or NULL if none is found. - */ -dmnsn_canvas_optimizer * -dmnsn_canvas_find_optimizer(const dmnsn_canvas *canvas, - dmnsn_canvas_optimizer_fn *optimizer_fn); - -/* Pixel accessors */ - -/** - * Get the color of a pixel. - * @param[in] canvas The canvas to access. - * @param[in] x The x coordinate. - * @param[in] y The y coordinate. - * @return The color of the pixel at (\p x, \p y). - */ -DMNSN_INLINE dmnsn_tcolor -dmnsn_canvas_get_pixel(const dmnsn_canvas *canvas, size_t x, size_t y) -{ - dmnsn_assert(x < canvas->width && y < canvas->height, - "Canvas access out of bounds."); - return canvas->pixels[y*canvas->width + x]; +#ifdef __cplusplus } +#endif -/** - * Set the value of a pixel. - * @param[in,out] canvas The canvas to modify. - * @param[in] x The x coordinate of the pixel. - * @param[in] y The y coordinate of the pixel. - * @param[in] tcolor The value to set the pixel at (\p x, \p y) to. - */ -void dmnsn_canvas_set_pixel(dmnsn_canvas *canvas, size_t x, size_t y, - dmnsn_tcolor tcolor); - -/** - * Clear a canvas uniformly with a given color. - * @param[in,out] canvas The canvas to erase. - * @param[in] tcolor The color to paint it with. - */ -void dmnsn_canvas_clear(dmnsn_canvas *canvas, dmnsn_tcolor tcolor); +#endif /* DMNSN_CANVAS_H */ diff --git a/libdimension/dimension/canvas/canvas.h b/libdimension/dimension/canvas/canvas.h new file mode 100644 index 0000000..07d4fde --- /dev/null +++ b/libdimension/dimension/canvas/canvas.h @@ -0,0 +1,131 @@ +/************************************************************************* + * 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 + * A canvas which is rendered to. + */ + +#ifndef DMNSN_CANVAS_H +#error "Please include instead of this header directly." +#endif + +#include + +/** A canvas, or image. */ +typedef struct dmnsn_canvas { + size_t width; /**< Canvas width. */ + size_t height; /**< Canvas height. */ + + /** An array of dmnsn_canvas_optimizers. */ + dmnsn_array *optimizers; + + /** + * @internal + * Stored in first-quadrant representation (origin is bottom-left). The pixel + * at (a,b) is accessible as pixels[b*width + a]. + */ + dmnsn_tcolor *pixels; +} dmnsn_canvas; + +/* Forward-declare dmnsn_canvas_optimizer. */ +typedef struct dmnsn_canvas_optimizer dmnsn_canvas_optimizer; + +/** + * Canvas optimizer callback type. + * @param[in] optimizer The canvas optimizer. + * @param[in] canvas The canvas that was just updated. + * @param[in] x The x-coordinate that was just updated. + * @param[in] y The y-coordinate that was just updated. + */ +typedef void dmnsn_canvas_optimizer_fn(dmnsn_canvas_optimizer *optimizer, const dmnsn_canvas *canvas, size_t x, size_t y); + +/** Canvas optimizer. */ +struct dmnsn_canvas_optimizer { + dmnsn_canvas_optimizer_fn *optimizer_fn; /**< Optimizer callback. */ +}; + +/** + * Allocate a new canvas. + * @param[in] pool The memory pool to allocate from. + * @param[in] width The width of the canvas to allocate (in pixels). + * @param[in] height The height of the canvas to allocate (in pixels). + * @return The allocated canvas. + */ +dmnsn_canvas *dmnsn_new_canvas(dmnsn_pool *pool, size_t width, size_t height); + +/** + * Initialize a dmnsn_canvas_optimizer field + * @param[in] optimizer The optimizer to initialize. + */ +void dmnsn_init_canvas_optimizer(dmnsn_canvas_optimizer *optimizer); + +/** + * Set a canvas optimizer + * @param[in,out] canvas The canvas to optimize. + * @param[in] optimizer The optimizer to use. + */ +void dmnsn_canvas_optimize(dmnsn_canvas *canvas, + const dmnsn_canvas_optimizer *optimizer); + +/** + * Find a canvas optimizer by its callback. + * @param[in] canvas The canvas to check. + * @param[in] optimizer_fn The callback to search for for. + * @return A pointer to the canvas optimizer with the callback \p optimizer_fn, + * or NULL if none is found. + */ +dmnsn_canvas_optimizer * +dmnsn_canvas_find_optimizer(const dmnsn_canvas *canvas, + dmnsn_canvas_optimizer_fn *optimizer_fn); + +/* Pixel accessors */ + +/** + * Get the color of a pixel. + * @param[in] canvas The canvas to access. + * @param[in] x The x coordinate. + * @param[in] y The y coordinate. + * @return The color of the pixel at (\p x, \p y). + */ +DMNSN_INLINE dmnsn_tcolor +dmnsn_canvas_get_pixel(const dmnsn_canvas *canvas, size_t x, size_t y) +{ + dmnsn_assert(x < canvas->width && y < canvas->height, + "Canvas access out of bounds."); + return canvas->pixels[y*canvas->width + x]; +} + +/** + * Set the value of a pixel. + * @param[in,out] canvas The canvas to modify. + * @param[in] x The x coordinate of the pixel. + * @param[in] y The y coordinate of the pixel. + * @param[in] tcolor The value to set the pixel at (\p x, \p y) to. + */ +void dmnsn_canvas_set_pixel(dmnsn_canvas *canvas, size_t x, size_t y, + dmnsn_tcolor tcolor); + +/** + * Clear a canvas uniformly with a given color. + * @param[in,out] canvas The canvas to erase. + * @param[in] tcolor The color to paint it with. + */ +void dmnsn_canvas_clear(dmnsn_canvas *canvas, dmnsn_tcolor tcolor); diff --git a/libdimension/dimension/canvas/gl.h b/libdimension/dimension/canvas/gl.h new file mode 100644 index 0000000..c2d77a1 --- /dev/null +++ b/libdimension/dimension/canvas/gl.h @@ -0,0 +1,52 @@ +/************************************************************************* + * 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 + * OpenGL export/import of canvases. + */ + +#ifndef DMNSN_CANVAS_H +#error "Please include instead of this header directly." +#endif + +/** + * Optimize a canvas for GL drawing + * @param[in] pool The memory pool to allocate from. + * @param[in,out] canvas The canvas to optimize. + * @return Whether the canvas was successfully optimized. + */ +int dmnsn_gl_optimize_canvas(dmnsn_pool *pool, dmnsn_canvas *canvas); + +/** + * Write canvas to GL framebuffer. + * @param[in] canvas The canvas to draw. + * @return 0 on success, non-zero on failure. + */ +int dmnsn_gl_write_canvas(const dmnsn_canvas *canvas); + +/** + * Read a canvas from a GL framebuffer. + * @param[in] canvas The canvas to write to. + * @param[in] x0 The \a x screen coordinate to start copying from. + * @param[in] y0 The \a y screen coordinate to start copying from. + * @return 0 on success, non-zero on failure. + */ +int dmnsn_gl_read_canvas(dmnsn_canvas *canvas, size_t x0, size_t y0); diff --git a/libdimension/dimension/canvas/png.h b/libdimension/dimension/canvas/png.h new file mode 100644 index 0000000..57a68c2 --- /dev/null +++ b/libdimension/dimension/canvas/png.h @@ -0,0 +1,75 @@ +/************************************************************************* + * 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 + * PNG import/export of canvases. + */ + +#ifndef DMNSN_CANVAS_H +#error "Please include instead of this header directly." +#endif + +#include + +/** + * Optimize a canvas for PNG exporting + * @param[in] pool The memory pool to allocate from. + * @param[in,out] canvas The canvas to optimize. + * @return Whether the canvas was successfully optimized. + */ +int dmnsn_png_optimize_canvas(dmnsn_pool *pool, dmnsn_canvas *canvas); + +/** + * Write a canvas to a file in PNG format. + * @param[in] canvas The canvas to write. + * @param[in,out] file The file to write to. + * @return 0 on success, non-zero on failure. + */ +int dmnsn_png_write_canvas(const dmnsn_canvas *canvas, FILE *file); + +/** + * Write a canvas to a PNG file in the background. + * @param[in] canvas The canvas to write. + * @param[in,out] file The file to write to. + * @return A \ref dmnsn_future object, or NULL on failure. + */ +dmnsn_future *dmnsn_png_write_canvas_async(const dmnsn_canvas *canvas, + FILE *file); + +/** + * Read a canvas from a PNG file. + * @param[in] pool The memory pool to allocate from. + * @param[in,out] file The PNG file to read. + * @return The new canvas, or NULL on failure. + */ +dmnsn_canvas *dmnsn_png_read_canvas(dmnsn_pool *pool, FILE *file); + +/** + * Read a canvas from a PNG file in the background. + * @param[out] canvas The address of a non-allocated canvas object. The canvas + * object will be allocated and filled with the contents of + * \p file. Do not read from this object until the + * background task has finished. + * @param[in] pool The memory pool to allocate from. + * @param[in,out] file The PNG file to read. + * @return A \ref dmnsn_future object, or NULL on failure. + */ +dmnsn_future *dmnsn_png_read_canvas_async(dmnsn_canvas **canvas, dmnsn_pool *pool, FILE *file); diff --git a/libdimension/dimension/color.h b/libdimension/dimension/color.h index adbd396..74bed59 100644 --- a/libdimension/dimension/color.h +++ b/libdimension/dimension/color.h @@ -1,5 +1,5 @@ /************************************************************************* - * Copyright (C) 2009-2014 Tavian Barnes * + * Copyright (C) 2014 Tavian Barnes * * * * This file is part of The Dimension Library. * * * @@ -20,174 +20,23 @@ /** * @file - * Colors. + * Color handling. */ -#include +#ifndef DMNSN_COLOR_H +#define DMNSN_COLOR_H -/** A color value. */ -typedef struct { - double R; /**< Red component. */ - double G; /**< Green component. */ - double B; /**< Blue component. */ -} dmnsn_color; +#ifdef __cplusplus +extern "C" { +#endif -/** A standard format string for colors. */ -#define DMNSN_COLOR_FORMAT "Color<%g, %g, %g>" -/** The appropriate arguements to printf() a color. */ -#define DMNSN_COLOR_PRINTF(c) (c).R, (c).G, (c).B +#include -/** Construct a new color. */ -DMNSN_INLINE dmnsn_color -dmnsn_new_color(double R, double G, double B) -{ - dmnsn_color ret = { R, G, B }; - return ret; -} - -/** Apply sRGB gamma */ -DMNSN_INLINE double -dmnsn_sRGB_gamma(double Clinear) -{ - /* - * If C represents R, G, and B, then the sRGB values are now found as follows: - * - * { 12.92*Clinear, Clinear <= 0.0031308 - * Csrgb = { 1/2.4 - * { (1.055)*Clinear - 0.055, Clinear > 0.0031308 - */ - if (Clinear == 1.0) { - return 1.0; /* Map 1.0 to 1.0 instead of 0.9999999999999999 */ - } else if (Clinear > 0.0031308) { - return 1.055*pow(Clinear, 1.0/2.4) - 0.055; - } else { - return 12.92*Clinear; - } -} - -/** Convert to sRGB space. */ -DMNSN_INLINE dmnsn_color -dmnsn_color_to_sRGB(dmnsn_color color) -{ - return dmnsn_new_color( - dmnsn_sRGB_gamma(color.R), - dmnsn_sRGB_gamma(color.G), - dmnsn_sRGB_gamma(color.B) - ); -} - -/** Remove sRGB gamma */ -DMNSN_INLINE double -dmnsn_sRGB_inverse_gamma(double CsRGB) -{ - /* - * If C represents R, G, and B, then the Clinear values are now found as - * follows: - * - * { Csrgb/12.92, Csrgb <= 0.04045 - * Clinear = { 2.4 - * { ((Csrgb + 0.055)/1.055) , Csrgb > 0.04045 - */ - if (CsRGB == 1.0) { - return 1.0; /* Map 1.0 to 1.0 instead of 0.9999999999999999 */ - } else if (CsRGB <= 0.040449936) { - return CsRGB/12.92; - } else { - return pow((CsRGB + 0.055)/1.055, 2.4); - } -} - -/** Convert from sRGB space. */ -DMNSN_INLINE dmnsn_color -dmnsn_color_from_sRGB(dmnsn_color color) -{ - return dmnsn_new_color( - dmnsn_sRGB_inverse_gamma(color.R), - dmnsn_sRGB_inverse_gamma(color.G), - dmnsn_sRGB_inverse_gamma(color.B) - ); -} - -/** Greyscale color intensity. */ -DMNSN_INLINE double -dmnsn_color_intensity(dmnsn_color color) -{ - return 0.2126*color.R + 0.7152*color.G + 0.0722*color.B; -} - -/** Add two colors together. */ -DMNSN_INLINE dmnsn_color -dmnsn_color_add(dmnsn_color lhs, dmnsn_color rhs) -{ - return dmnsn_new_color(lhs.R + rhs.R, lhs.G + rhs.G, lhs.B + rhs.B); -} - -/** Subtract two colors. */ -DMNSN_INLINE dmnsn_color -dmnsn_color_sub(dmnsn_color lhs, dmnsn_color rhs) -{ - return dmnsn_new_color(lhs.R - rhs.R, lhs.G - rhs.G, lhs.B - rhs.B); -} - -/** Scale a color's intensity. */ -DMNSN_INLINE dmnsn_color -dmnsn_color_mul(double n, dmnsn_color color) -{ - return dmnsn_new_color(n*color.R, n*color.G, n*color.B); -} - -/** Return the color at \p n on a gradient from \p c1 at 0 to \p c2 at 1. */ -DMNSN_INLINE dmnsn_color -dmnsn_color_gradient(dmnsn_color c1, dmnsn_color c2, double n) -{ - return dmnsn_new_color( - n*(c2.R - c1.R) + c1.R, - n*(c2.G - c1.G) + c1.G, - n*(c2.B - c1.B) + c1.B - ); -} - -/** Illuminate \p color with \p light. */ -DMNSN_INLINE dmnsn_color -dmnsn_color_illuminate(dmnsn_color light, dmnsn_color color) -{ - return dmnsn_new_color(light.R*color.R, light.G*color.G, light.B*color.B); -} +#include +#include -/** Saturate the color components to [0.0, 1.0]. */ -DMNSN_INLINE dmnsn_color -dmnsn_color_clamp(dmnsn_color color) -{ - color.R = dmnsn_clamp(color.R, 0.0, 1.0); - color.G = dmnsn_clamp(color.G, 0.0, 1.0); - color.B = dmnsn_clamp(color.B, 0.0, 1.0); - return color; +#ifdef __cplusplus } +#endif -/** Return whether a color contains any NaN components. */ -DMNSN_INLINE bool -dmnsn_color_isnan(dmnsn_color color) -{ - return dmnsn_isnan(color.R) || dmnsn_isnan(color.G) || dmnsn_isnan(color.B); -} - -/* Standard colors */ - -/** Black. */ -#define dmnsn_black dmnsn_new_color(0.0, 0.0, 0.0) -/** White. */ -#define dmnsn_white dmnsn_new_color(1.0, 1.0, 1.0) -/** Red. */ -#define dmnsn_red dmnsn_new_color(1.0, 0.0, 0.0) -/** Green. */ -#define dmnsn_green dmnsn_new_color(0.0, 1.0, 0.0) -/** Blue. */ -#define dmnsn_blue dmnsn_new_color(0.0, 0.0, 1.0) -/** Magenta. */ -#define dmnsn_magenta dmnsn_new_color(1.0, 0.0, 1.0) -/** Orange. */ -#define dmnsn_orange dmnsn_new_color(1.0, 0.21404114048223255, 0.0) -/** Yellow. */ -#define dmnsn_yellow dmnsn_new_color(1.0, 1.0, 0.0) -/** Cyan. */ -#define dmnsn_cyan dmnsn_new_color(0.0, 1.0, 1.0) +#endif /* DMNSN_COLOR_H */ diff --git a/libdimension/dimension/color/color.h b/libdimension/dimension/color/color.h new file mode 100644 index 0000000..84e66ea --- /dev/null +++ b/libdimension/dimension/color/color.h @@ -0,0 +1,198 @@ +/************************************************************************* + * 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 + * Colors. + */ + +#ifndef DMNSN_COLOR_H +#error "Please include instead of this header directly." +#endif + +#include +#include + +/** A color value. */ +typedef struct { + double R; /**< Red component. */ + double G; /**< Green component. */ + double B; /**< Blue component. */ +} dmnsn_color; + +/** A standard format string for colors. */ +#define DMNSN_COLOR_FORMAT "Color<%g, %g, %g>" +/** The appropriate arguements to printf() a color. */ +#define DMNSN_COLOR_PRINTF(c) (c).R, (c).G, (c).B + +/** Construct a new color. */ +DMNSN_INLINE dmnsn_color +dmnsn_new_color(double R, double G, double B) +{ + dmnsn_color ret = { R, G, B }; + return ret; +} + +/** Apply sRGB gamma */ +DMNSN_INLINE double +dmnsn_sRGB_gamma(double Clinear) +{ + /* + * If C represents R, G, and B, then the sRGB values are now found as follows: + * + * { 12.92*Clinear, Clinear <= 0.0031308 + * Csrgb = { 1/2.4 + * { (1.055)*Clinear - 0.055, Clinear > 0.0031308 + */ + if (Clinear == 1.0) { + return 1.0; /* Map 1.0 to 1.0 instead of 0.9999999999999999 */ + } else if (Clinear > 0.0031308) { + return 1.055*pow(Clinear, 1.0/2.4) - 0.055; + } else { + return 12.92*Clinear; + } +} + +/** Convert to sRGB space. */ +DMNSN_INLINE dmnsn_color +dmnsn_color_to_sRGB(dmnsn_color color) +{ + return dmnsn_new_color( + dmnsn_sRGB_gamma(color.R), + dmnsn_sRGB_gamma(color.G), + dmnsn_sRGB_gamma(color.B) + ); +} + +/** Remove sRGB gamma */ +DMNSN_INLINE double +dmnsn_sRGB_inverse_gamma(double CsRGB) +{ + /* + * If C represents R, G, and B, then the Clinear values are now found as + * follows: + * + * { Csrgb/12.92, Csrgb <= 0.04045 + * Clinear = { 2.4 + * { ((Csrgb + 0.055)/1.055) , Csrgb > 0.04045 + */ + if (CsRGB == 1.0) { + return 1.0; /* Map 1.0 to 1.0 instead of 0.9999999999999999 */ + } else if (CsRGB <= 0.040449936) { + return CsRGB/12.92; + } else { + return pow((CsRGB + 0.055)/1.055, 2.4); + } +} + +/** Convert from sRGB space. */ +DMNSN_INLINE dmnsn_color +dmnsn_color_from_sRGB(dmnsn_color color) +{ + return dmnsn_new_color( + dmnsn_sRGB_inverse_gamma(color.R), + dmnsn_sRGB_inverse_gamma(color.G), + dmnsn_sRGB_inverse_gamma(color.B) + ); +} + +/** Greyscale color intensity. */ +DMNSN_INLINE double +dmnsn_color_intensity(dmnsn_color color) +{ + return 0.2126*color.R + 0.7152*color.G + 0.0722*color.B; +} + +/** Add two colors together. */ +DMNSN_INLINE dmnsn_color +dmnsn_color_add(dmnsn_color lhs, dmnsn_color rhs) +{ + return dmnsn_new_color(lhs.R + rhs.R, lhs.G + rhs.G, lhs.B + rhs.B); +} + +/** Subtract two colors. */ +DMNSN_INLINE dmnsn_color +dmnsn_color_sub(dmnsn_color lhs, dmnsn_color rhs) +{ + return dmnsn_new_color(lhs.R - rhs.R, lhs.G - rhs.G, lhs.B - rhs.B); +} + +/** Scale a color's intensity. */ +DMNSN_INLINE dmnsn_color +dmnsn_color_mul(double n, dmnsn_color color) +{ + return dmnsn_new_color(n*color.R, n*color.G, n*color.B); +} + +/** Return the color at \p n on a gradient from \p c1 at 0 to \p c2 at 1. */ +DMNSN_INLINE dmnsn_color +dmnsn_color_gradient(dmnsn_color c1, dmnsn_color c2, double n) +{ + return dmnsn_new_color( + n*(c2.R - c1.R) + c1.R, + n*(c2.G - c1.G) + c1.G, + n*(c2.B - c1.B) + c1.B + ); +} + +/** Illuminate \p color with \p light. */ +DMNSN_INLINE dmnsn_color +dmnsn_color_illuminate(dmnsn_color light, dmnsn_color color) +{ + return dmnsn_new_color(light.R*color.R, light.G*color.G, light.B*color.B); +} + +/** Saturate the color components to [0.0, 1.0]. */ +DMNSN_INLINE dmnsn_color +dmnsn_color_clamp(dmnsn_color color) +{ + color.R = dmnsn_clamp(color.R, 0.0, 1.0); + color.G = dmnsn_clamp(color.G, 0.0, 1.0); + color.B = dmnsn_clamp(color.B, 0.0, 1.0); + return color; +} + +/** Return whether a color contains any NaN components. */ +DMNSN_INLINE bool +dmnsn_color_isnan(dmnsn_color color) +{ + return dmnsn_isnan(color.R) || dmnsn_isnan(color.G) || dmnsn_isnan(color.B); +} + +/* Standard colors */ + +/** Black. */ +#define dmnsn_black dmnsn_new_color(0.0, 0.0, 0.0) +/** White. */ +#define dmnsn_white dmnsn_new_color(1.0, 1.0, 1.0) +/** Red. */ +#define dmnsn_red dmnsn_new_color(1.0, 0.0, 0.0) +/** Green. */ +#define dmnsn_green dmnsn_new_color(0.0, 1.0, 0.0) +/** Blue. */ +#define dmnsn_blue dmnsn_new_color(0.0, 0.0, 1.0) +/** Magenta. */ +#define dmnsn_magenta dmnsn_new_color(1.0, 0.0, 1.0) +/** Orange. */ +#define dmnsn_orange dmnsn_new_color(1.0, 0.21404114048223255, 0.0) +/** Yellow. */ +#define dmnsn_yellow dmnsn_new_color(1.0, 1.0, 0.0) +/** Cyan. */ +#define dmnsn_cyan dmnsn_new_color(0.0, 1.0, 1.0) diff --git a/libdimension/dimension/color/tcolor.h b/libdimension/dimension/color/tcolor.h new file mode 100644 index 0000000..b4b4167 --- /dev/null +++ b/libdimension/dimension/color/tcolor.h @@ -0,0 +1,116 @@ +/************************************************************************* + * 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 + * Colors with transparency information. + */ + +#ifndef DMNSN_COLOR_H +#error "Please include instead of this header directly." +#endif + +/** A transparent color. */ +typedef struct dmnsn_tcolor { + dmnsn_color c; /**< Color. */ + double T; /**< Transparency. */ + double F; /**< Proportion of filtered transparency. */ +} dmnsn_tcolor; + +/** A standard format string for colors. */ +#define DMNSN_TCOLOR_FORMAT "TColor<%g, %g, %g, %g, %g>" +/** The appropriate arguements to printf() a color. */ +#define DMNSN_TCOLOR_PRINTF(tc) (tc).c.R, (tc).c.G, (tc).c.B, (tc).T, (tc).F + +/** Create a tcolor. */ +DMNSN_INLINE dmnsn_tcolor +dmnsn_new_tcolor(dmnsn_color c, double T, double F) +{ + dmnsn_tcolor ret = { c, T, F }; + return ret; +} + +/** Convert a dmnsn_color into a dmnsn_tcolor. */ +#define DMNSN_TCOLOR(c) dmnsn_new_tcolor(c, 0.0, 0.0) + +/** Create a tcolor with individually-specified components. */ +DMNSN_INLINE dmnsn_tcolor +dmnsn_new_tcolor5(double R, double G, double B, double T, double F) +{ + dmnsn_tcolor ret = { dmnsn_new_color(R, G, B), T, F }; + return ret; +} + +/** Return the color at \p n on a gradient from \p c1 at 0 to \p c2 at 1. */ +DMNSN_INLINE dmnsn_tcolor +dmnsn_tcolor_gradient(dmnsn_tcolor c1, dmnsn_tcolor c2, double n) +{ + return dmnsn_new_tcolor( + dmnsn_color_gradient(c1.c, c2.c, n), + n*(c2.T - c1.T) + c1.T, + n*(c2.F - c1.F) + c1.F + ); +} + +/** Filter \p light through \p filter. */ +DMNSN_INLINE dmnsn_color +dmnsn_tcolor_filter(dmnsn_color light, dmnsn_tcolor filter) +{ + dmnsn_color filtered = + dmnsn_color_mul(filter.T*filter.F, dmnsn_color_illuminate(light, filter.c)); + dmnsn_color transmitted = dmnsn_color_mul(filter.T*(1.0 - filter.F), light); + return dmnsn_color_add(filtered, transmitted); +} + +/** Remove the filtered component of a tcolor. */ +DMNSN_INLINE dmnsn_tcolor +dmnsn_tcolor_remove_filter(dmnsn_tcolor tcolor) +{ + double intensity = dmnsn_color_intensity(tcolor.c); + double newtrans = (1.0 - (1.0 - intensity)*tcolor.F)*tcolor.T; + if (1.0 - newtrans >= dmnsn_epsilon) { + tcolor.c = dmnsn_color_mul((1.0 - tcolor.T)/(1.0 - newtrans), tcolor.c); + } + tcolor.T = newtrans; + tcolor.F = 0.0; + return tcolor; +} + +/** Saturate the tcolor components to [0.0, 1.0]. */ +DMNSN_INLINE dmnsn_tcolor +dmnsn_tcolor_clamp(dmnsn_tcolor tcolor) +{ + tcolor.c = dmnsn_color_clamp(tcolor.c); + tcolor.T = dmnsn_clamp(tcolor.T, 0.0, 1.0); + tcolor.F = dmnsn_clamp(tcolor.F, 0.0, 1.0); + return tcolor; +} + +/** Return whether a tcolor contains any NaN components. */ +DMNSN_INLINE bool +dmnsn_tcolor_isnan(dmnsn_tcolor tcolor) +{ + return dmnsn_color_isnan(tcolor.c) || dmnsn_isnan(tcolor.T) || dmnsn_isnan(tcolor.F); +} + +/* Standard tcolors */ + +/** Clear. */ +#define dmnsn_clear dmnsn_new_tcolor5(0.0, 0.0, 0.0, 1.0, 0.0) diff --git a/libdimension/dimension/common.h b/libdimension/dimension/common.h deleted file mode 100644 index 15bafd8..0000000 --- a/libdimension/dimension/common.h +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************* - * Copyright (C) 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 - * Common types and utilities. - */ - -/** - * Generic callback type. - * @param[in,out] ptr A pointer to an object to act on. - */ -typedef void dmnsn_callback_fn(void *ptr); diff --git a/libdimension/dimension/compiler.h b/libdimension/dimension/compiler.h deleted file mode 100644 index af3f4c8..0000000 --- a/libdimension/dimension/compiler.h +++ /dev/null @@ -1,135 +0,0 @@ -/************************************************************************* - * 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 - * Compiler abstractions. - */ - -/** - * @internal - * @def DMNSN_C_VERSION - * The C version according to \p __STDC_VERSION__ if available, otherwise 0. - */ -#ifdef __STDC_VERSION__ - #define DMNSN_C_VERSION __STDC_VERSION__ -#else - #define DMNSN_C_VERSION 0L -#endif - -/** - * @internal - * @def DMNSN_CXX_VERSION - * The C++ version according to \p __cplusplus if available, otherwise 0. - */ -#ifdef __cplusplus - #define DMNSN_CXX_VERSION __cplusplus -#else - #define DMNSN_CXX_VERSION 0L -#endif - -/** - * @internal - * Whether we're being compiled as C++. - */ -#define DMNSN_CXX (DMNSN_CXX_VERSION > 0) - -/** - * @internal - * Whether C++11 features are supported. - */ -#define DMNSN_CXX11 (DMNSN_CXX_VERSION >= 201103L) - -/** - * @internal - * Whether C99 features are supported. - */ -#define DMNSN_C99 (DMNSN_C_VERSION >= 199901L || DMNSN_CXX11) - -/** - * @internal - * Whether C11 features are supported. - */ -#define DMNSN_C11 (DMNSN_C_VERSION >= 201112L) - -/** - * @internal - * Whether GNU C features are supported. - */ -#define DMNSN_GNUC defined(__GNUC__) - -/** - * @def DMNSN_INLINE - * A portable inline specifier. Expands to the correct method of declaring - * inline functions for the version of C you are using. - */ -#ifndef DMNSN_INLINE - #if DMNSN_CXX - /* C++ inline semantics */ - #define DMNSN_INLINE inline - #elif DMNSN_C99 - /* C99 inline semantics */ - #define DMNSN_INLINE inline - #elif DMNSN_GNUC - /* GCC inline semantics */ - #define DMNSN_INLINE __extension__ extern __inline__ - #else - /* Unknown C - mark functions static and hope the compiler is smart enough - to inline them */ - #define DMNSN_INLINE static - #endif -#endif - -/** - * @def DMNSN_NORETURN - * A portable noreturn attribute. - */ -#if DMNSN_CXX11 - #define DMNSN_NORETURN [[noreturn]] void -#elif DMNSN_C11 - #define DMNSN_NORETURN _Noreturn void -#elif DMNSN_GNUC - #define DMNSN_NORETURN __attribute__((noreturn)) void -#else - #define DMNSN_NORETURN void -#endif - -/** - * @internal - * @def DMNSN_FUNC - * @brief Expands to the name of the current function - */ -#if DMNSN_GNUC - #define DMNSN_FUNC __PRETTY_FUNCTION__ -#elif DMNSN_C99 - #define DMNSN_FUNC __func__ -#else - #define DMNSN_FUNC "" -#endif - -/** - * @internal - * An unreachable statement. - */ -#if DMNSN_GNUC - #define DMNSN_UNREACHABLE() __builtin_unreachable() -#else - #define DMNSN_UNREACHABLE() ((void)0) -#endif diff --git a/libdimension/dimension/concurrency.h b/libdimension/dimension/concurrency.h new file mode 100644 index 0000000..6c8c29c --- /dev/null +++ b/libdimension/dimension/concurrency.h @@ -0,0 +1,39 @@ +/************************************************************************* + * Copyright (C) 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 + * Concurrency concerns. + */ + +#ifndef DMNSN_CONCURRENCY_H +#define DMNSN_CONCURRENCY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#ifdef __cplusplus +} +#endif + +#endif /* DMNSN_CONCURRENCY_H */ diff --git a/libdimension/dimension/concurrency/future.h b/libdimension/dimension/concurrency/future.h new file mode 100644 index 0000000..24d5ee2 --- /dev/null +++ b/libdimension/dimension/concurrency/future.h @@ -0,0 +1,85 @@ +/************************************************************************* + * 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 + * An interface for asynchronous tasks. *_async() versions of functions + * return a dmnsn_future* object which can indicate the progress of the + * background task, and wait for task completion. The task's return value + * is returned as an int from dmnsn_finish_progress(). + */ + +#ifndef DMNSN_CONCURRENCY_H +#error "Please include instead of this header directly." +#endif + +#include + +/** A future object. */ +typedef struct dmnsn_future dmnsn_future; + +/** + * Join the worker thread and return its integer return value in addition to + * deleting \p future. + * @param[in,out] future The background task to join. + * @return The return value of the background task. + */ +int dmnsn_future_join(dmnsn_future *future); + +/** + * Interrupt the execution of a background thread. + * @param[in,out] future The background task to cancel. + */ +void dmnsn_future_cancel(dmnsn_future *future); + +/** + * Get the progress of the background task. + * @param[in] future The background task to examine. + * @return The progress of the background task, in [0.0, 1.0]. + */ +double dmnsn_future_progress(const dmnsn_future *future); + +/** + * Find out if a background task is finished. + * @param[in] future The background task to examine. + * @return true if the task is done, false otherwise. + */ +bool dmnsn_future_is_done(const dmnsn_future *future); + +/** + * Wait for a certain amount of progress. Always use this rather than + * spinlocking. + * @param[in] future The background task to monitor. + * @param[in] progress The progress value to wait for. + */ +void dmnsn_future_wait(const dmnsn_future *future, double progress); + +/** + * Pause all threads working on the given future. Once this function returns, + * it is safe to examine the intermediate state of the asynchronous computation. + * @param[in,out] future The background task to pause. + */ +void dmnsn_future_pause(dmnsn_future *future); + +/** + * Resume a previously paused future object. + * @param[in,out] future The background task to resume. + */ +void dmnsn_future_resume(dmnsn_future *future); diff --git a/libdimension/dimension/csg.h b/libdimension/dimension/csg.h deleted file mode 100644 index b2ce83f..0000000 --- a/libdimension/dimension/csg.h +++ /dev/null @@ -1,59 +0,0 @@ -/************************************************************************* - * 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/dictionary.h b/libdimension/dimension/dictionary.h deleted file mode 100644 index 887b171..0000000 --- a/libdimension/dimension/dictionary.h +++ /dev/null @@ -1,83 +0,0 @@ -/************************************************************************* - * Copyright (C) 2010-2011 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 - * Simple associative arrays. - */ - -/** A string-object associative array. */ -typedef struct dmnsn_dictionary dmnsn_dictionary; - -/** - * Allocate a dictionary. - * @param[in] obj_size The size of the objects to store in the dictionary. - * @return An empty dictionary. - */ -dmnsn_dictionary *dmnsn_new_dictionary(size_t obj_size); - -/** - * Delete a dictionary. - * @param[in,out] dict The dictionary to delete. - */ -void dmnsn_delete_dictionary(dmnsn_dictionary *dict); - -/** - * Find an element in a dictionary. - * @param[in] dict The dictionary to search. - * @param[in] key The key to search for. - * @param[out] obj The location to store the found object. - * @return Whether the element was found. - */ -bool dmnsn_dictionary_get(const dmnsn_dictionary *dict, const char *key, - void *obj); - -/** - * Access an element in a dictionary. - * @param[in] dict The dictionary to search. - * @param[in] key The key to search for. - * @return A pointer to the element if found, otherwise NULL. - */ -void *dmnsn_dictionary_at(const dmnsn_dictionary *dict, const char *key); - -/** - * Insert a (key, value) pair into a dictionary. - * @param[in,out] dict The dictionary to modify. - * @param[in] key The key to insert. - * @param[in] obj The object to insert. - */ -void dmnsn_dictionary_insert(dmnsn_dictionary *dict, const char *key, - const void *obj); - -/** - * Remove a (key, value) pair from a dictionary. - * @param[in,out] dict The dictionary to modify. - * @param[in] key The key to remove. - * @return Whether the key existed in the dictionary. - */ -bool dmnsn_dictionary_remove(dmnsn_dictionary *dict, const char *key); - -/** - * Apply a callback to all elements in a dictionary. - * @param[in,out] dict The dictionary. - * @param[in] callback The callback to apply to the elements. - */ -void dmnsn_dictionary_apply(dmnsn_dictionary *dict, - dmnsn_callback_fn *callback); diff --git a/libdimension/dimension/error.h b/libdimension/dimension/error.h deleted file mode 100644 index 0561b8a..0000000 --- a/libdimension/dimension/error.h +++ /dev/null @@ -1,117 +0,0 @@ -/************************************************************************* - * 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 - * Error reporting interface. Errors are reported at a given severity by the - * dmnsn_error() macro at a given severity, which prints a warning if it is - * below the set resilience, or prints an error and exits if it's at or above - * the set resilience. - */ - -#include - -/** - * Report a warning. - * @param[in] str A string to print explaining the warning. - */ -#define dmnsn_warning(str) \ - dmnsn_report_warning(DMNSN_FUNC, __FILE__, __LINE__, str) - -/** - * Report an error. - * @param[in] str A string to print explaining the error. - */ -#define dmnsn_error(str) \ - dmnsn_report_error(DMNSN_FUNC, __FILE__, __LINE__, str) - -/** - * @def dmnsn_assert - * Make an assertion. - * @param[in] expr The expression to assert. - * @param[in] str A string to print if the assertion fails. - */ -#if DMNSN_DEBUG - #define dmnsn_assert(expr, str) \ - do { \ - if (!(expr)) { \ - dmnsn_error((str)); \ - } \ - } while (0) -#else - #define dmnsn_assert(expr, str) ((void)0) -#endif - -/** - * @def dmnsn_unreachable - * Express that a line of code is unreachable. - * @param[in] str A string to print if the line is reached. - */ -#if DMNSN_DEBUG - #define dmnsn_unreachable(str) dmnsn_error((str)) -#else - #define dmnsn_unreachable(str) DMNSN_UNREACHABLE() -#endif - -/** - * @internal - * Called by dmnsn_warning(); don't call directly. - * @param[in] func The name of the function where the error originated. - * @param[in] file The file where the error originated. - * @param[in] line The line number where the error originated. - * @param[in] str A string describing the error. - */ -void dmnsn_report_warning(const char *func, const char *file, unsigned int line, const char *str); - -/** - * @internal - * Called by dmnsn_error(); don't call directly. - * @param[in] func The name of the function where the error originated. - * @param[in] file The file where the error originated. - * @param[in] line The line number where the error originated. - * @param[in] str A string describing the error. - */ -DMNSN_NORETURN dmnsn_report_error(const char *func, const char *file, unsigned int line, const char *str); - -/** - * Treat warnings as errors. - * @param[in] always_die Whether to die on warnings. - */ -void dmnsn_die_on_warnings(bool always_die); - -/** - * Fatal error callback type. This function should never return. - */ -typedef void dmnsn_fatal_error_fn(void); - -/** - * Get the libdimension fatal error handler, thread-safely. The default fatal - * error handler terminates the current thread, or the entire program if the - * current thread is the main thread. - * @return The current fatal error handler. - */ -dmnsn_fatal_error_fn *dmnsn_get_fatal_error_fn(void); - -/** - * Set the libdimension fatal error handler, thread-safely. - * @param[in] fatal The new fatal error handler. This function must never - * return. - */ -void dmnsn_set_fatal_error_fn(dmnsn_fatal_error_fn *fatal); diff --git a/libdimension/dimension/finish.h b/libdimension/dimension/finish.h deleted file mode 100644 index d975877..0000000 --- a/libdimension/dimension/finish.h +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************* - * 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/finishes.h b/libdimension/dimension/finishes.h deleted file mode 100644 index e1f7b44..0000000 --- a/libdimension/dimension/finishes.h +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************* - * 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/future.h b/libdimension/dimension/future.h deleted file mode 100644 index 9ba28b1..0000000 --- a/libdimension/dimension/future.h +++ /dev/null @@ -1,79 +0,0 @@ -/************************************************************************* - * 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 - * An interface for asynchronous tasks. *_async() versions of functions - * return a dmnsn_future* object which can indicate the progress of the - * background task, and wait for task completion. The task's return value - * is returned as an int from dmnsn_finish_progress(). - */ - -/** A future object. */ -typedef struct dmnsn_future dmnsn_future; - -/** - * Join the worker thread and return its integer return value in addition to - * deleting \p future. - * @param[in,out] future The background task to join. - * @return The return value of the background task. - */ -int dmnsn_future_join(dmnsn_future *future); - -/** - * Interrupt the execution of a background thread. - * @param[in,out] future The background task to cancel. - */ -void dmnsn_future_cancel(dmnsn_future *future); - -/** - * Get the progress of the background task. - * @param[in] future The background task to examine. - * @return The progress of the background task, in [0.0, 1.0]. - */ -double dmnsn_future_progress(const dmnsn_future *future); - -/** - * Find out if a background task is finished. - * @param[in] future The background task to examine. - * @return true if the task is done, false otherwise. - */ -bool dmnsn_future_is_done(const dmnsn_future *future); - -/** - * Wait for a certain amount of progress. Always use this rather than - * spinlocking. - * @param[in] future The background task to monitor. - * @param[in] progress The progress value to wait for. - */ -void dmnsn_future_wait(const dmnsn_future *future, double progress); - -/** - * Pause all threads working on the given future. Once this function returns, - * it is safe to examine the intermediate state of the asynchronous computation. - * @param[in,out] future The background task to pause. - */ -void dmnsn_future_pause(dmnsn_future *future); - -/** - * Resume a previously paused future object. - * @param[in,out] future The background task to resume. - */ -void dmnsn_future_resume(dmnsn_future *future); diff --git a/libdimension/dimension/geometry.h b/libdimension/dimension/geometry.h deleted file mode 100644 index 2ea10ca..0000000 --- a/libdimension/dimension/geometry.h +++ /dev/null @@ -1,500 +0,0 @@ -/************************************************************************* - * 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 - * Core geometric types like vectors, matricies, and rays. - */ - -#include -#include - -/** A vector in 3 dimensions. */ -typedef struct dmnsn_vector { - double x; /**< The x component. */ - double y; /**< The y component. */ - double z; /**< The z component. */ -} dmnsn_vector; - -/** A standard format string for vectors. */ -#define DMNSN_VECTOR_FORMAT "<%g, %g, %g>" -/** The appropriate arguements to printf() a vector. */ -#define DMNSN_VECTOR_PRINTF(v) (v).x, (v).y, (v).z - -/** A 4x4 affine transformation matrix, with implied [0 0 0 1] bottom row. */ -typedef struct dmnsn_matrix { - double n[3][4]; /**< The matrix elements in row-major order. */ -} dmnsn_matrix; - -/** A standard format string for matricies. */ -#define DMNSN_MATRIX_FORMAT \ - "[%g\t%g\t%g\t%g]\n" \ - "[%g\t%g\t%g\t%g]\n" \ - "[%g\t%g\t%g\t%g]\n" \ - "[%g\t%g\t%g\t%g]" -/** The appropriate arguements to printf() a matrix. */ -#define DMNSN_MATRIX_PRINTF(m) \ - (m).n[0][0], (m).n[0][1], (m).n[0][2], (m).n[0][3], \ - (m).n[1][0], (m).n[1][1], (m).n[1][2], (m).n[1][3], \ - (m).n[2][0], (m).n[2][1], (m).n[2][2], (m).n[2][3], \ - 0.0, 0.0, 0.0, 1.0 - -/** A line, or ray. */ -typedef struct dmnsn_line { - dmnsn_vector x0; /**< A point on the line. */ - dmnsn_vector n; /**< A normal vector; the direction of the line. */ -} dmnsn_line; - -/** A standard format string for lines. */ -#define DMNSN_LINE_FORMAT "(<%g, %g, %g> + t*<%g, %g, %g>)" -/** The appropriate arguements to printf() a line. */ -#define DMNSN_LINE_PRINTF(l) \ - DMNSN_VECTOR_PRINTF((l).x0), DMNSN_VECTOR_PRINTF((l).n) - -/** An axis-aligned bounding box (AABB). */ -typedef struct dmnsn_bounding_box { - dmnsn_vector min; /**< The coordinate-wise minimum extent of the box. */ - dmnsn_vector max; /**< The coordinate-wise maximum extent of the box. */ -} dmnsn_bounding_box; - -/** A standard format string for bounding boxes. */ -#define DMNSN_BOUNDING_BOX_FORMAT "(<%g, %g, %g> ==> <%g, %g, %g>)" -/** The appropriate arguements to printf() a bounding box. */ -#define DMNSN_BOUNDING_BOX_PRINTF(box) \ - DMNSN_VECTOR_PRINTF((box).min), DMNSN_VECTOR_PRINTF((box).max) - -/* Constants */ - -/** The zero vector. */ -static const dmnsn_vector dmnsn_zero = { 0.0, 0.0, 0.0 }; -/** The x vector. */ -static const dmnsn_vector dmnsn_x = { 1.0, 0.0, 0.0 }; -/** The y vector. */ -static const dmnsn_vector dmnsn_y = { 0.0, 1.0, 0.0 }; -/** The z vector. */ -static const dmnsn_vector dmnsn_z = { 0.0, 0.0, 1.0 }; - -/* Shorthand for vector/matrix construction */ - -/** Construct a new vector. */ -DMNSN_INLINE dmnsn_vector -dmnsn_new_vector(double x, double y, double z) -{ - dmnsn_vector v = { x, y, z }; - return v; -} - -/** Construct a new transformation matrix. */ -DMNSN_INLINE dmnsn_matrix -dmnsn_new_matrix(double a0, double a1, double a2, double a3, - double b0, double b1, double b2, double b3, - double c0, double c1, double c2, double c3) -{ - dmnsn_matrix m = { { { a0, a1, a2, a3 }, - { b0, b1, b2, b3 }, - { c0, c1, c2, c3 } } }; - return m; -} - -/** Construct a new transformation matrix from column vectors. */ -DMNSN_INLINE dmnsn_matrix -dmnsn_new_matrix4(dmnsn_vector a, dmnsn_vector b, dmnsn_vector c, - dmnsn_vector d) -{ - dmnsn_matrix m = { { { a.x, b.x, c.x, d.x }, - { a.y, b.y, c.y, d.y }, - { a.z, b.z, c.z, d.z } } }; - return m; -} - -/** Extract column vectors from a matrix. */ -DMNSN_INLINE dmnsn_vector -dmnsn_matrix_column(dmnsn_matrix M, unsigned int i) -{ - return dmnsn_new_vector(M.n[0][i], M.n[1][i], M.n[2][i]); -} - -/** Return the identity matrix. */ -dmnsn_matrix dmnsn_identity_matrix(void); - -/** - * A scale transformation. - * @param[in] s A vector with components representing the scaling factor in - * each axis. - * @return The transformation matrix. - */ -dmnsn_matrix dmnsn_scale_matrix(dmnsn_vector s); -/** - * A translation. - * @param[in] d The vector to translate by. - * @return The transformation matrix. - */ -dmnsn_matrix dmnsn_translation_matrix(dmnsn_vector d); -/** - * A left-handed rotation. - * @param[in] theta A vector representing an axis and angle. - * @f$ axis = \vec{\theta}/|\vec{\theta}| @f$, - * @f$ angle = |\vec{\theta}| @f$ - * @return The transformation matrix. - */ -dmnsn_matrix dmnsn_rotation_matrix(dmnsn_vector theta); -/** - * An alignment matrix. - * @param[in] from The initial vector. - * @param[in] to The desired direction. - * @param[in] axis1 The first axis about which to rotate. - * @param[in] axis2 The second axis about which to rotate. - * @return A transformation matrix that will rotate \p from to \p to. - */ -dmnsn_matrix dmnsn_alignment_matrix(dmnsn_vector from, dmnsn_vector to, - dmnsn_vector axis1, dmnsn_vector axis2); - -/** - * Construct a new line. - * @param[in] x0 A point on the line. - * @param[in] n The direction of the line. - * @return The new line. - */ -DMNSN_INLINE dmnsn_line -dmnsn_new_line(dmnsn_vector x0, dmnsn_vector n) -{ - dmnsn_line l = { x0, n }; - return l; -} - -/** - * Construct a new bounding box. - * @param[in] min The minimal extent of the bounding box. - * @param[in] max The maximal extent of the bounding box. - * @return The new bounding box. - */ -DMNSN_INLINE dmnsn_bounding_box -dmnsn_new_bounding_box(dmnsn_vector min, dmnsn_vector max) -{ - dmnsn_bounding_box box = { min, max }; - return box; -} - -/** Return the bounding box which contains nothing. */ -DMNSN_INLINE dmnsn_bounding_box -dmnsn_zero_bounding_box(void) -{ - dmnsn_bounding_box box = { - { DMNSN_INFINITY, DMNSN_INFINITY, DMNSN_INFINITY }, - { -DMNSN_INFINITY, -DMNSN_INFINITY, -DMNSN_INFINITY } - }; - return box; -} - -/** Return the bounding box which contains everything. */ -DMNSN_INLINE dmnsn_bounding_box -dmnsn_infinite_bounding_box(void) -{ - dmnsn_bounding_box box = { - { -DMNSN_INFINITY, -DMNSN_INFINITY, -DMNSN_INFINITY }, - { DMNSN_INFINITY, DMNSN_INFINITY, DMNSN_INFINITY } - }; - return box; -} - -/* Vector and matrix arithmetic */ - -/** Negate a vector. */ -DMNSN_INLINE dmnsn_vector -dmnsn_vector_negate(dmnsn_vector rhs) -{ - /* 3 negations */ - dmnsn_vector v = { -rhs.x, -rhs.y, -rhs.z }; - return v; -} - -/** Add two vectors. */ -DMNSN_INLINE dmnsn_vector -dmnsn_vector_add(dmnsn_vector lhs, dmnsn_vector rhs) -{ - /* 3 additions */ - dmnsn_vector v = { lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z }; - return v; -} - -/** Subtract two vectors. */ -DMNSN_INLINE dmnsn_vector -dmnsn_vector_sub(dmnsn_vector lhs, dmnsn_vector rhs) -{ - /* 3 additions */ - dmnsn_vector v = { lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z }; - return v; -} - -/** Multiply a vector by a scalar. */ -DMNSN_INLINE dmnsn_vector -dmnsn_vector_mul(double lhs, dmnsn_vector rhs) -{ - /* 3 multiplications */ - dmnsn_vector v = { lhs*rhs.x, lhs*rhs.y, lhs*rhs.z }; - return v; -} - -/** Divide a vector by a scalar. */ -DMNSN_INLINE dmnsn_vector -dmnsn_vector_div(dmnsn_vector lhs, double rhs) -{ - /* 3 divisions */ - dmnsn_vector v = { lhs.x/rhs, lhs.y/rhs, lhs.z/rhs }; - return v; -} - -/** Return the dot product of two vectors. */ -DMNSN_INLINE double -dmnsn_vector_dot(dmnsn_vector lhs, dmnsn_vector rhs) -{ - /* 3 multiplications, 2 additions */ - return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; -} - -/** Return the cross product of two vectors. */ -DMNSN_INLINE dmnsn_vector -dmnsn_vector_cross(dmnsn_vector lhs, dmnsn_vector rhs) -{ - /* 6 multiplications, 3 additions */ - dmnsn_vector v = { lhs.y*rhs.z - lhs.z*rhs.y, - lhs.z*rhs.x - lhs.x*rhs.z, - lhs.x*rhs.y - lhs.y*rhs.x }; - return v; -} - -/** Return the projection of \p u onto \p d. */ -DMNSN_INLINE dmnsn_vector -dmnsn_vector_proj(dmnsn_vector u, dmnsn_vector d) -{ - /* 1 division, 9 multiplications, 4 additions */ - return dmnsn_vector_mul(dmnsn_vector_dot(u, d)/dmnsn_vector_dot(d, d), d); -} - -/** Return the magnitude of a vector. */ -DMNSN_INLINE double -dmnsn_vector_norm(dmnsn_vector n) -{ - /* 1 sqrt, 3 multiplications, 2 additions */ - return sqrt(dmnsn_vector_dot(n, n)); -} - -/** Return the direction of a vector. */ -DMNSN_INLINE dmnsn_vector -dmnsn_vector_normalized(dmnsn_vector n) -{ - /* 1 sqrt, 3 divisions, 3 multiplications, 2 additions */ - return dmnsn_vector_div(n, dmnsn_vector_norm(n)); -} - -/** Return the component-wise minimum of two vectors. */ -DMNSN_INLINE dmnsn_vector -dmnsn_vector_min(dmnsn_vector a, dmnsn_vector b) -{ - return dmnsn_new_vector( - dmnsn_min(a.x, b.x), - dmnsn_min(a.y, b.y), - dmnsn_min(a.z, b.z) - ); -} - -/** Return the component-wise maximum of two vectors. */ -DMNSN_INLINE dmnsn_vector -dmnsn_vector_max(dmnsn_vector a, dmnsn_vector b) -{ - return dmnsn_new_vector( - dmnsn_max(a.x, b.x), - dmnsn_max(a.y, b.y), - dmnsn_max(a.z, b.z) - ); -} - -/** Invert a matrix. */ -dmnsn_matrix dmnsn_matrix_inverse(dmnsn_matrix A); - -/** Multiply two matricies. */ -dmnsn_matrix dmnsn_matrix_mul(dmnsn_matrix lhs, dmnsn_matrix rhs); - -/** Transform a point by a matrix. */ -DMNSN_INLINE dmnsn_vector -dmnsn_transform_point(dmnsn_matrix T, dmnsn_vector v) -{ - /* 9 multiplications, 9 additions */ - dmnsn_vector r; - r.x = T.n[0][0]*v.x + T.n[0][1]*v.y + T.n[0][2]*v.z + T.n[0][3]; - r.y = T.n[1][0]*v.x + T.n[1][1]*v.y + T.n[1][2]*v.z + T.n[1][3]; - r.z = T.n[2][0]*v.x + T.n[2][1]*v.y + T.n[2][2]*v.z + T.n[2][3]; - return r; -} - -/** Transform a direction by a matrix. */ -DMNSN_INLINE dmnsn_vector -dmnsn_transform_direction(dmnsn_matrix T, dmnsn_vector v) -{ - /* 9 multiplications, 6 additions */ - dmnsn_vector r; - r.x = T.n[0][0]*v.x + T.n[0][1]*v.y + T.n[0][2]*v.z; - r.y = T.n[1][0]*v.x + T.n[1][1]*v.y + T.n[1][2]*v.z; - r.z = T.n[2][0]*v.x + T.n[2][1]*v.y + T.n[2][2]*v.z; - return r; -} - -/** - * Transform a pseudovector by a matrix. - * @param[in] Tinv The inverse of the transformation matrix. - * @param[in] v The pseudovector to transform - * @return The transformed pseudovector. - */ -DMNSN_INLINE dmnsn_vector -dmnsn_transform_normal(dmnsn_matrix Tinv, dmnsn_vector v) -{ - /* Multiply by the transpose of the inverse - (9 multiplications, 6 additions) */ - dmnsn_vector r; - r.x = Tinv.n[0][0]*v.x + Tinv.n[1][0]*v.y + Tinv.n[2][0]*v.z; - r.y = Tinv.n[0][1]*v.x + Tinv.n[1][1]*v.y + Tinv.n[2][1]*v.z; - r.z = Tinv.n[0][2]*v.x + Tinv.n[1][2]*v.y + Tinv.n[2][2]*v.z; - return r; -} - -/** Transform a bounding box by a matrix. */ -dmnsn_bounding_box dmnsn_transform_bounding_box(dmnsn_matrix T, - dmnsn_bounding_box box); - -/** - * Transform a line by a matrix. - * \f$ n' = T(l.\vec{x_0} + l.\vec{n}) - T(l.\vec{x_0}) \f$, - * \f$ \vec{x_0}' = T(l.\vec{x_0}) \f$ - */ -DMNSN_INLINE dmnsn_line -dmnsn_transform_line(dmnsn_matrix T, dmnsn_line l) -{ - /* 18 multiplications, 15 additions */ - dmnsn_line ret; - ret.x0 = dmnsn_transform_point(T, l.x0); - ret.n = dmnsn_transform_direction(T, l.n); - return ret; -} - -/** - * Return the point at \p t on a line. - * The point is defined by \f$ l.\vec{x_0} + t \cdot l.\vec{n} \f$ - */ -DMNSN_INLINE dmnsn_vector -dmnsn_line_point(dmnsn_line l, double t) -{ - return dmnsn_vector_add(l.x0, dmnsn_vector_mul(t, l.n)); -} - -/** Add epsilon*l.n to l.x0, to avoid self-intersections. */ -DMNSN_INLINE dmnsn_line -dmnsn_line_add_epsilon(dmnsn_line l) -{ - return dmnsn_new_line( - dmnsn_vector_add( - l.x0, - dmnsn_vector_mul(1.0e3*dmnsn_epsilon, l.n) - ), - l.n - ); -} - -/** - * Construct a new symmetric bounding box. - * @param[in] r The extent of the bounding box from the origin. - * @return The new bounding box. - */ -DMNSN_INLINE dmnsn_bounding_box -dmnsn_symmetric_bounding_box(dmnsn_vector r) -{ - dmnsn_vector minus_r = dmnsn_vector_negate(r); - dmnsn_bounding_box box = { - dmnsn_vector_min(r, minus_r), - dmnsn_vector_max(r, minus_r) - }; - return box; -} - -/** Return whether \p p is within the axis-aligned bounding box. */ -DMNSN_INLINE bool -dmnsn_bounding_box_contains(dmnsn_bounding_box box, dmnsn_vector p) -{ - return (p.x >= box.min.x && p.y >= box.min.y && p.z >= box.min.z) - && (p.x <= box.max.x && p.y <= box.max.y && p.z <= box.max.z); -} - -/** Return whether a bounding box is infinite. */ -DMNSN_INLINE bool -dmnsn_bounding_box_is_infinite(dmnsn_bounding_box box) -{ - return box.min.x == -DMNSN_INFINITY; -} - -/** - * Expand a bounding box to contain a point - * @param[in] box The bounding box to expand. - * @param[in] point The point to swallow. - * @return The expanded bounding box. - */ -DMNSN_INLINE dmnsn_bounding_box -dmnsn_bounding_box_swallow(dmnsn_bounding_box box, dmnsn_vector point) -{ - dmnsn_bounding_box ret = { - dmnsn_vector_min(box.min, point), - dmnsn_vector_max(box.max, point) - }; - return ret; -} - -/** Return whether a vector contains any NaN components. */ -DMNSN_INLINE bool -dmnsn_vector_isnan(dmnsn_vector v) -{ - return dmnsn_isnan(v.x) || dmnsn_isnan(v.y) || dmnsn_isnan(v.z); -} - -/** Return whether a matrix contains any NaN components. */ -DMNSN_INLINE bool -dmnsn_matrix_isnan(dmnsn_matrix m) -{ - size_t i, j; - for (i = 0; i < 3; ++i) { - for (j = 0; j < 4; ++j) { - if (dmnsn_isnan(m.n[i][j])) { - return true; - } - } - } - return false; -} - -/** Return whether a line contains any NaN entries. */ -DMNSN_INLINE bool -dmnsn_line_isnan(dmnsn_line l) -{ - return dmnsn_vector_isnan(l.x0) || dmnsn_vector_isnan(l.n); -} - -/** Return whether a bounding box has any NaN components. */ -DMNSN_INLINE bool -dmnsn_bounding_box_isnan(dmnsn_bounding_box box) -{ - return dmnsn_vector_isnan(box.min) || dmnsn_vector_isnan(box.max); -} diff --git a/libdimension/dimension/gl.h b/libdimension/dimension/gl.h deleted file mode 100644 index 284a248..0000000 --- a/libdimension/dimension/gl.h +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************************************* - * 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 - * OpenGL export/import of canvases. - */ - -/** - * Optimize a canvas for GL drawing - * @param[in] pool The memory pool to allocate from. - * @param[in,out] canvas The canvas to optimize. - * @return Whether the canvas was successfully optimized. - */ -int dmnsn_gl_optimize_canvas(dmnsn_pool *pool, dmnsn_canvas *canvas); - -/** - * Write canvas to GL framebuffer. - * @param[in] canvas The canvas to draw. - * @return 0 on success, non-zero on failure. - */ -int dmnsn_gl_write_canvas(const dmnsn_canvas *canvas); - -/** - * Read a canvas from a GL framebuffer. - * @param[in] canvas The canvas to write to. - * @param[in] x0 The \a x screen coordinate to start copying from. - * @param[in] y0 The \a y screen coordinate to start copying from. - * @return 0 on success, non-zero on failure. - */ -int dmnsn_gl_read_canvas(dmnsn_canvas *canvas, size_t x0, size_t y0); diff --git a/libdimension/dimension/interior.h b/libdimension/dimension/interior.h deleted file mode 100644 index 0ff697d..0000000 --- a/libdimension/dimension/interior.h +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************************* - * 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/light.h b/libdimension/dimension/light.h deleted file mode 100644 index 218611d..0000000 --- a/libdimension/dimension/light.h +++ /dev/null @@ -1,76 +0,0 @@ -/************************************************************************* - * 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/lights.h b/libdimension/dimension/lights.h deleted file mode 100644 index e7de4cc..0000000 --- a/libdimension/dimension/lights.h +++ /dev/null @@ -1,33 +0,0 @@ -/************************************************************************* - * 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/malloc.h b/libdimension/dimension/malloc.h deleted file mode 100644 index 742e3a2..0000000 --- a/libdimension/dimension/malloc.h +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************* - * 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 - * Dynamic memory. dmnsn_malloc() and friends behave like their - * non-dmnsn_-prefixed counterparts, but never return NULL. If allocation - * fails, they instead call dmnsn_error(). - */ - -#include /* For size_t */ - -/** - * Allocate some memory. Always use dmnsn_free() to free this memory, never - * free(). - * @param[in] size The size of the memory block to allocate. - * @return The allocated memory area. - */ -void *dmnsn_malloc(size_t size); - -/** - * Allocate some memory. Always use dmnsn_free() to free this memory, never - * free(). - * @param[in] type The type of the memory block to allocate. - * @return The allocated memory area. - */ -#define DMNSN_MALLOC(type) ((type *)dmnsn_malloc(sizeof(type))) - -/** - * Expand or shrink an allocation created by dmnsn_malloc(). - * @param[in] ptr The block to resize. - * @param[in] size The new size. - * @return The resized memory area. - */ -void *dmnsn_realloc(void *ptr, size_t size); - -/** - * Duplicate a string. - * @param[in] s The string to duplicate. - * @return A string with the same contents as \p s, suitable for release by - * dmnsn_free(). - */ -char *dmnsn_strdup(const char *s); - -/** - * Free memory allocated by dmnsn_malloc() or dmnsn_strdup(). - * @param[in] ptr The memory block to free, or NULL. - */ -void dmnsn_free(void *ptr); diff --git a/libdimension/dimension/map.h b/libdimension/dimension/map.h deleted file mode 100644 index 7229a24..0000000 --- a/libdimension/dimension/map.h +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************* - * 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 - * Generic maps (backend for pigment_maps, etc.). - */ - -/** A map. */ -typedef struct dmnsn_map dmnsn_map; - -/** - * Create an empty map. - * @param[in] pool The memory pool to allocate from. - * @param[in] size The size of the objects to store in the map. - * @return A map with no entries. - */ -dmnsn_map *dmnsn_new_map(dmnsn_pool *pool, size_t size); - -/** - * Add an entry (a scalar-object pair) to a map. - * @param[in,out] map The map to add to. - * @param[in] n The index of the entry. - * @param[in] obj The value of the entry. - */ -void dmnsn_map_add_entry(dmnsn_map *map, double n, const void *obj); - -/** - * Return the number of entries in a map. - * @param[in] map The map to measure. - * @return The size of \p map. - */ -size_t dmnsn_map_size(const dmnsn_map *map); - -/** - * Evaluate a map. - * @param[in] map The map to evaluate. - * @param[in] n The index to evaluate. - * @param[out] val The normalized distance of \p n from \p obj1. - * @param[out] obj1 The first object. - * @param[out] obj2 The second object. - */ -void dmnsn_map_evaluate(const dmnsn_map *map, double n, - double *val, void *obj1, void *obj2); - -/** - * Apply a callback to each element of a map. - * @param[in,out] map The map. - * @param[in] callback The callback to apply to the elements. - */ -void dmnsn_map_apply(dmnsn_map *map, dmnsn_callback_fn *callback); diff --git a/libdimension/dimension/math.h b/libdimension/dimension/math.h index 597be36..603373f 100644 --- a/libdimension/dimension/math.h +++ b/libdimension/dimension/math.h @@ -20,80 +20,26 @@ /** * @file - * Useful math functions. + * Mathematical functions and types. */ -#include -#include +#ifndef DMNSN_MATH_H +#define DMNSN_MATH_H -/** The smallest value considered non-zero by some numerical algorithms. */ -#define dmnsn_epsilon 1.0e-10 - -/** - * @def DMNSN_INFINITY - * Expands to floating-point infinity. - */ -#if defined(INFINITY) || DMNSN_C99 - #define DMNSN_INFINITY INFINITY -#else - #define DMNSN_INFINITY HUGE_VAL +#ifdef __cplusplus +extern "C" { #endif -/** Find the minimum of two values. */ -DMNSN_INLINE double -dmnsn_min(double a, double b) -{ - return a < b ? a : b; -} - -/** Find the maximum of two values. */ -DMNSN_INLINE double -dmnsn_max(double a, double b) -{ - return a > b ? a : b; -} - -/** Clamp a value to an interval. */ -DMNSN_INLINE double -dmnsn_clamp(double n, double min, double max) -{ - return dmnsn_min(dmnsn_max(n, min), max); -} - -/** Convert degrees to radians. */ -DMNSN_INLINE double -dmnsn_radians(double degrees) -{ - return degrees*(atan(1.0)/45.0); -} +#include -/** Convert radians to degrees. */ -DMNSN_INLINE double -dmnsn_degrees(double radians) -{ - return radians*(45.0/atan(1.0)); -} +#include +#include +#include +#include +#include -/** Signum function: return the sign of a value. */ -DMNSN_INLINE int -dmnsn_sgn(double n) -{ - if (n > 0.0) { - return 1; - } else if (n < 0.0) { - return -1; - } else { - return 0; - } +#ifdef __cplusplus } - -/** Return whether a value is NaN. */ -DMNSN_INLINE bool -dmnsn_isnan(double n) -{ -#if DMNSN_C99 - return isnan(n); -#else - return n != n; #endif -} + +#endif /* DMNSN_MATH_H */ diff --git a/libdimension/dimension/math/aabb.h b/libdimension/dimension/math/aabb.h new file mode 100644 index 0000000..14cc575 --- /dev/null +++ b/libdimension/dimension/math/aabb.h @@ -0,0 +1,129 @@ +/************************************************************************* + * 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 + * Axis-aligned bounding boxes. + */ + +#ifndef DMNSN_MATH_H +#error "Please include instead of this header directly." +#endif + +/** An axis-aligned bounding box. */ +typedef struct dmnsn_aabb { + dmnsn_vector min; /**< The coordinate-wise minimum extent of the box. */ + dmnsn_vector max; /**< The coordinate-wise maximum extent of the box. */ +} dmnsn_aabb; + +/** A standard format string for bounding boxes. */ +#define DMNSN_AABB_FORMAT "(<%g, %g, %g> ==> <%g, %g, %g>)" +/** The appropriate arguements to printf() a bounding box. */ +#define DMNSN_AABB_PRINTF(box) \ + DMNSN_VECTOR_PRINTF((box).min), DMNSN_VECTOR_PRINTF((box).max) + +/** + * Construct a new bounding box. + * @param[in] min The minimal extent of the bounding box. + * @param[in] max The maximal extent of the bounding box. + * @return The new bounding box. + */ +DMNSN_INLINE dmnsn_aabb +dmnsn_new_aabb(dmnsn_vector min, dmnsn_vector max) +{ + dmnsn_aabb box = { min, max }; + return box; +} + +/** Return the bounding box which contains nothing. */ +DMNSN_INLINE dmnsn_aabb +dmnsn_zero_aabb(void) +{ + dmnsn_aabb box = { + { DMNSN_INFINITY, DMNSN_INFINITY, DMNSN_INFINITY }, + { -DMNSN_INFINITY, -DMNSN_INFINITY, -DMNSN_INFINITY } + }; + return box; +} + +/** Return the bounding box which contains everything. */ +DMNSN_INLINE dmnsn_aabb +dmnsn_infinite_aabb(void) +{ + dmnsn_aabb box = { + { -DMNSN_INFINITY, -DMNSN_INFINITY, -DMNSN_INFINITY }, + { DMNSN_INFINITY, DMNSN_INFINITY, DMNSN_INFINITY } + }; + return box; +} + +/** + * Construct a new symmetric bounding box. + * @param[in] r The extent of the bounding box from the origin. + * @return The new bounding box. + */ +DMNSN_INLINE dmnsn_aabb +dmnsn_symmetric_aabb(dmnsn_vector r) +{ + dmnsn_vector minus_r = dmnsn_vector_negate(r); + dmnsn_aabb box = { + dmnsn_vector_min(r, minus_r), + dmnsn_vector_max(r, minus_r) + }; + return box; +} + +/** Return whether \p p is within the axis-aligned bounding box. */ +DMNSN_INLINE bool +dmnsn_aabb_contains(dmnsn_aabb box, dmnsn_vector p) +{ + return (p.x >= box.min.x && p.y >= box.min.y && p.z >= box.min.z) + && (p.x <= box.max.x && p.y <= box.max.y && p.z <= box.max.z); +} + +/** Return whether a bounding box is infinite. */ +DMNSN_INLINE bool +dmnsn_aabb_is_infinite(dmnsn_aabb box) +{ + return box.min.x == -DMNSN_INFINITY; +} + +/** + * Expand a bounding box to contain a point + * @param[in] box The bounding box to expand. + * @param[in] point The point to swallow. + * @return The expanded bounding box. + */ +DMNSN_INLINE dmnsn_aabb +dmnsn_aabb_swallow(dmnsn_aabb box, dmnsn_vector point) +{ + dmnsn_aabb ret = { + dmnsn_vector_min(box.min, point), + dmnsn_vector_max(box.max, point) + }; + return ret; +} + +/** Return whether a bounding box has any NaN components. */ +DMNSN_INLINE bool +dmnsn_aabb_isnan(dmnsn_aabb box) +{ + return dmnsn_vector_isnan(box.min) || dmnsn_vector_isnan(box.max); +} diff --git a/libdimension/dimension/math/matrix.h b/libdimension/dimension/math/matrix.h new file mode 100644 index 0000000..7471bf5 --- /dev/null +++ b/libdimension/dimension/math/matrix.h @@ -0,0 +1,193 @@ +/************************************************************************* + * 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 + * Affine transformation matrices. + */ + +#ifndef DMNSN_MATH_H +#error "Please include instead of this header directly." +#endif + +/** A 4x4 affine transformation matrix, with implied [0 0 0 1] bottom row. */ +typedef struct dmnsn_matrix { + double n[3][4]; /**< The matrix elements in row-major order. */ +} dmnsn_matrix; + +/** A standard format string for matricies. */ +#define DMNSN_MATRIX_FORMAT \ + "[%g\t%g\t%g\t%g]\n" \ + "[%g\t%g\t%g\t%g]\n" \ + "[%g\t%g\t%g\t%g]\n" \ + "[%g\t%g\t%g\t%g]" +/** The appropriate arguements to printf() a matrix. */ +#define DMNSN_MATRIX_PRINTF(m) \ + (m).n[0][0], (m).n[0][1], (m).n[0][2], (m).n[0][3], \ + (m).n[1][0], (m).n[1][1], (m).n[1][2], (m).n[1][3], \ + (m).n[2][0], (m).n[2][1], (m).n[2][2], (m).n[2][3], \ + 0.0, 0.0, 0.0, 1.0 + +/** Construct a new transformation matrix. */ +DMNSN_INLINE dmnsn_matrix +dmnsn_new_matrix(double a0, double a1, double a2, double a3, + double b0, double b1, double b2, double b3, + double c0, double c1, double c2, double c3) +{ + dmnsn_matrix m = { { { a0, a1, a2, a3 }, + { b0, b1, b2, b3 }, + { c0, c1, c2, c3 } } }; + return m; +} + +/** Construct a new transformation matrix from column vectors. */ +DMNSN_INLINE dmnsn_matrix +dmnsn_new_matrix4(dmnsn_vector a, dmnsn_vector b, dmnsn_vector c, + dmnsn_vector d) +{ + dmnsn_matrix m = { { { a.x, b.x, c.x, d.x }, + { a.y, b.y, c.y, d.y }, + { a.z, b.z, c.z, d.z } } }; + return m; +} + +/** Extract column vectors from a matrix. */ +DMNSN_INLINE dmnsn_vector +dmnsn_matrix_column(dmnsn_matrix M, unsigned int i) +{ + return dmnsn_new_vector(M.n[0][i], M.n[1][i], M.n[2][i]); +} + +/** Return the identity matrix. */ +dmnsn_matrix dmnsn_identity_matrix(void); + +/** + * A scale transformation. + * @param[in] s A vector with components representing the scaling factor in + * each axis. + * @return The transformation matrix. + */ +dmnsn_matrix dmnsn_scale_matrix(dmnsn_vector s); +/** + * A translation. + * @param[in] d The vector to translate by. + * @return The transformation matrix. + */ +dmnsn_matrix dmnsn_translation_matrix(dmnsn_vector d); +/** + * A left-handed rotation. + * @param[in] theta A vector representing an axis and angle. + * @f$ axis = \vec{\theta}/|\vec{\theta}| @f$, + * @f$ angle = |\vec{\theta}| @f$ + * @return The transformation matrix. + */ +dmnsn_matrix dmnsn_rotation_matrix(dmnsn_vector theta); + +/** + * An alignment matrix. + * @param[in] from The initial vector. + * @param[in] to The desired direction. + * @param[in] axis1 The first axis about which to rotate. + * @param[in] axis2 The second axis about which to rotate. + * @return A transformation matrix that will rotate \p from to \p to. + */ +dmnsn_matrix dmnsn_alignment_matrix(dmnsn_vector from, dmnsn_vector to, + dmnsn_vector axis1, dmnsn_vector axis2); + +/** Invert a matrix. */ +dmnsn_matrix dmnsn_matrix_inverse(dmnsn_matrix A); + +/** Multiply two matricies. */ +dmnsn_matrix dmnsn_matrix_mul(dmnsn_matrix lhs, dmnsn_matrix rhs); + +/** Transform a point by a matrix. */ +DMNSN_INLINE dmnsn_vector +dmnsn_transform_point(dmnsn_matrix T, dmnsn_vector v) +{ + /* 9 multiplications, 9 additions */ + dmnsn_vector r; + r.x = T.n[0][0]*v.x + T.n[0][1]*v.y + T.n[0][2]*v.z + T.n[0][3]; + r.y = T.n[1][0]*v.x + T.n[1][1]*v.y + T.n[1][2]*v.z + T.n[1][3]; + r.z = T.n[2][0]*v.x + T.n[2][1]*v.y + T.n[2][2]*v.z + T.n[2][3]; + return r; +} + +/** Transform a direction by a matrix. */ +DMNSN_INLINE dmnsn_vector +dmnsn_transform_direction(dmnsn_matrix T, dmnsn_vector v) +{ + /* 9 multiplications, 6 additions */ + dmnsn_vector r; + r.x = T.n[0][0]*v.x + T.n[0][1]*v.y + T.n[0][2]*v.z; + r.y = T.n[1][0]*v.x + T.n[1][1]*v.y + T.n[1][2]*v.z; + r.z = T.n[2][0]*v.x + T.n[2][1]*v.y + T.n[2][2]*v.z; + return r; +} + +/** + * Transform a pseudovector by a matrix. + * @param[in] Tinv The inverse of the transformation matrix. + * @param[in] v The pseudovector to transform + * @return The transformed pseudovector. + */ +DMNSN_INLINE dmnsn_vector +dmnsn_transform_normal(dmnsn_matrix Tinv, dmnsn_vector v) +{ + /* Multiply by the transpose of the inverse + (9 multiplications, 6 additions) */ + dmnsn_vector r; + r.x = Tinv.n[0][0]*v.x + Tinv.n[1][0]*v.y + Tinv.n[2][0]*v.z; + r.y = Tinv.n[0][1]*v.x + Tinv.n[1][1]*v.y + Tinv.n[2][1]*v.z; + r.z = Tinv.n[0][2]*v.x + Tinv.n[1][2]*v.y + Tinv.n[2][2]*v.z; + return r; +} + +/** + * Transform a ray by a matrix. + * \f$ n' = T(l.\vec{x_0} + l.\vec{n}) - T(l.\vec{x_0}) \f$, + * \f$ \vec{x_0}' = T(l.\vec{x_0}) \f$ + */ +DMNSN_INLINE dmnsn_ray +dmnsn_transform_ray(dmnsn_matrix T, dmnsn_ray l) +{ + /* 18 multiplications, 15 additions */ + dmnsn_ray ret; + ret.x0 = dmnsn_transform_point(T, l.x0); + ret.n = dmnsn_transform_direction(T, l.n); + return ret; +} + +/** Transform a bounding box by a matrix. */ +dmnsn_aabb dmnsn_transform_aabb(dmnsn_matrix T, dmnsn_aabb box); + +/** Return whether a matrix contains any NaN components. */ +DMNSN_INLINE bool +dmnsn_matrix_isnan(dmnsn_matrix m) +{ + size_t i, j; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 4; ++j) { + if (dmnsn_isnan(m.n[i][j])) { + return true; + } + } + } + return false; +} diff --git a/libdimension/dimension/math/ray.h b/libdimension/dimension/math/ray.h new file mode 100644 index 0000000..1dd98f7 --- /dev/null +++ b/libdimension/dimension/math/ray.h @@ -0,0 +1,83 @@ +/************************************************************************* + * 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 + * Lines in 3-D space. + */ + +#ifndef DMNSN_MATH_H +#error "Please include instead of this header directly." +#endif + +/** A line, or ray. */ +typedef struct dmnsn_ray { + dmnsn_vector x0; /**< The origin of the ray. */ + dmnsn_vector n; /**< The direction of the ray. */ +} dmnsn_ray; + +/** A standard format string for rays. */ +#define DMNSN_RAY_FORMAT "(<%g, %g, %g> + t*<%g, %g, %g>)" +/** The appropriate arguements to printf() a ray. */ +#define DMNSN_RAY_PRINTF(l) \ + DMNSN_VECTOR_PRINTF((l).x0), DMNSN_VECTOR_PRINTF((l).n) + +/** + * Construct a new ray. + * @param[in] x0 The origin of the ray. + * @param[in] n The direction of the ray. + * @return The new ray. + */ +DMNSN_INLINE dmnsn_ray +dmnsn_new_ray(dmnsn_vector x0, dmnsn_vector n) +{ + dmnsn_ray l = { x0, n }; + return l; +} + +/** + * Return the point at \p t on a ray. + * The point is defined by \f$ l.\vec{x_0} + t \cdot l.\vec{n} \f$ + */ +DMNSN_INLINE dmnsn_vector +dmnsn_ray_point(dmnsn_ray l, double t) +{ + return dmnsn_vector_add(l.x0, dmnsn_vector_mul(t, l.n)); +} + +/** Add epsilon*l.n to l.x0, to avoid self-intersections. */ +DMNSN_INLINE dmnsn_ray +dmnsn_ray_add_epsilon(dmnsn_ray l) +{ + return dmnsn_new_ray( + dmnsn_vector_add( + l.x0, + dmnsn_vector_mul(1.0e3*dmnsn_epsilon, l.n) + ), + l.n + ); +} + +/** Return whether a ray contains any NaN entries. */ +DMNSN_INLINE bool +dmnsn_ray_isnan(dmnsn_ray l) +{ + return dmnsn_vector_isnan(l.x0) || dmnsn_vector_isnan(l.n); +} diff --git a/libdimension/dimension/math/scalar.h b/libdimension/dimension/math/scalar.h new file mode 100644 index 0000000..3887c14 --- /dev/null +++ b/libdimension/dimension/math/scalar.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 + * Mathematical functions of one variable. + */ + +#ifndef DMNSN_MATH_H +#error "Please include instead of this header directly." +#endif + +#include +#include + +/** The smallest value considered non-zero by some numerical algorithms. */ +#define dmnsn_epsilon 1.0e-10 + +/** + * @def DMNSN_INFINITY + * Expands to floating-point infinity. + */ +#if defined(INFINITY) || DMNSN_C99 + #define DMNSN_INFINITY INFINITY +#else + #define DMNSN_INFINITY HUGE_VAL +#endif + +/** Find the minimum of two values. */ +DMNSN_INLINE double +dmnsn_min(double a, double b) +{ + return a < b ? a : b; +} + +/** Find the maximum of two values. */ +DMNSN_INLINE double +dmnsn_max(double a, double b) +{ + return a > b ? a : b; +} + +/** Clamp a value to an interval. */ +DMNSN_INLINE double +dmnsn_clamp(double n, double min, double max) +{ + return dmnsn_min(dmnsn_max(n, min), max); +} + +/** Convert degrees to radians. */ +DMNSN_INLINE double +dmnsn_radians(double degrees) +{ + return degrees*(atan(1.0)/45.0); +} + +/** Convert radians to degrees. */ +DMNSN_INLINE double +dmnsn_degrees(double radians) +{ + return radians*(45.0/atan(1.0)); +} + +/** Signum function: return the sign of a value. */ +DMNSN_INLINE int +dmnsn_sgn(double n) +{ + if (n > 0.0) { + return 1; + } else if (n < 0.0) { + return -1; + } else { + return 0; + } +} + +/** Return whether a value is NaN. */ +DMNSN_INLINE bool +dmnsn_isnan(double n) +{ +#if DMNSN_C99 + return isnan(n); +#else + return n != n; +#endif +} diff --git a/libdimension/dimension/math/vector.h b/libdimension/dimension/math/vector.h new file mode 100644 index 0000000..8eacee9 --- /dev/null +++ b/libdimension/dimension/math/vector.h @@ -0,0 +1,183 @@ +/************************************************************************* + * 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 + * Vectors in 3-D space. + */ + +#ifndef DMNSN_MATH_H +#error "Please include instead of this header directly." +#endif + +#include +#include + +/** A vector in 3 dimensions. */ +typedef struct dmnsn_vector { + double x; /**< The x component. */ + double y; /**< The y component. */ + double z; /**< The z component. */ +} dmnsn_vector; + +/** A standard format string for vectors. */ +#define DMNSN_VECTOR_FORMAT "<%g, %g, %g>" +/** The appropriate arguements to printf() a vector. */ +#define DMNSN_VECTOR_PRINTF(v) (v).x, (v).y, (v).z + +/* Constants */ + +/** The zero vector. */ +static const dmnsn_vector dmnsn_zero = { 0.0, 0.0, 0.0 }; +/** The x vector. */ +static const dmnsn_vector dmnsn_x = { 1.0, 0.0, 0.0 }; +/** The y vector. */ +static const dmnsn_vector dmnsn_y = { 0.0, 1.0, 0.0 }; +/** The z vector. */ +static const dmnsn_vector dmnsn_z = { 0.0, 0.0, 1.0 }; + +/* Shorthand for vector construction */ + +/** Construct a new vector. */ +DMNSN_INLINE dmnsn_vector +dmnsn_new_vector(double x, double y, double z) +{ + dmnsn_vector v = { x, y, z }; + return v; +} + +/* Vector arithmetic */ + +/** Negate a vector. */ +DMNSN_INLINE dmnsn_vector +dmnsn_vector_negate(dmnsn_vector rhs) +{ + /* 3 negations */ + dmnsn_vector v = { -rhs.x, -rhs.y, -rhs.z }; + return v; +} + +/** Add two vectors. */ +DMNSN_INLINE dmnsn_vector +dmnsn_vector_add(dmnsn_vector lhs, dmnsn_vector rhs) +{ + /* 3 additions */ + dmnsn_vector v = { lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z }; + return v; +} + +/** Subtract two vectors. */ +DMNSN_INLINE dmnsn_vector +dmnsn_vector_sub(dmnsn_vector lhs, dmnsn_vector rhs) +{ + /* 3 additions */ + dmnsn_vector v = { lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z }; + return v; +} + +/** Multiply a vector by a scalar. */ +DMNSN_INLINE dmnsn_vector +dmnsn_vector_mul(double lhs, dmnsn_vector rhs) +{ + /* 3 multiplications */ + dmnsn_vector v = { lhs*rhs.x, lhs*rhs.y, lhs*rhs.z }; + return v; +} + +/** Divide a vector by a scalar. */ +DMNSN_INLINE dmnsn_vector +dmnsn_vector_div(dmnsn_vector lhs, double rhs) +{ + /* 3 divisions */ + dmnsn_vector v = { lhs.x/rhs, lhs.y/rhs, lhs.z/rhs }; + return v; +} + +/** Return the dot product of two vectors. */ +DMNSN_INLINE double +dmnsn_vector_dot(dmnsn_vector lhs, dmnsn_vector rhs) +{ + /* 3 multiplications, 2 additions */ + return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; +} + +/** Return the cross product of two vectors. */ +DMNSN_INLINE dmnsn_vector +dmnsn_vector_cross(dmnsn_vector lhs, dmnsn_vector rhs) +{ + /* 6 multiplications, 3 additions */ + dmnsn_vector v = { lhs.y*rhs.z - lhs.z*rhs.y, + lhs.z*rhs.x - lhs.x*rhs.z, + lhs.x*rhs.y - lhs.y*rhs.x }; + return v; +} + +/** Return the projection of \p u onto \p d. */ +DMNSN_INLINE dmnsn_vector +dmnsn_vector_proj(dmnsn_vector u, dmnsn_vector d) +{ + /* 1 division, 9 multiplications, 4 additions */ + return dmnsn_vector_mul(dmnsn_vector_dot(u, d)/dmnsn_vector_dot(d, d), d); +} + +/** Return the magnitude of a vector. */ +DMNSN_INLINE double +dmnsn_vector_norm(dmnsn_vector n) +{ + /* 1 sqrt, 3 multiplications, 2 additions */ + return sqrt(dmnsn_vector_dot(n, n)); +} + +/** Return the direction of a vector. */ +DMNSN_INLINE dmnsn_vector +dmnsn_vector_normalized(dmnsn_vector n) +{ + /* 1 sqrt, 3 divisions, 3 multiplications, 2 additions */ + return dmnsn_vector_div(n, dmnsn_vector_norm(n)); +} + +/** Return the component-wise minimum of two vectors. */ +DMNSN_INLINE dmnsn_vector +dmnsn_vector_min(dmnsn_vector a, dmnsn_vector b) +{ + return dmnsn_new_vector( + dmnsn_min(a.x, b.x), + dmnsn_min(a.y, b.y), + dmnsn_min(a.z, b.z) + ); +} + +/** Return the component-wise maximum of two vectors. */ +DMNSN_INLINE dmnsn_vector +dmnsn_vector_max(dmnsn_vector a, dmnsn_vector b) +{ + return dmnsn_new_vector( + dmnsn_max(a.x, b.x), + dmnsn_max(a.y, b.y), + dmnsn_max(a.z, b.z) + ); +} + +/** Return whether a vector contains any NaN components. */ +DMNSN_INLINE bool +dmnsn_vector_isnan(dmnsn_vector v) +{ + return dmnsn_isnan(v.x) || dmnsn_isnan(v.y) || dmnsn_isnan(v.z); +} diff --git a/libdimension/dimension/model.h b/libdimension/dimension/model.h new file mode 100644 index 0000000..5367729 --- /dev/null +++ b/libdimension/dimension/model.h @@ -0,0 +1,59 @@ +/************************************************************************* + * Copyright (C) 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 + * Scene modeling. + */ + +#ifndef DMNSN_MODEL_H +#define DMNSN_MODEL_H + +#include "dimension/base.h" +#include "dimension/color.h" +#include "dimension/canvas.h" +#include "dimension/pattern.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif /* DMNSN_MODEL_H */ 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); diff --git a/libdimension/dimension/object.h b/libdimension/dimension/object.h deleted file mode 100644 index c8e9d86..0000000 --- a/libdimension/dimension/object.h +++ /dev/null @@ -1,164 +0,0 @@ -/************************************************************************* - * 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_line ray; /**< The ray that intersected. */ - double t; /**< The line 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] line The line to test. - * @param[out] intersection Where to store the intersection details of the - * closest (if any) intersection. - * @return Whether \p line intersected \p object. - */ -typedef bool dmnsn_object_intersection_fn(const dmnsn_object *object, dmnsn_line line, 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. - */ -typedef dmnsn_bounding_box 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_bounding_box bounding_box; /**< 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] line 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_line line, - dmnsn_intersection *intersection) -{ - dmnsn_line line_trans = dmnsn_transform_line(object->trans_inv, line); - intersection->object = NULL; - if (object->vtable->intersection_fn(object, line_trans, intersection)) { - /* Get us back into world coordinates */ - intersection->ray = line; - 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/objects.h b/libdimension/dimension/objects.h deleted file mode 100644 index 2865d82..0000000 --- a/libdimension/dimension/objects.h +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************* - * 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/pattern.h b/libdimension/dimension/pattern.h index 2caed07..17a43a9 100644 --- a/libdimension/dimension/pattern.h +++ b/libdimension/dimension/pattern.h @@ -1,5 +1,5 @@ /************************************************************************* - * Copyright (C) 2009-2014 Tavian Barnes * + * Copyright (C) 2014 Tavian Barnes * * * * This file is part of The Dimension Library. * * * @@ -20,43 +20,25 @@ /** * @file - * Patterns. Patterns are functions which map vectors to scalars, which are - * used for pigments and normals. + * Patterns. */ -/* Forward-declare dmnsn_pattern */ -typedef struct dmnsn_pattern dmnsn_pattern; +#ifndef DMNSN_PATTERN_H +#define DMNSN_PATTERN_H -/** - * Pattern callback. - * @param[in] pattern The pattern itself. - * @param[in] v The point at which to evaluate the pattern. - * @return The value of the pattern at \p v. - */ -typedef double dmnsn_pattern_fn(const dmnsn_pattern *pattern, dmnsn_vector v); +#ifdef __cplusplus +extern "C" { +#endif -/** A pattern. */ -struct dmnsn_pattern { - dmnsn_pattern_fn *pattern_fn; /**< The pattern callback. */ -}; +#include +#include -/** - * Allocate a dummy pattern. - * @param[in] pool The memory pool to allocate from. - * @return A pattern with no callbacks set. - */ -dmnsn_pattern *dmnsn_new_pattern(dmnsn_pool *pool); +#include +#include +#include -/** - * Initialize a dmnsn_pattern field. - * @param[out] pattern The pattern to initialize. - */ -void dmnsn_init_pattern(dmnsn_pattern *pattern); +#ifdef __cplusplus +} +#endif -/** - * Invoke the pattern callback. - * @param[in] pattern The pattern to evaluate. - * @param[in] v The point to get the pattern value for. - * @return The value of the pattern at \p v. - */ -double dmnsn_pattern_value(const dmnsn_pattern *pattern, dmnsn_vector v); +#endif /* DMNSN_PATTERN_H */ diff --git a/libdimension/dimension/pattern/map.h b/libdimension/dimension/pattern/map.h new file mode 100644 index 0000000..7229a24 --- /dev/null +++ b/libdimension/dimension/pattern/map.h @@ -0,0 +1,68 @@ +/************************************************************************* + * 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 + * Generic maps (backend for pigment_maps, etc.). + */ + +/** A map. */ +typedef struct dmnsn_map dmnsn_map; + +/** + * Create an empty map. + * @param[in] pool The memory pool to allocate from. + * @param[in] size The size of the objects to store in the map. + * @return A map with no entries. + */ +dmnsn_map *dmnsn_new_map(dmnsn_pool *pool, size_t size); + +/** + * Add an entry (a scalar-object pair) to a map. + * @param[in,out] map The map to add to. + * @param[in] n The index of the entry. + * @param[in] obj The value of the entry. + */ +void dmnsn_map_add_entry(dmnsn_map *map, double n, const void *obj); + +/** + * Return the number of entries in a map. + * @param[in] map The map to measure. + * @return The size of \p map. + */ +size_t dmnsn_map_size(const dmnsn_map *map); + +/** + * Evaluate a map. + * @param[in] map The map to evaluate. + * @param[in] n The index to evaluate. + * @param[out] val The normalized distance of \p n from \p obj1. + * @param[out] obj1 The first object. + * @param[out] obj2 The second object. + */ +void dmnsn_map_evaluate(const dmnsn_map *map, double n, + double *val, void *obj1, void *obj2); + +/** + * Apply a callback to each element of a map. + * @param[in,out] map The map. + * @param[in] callback The callback to apply to the elements. + */ +void dmnsn_map_apply(dmnsn_map *map, dmnsn_callback_fn *callback); diff --git a/libdimension/dimension/pattern/pattern.h b/libdimension/dimension/pattern/pattern.h new file mode 100644 index 0000000..2caed07 --- /dev/null +++ b/libdimension/dimension/pattern/pattern.h @@ -0,0 +1,62 @@ +/************************************************************************* + * 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 + * Patterns. Patterns are functions which map vectors to scalars, which are + * used for pigments and normals. + */ + +/* Forward-declare dmnsn_pattern */ +typedef struct dmnsn_pattern dmnsn_pattern; + +/** + * Pattern callback. + * @param[in] pattern The pattern itself. + * @param[in] v The point at which to evaluate the pattern. + * @return The value of the pattern at \p v. + */ +typedef double dmnsn_pattern_fn(const dmnsn_pattern *pattern, dmnsn_vector v); + +/** A pattern. */ +struct dmnsn_pattern { + dmnsn_pattern_fn *pattern_fn; /**< The pattern callback. */ +}; + +/** + * Allocate a dummy pattern. + * @param[in] pool The memory pool to allocate from. + * @return A pattern with no callbacks set. + */ +dmnsn_pattern *dmnsn_new_pattern(dmnsn_pool *pool); + +/** + * Initialize a dmnsn_pattern field. + * @param[out] pattern The pattern to initialize. + */ +void dmnsn_init_pattern(dmnsn_pattern *pattern); + +/** + * Invoke the pattern callback. + * @param[in] pattern The pattern to evaluate. + * @param[in] v The point to get the pattern value for. + * @return The value of the pattern at \p v. + */ +double dmnsn_pattern_value(const dmnsn_pattern *pattern, dmnsn_vector v); diff --git a/libdimension/dimension/pattern/patterns.h b/libdimension/dimension/pattern/patterns.h new file mode 100644 index 0000000..59b7fec --- /dev/null +++ b/libdimension/dimension/pattern/patterns.h @@ -0,0 +1,48 @@ +/************************************************************************* + * 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 patterns. + */ + +/** + * A checker pattern. The pattern is composed of tesselating unit cubes + * alternating between 0 and 1. + * @param[in] pool The memory pool to allocate from. + * @return A checker pattern. + */ +dmnsn_pattern *dmnsn_new_checker_pattern(dmnsn_pool *pool); + +/** + * A gradient. The value starts at 0 at the origin, and goes linearly to 1 in + * the direction of \p orientation, then repeats after a distance of 1. + * @param[in] pool The memory pool to allocate from. + * @param[in] orientation The direction of the gradient. + * @return A gradient pattern. + */ +dmnsn_pattern *dmnsn_new_gradient_pattern(dmnsn_pool *pool, dmnsn_vector orientation); + +/** + * A leopard pattern. + * @param[in] pool The memory pool to allocate from. + * @return A leopard pattern. + */ +dmnsn_pattern *dmnsn_new_leopard_pattern(dmnsn_pool *pool); diff --git a/libdimension/dimension/patterns.h b/libdimension/dimension/patterns.h deleted file mode 100644 index 59b7fec..0000000 --- a/libdimension/dimension/patterns.h +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************************************* - * 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 patterns. - */ - -/** - * A checker pattern. The pattern is composed of tesselating unit cubes - * alternating between 0 and 1. - * @param[in] pool The memory pool to allocate from. - * @return A checker pattern. - */ -dmnsn_pattern *dmnsn_new_checker_pattern(dmnsn_pool *pool); - -/** - * A gradient. The value starts at 0 at the origin, and goes linearly to 1 in - * the direction of \p orientation, then repeats after a distance of 1. - * @param[in] pool The memory pool to allocate from. - * @param[in] orientation The direction of the gradient. - * @return A gradient pattern. - */ -dmnsn_pattern *dmnsn_new_gradient_pattern(dmnsn_pool *pool, dmnsn_vector orientation); - -/** - * A leopard pattern. - * @param[in] pool The memory pool to allocate from. - * @return A leopard pattern. - */ -dmnsn_pattern *dmnsn_new_leopard_pattern(dmnsn_pool *pool); diff --git a/libdimension/dimension/pigment.h b/libdimension/dimension/pigment.h deleted file mode 100644 index 14d8bae..0000000 --- a/libdimension/dimension/pigment.h +++ /dev/null @@ -1,86 +0,0 @@ -/************************************************************************* - * 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/pigments.h b/libdimension/dimension/pigments.h deleted file mode 100644 index 100016d..0000000 --- a/libdimension/dimension/pigments.h +++ /dev/null @@ -1,66 +0,0 @@ -/************************************************************************* - * 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/platform.h b/libdimension/dimension/platform.h new file mode 100644 index 0000000..4c01709 --- /dev/null +++ b/libdimension/dimension/platform.h @@ -0,0 +1,39 @@ +/************************************************************************* + * Copyright (C) 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 + * Platform abstractions. + */ + +#ifndef DMNSN_PLATFORM_H +#define DMNSN_PLATFORM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#ifdef __cplusplus +} +#endif + +#endif /* DMNSN_PLATFORM_H */ diff --git a/libdimension/dimension/platform/timer.h b/libdimension/dimension/platform/timer.h new file mode 100644 index 0000000..bcf4a9d --- /dev/null +++ b/libdimension/dimension/platform/timer.h @@ -0,0 +1,58 @@ +/************************************************************************* + * Copyright (C) 2010-2011 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 + * A platform-agnostic timer abstraction. + */ + +#ifndef DMNSN_PLATFORM_H +#error "Please include instead of this header directly." +#endif + +/** A platform-agnotic timer. */ +typedef struct dmnsn_timer { + double real; /**< Wall-clock time. */ + double user; /**< Time spent executing. */ + double system; /**< Time spent waiting for the system. */ +} dmnsn_timer; + +/** A standard format string for timers. */ +#define DMNSN_TIMER_FORMAT "%.2fs (user: %.2fs; system: %.2fs)" +/** + * The appropriate arguments to printf() a timer. For example: + * @code + * printf(DMNSN_TIMER_FORMAT "\n", DMNSN_TIMER_PRINTF(timer)); + * @endcode + * will print something like "1.00s (user: 0.99s; system: 0.01s)". + */ +#define DMNSN_TIMER_PRINTF(t) (t).real, (t).user, (t).system + +/** + * Start a timer. The values of an unfinished timer are undefined. + * @param[in,out] timer The timer to start. + */ +void dmnsn_timer_start(dmnsn_timer *timer); + +/** + * Finish timing. The members of the timer struct will now contain timing data. + * @param[in,out] timer The timer to stop. + */ +void dmnsn_timer_stop(dmnsn_timer *timer); diff --git a/libdimension/dimension/png.h b/libdimension/dimension/png.h deleted file mode 100644 index f4d2c1e..0000000 --- a/libdimension/dimension/png.h +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************* - * 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 - * PNG import/export of canvases. - */ - -#include - -/** - * Optimize a canvas for PNG exporting - * @param[in] pool The memory pool to allocate from. - * @param[in,out] canvas The canvas to optimize. - * @return Whether the canvas was successfully optimized. - */ -int dmnsn_png_optimize_canvas(dmnsn_pool *pool, dmnsn_canvas *canvas); - -/** - * Write a canvas to a file in PNG format. - * @param[in] canvas The canvas to write. - * @param[in,out] file The file to write to. - * @return 0 on success, non-zero on failure. - */ -int dmnsn_png_write_canvas(const dmnsn_canvas *canvas, FILE *file); - -/** - * Write a canvas to a PNG file in the background. - * @param[in] canvas The canvas to write. - * @param[in,out] file The file to write to. - * @return A \ref dmnsn_future object, or NULL on failure. - */ -dmnsn_future *dmnsn_png_write_canvas_async(const dmnsn_canvas *canvas, - FILE *file); - -/** - * Read a canvas from a PNG file. - * @param[in] pool The memory pool to allocate from. - * @param[in,out] file The PNG file to read. - * @return The new canvas, or NULL on failure. - */ -dmnsn_canvas *dmnsn_png_read_canvas(dmnsn_pool *pool, FILE *file); - -/** - * Read a canvas from a PNG file in the background. - * @param[out] canvas The address of a non-allocated canvas object. The canvas - * object will be allocated and filled with the contents of - * \p file. Do not read from this object until the - * background task has finished. - * @param[in] pool The memory pool to allocate from. - * @param[in,out] file The PNG file to read. - * @return A \ref dmnsn_future object, or NULL on failure. - */ -dmnsn_future *dmnsn_png_read_canvas_async(dmnsn_canvas **canvas, dmnsn_pool *pool, FILE *file); diff --git a/libdimension/dimension/polynomial.h b/libdimension/dimension/polynomial.h deleted file mode 100644 index ab95d50..0000000 --- a/libdimension/dimension/polynomial.h +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2011 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 - * Utility functions for working with and numerically solving polynomials. - * Polynomials are represented as simple arrays where the ith element is the - * coefficient on x^i. In general, we are only interested in positive roots. - */ - -#include -#include - -/** - * Evaluate a polynomial at \p x. - * @param[in] poly The coefficients of the polynomial to evaluate, in order - * from lowest degree to highest degree. The array should - * have dimension degree + 1. - * @param[in] degree The degree of the polynomial. - * @param[in] x The value of the variable at which to evaluate. - */ -DMNSN_INLINE double -dmnsn_polynomial_evaluate(const double poly[], size_t degree, double x) -{ - double ret = poly[degree]; - size_t i; - for (i = degree; i-- > 0;) { - ret = ret*x + poly[i]; - } - return ret; -} - -/** - * Evaluate the derivative of a polynomial at \p x. - * @param[in] poly The coefficients of the polynomial to evaluate. - * @param[in] degree The degree of the polynomial. - * @param[in] x The value of the variable at which to evaluate. - */ -DMNSN_INLINE double -dmnsn_polynomial_evaluate_derivative(const double poly[], size_t degree, - double x) -{ - double ret = poly[degree]*degree; - size_t i; - for (i = degree - 1; i >= 1; --i) { - ret = ret*x + poly[i]*i; - } - return ret; -} - -/** - * Find the positive roots of a polynomial. - * @param[in] poly The coefficients of the polynomial to solve. - * @param[in] degree The degree of the polynomial. - * @param[out] x An array in which to store the roots. It should have - * dimension \p degree. - * @return The number of positive roots stored in \c x[]. - */ -size_t dmnsn_polynomial_solve(const double poly[], size_t degree, double x[]); - -/** - * Output a polynomial. The polynomial is printed as a function of x suitable - * for input into a CAS, and without a trailing newline. - * @param[in,out] file The file to write to. - * @param[in] poly The coefficients of the polynomial to print. - * @param[in] degree The degree of the polynomial. - */ -void dmnsn_polynomial_print(FILE *file, const double poly[], size_t degree); diff --git a/libdimension/dimension/pool.h b/libdimension/dimension/pool.h deleted file mode 100644 index 164bbbc..0000000 --- a/libdimension/dimension/pool.h +++ /dev/null @@ -1,77 +0,0 @@ -/************************************************************************* - * Copyright (C) 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 - * Memory pools. Rather than more complicated garbage collection methods like - * reference counting, objects are allocated out of pools which are freed all at - * once once a scene is rendered (for example). - */ - -#include /* For size_t */ - -/* Forward-declare dmnsn_pool. */ -typedef struct dmnsn_pool dmnsn_pool; - -/** - * Create a new memory pool. - * @return The new pool. - */ -dmnsn_pool *dmnsn_new_pool(void); - -/** - * Allocate some memory from a pool. - * @param[in] pool The memory pool to allocate from. - * @param[in] size The size of the memory block to allocate. - * @return The allocated memory area. - */ -void *dmnsn_palloc(dmnsn_pool *pool, size_t size); - -/** - * Allocate some memory from a pool. - * @param[in] pool The memory pool to allocate from. - * @param[in] size The size of the memory block to allocate. - * @param[in] cleanup_fn A callback to invoke before the memory is freed. - * @return The allocated memory area. - */ -void *dmnsn_palloc_tidy(dmnsn_pool *pool, size_t size, dmnsn_callback_fn *cleanup_fn); - -/** - * Allocate some memory from a pool. - * @param[in] pool The memory pool to allocate from. - * @param[in] type The type of the memory block to allocate. - * @return The allocated memory area. - */ -#define DMNSN_PALLOC(pool, type) ((type *)dmnsn_palloc((pool), sizeof(type))) - -/** - * Allocate some memory from a pool. - * @param[in] pool The memory pool to allocate from. - * @param[in] type The type of the memory block to allocate. - * @param[in] cleanup_fn A callback to invoke before the memory is freed. - * @return The allocated memory area. - */ -#define DMNSN_PALLOC_TIDY(pool, type, cleanup_fn) ((type *)dmnsn_palloc_tidy((pool), sizeof(type), (cleanup_fn))) - -/** - * Free a memory pool and all associated allocations. - * @param[in] pool The memory pool to free. - */ -void dmnsn_delete_pool(dmnsn_pool *pool); diff --git a/libdimension/dimension/ray_trace.h b/libdimension/dimension/ray_trace.h deleted file mode 100644 index 82fb759..0000000 --- a/libdimension/dimension/ray_trace.h +++ /dev/null @@ -1,37 +0,0 @@ -/************************************************************************* - * Copyright (C) 2009-2011 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 - * Ray-trace a scene. - */ - -/** - * Render a scene by ray tracing. - * @param[in,out] scene The scene to render. - */ -void dmnsn_ray_trace(dmnsn_scene *scene); - -/** - * Render a scene in the background. - * @param[in,out] scene The scene to render. - * @return A \p dmnsn_future object. - */ -dmnsn_future *dmnsn_ray_trace_async(dmnsn_scene *scene); diff --git a/libdimension/dimension/render.h b/libdimension/dimension/render.h new file mode 100644 index 0000000..296d7a3 --- /dev/null +++ b/libdimension/dimension/render.h @@ -0,0 +1,41 @@ +/************************************************************************* + * Copyright (C) 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 + * Rendering. + */ + +#ifndef DMNSN_RENDER_H +#define DMNSN_RENDER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +#ifdef __cplusplus +} +#endif + +#endif /* DMNSN_RENDER_H */ diff --git a/libdimension/dimension/render/render.h b/libdimension/dimension/render/render.h new file mode 100644 index 0000000..69f52c2 --- /dev/null +++ b/libdimension/dimension/render/render.h @@ -0,0 +1,41 @@ +/************************************************************************* + * 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 + * Rendering. + */ + +#ifndef DMNSN_RENDER_H +#error "Please include instead of this header directly." +#endif + +/** + * Render a scene. + * @param[in,out] scene The scene to render. + */ +void dmnsn_render(dmnsn_scene *scene); + +/** + * Render a scene in the background. + * @param[in,out] scene The scene to render. + * @return A \p dmnsn_future object. + */ +dmnsn_future *dmnsn_render_async(dmnsn_scene *scene); diff --git a/libdimension/dimension/scene.h b/libdimension/dimension/scene.h deleted file mode 100644 index dd0c1ba..0000000 --- a/libdimension/dimension/scene.h +++ /dev/null @@ -1,95 +0,0 @@ -/************************************************************************* - * 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/tcolor.h b/libdimension/dimension/tcolor.h deleted file mode 100644 index 8c48800..0000000 --- a/libdimension/dimension/tcolor.h +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************* - * 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 - * Colors with transparency information. - */ - -/** A transparent color. */ -typedef struct dmnsn_tcolor { - dmnsn_color c; /**< Color. */ - double T; /**< Transparency. */ - double F; /**< Proportion of filtered transparency. */ -} dmnsn_tcolor; - -/** A standard format string for colors. */ -#define DMNSN_TCOLOR_FORMAT "TColor<%g, %g, %g, %g, %g>" -/** The appropriate arguements to printf() a color. */ -#define DMNSN_TCOLOR_PRINTF(tc) (tc).c.R, (tc).c.G, (tc).c.B, (tc).T, (tc).F - -/** Create a tcolor. */ -DMNSN_INLINE dmnsn_tcolor -dmnsn_new_tcolor(dmnsn_color c, double T, double F) -{ - dmnsn_tcolor ret = { c, T, F }; - return ret; -} - -/** Convert a dmnsn_color into a dmnsn_tcolor. */ -#define DMNSN_TCOLOR(c) dmnsn_new_tcolor(c, 0.0, 0.0) - -/** Create a tcolor with individually-specified components. */ -DMNSN_INLINE dmnsn_tcolor -dmnsn_new_tcolor5(double R, double G, double B, double T, double F) -{ - dmnsn_tcolor ret = { dmnsn_new_color(R, G, B), T, F }; - return ret; -} - -/** Return the color at \p n on a gradient from \p c1 at 0 to \p c2 at 1. */ -DMNSN_INLINE dmnsn_tcolor -dmnsn_tcolor_gradient(dmnsn_tcolor c1, dmnsn_tcolor c2, double n) -{ - return dmnsn_new_tcolor( - dmnsn_color_gradient(c1.c, c2.c, n), - n*(c2.T - c1.T) + c1.T, - n*(c2.F - c1.F) + c1.F - ); -} - -/** Filter \p light through \p filter. */ -DMNSN_INLINE dmnsn_color -dmnsn_tcolor_filter(dmnsn_color light, dmnsn_tcolor filter) -{ - dmnsn_color filtered = - dmnsn_color_mul(filter.T*filter.F, dmnsn_color_illuminate(light, filter.c)); - dmnsn_color transmitted = dmnsn_color_mul(filter.T*(1.0 - filter.F), light); - return dmnsn_color_add(filtered, transmitted); -} - -/** Remove the filtered component of a tcolor. */ -DMNSN_INLINE dmnsn_tcolor -dmnsn_tcolor_remove_filter(dmnsn_tcolor tcolor) -{ - double intensity = dmnsn_color_intensity(tcolor.c); - double newtrans = (1.0 - (1.0 - intensity)*tcolor.F)*tcolor.T; - if (1.0 - newtrans >= dmnsn_epsilon) { - tcolor.c = dmnsn_color_mul((1.0 - tcolor.T)/(1.0 - newtrans), tcolor.c); - } - tcolor.T = newtrans; - tcolor.F = 0.0; - return tcolor; -} - -/** Saturate the tcolor components to [0.0, 1.0]. */ -DMNSN_INLINE dmnsn_tcolor -dmnsn_tcolor_clamp(dmnsn_tcolor tcolor) -{ - tcolor.c = dmnsn_color_clamp(tcolor.c); - tcolor.T = dmnsn_clamp(tcolor.T, 0.0, 1.0); - tcolor.F = dmnsn_clamp(tcolor.F, 0.0, 1.0); - return tcolor; -} - -/** Return whether a tcolor contains any NaN components. */ -DMNSN_INLINE bool -dmnsn_tcolor_isnan(dmnsn_tcolor tcolor) -{ - return dmnsn_color_isnan(tcolor.c) || dmnsn_isnan(tcolor.T) || dmnsn_isnan(tcolor.F); -} - -/* Standard tcolors */ - -/** Clear. */ -#define dmnsn_clear dmnsn_new_tcolor5(0.0, 0.0, 0.0, 1.0, 0.0) diff --git a/libdimension/dimension/texture.h b/libdimension/dimension/texture.h deleted file mode 100644 index df08a4a..0000000 --- a/libdimension/dimension/texture.h +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************* - * 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); diff --git a/libdimension/dimension/timer.h b/libdimension/dimension/timer.h deleted file mode 100644 index 55d66ff..0000000 --- a/libdimension/dimension/timer.h +++ /dev/null @@ -1,54 +0,0 @@ -/************************************************************************* - * Copyright (C) 2010-2011 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 - * A platform-agnostic timer abstraction. - */ - -/** A platform-agnotic timer. */ -typedef struct dmnsn_timer { - double real; /**< Wall-clock time. */ - double user; /**< Time spent executing. */ - double system; /**< Time spent waiting for the system. */ -} dmnsn_timer; - -/** A standard format string for timers. */ -#define DMNSN_TIMER_FORMAT "%.2fs (user: %.2fs; system: %.2fs)" -/** - * The appropriate arguments to printf() a timer. For example: - * @code - * printf(DMNSN_TIMER_FORMAT "\n", DMNSN_TIMER_PRINTF(timer)); - * @endcode - * will print something like "1.00s (user: 0.99s; system: 0.01s)". - */ -#define DMNSN_TIMER_PRINTF(t) (t).real, (t).user, (t).system - -/** - * Start a timer. The values of an unfinished timer are undefined. - * @param[in,out] timer The timer to start. - */ -void dmnsn_timer_start(dmnsn_timer *timer); - -/** - * Finish timing. The members of the timer struct will now contain timing data. - * @param[in,out] timer The timer to stop. - */ -void dmnsn_timer_stop(dmnsn_timer *timer); -- cgit v1.2.3