summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-11-25 14:09:06 -0500
committerTavian Barnes <tavianator@gmail.com>2009-11-25 14:09:06 -0500
commit32f46ae1ccdb01533ea61265e4c977b9307c710d (patch)
tree79e0137ea2a30fa65f9fc2b0a8c441094ec22050
parentaa6106d8f1d60077aea53f216d9098a686e170f1 (diff)
downloaddimension-32f46ae1ccdb01533ea61265e4c977b9307c710d.tar.xz
Support solid-color pigments.
-rw-r--r--dimension/grammar.y12
-rw-r--r--dimension/lexer.l6
-rw-r--r--dimension/parse.h2
-rw-r--r--dimension/realize.c134
-rw-r--r--tests/dimension/demo.pov6
-rwxr-xr-xtests/dimension/demo.sh19
6 files changed, 167 insertions, 12 deletions
diff --git a/dimension/grammar.y b/dimension/grammar.y
index 2950941..5a271cc 100644
--- a/dimension/grammar.y
+++ b/dimension/grammar.y
@@ -505,7 +505,7 @@ yyerror(YYLTYPE *locp, dmnsn_array *astree, dmnsn_token_iterator *iterator,
%token DMNSN_T_PHONG_SIZE
%token DMNSN_T_PHOTONS
%token DMNSN_T_PI
-%token DMNSN_T_PIGMENT
+%token DMNSN_T_PIGMENT "pigment"
%token DMNSN_T_PIGMENT_MAP
%token DMNSN_T_PIGMENT_PATTERN
%token DMNSN_T_PLANAR
@@ -547,10 +547,10 @@ yyerror(YYLTYPE *locp, dmnsn_array *astree, dmnsn_token_iterator *iterator,
%token DMNSN_T_REFLECTION_EXPONENT
%token DMNSN_T_REFRACTION
%token DMNSN_T_REPEAT
-%token DMNSN_T_RGB
-%token DMNSN_T_RGBF
-%token DMNSN_T_RGBFT
-%token DMNSN_T_RGBT
+%token DMNSN_T_RGB "rgb"
+%token DMNSN_T_RGBF "rgbf"
+%token DMNSN_T_RGBFT "rgbft"
+%token DMNSN_T_RGBT "rgbt"
%token DMNSN_T_RIGHT
%token DMNSN_T_RIPPLES
%token DMNSN_T_ROTATE "rotate"
@@ -1464,8 +1464,6 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type)
dmnsn_astnode_map(DMNSN_AST_VECTOR, "vector");
- dmnsn_astnode_map(DMNSN_AST_COLOR, "color");
-
dmnsn_astnode_map(DMNSN_AST_NEGATE, "-");
dmnsn_astnode_map(DMNSN_AST_ADD, "+");
dmnsn_astnode_map(DMNSN_AST_SUB, "-");
diff --git a/dimension/lexer.l b/dimension/lexer.l
index 618bb7b..942a89f 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -159,10 +159,16 @@ unsigned long wchar;
"gray" PUSH_TOKEN(DMNSN_T_GRAY);
"grey" PUSH_TOKEN(DMNSN_T_GRAY);
"green" PUSH_TOKEN(DMNSN_T_GREEN);
+"pigment" PUSH_TOKEN(DMNSN_T_PIGMENT);
"red" PUSH_TOKEN(DMNSN_T_RED);
+"rgb" PUSH_TOKEN(DMNSN_T_RGB);
+"rgbf" PUSH_TOKEN(DMNSN_T_RGBF);
+"rgbft" PUSH_TOKEN(DMNSN_T_RGBFT);
+"rgbt" PUSH_TOKEN(DMNSN_T_RGBT);
"rotate" PUSH_TOKEN(DMNSN_T_ROTATE);
"sphere" PUSH_TOKEN(DMNSN_T_SPHERE);
"t" PUSH_TOKEN(DMNSN_T_T);
+"texture" PUSH_TOKEN(DMNSN_T_TEXTURE);
"transmit" PUSH_TOKEN(DMNSN_T_TRANSMIT);
"u" PUSH_TOKEN(DMNSN_T_U);
"v" PUSH_TOKEN(DMNSN_T_V);
diff --git a/dimension/parse.h b/dimension/parse.h
index f9d1dc9..eeb4492 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -42,8 +42,6 @@ typedef enum {
DMNSN_AST_VECTOR,
- DMNSN_AST_COLOR,
-
DMNSN_AST_NEGATE,
DMNSN_AST_ADD,
DMNSN_AST_SUB,
diff --git a/dimension/realize.c b/dimension/realize.c
index 3b1d327..84d04c6 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -56,9 +56,42 @@ dmnsn_realize_vector(dmnsn_astnode astnode)
return dmnsn_new_vector(x, y, z);
}
+static dmnsn_color
+dmnsn_realize_color(dmnsn_astnode astnode)
+{
+ if (astnode.type != DMNSN_AST_VECTOR) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a color.");
+ }
+
+
+ dmnsn_astnode rnode, gnode, bnode, fnode, tnode;
+ dmnsn_array_get(astnode.children, 0, &rnode);
+ dmnsn_array_get(astnode.children, 1, &gnode);
+ dmnsn_array_get(astnode.children, 2, &bnode);
+ dmnsn_array_get(astnode.children, 3, &fnode);
+ dmnsn_array_get(astnode.children, 4, &tnode);
+
+ double r = dmnsn_realize_float(rnode),
+ g = dmnsn_realize_float(gnode),
+ b = dmnsn_realize_float(bnode),
+ f = dmnsn_realize_float(fnode),
+ t = dmnsn_realize_float(tnode);
+
+ dmnsn_sRGB sRGB = { .R = r, .G = g, .B = b };
+ dmnsn_color color = dmnsn_color_from_sRGB(sRGB);
+ color.filter = f;
+ color.trans = t;
+
+ return color;
+}
+
static dmnsn_object *
dmnsn_realize_rotation(dmnsn_astnode astnode, dmnsn_object *object)
{
+ if (astnode.type != DMNSN_AST_ROTATION) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a rotation.");
+ }
+
const double deg2rad = atan(1.0)/45.0;
dmnsn_astnode angle_node;
@@ -89,6 +122,10 @@ dmnsn_realize_rotation(dmnsn_astnode astnode, dmnsn_object *object)
static dmnsn_object *
dmnsn_realize_scale(dmnsn_astnode astnode, dmnsn_object *object)
{
+ if (astnode.type != DMNSN_AST_SCALE) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a scale.");
+ }
+
dmnsn_astnode scale_node;
dmnsn_array_get(astnode.children, 0, &scale_node);
dmnsn_vector scale = dmnsn_realize_vector(scale_node);
@@ -100,6 +137,10 @@ dmnsn_realize_scale(dmnsn_astnode astnode, dmnsn_object *object)
static dmnsn_object *
dmnsn_realize_translation(dmnsn_astnode astnode, dmnsn_object *object)
{
+ if (astnode.type != DMNSN_AST_TRANSLATION) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a translation.");
+ }
+
dmnsn_astnode trans_node;
dmnsn_array_get(astnode.children, 0, &trans_node);
dmnsn_vector trans = dmnsn_realize_vector(trans_node);
@@ -112,8 +153,77 @@ dmnsn_realize_translation(dmnsn_astnode astnode, dmnsn_object *object)
}
static dmnsn_object *
+dmnsn_realize_pigment(dmnsn_astnode astnode, dmnsn_object *object)
+{
+ if (astnode.type != DMNSN_AST_PIGMENT) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a pigment.");
+ }
+
+ if (!object->texture) {
+ object->texture = dmnsn_new_texture();
+ if (!object->texture) {
+ dmnsn_delete_object(object);
+ return NULL;
+ }
+ }
+ dmnsn_delete_pigment(object->texture->pigment);
+
+ dmnsn_astnode color_node;
+ dmnsn_array_get(astnode.children, 0, &color_node);
+
+ dmnsn_color color;
+ switch (color_node.type) {
+ case DMNSN_AST_NONE:
+ break;
+
+ case DMNSN_AST_VECTOR:
+ color = dmnsn_realize_color(color_node);
+ object->texture->pigment = dmnsn_new_solid_pigment(color);
+ if (!object->texture->pigment) {
+ dmnsn_delete_object(object);
+ return NULL;
+ }
+ break;
+
+ default:
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Invalid pigment color.");
+ }
+
+ return object;
+}
+
+static dmnsn_object *
+dmnsn_realize_texture(dmnsn_astnode astnode, dmnsn_object *object)
+{
+ if (astnode.type != DMNSN_AST_TEXTURE) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a texture.");
+ }
+
+ unsigned int i;
+ for (i = 0; i < dmnsn_array_size(astnode.children); ++i) {
+ dmnsn_astnode modifier;
+ dmnsn_array_get(astnode.children, i, &modifier);
+
+ switch (modifier.type) {
+ case DMNSN_AST_PIGMENT:
+ object = dmnsn_realize_pigment(modifier, object);
+ break;
+
+ default:
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Invalid texture item.");
+ }
+ }
+
+ return object;
+}
+
+static dmnsn_object *
dmnsn_realize_object_modifiers(dmnsn_astnode astnode, dmnsn_object *object)
{
+ if (astnode.type != DMNSN_AST_OBJECT_MODIFIERS) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected object modifiers.");
+ }
+
unsigned int i;
for (i = 0; i < dmnsn_array_size(astnode.children); ++i) {
dmnsn_astnode modifier;
@@ -130,6 +240,10 @@ dmnsn_realize_object_modifiers(dmnsn_astnode astnode, dmnsn_object *object)
object = dmnsn_realize_translation(modifier, object);
break;
+ case DMNSN_AST_TEXTURE:
+ object = dmnsn_realize_texture(modifier, object);
+ break;
+
default:
dmnsn_error(DMNSN_SEVERITY_HIGH, "Invalid object modifier.");
}
@@ -225,6 +339,14 @@ dmnsn_realize(const dmnsn_array *astree)
return NULL;
}
+ /* Default finish */
+ scene->default_texture->finish = dmnsn_new_phong_finish(1.0, 0.5, 50.0);
+ if (!scene->default_texture->finish) {
+ dmnsn_delete_scene(scene);
+ return NULL;
+ }
+ scene->default_texture->finish->ambient = 0.1;
+
/* Background color */
dmnsn_sRGB background_sRGB = { .R = 0.0, .G = 0.0, .B = 0.1 };
scene->background = dmnsn_color_from_sRGB(background_sRGB);
@@ -260,6 +382,18 @@ dmnsn_realize(const dmnsn_array *astree)
}
dmnsn_set_perspective_camera_trans(scene->camera, trans);
+ /* Make a light */
+
+ dmnsn_light *light = dmnsn_new_point_light(
+ dmnsn_new_vector(-15.0, 20.0, 10.0),
+ dmnsn_white
+ );
+ if (!light) {
+ dmnsn_delete_scene(scene);
+ return NULL;
+ }
+ dmnsn_array_push(scene->lights, &light);
+
/*
* Now parse the abstract syntax tree
*/
diff --git a/tests/dimension/demo.pov b/tests/dimension/demo.pov
index 453ebfc..5aa044e 100644
--- a/tests/dimension/demo.pov
+++ b/tests/dimension/demo.pov
@@ -22,8 +22,14 @@
box {
<-1, -1, -1>, <1, 1, 1>
rotate <45, 0, 0>
+ pigment {
+ color rgbft <0, 0, 1, 0.25, 0.25>
+ }
}
sphere {
<0, 0, 0>, 1.25
+ pigment {
+ color rgb <0, 1, 0>
+ }
}
diff --git a/tests/dimension/demo.sh b/tests/dimension/demo.sh
index 0e0303a..ae65a9d 100755
--- a/tests/dimension/demo.sh
+++ b/tests/dimension/demo.sh
@@ -25,9 +25,16 @@ demo_exp="$(echo -n \
< - (integer "1") , - (integer "1") , - (integer "1") > ,
< (integer "1") , (integer "1") , (integer "1") >
rotate < (integer "45") , (integer "0") , (integer "0") >
+ pigment {
+ color rgbft < (integer "0") , (integer "0") , (integer "1") ,
+ (float "0.25") , (float "0.25") >
+ }
}
sphere {
< (integer "0") , (integer "0") , (integer "0") > , (float "1.25")
+ pigment {
+ color rgb < (integer "0") , (integer "1") , (integer "0") >
+ }
})' \
| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')
$(echo -n \
@@ -35,12 +42,18 @@ $(echo -n \
(vector (integer -1) (integer -1) (integer -1) (integer 0) (integer 0))
(vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0))
(object-modifiers
- (rotate (vector (integer 45) (integer 0) (integer 0) (integer 0)
- (integer 0)))))
+ (rotate (vector (integer 45) (integer 0) (integer 0)
+ (integer 0) (integer 0)))
+ (texture
+ (pigment (vector (integer 0) (integer 0) (integer 1)
+ (float 0.25) (float 0.25))))))
(sphere
(vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0))
(float 1.25)
- object-modifiers))' \
+ (object-modifiers
+ (texture
+ (pigment (vector (integer 0) (integer 1) (integer 0)
+ (integer 0) (integer 0)))))))' \
| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')"
if [ "$demo" != "$demo_exp" ]; then