From 32f46ae1ccdb01533ea61265e4c977b9307c710d Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 25 Nov 2009 14:09:06 -0500 Subject: Support solid-color pigments. --- dimension/grammar.y | 12 ++--- dimension/lexer.l | 6 +++ dimension/parse.h | 2 - dimension/realize.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++ tests/dimension/demo.pov | 6 +++ tests/dimension/demo.sh | 19 +++++-- 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); @@ -111,9 +152,78 @@ dmnsn_realize_translation(dmnsn_astnode astnode, dmnsn_object *object) return 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 -- cgit v1.2.3