diff options
-rw-r--r-- | libdimension/Makefile.am | 14 | ||||
-rw-r--r-- | libdimension/ambient.c | 53 | ||||
-rw-r--r-- | libdimension/cube.c (renamed from libdimension/objects.c) | 68 | ||||
-rw-r--r-- | libdimension/diffuse.c | 58 | ||||
-rw-r--r-- | libdimension/finish_combination.c (renamed from libdimension/finishes.c) | 109 | ||||
-rw-r--r-- | libdimension/perspective.c (renamed from libdimension/cameras.c) | 0 | ||||
-rw-r--r-- | libdimension/phong.c | 67 | ||||
-rw-r--r-- | libdimension/point_light.c (renamed from libdimension/lights.c) | 0 | ||||
-rw-r--r-- | libdimension/solid_pigment.c (renamed from libdimension/pigments.c) | 0 | ||||
-rw-r--r-- | libdimension/sphere.c | 91 |
10 files changed, 278 insertions, 182 deletions
diff --git a/libdimension/Makefile.am b/libdimension/Makefile.am index e67f09e..49685c7 100644 --- a/libdimension/Makefile.am +++ b/libdimension/Makefile.am @@ -41,27 +41,31 @@ nobase_include_HEADERS = dimension.h \ lib_LTLIBRARIES = libdimension.la libdimension_la_SOURCES = $(nobase_include_HEADERS) \ + ambient.c \ camera.c \ - cameras.c \ canvas.c \ color.c \ + cube.c \ + diffuse.c \ dimension_impl.h \ error.c \ - finishes.c \ + finish_combination.c \ geometry.c \ gl.c \ inlines.c \ kD_splay_tree.c \ kD_splay_tree.h \ light.c \ - lights.c \ object.c \ - objects.c \ - pigments.c \ + perspective.c \ + phong.c \ png.c \ + point_light.c \ progress.c \ raytrace.c \ scene.c \ + solid_pigment.c \ + sphere.c \ texture.c libdimension_la_LDFLAGS = -version-info 0:0:0 libdimension_la_LIBADD = -lm -lpthread -lpng -lGL diff --git a/libdimension/ambient.c b/libdimension/ambient.c new file mode 100644 index 0000000..916ba67 --- /dev/null +++ b/libdimension/ambient.c @@ -0,0 +1,53 @@ +/************************************************************************* + * Copyright (C) 2009 Tavian Barnes <tavianator@gmail.com> * + * * + * This file is part of The Dimension Library. * + * * + * The Dimension Library is free software; you can redistribute it and/ * + * or modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Library is distributed in the hope that it will be * + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this program. If not, see * + * <http://www.gnu.org/licenses/>. * + *************************************************************************/ + +#include "dimension.h" +#include <stdlib.h> /* For malloc */ +#include <math.h> + +/* + * Ambient finish + */ + +static dmnsn_color +dmnsn_ambient_finish_fn(const dmnsn_finish *finish, dmnsn_color pigment) +{ + dmnsn_color *ambient = finish->ptr; + return dmnsn_color_illuminate(*ambient, pigment); +} + +dmnsn_finish * +dmnsn_new_ambient_finish(dmnsn_color ambient) +{ + dmnsn_finish *finish = dmnsn_new_finish(); + if (finish) { + dmnsn_color *param = malloc(sizeof(dmnsn_color)); + if (!param) { + dmnsn_delete_finish(finish); + return NULL; + } + + *param = ambient; + finish->ptr = param; + finish->ambient_fn = &dmnsn_ambient_finish_fn; + finish->free_fn = &free; + } + return finish; +} diff --git a/libdimension/objects.c b/libdimension/cube.c index 3470506..57dd12b 100644 --- a/libdimension/objects.c +++ b/libdimension/cube.c @@ -23,74 +23,6 @@ #include <math.h> /* For sqrt */ /* - * Sphere - */ - -/* Sphere object callbacks */ - -static dmnsn_intersection * -dmnsn_sphere_intersection_fn(const dmnsn_object *sphere, dmnsn_line line); - -static int dmnsn_sphere_inside_fn(const dmnsn_object *sphere, - dmnsn_vector point); - -/* Allocate a new sphere */ -dmnsn_object * -dmnsn_new_sphere() -{ - dmnsn_object *sphere = dmnsn_new_object(); - if (sphere) { - sphere->intersection_fn = &dmnsn_sphere_intersection_fn; - sphere->inside_fn = &dmnsn_sphere_inside_fn; - sphere->min = dmnsn_new_vector(-1.0, -1.0, -1.0); - sphere->max = dmnsn_new_vector(1.0, 1.0, 1.0); - } - return sphere; -} - -/* Returns the closest intersection of `line' with `sphere' */ -static dmnsn_intersection * -dmnsn_sphere_intersection_fn(const dmnsn_object *sphere, dmnsn_line line) -{ - double a, b, c, t; - dmnsn_intersection *intersection = NULL; - - /* Solve (x0 + nx*t)^2 + (y0 + ny*t)^2 + (z0 + nz*t)^2 == 1 */ - - a = line.n.x*line.n.x + line.n.y*line.n.y + line.n.z*line.n.z; - b = 2.0*(line.n.x*line.x0.x + line.n.y*line.x0.y + line.n.z*line.x0.z); - c = line.x0.x*line.x0.x + line.x0.y*line.x0.y + line.x0.z*line.x0.z - 1.0; - - if (b*b - 4.0*a*c >= 0) { - t = (-b - sqrt(b*b - 4.0*a*c))/(2*a); - if (t < 0.0) { - t = (-b + sqrt(b*b - 4.0*a*c))/(2*a); - } - - if (t >= 0.0) { - intersection = dmnsn_new_intersection(); - intersection->ray = line; - intersection->t = t; - intersection->normal = dmnsn_line_point(line, t); - intersection->texture = sphere->texture; - - /* Flip the normal if we're inside the sphere */ - if (dmnsn_vector_dot(line.n, intersection->normal) > 0.0) - intersection->normal = dmnsn_vector_negate(intersection->normal); - } - } - - return intersection; -} - -/* Return whether a point is inside a sphere (x**2 + y**2 + z**2 < 1.0) */ -static int -dmnsn_sphere_inside_fn(const dmnsn_object *sphere, dmnsn_vector point) -{ - return point.x*point.x + point.y*point.y + point.z*point.z < 1.0; -} - -/* * Cube */ diff --git a/libdimension/diffuse.c b/libdimension/diffuse.c new file mode 100644 index 0000000..4da51ee --- /dev/null +++ b/libdimension/diffuse.c @@ -0,0 +1,58 @@ +/************************************************************************* + * Copyright (C) 2009 Tavian Barnes <tavianator@gmail.com> * + * * + * This file is part of The Dimension Library. * + * * + * The Dimension Library is free software; you can redistribute it and/ * + * or modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Library is distributed in the hope that it will be * + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this program. If not, see * + * <http://www.gnu.org/licenses/>. * + *************************************************************************/ + +#include "dimension.h" +#include <stdlib.h> /* For malloc */ +#include <math.h> + +/* + * Diffuse finish + */ + +static dmnsn_color +dmnsn_diffuse_finish_fn(const dmnsn_finish *finish, + dmnsn_color light, dmnsn_color color, + dmnsn_vector ray, dmnsn_vector normal, + dmnsn_vector viewer) +{ + double *diffuse = finish->ptr; + double diffuse_factor = (*diffuse)*dmnsn_vector_dot(ray, normal); + return dmnsn_color_mul(diffuse_factor, dmnsn_color_illuminate(light, color)); +} + +dmnsn_finish * +dmnsn_new_diffuse_finish(double diffuse) +{ + dmnsn_finish *finish = dmnsn_new_finish(); + if (finish) { + double *param = malloc(sizeof(double)); + if (!param) { + dmnsn_delete_finish(finish); + return NULL; + } + + *param = diffuse; + + finish->ptr = param; + finish->finish_fn = &dmnsn_diffuse_finish_fn; + finish->free_fn = &free; + } + return finish; +} diff --git a/libdimension/finishes.c b/libdimension/finish_combination.c index a1b10e7..045db96 100644 --- a/libdimension/finishes.c +++ b/libdimension/finish_combination.c @@ -110,112 +110,3 @@ dmnsn_new_finish_combination(dmnsn_finish *f1, dmnsn_finish *f2) return NULL; } - -/* - * Ambient finish - */ - -static dmnsn_color -dmnsn_ambient_finish_fn(const dmnsn_finish *finish, dmnsn_color pigment) -{ - dmnsn_color *ambient = finish->ptr; - return dmnsn_color_illuminate(*ambient, pigment); -} - -dmnsn_finish * -dmnsn_new_ambient_finish(dmnsn_color ambient) -{ - dmnsn_finish *finish = dmnsn_new_finish(); - if (finish) { - dmnsn_color *param = malloc(sizeof(dmnsn_color)); - if (!param) { - dmnsn_delete_finish(finish); - return NULL; - } - - *param = ambient; - finish->ptr = param; - finish->ambient_fn = &dmnsn_ambient_finish_fn; - finish->free_fn = &free; - } - return finish; -} - -/* - * Diffuse finish - */ - -static dmnsn_color -dmnsn_diffuse_finish_fn(const dmnsn_finish *finish, - dmnsn_color light, dmnsn_color color, - dmnsn_vector ray, dmnsn_vector normal, - dmnsn_vector viewer) -{ - double *diffuse = finish->ptr; - double diffuse_factor = (*diffuse)*dmnsn_vector_dot(ray, normal); - return dmnsn_color_mul(diffuse_factor, dmnsn_color_illuminate(light, color)); -} - -dmnsn_finish * -dmnsn_new_diffuse_finish(double diffuse) -{ - dmnsn_finish *finish = dmnsn_new_finish(); - if (finish) { - double *param = malloc(sizeof(double)); - if (!param) { - dmnsn_delete_finish(finish); - return NULL; - } - - *param = diffuse; - - finish->ptr = param; - finish->finish_fn = &dmnsn_diffuse_finish_fn; - finish->free_fn = &free; - } - return finish; -} - -/* - * Phong finish - */ - -static dmnsn_color -dmnsn_phong_finish_fn(const dmnsn_finish *finish, - dmnsn_color light, dmnsn_color color, - dmnsn_vector ray, dmnsn_vector normal, - dmnsn_vector viewer) -{ - double *params = finish->ptr; - - double specular = params[0]; - double exp = params[1]; - - dmnsn_vector proj = dmnsn_vector_mul(2*dmnsn_vector_dot(ray, normal), normal); - dmnsn_vector reflected = dmnsn_vector_sub(proj, ray); - - double specular_factor = pow(dmnsn_vector_dot(reflected, viewer), exp); - return dmnsn_color_mul(specular*specular_factor, light); -} - -/* A phong finish */ -dmnsn_finish * -dmnsn_new_phong_finish(double specular, double exp) -{ - dmnsn_finish *finish = dmnsn_new_finish(); - if (finish) { - double *params = malloc(2*sizeof(double)); - if (!params) { - dmnsn_delete_finish(finish); - return NULL; - } - - params[0] = specular; - params[1] = exp; - - finish->ptr = params; - finish->finish_fn = &dmnsn_phong_finish_fn; - finish->free_fn = &free; - } - return finish; -} diff --git a/libdimension/cameras.c b/libdimension/perspective.c index 3389cc7..3389cc7 100644 --- a/libdimension/cameras.c +++ b/libdimension/perspective.c diff --git a/libdimension/phong.c b/libdimension/phong.c new file mode 100644 index 0000000..815885f --- /dev/null +++ b/libdimension/phong.c @@ -0,0 +1,67 @@ +/************************************************************************* + * Copyright (C) 2009 Tavian Barnes <tavianator@gmail.com> * + * * + * This file is part of The Dimension Library. * + * * + * The Dimension Library is free software; you can redistribute it and/ * + * or modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Library is distributed in the hope that it will be * + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this program. If not, see * + * <http://www.gnu.org/licenses/>. * + *************************************************************************/ + +#include "dimension.h" +#include <stdlib.h> /* For malloc */ +#include <math.h> + +/* + * Phong finish + */ + +static dmnsn_color +dmnsn_phong_finish_fn(const dmnsn_finish *finish, + dmnsn_color light, dmnsn_color color, + dmnsn_vector ray, dmnsn_vector normal, + dmnsn_vector viewer) +{ + double *params = finish->ptr; + + double specular = params[0]; + double exp = params[1]; + + dmnsn_vector proj = dmnsn_vector_mul(2*dmnsn_vector_dot(ray, normal), normal); + dmnsn_vector reflected = dmnsn_vector_sub(proj, ray); + + double specular_factor = pow(dmnsn_vector_dot(reflected, viewer), exp); + return dmnsn_color_mul(specular*specular_factor, light); +} + +/* A phong finish */ +dmnsn_finish * +dmnsn_new_phong_finish(double specular, double exp) +{ + dmnsn_finish *finish = dmnsn_new_finish(); + if (finish) { + double *params = malloc(2*sizeof(double)); + if (!params) { + dmnsn_delete_finish(finish); + return NULL; + } + + params[0] = specular; + params[1] = exp; + + finish->ptr = params; + finish->finish_fn = &dmnsn_phong_finish_fn; + finish->free_fn = &free; + } + return finish; +} diff --git a/libdimension/lights.c b/libdimension/point_light.c index 9862506..9862506 100644 --- a/libdimension/lights.c +++ b/libdimension/point_light.c diff --git a/libdimension/pigments.c b/libdimension/solid_pigment.c index adf44c4..adf44c4 100644 --- a/libdimension/pigments.c +++ b/libdimension/solid_pigment.c diff --git a/libdimension/sphere.c b/libdimension/sphere.c new file mode 100644 index 0000000..c61a46f --- /dev/null +++ b/libdimension/sphere.c @@ -0,0 +1,91 @@ +/************************************************************************* + * Copyright (C) 2009 Tavian Barnes <tavianator@gmail.com> * + * * + * This file is part of The Dimension Library. * + * * + * The Dimension Library is free software; you can redistribute it and/ * + * or modify it under the terms of the GNU Lesser General Public License * + * as published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Library is distributed in the hope that it will be * + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this program. If not, see * + * <http://www.gnu.org/licenses/>. * + *************************************************************************/ + +#include "dimension.h" +#include <stdlib.h> /* For malloc */ +#include <math.h> /* For sqrt */ + +/* + * Sphere + */ + +/* Sphere object callbacks */ + +static dmnsn_intersection * +dmnsn_sphere_intersection_fn(const dmnsn_object *sphere, dmnsn_line line); + +static int dmnsn_sphere_inside_fn(const dmnsn_object *sphere, + dmnsn_vector point); + +/* Allocate a new sphere */ +dmnsn_object * +dmnsn_new_sphere() +{ + dmnsn_object *sphere = dmnsn_new_object(); + if (sphere) { + sphere->intersection_fn = &dmnsn_sphere_intersection_fn; + sphere->inside_fn = &dmnsn_sphere_inside_fn; + sphere->min = dmnsn_new_vector(-1.0, -1.0, -1.0); + sphere->max = dmnsn_new_vector(1.0, 1.0, 1.0); + } + return sphere; +} + +/* Returns the closest intersection of `line' with `sphere' */ +static dmnsn_intersection * +dmnsn_sphere_intersection_fn(const dmnsn_object *sphere, dmnsn_line line) +{ + double a, b, c, t; + dmnsn_intersection *intersection = NULL; + + /* Solve (x0 + nx*t)^2 + (y0 + ny*t)^2 + (z0 + nz*t)^2 == 1 */ + + a = line.n.x*line.n.x + line.n.y*line.n.y + line.n.z*line.n.z; + b = 2.0*(line.n.x*line.x0.x + line.n.y*line.x0.y + line.n.z*line.x0.z); + c = line.x0.x*line.x0.x + line.x0.y*line.x0.y + line.x0.z*line.x0.z - 1.0; + + if (b*b - 4.0*a*c >= 0) { + t = (-b - sqrt(b*b - 4.0*a*c))/(2*a); + if (t < 0.0) { + t = (-b + sqrt(b*b - 4.0*a*c))/(2*a); + } + + if (t >= 0.0) { + intersection = dmnsn_new_intersection(); + intersection->ray = line; + intersection->t = t; + intersection->normal = dmnsn_line_point(line, t); + intersection->texture = sphere->texture; + + /* Flip the normal if we're inside the sphere */ + if (dmnsn_vector_dot(line.n, intersection->normal) > 0.0) + intersection->normal = dmnsn_vector_negate(intersection->normal); + } + } + + return intersection; +} + +/* Return whether a point is inside a sphere (x**2 + y**2 + z**2 < 1.0) */ +static int +dmnsn_sphere_inside_fn(const dmnsn_object *sphere, dmnsn_vector point) +{ + return point.x*point.x + point.y*point.y + point.z*point.z < 1.0; +} |