summaryrefslogtreecommitdiffstats
path: root/libdimension/dimension
diff options
context:
space:
mode:
Diffstat (limited to 'libdimension/dimension')
-rw-r--r--libdimension/dimension/finish.h158
-rw-r--r--libdimension/dimension/finishes.h28
-rw-r--r--libdimension/dimension/interior.h8
-rw-r--r--libdimension/dimension/object.h15
-rw-r--r--libdimension/dimension/pattern.h2
-rw-r--r--libdimension/dimension/pigment.h12
-rw-r--r--libdimension/dimension/refcount.h5
-rw-r--r--libdimension/dimension/scene.h44
-rw-r--r--libdimension/dimension/sky_sphere.h5
-rw-r--r--libdimension/dimension/texture.h12
10 files changed, 179 insertions, 110 deletions
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
@@ -24,41 +24,33 @@
*/
/**
- * 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);