From 7acd8ea6673b7a90ed4041408ccf1b024b8a007a Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sun, 12 Jun 2011 02:37:51 -0600 Subject: Vast libdimension API and internals improvements. Couldn't really do these while I was trying to be POV-Ray compatible, 'cause they would've broken compatibility. --- libdimension/dimension/finish.h | 158 ++++++++++++++++++++++++++---------- libdimension/dimension/finishes.h | 28 +++---- libdimension/dimension/interior.h | 8 ++ libdimension/dimension/object.h | 15 ++-- libdimension/dimension/pattern.h | 2 + libdimension/dimension/pigment.h | 12 +++ libdimension/dimension/refcount.h | 5 +- libdimension/dimension/scene.h | 44 ++-------- libdimension/dimension/sky_sphere.h | 5 +- libdimension/dimension/texture.h | 12 ++- 10 files changed, 179 insertions(+), 110 deletions(-) (limited to 'libdimension/dimension') diff --git a/libdimension/dimension/finish.h b/libdimension/dimension/finish.h index f2b1df7..a163496 100644 --- a/libdimension/dimension/finish.h +++ b/libdimension/dimension/finish.h @@ -23,76 +23,148 @@ * Object finishes. */ -/* Forward-declare dmnsn_finish */ -typedef struct dmnsn_finish dmnsn_finish; +/* Ambient component */ + +typedef struct dmnsn_ambient dmnsn_ambient; + +/** + * Ambient light callback. + * @param[in] ambient The ambient object itself. + * @param[in] pigment The pigment of the object. + * @return The ambient contribution to the object's color. + */ +typedef dmnsn_color dmnsn_ambient_fn(const dmnsn_ambient *ambient, + dmnsn_color pigment); + +struct dmnsn_ambient { + dmnsn_ambient_fn *ambient_fn; /**< Ambient callback. */ + dmnsn_free_fn *free_fn; /**< Destructor callback. */ + void *ptr; /**< Generic data pointer. */ + dmnsn_refcount refcount; /**< @internal Reference count. */ +}; + +/** Allocate a dummy ambient component. */ +dmnsn_ambient *dmnsn_new_ambient(void); +/** Delete an ambient component. */ +void dmnsn_delete_ambient(dmnsn_ambient *ambient); + +/* Diffuse component */ + +typedef struct dmnsn_diffuse dmnsn_diffuse; /** * Diffuse reflection callback. - * @param[in] finish The finish 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] 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_finish *finish, +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. */ + dmnsn_free_fn *free_fn; /**< Destructor callback. */ + void *ptr; /**< Generic data pointer. */ + dmnsn_refcount refcount; /**< @internal Reference count. */ +}; + +/** Allocate a dummy diffuse component. */ +dmnsn_diffuse *dmnsn_new_diffuse(void); +/** Delete a diffuse component. */ +void dmnsn_delete_diffuse(dmnsn_diffuse *diffuse); + +/* Specular component */ + +typedef struct dmnsn_specular dmnsn_specular; + /** * Specular highlight callback. - * @param[in] finish The finish 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. + * @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_finish *finish, +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); -/** - * Ambient light callback. - * @param[in] finish The finish itself. - * @param[in] pigment The pigment of the object. - * @return The ambient contribution to the object's color. - */ -typedef dmnsn_color dmnsn_ambient_fn(const dmnsn_finish *finish, - dmnsn_color pigment); + +struct dmnsn_specular { + dmnsn_specular_fn *specular_fn; /**< Specular callback. */ + dmnsn_free_fn *free_fn; /**< Destructor callback. */ + void *ptr; /**< Generic data pointer. */ + dmnsn_refcount refcount; /**< @internal Reference count. */ +}; + +/** Allocate a dummy specular component. */ +dmnsn_specular *dmnsn_new_specular(void); +/** Delete a specular component. */ +void dmnsn_delete_specular(dmnsn_specular *specular); + +/* Reflection component */ + +typedef struct dmnsn_reflection dmnsn_reflection; + /** * Reflected light callback. - * @param[in] finish The finish 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. + * @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_finish *finish, +typedef dmnsn_color dmnsn_reflection_fn(const dmnsn_reflection *reflection, dmnsn_color reflect, dmnsn_color color, dmnsn_vector ray, dmnsn_vector normal); -/** A finish. */ -struct dmnsn_finish { - dmnsn_diffuse_fn *diffuse_fn; /**< The diffuse callback. */ - dmnsn_specular_fn *specular_fn; /**< The specular callback. */ - dmnsn_ambient_fn *ambient_fn; /**< The ambient callback. */ - dmnsn_reflection_fn *reflection_fn; /**< The reflection callback. */ - dmnsn_free_fn *free_fn; /**< The destruction callback. */ - - /** Generic pointer. */ - void *ptr; +/** The reflection component. */ +struct dmnsn_reflection { + dmnsn_reflection_fn *reflection_fn; /**< Reflection callback. */ + dmnsn_free_fn *free_fn; /**< Destructor callback. */ + void *ptr; /**< Generic data pointer. */ + dmnsn_refcount refcount; /**< @internal Reference count. */ }; +/** Allocate a dummy reflection component. */ +dmnsn_reflection *dmnsn_new_reflection(void); +/** Delete a reflection component. */ +void dmnsn_delete_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; + /** - * Allocate a new dummy finish. - * @return The allocated finish. + * Create a new blank finish. + * @return The new finish. */ -dmnsn_finish *dmnsn_new_finish(void); +dmnsn_finish dmnsn_new_finish(void); /** * Delete a finish. * @param[in,out] finish The finish to delete. */ -void dmnsn_delete_finish(dmnsn_finish *finish); +void dmnsn_delete_finish(dmnsn_finish finish); + +/** + * 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 index e3c308c..81b0ff6 100644 --- a/libdimension/dimension/finishes.h +++ b/libdimension/dimension/finishes.h @@ -23,42 +23,34 @@ * Pre-defined finishes. */ -/** - * Add two finishes together. - * @param[in,out] f1 The first finish. - * @param[in,out] f2 The second finish. - * @return A finish that adds the values of two finishes together. - */ -dmnsn_finish *dmnsn_new_finish_combination(dmnsn_finish *f1, dmnsn_finish *f2); - /** * Ambient finish. * @param[in] ambient The color of the ambient light. - * @return A finish with ambient light. + * @return An ambient finish component. */ -dmnsn_finish *dmnsn_new_ambient_finish(dmnsn_color ambient); +dmnsn_ambient *dmnsn_new_basic_ambient(dmnsn_color ambient); /** - * Diffuse finish. + * Regular diffuse finish. * @param[in] diffuse The diffuse reflection coefficient. - * @return A finish with diffuse reflection. + * @return A diffuse finish component. */ -dmnsn_finish *dmnsn_new_diffuse_finish(double diffuse); +dmnsn_diffuse *dmnsn_new_lambertian(double diffuse); /** * A phong specular highlight. * @param[in] specular The specular reflection coefficient. * @param[in] exp The exponent (roughly the highlight size). - * @return A finish with phong specular highlight. + * @return A phong specular finish component. */ -dmnsn_finish *dmnsn_new_phong_finish(double specular, double exp); +dmnsn_specular *dmnsn_new_phong(double specular, double exp); /** * Specular (mirror) reflection. * @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 finish with specular reflection. + * @return A reflective finish component. */ -dmnsn_finish *dmnsn_new_reflective_finish(dmnsn_color min, dmnsn_color max, - double falloff); +dmnsn_reflection *dmnsn_new_basic_reflection(dmnsn_color min, dmnsn_color max, + double falloff); diff --git a/libdimension/dimension/interior.h b/libdimension/dimension/interior.h index 22a9091..a52c225 100644 --- a/libdimension/dimension/interior.h +++ b/libdimension/dimension/interior.h @@ -47,3 +47,11 @@ dmnsn_interior *dmnsn_new_interior(void); * @param[in,out] interior The interior to delete. */ void dmnsn_delete_interior(dmnsn_interior *interior); + +/** + * 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/object.h b/libdimension/dimension/object.h index 02daaba..24e1bcb 100644 --- a/libdimension/dimension/object.h +++ b/libdimension/dimension/object.h @@ -71,7 +71,7 @@ typedef bool dmnsn_object_inside_fn(const dmnsn_object *object, /** An object. */ struct dmnsn_object { - dmnsn_texture *texture; /**< Surface properties. */ + dmnsn_texture *texture; /**< Surface properties. */ dmnsn_interior *interior; /**< Interior properties. */ dmnsn_matrix trans; /**< Transformation matrix. */ @@ -79,20 +79,18 @@ struct dmnsn_object { dmnsn_bounding_box bounding_box; /**< Object bounding box. */ - /** Child objects. This array lists objects that can be split into - sub-objects for bounding purposes (for unions and meshes, for example). */ - dmnsn_array *children; + dmnsn_array *children; /**< Child objects. */ + bool split_children; /**< Whether the child objects can be split. */ dmnsn_object_initialize_fn *initialize_fn; /**< Initialization callback. */ dmnsn_object_intersection_fn *intersection_fn; /**< Intersection callback. */ dmnsn_object_inside_fn *inside_fn; /**< Inside callback. */ dmnsn_free_fn *free_fn; /**< Destruction callback. */ - /** Generic pointer for object info. */ - void *ptr; + void *ptr; /**< Generic pointer for object info. */ - /** @internal Reference count. */ - dmnsn_refcount refcount; + dmnsn_refcount refcount; /**< @internal Reference count. */ + bool initialized; /**< @internal Whether the object is initialized yet. */ }; /** @@ -113,7 +111,6 @@ void dmnsn_delete_object(dmnsn_object *object); */ void dmnsn_initialize_object(dmnsn_object *object); - /** * Transform a surface normal vector. * @param[in] trans The transformation matrix. diff --git a/libdimension/dimension/pattern.h b/libdimension/dimension/pattern.h index beeb9f7..de37286 100644 --- a/libdimension/dimension/pattern.h +++ b/libdimension/dimension/pattern.h @@ -44,6 +44,8 @@ struct dmnsn_pattern { dmnsn_matrix trans_inv; /**< The inverse of the transformation matrix. */ void *ptr; /**< Generic pointer. */ + + dmnsn_refcount refcount; /**< @internal Reference count. */ }; /** diff --git a/libdimension/dimension/pigment.h b/libdimension/dimension/pigment.h index 896c0bc..8b3ce4b 100644 --- a/libdimension/dimension/pigment.h +++ b/libdimension/dimension/pigment.h @@ -55,6 +55,9 @@ struct dmnsn_pigment { /** Generic pointer. */ void *ptr; + + dmnsn_refcount refcount; /** @internal Reference count. */ + bool initialized; /** @internal Whether the pigment is initialized. */ }; /** @@ -76,3 +79,12 @@ void dmnsn_delete_pigment(dmnsn_pigment *pigment); * @param[in,out] pigment The pigment to initialize. */ void dmnsn_initialize_pigment(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_color dmnsn_evaluate_pigment(const dmnsn_pigment *pigment, + dmnsn_vector v); diff --git a/libdimension/dimension/refcount.h b/libdimension/dimension/refcount.h index 4431cbc..be437a8 100644 --- a/libdimension/dimension/refcount.h +++ b/libdimension/dimension/refcount.h @@ -32,7 +32,7 @@ typedef unsigned int dmnsn_refcount; * Increment a reference count. * @param[in,out] object The reference-counted object to acquire. */ -#define DMNSN_INCREF(obj) ((void)++(obj)->refcount) +#define DMNSN_INCREF(obj) ((void)((obj) && ++(obj)->refcount)) /** * @internal @@ -40,4 +40,5 @@ typedef unsigned int dmnsn_refcount; * @param[in,out] object The reference-counted object to release. * @return Whether the object is now garbage. */ -#define DMNSN_DECREF(obj) ((obj)->refcount == 0 || --(obj)->refcount == 0) +#define DMNSN_DECREF(obj) \ + ((obj) && ((obj)->refcount == 0 || --(obj)->refcount == 0)) diff --git a/libdimension/dimension/scene.h b/libdimension/dimension/scene.h index bb47ee9..969fa45 100644 --- a/libdimension/dimension/scene.h +++ b/libdimension/dimension/scene.h @@ -40,13 +40,10 @@ typedef unsigned int dmnsn_quality; /** An entire scene. */ typedef struct dmnsn_scene { /* World attributes */ - dmnsn_color background; /**< Background color. */ - dmnsn_color ambient; /**< Global ambient color. */ - dmnsn_sky_sphere *sky_sphere; /**< Sky sphere. */ - dmnsn_texture *default_texture; /**< Default object texture. */ - - /** Camera. */ - dmnsn_camera *camera; + dmnsn_color background; /**< Background color. */ + dmnsn_sky_sphere *sky_sphere; /**< Sky sphere. */ + dmnsn_texture *default_texture; /**< Default object texture. */ + dmnsn_interior *default_interior; /**< Default object interior. */ /** Canvas. */ dmnsn_canvas *canvas; @@ -57,6 +54,9 @@ typedef struct dmnsn_scene { /** Lights. */ dmnsn_array *lights; + /** Camera. */ + dmnsn_camera *camera; + /** Render quality. */ dmnsn_quality quality; @@ -72,6 +72,8 @@ typedef struct dmnsn_scene { /** Timers. */ dmnsn_timer *bounding_timer; dmnsn_timer *render_timer; + + bool initialized; /**< @internal Whether the scene is initialized. */ } dmnsn_scene; /** @@ -91,31 +93,3 @@ void dmnsn_delete_scene(dmnsn_scene *scene); * @param[in,out] scene The scene to initalize. */ void dmnsn_initialize_scene(dmnsn_scene *scene); - -/** - * Set the output canvas for a scene. - * @param[in,out] scene The scene for which to set the canvas. - * @param[in] canvas The canvas to set. - */ -void dmnsn_scene_set_canvas(dmnsn_scene *scene, dmnsn_canvas *canvas); - -/** - * Add a light to a scene. - * @param[in,out] scene The scene to which to add the light. - * @param[in] object The object to light. - */ -void dmnsn_scene_add_light(dmnsn_scene *scene, dmnsn_light *light); - -/** - * Set the camera for a scene. - * @param[in,out] scene The scene for which to set the canvas. - * @param[in] camera The camera to set. - */ -void dmnsn_scene_set_camera(dmnsn_scene *scene, dmnsn_camera *camera); - -/** - * Add an object to a scene. - * @param[in,out] scene The scene to which to add the object. - * @param[in] object The object to add. - */ -void dmnsn_scene_add_object(dmnsn_scene *scene, dmnsn_object *object); diff --git a/libdimension/dimension/sky_sphere.h b/libdimension/dimension/sky_sphere.h index 43ad57e..2d2c834 100644 --- a/libdimension/dimension/sky_sphere.h +++ b/libdimension/dimension/sky_sphere.h @@ -27,7 +27,10 @@ typedef struct dmnsn_sky_sphere { /** An array of pigments in inside-to-outside order. */ dmnsn_array *pigments; - dmnsn_matrix trans; + + dmnsn_matrix trans; /**< Transformation matrix. */ + + dmnsn_refcount refcount; /**< @internal Reference count. */ } dmnsn_sky_sphere; /** diff --git a/libdimension/dimension/texture.h b/libdimension/dimension/texture.h index 7edcabc..0c944a9 100644 --- a/libdimension/dimension/texture.h +++ b/libdimension/dimension/texture.h @@ -26,13 +26,13 @@ /** A complete texture. */ typedef struct { dmnsn_pigment *pigment; /**< Pigment. */ - dmnsn_finish *finish; /**< Finish. */ + dmnsn_finish finish; /**< Finish. */ dmnsn_matrix trans; /**< Transformation matrix. */ dmnsn_matrix trans_inv; /**< The inverse of the transformation matrix. */ dmnsn_refcount refcount; /**< @internal Reference count. */ - bool should_init; /**< @internal Whether to initialize the texture. */ + bool initialized; /**< @internal Whether the texture is initialized yet. */ } dmnsn_texture; /** @@ -54,3 +54,11 @@ void dmnsn_delete_texture(dmnsn_texture *texture); * @param[in,out] texture The texture to initialize. */ void dmnsn_initialize_texture(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 **texture); -- cgit v1.2.3