From d6cfecdc224e95f1379f918d642074eada40627f Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 23 Nov 2010 13:14:16 -0500 Subject: Implement pigment maps. --- dimension/common.nonterminals | 5 ++ dimension/common.rules | 73 +++++++++++++++---- dimension/common.terminals | 2 +- dimension/directives.declarations | 2 +- dimension/grammar.declarations | 2 +- dimension/grammar.epilogue | 3 + dimension/lexer.l | 1 + dimension/parse.h | 3 + dimension/realize.c | 144 +++++++++++++++++++++++++++----------- 9 files changed, 177 insertions(+), 58 deletions(-) (limited to 'dimension') diff --git a/dimension/common.nonterminals b/dimension/common.nonterminals index c7140b5..3b4e239 100644 --- a/dimension/common.nonterminals +++ b/dimension/common.nonterminals @@ -71,12 +71,17 @@ /* Pigments */ %type PIGMENT +%type PIGMENT_BODY %type PIGMENT_TYPE %type PIGMENT_MODIFIERS %type COLOR_LIST2 %type COLOR_MAP %type COLOR_MAP_ENTRIES %type COLOR_MAP_ENTRY +%type PIGMENT_LIST2 +%type PIGMENT_MAP +%type PIGMENT_MAP_ENTRIES +%type PIGMENT_MAP_ENTRY %type BITMAP_TYPE /* Finishes */ diff --git a/dimension/common.rules b/dimension/common.rules index b4cf631..32eadc7 100644 --- a/dimension/common.rules +++ b/dimension/common.rules @@ -526,25 +526,32 @@ TEXTURE_ITEMS: /* empty */ { /* Pigments */ PIGMENT: "pigment" "{" - PIGMENT_TYPE - PIGMENT_MODIFIERS + PIGMENT_BODY "}" { - $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, $3, $4); - } - | "pigment" "{" - "checker" COLOR_LIST2 - PIGMENT_MODIFIERS - "}" - { - dmnsn_astnode checker = dmnsn_new_astnode(DMNSN_AST_CHECKER, @3); - dmnsn_astnode pattern = dmnsn_new_astnode1(DMNSN_AST_PATTERN, @3, - checker); - dmnsn_array_push($5.children, &$4); - $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, pattern, $5); + $$ = $3; } ; +PIGMENT_BODY: PIGMENT_TYPE PIGMENT_MODIFIERS { + $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, $1, $2); + } + | "checker" COLOR_LIST2 PIGMENT_MODIFIERS { + dmnsn_astnode checker = dmnsn_new_astnode(DMNSN_AST_CHECKER, @1); + dmnsn_astnode pattern = dmnsn_new_astnode1(DMNSN_AST_PATTERN, @1, + checker); + dmnsn_array_push($3.children, &$2); + $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, pattern, $3); + } + | "checker" PIGMENT_LIST2 PIGMENT_MODIFIERS { + dmnsn_astnode checker = dmnsn_new_astnode(DMNSN_AST_CHECKER, @1); + dmnsn_astnode pattern = dmnsn_new_astnode1(DMNSN_AST_PATTERN, @1, + checker); + dmnsn_array_push($3.children, &$2); + $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, pattern, $3); + } +; + PIGMENT_TYPE: COLOR | CONTINUOUS_PATTERN_TYPE | "image_map" "{" @@ -578,6 +585,10 @@ PIGMENT_MODIFIERS: /* empty */ { $$ = $1; dmnsn_array_push($$.children, &$2); } + | PIGMENT_MODIFIERS PIGMENT_MAP { + $$ = $1; + dmnsn_array_push($$.children, &$2); + } | PIGMENT_MODIFIERS "quick_color" COLOR { dmnsn_astnode quick_color = dmnsn_new_astnode1(DMNSN_AST_QUICK_COLOR, @2, $3); @@ -619,6 +630,40 @@ COLOR_MAP_ENTRY: "[" FLOAT "color" COLOR_BODY "]" { } ; +PIGMENT_LIST2: PIGMENT { + $$ = dmnsn_new_astnode1(DMNSN_AST_PIGMENT_LIST, @$, $1); + } + | PIGMENT PIGMENT { + $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT_LIST, @$, $1, $2); + } + | PIGMENT "," PIGMENT { + $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT_LIST, @$, $1, $3); + } +; + +PIGMENT_MAP: "pigment_map" "{" + PIGMENT_MAP_ENTRIES + "}" + { + $$ = $3; + } +; + +PIGMENT_MAP_ENTRIES: PIGMENT_MAP_ENTRY { + $$ = dmnsn_new_astnode1(DMNSN_AST_PIGMENT_MAP, @$, $1); + } + | PIGMENT_MAP_ENTRIES PIGMENT_MAP_ENTRY { + $$ = $1; + dmnsn_array_push($$.children, &$2); + } +; + +PIGMENT_MAP_ENTRY: "[" FLOAT PIGMENT_BODY "]" { + $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT_MAP_ENTRY, @$, + $2, $3); + } +; + /* Finishes */ FINISH: "finish" "{" FINISH_ITEMS diff --git a/dimension/common.terminals b/dimension/common.terminals index 4e8e6d1..d7ab854 100644 --- a/dimension/common.terminals +++ b/dimension/common.terminals @@ -332,7 +332,7 @@ %token DMNSN_T_PHOTONS %token DMNSN_T_PI "pi" %token DMNSN_T_PIGMENT "pigment" -%token DMNSN_T_PIGMENT_MAP +%token DMNSN_T_PIGMENT_MAP "pigment_map" %token DMNSN_T_PIGMENT_PATTERN %token DMNSN_T_PLANAR %token DMNSN_T_PLANE "plane" diff --git a/dimension/directives.declarations b/dimension/directives.declarations index 9f8c891..8867566 100644 --- a/dimension/directives.declarations +++ b/dimension/directives.declarations @@ -21,7 +21,7 @@ %name-prefix "dmnsn_ld_yy" -%expect 16 +%expect 19 %expect-rr 6 %parse-param {const char *filename} diff --git a/dimension/grammar.declarations b/dimension/grammar.declarations index ef3f7a2..cf8fcf1 100644 --- a/dimension/grammar.declarations +++ b/dimension/grammar.declarations @@ -23,7 +23,7 @@ %name-prefix "dmnsn_yy" -%expect 13 +%expect 16 %parse-param {const char *filename} %parse-param {void *yyscanner} diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue index 77a782a..bd8a89c 100644 --- a/dimension/grammar.epilogue +++ b/dimension/grammar.epilogue @@ -165,6 +165,9 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type) dmnsn_astnode_map(DMNSN_AST_COLOR_LIST, "color-list"); dmnsn_astnode_map(DMNSN_AST_COLOR_MAP, "color_map"); dmnsn_astnode_map(DMNSN_AST_COLOR_MAP_ENTRY, "color_map-entry"); + dmnsn_astnode_map(DMNSN_AST_PIGMENT_LIST, "pigment-list"); + dmnsn_astnode_map(DMNSN_AST_PIGMENT_MAP, "pigment_map"); + dmnsn_astnode_map(DMNSN_AST_PIGMENT_MAP_ENTRY, "pigment_map-entry"); dmnsn_astnode_map(DMNSN_AST_QUICK_COLOR, "quick_color"); dmnsn_astnode_map(DMNSN_AST_IMAGE_MAP, "image_map"); dmnsn_astnode_map(DMNSN_AST_PNG, "png"); diff --git a/dimension/lexer.l b/dimension/lexer.l index c5eeca7..45ba79a 100644 --- a/dimension/lexer.l +++ b/dimension/lexer.l @@ -240,6 +240,7 @@ unsigned long wchar; "phong_size" RETURN_TOKEN(DMNSN_T_PHONG_SIZE); "pi" RETURN_TOKEN(DMNSN_T_PI); "pigment" RETURN_TOKEN(DMNSN_T_PIGMENT); +"pigment_map" RETURN_TOKEN(DMNSN_T_PIGMENT_MAP); "plane" RETURN_TOKEN(DMNSN_T_PLANE); "png" RETURN_TOKEN(DMNSN_T_PNG); "pow" RETURN_TOKEN(DMNSN_T_POW); diff --git a/dimension/parse.h b/dimension/parse.h index 7bff5ba..62a0782 100644 --- a/dimension/parse.h +++ b/dimension/parse.h @@ -79,6 +79,9 @@ typedef enum { DMNSN_AST_COLOR_LIST, DMNSN_AST_COLOR_MAP, DMNSN_AST_COLOR_MAP_ENTRY, + DMNSN_AST_PIGMENT_LIST, + DMNSN_AST_PIGMENT_MAP, + DMNSN_AST_PIGMENT_MAP_ENTRY, DMNSN_AST_QUICK_COLOR, DMNSN_AST_IMAGE_MAP, DMNSN_AST_PNG, diff --git a/dimension/realize.c b/dimension/realize.c index ddccf89..56bd846 100644 --- a/dimension/realize.c +++ b/dimension/realize.c @@ -263,6 +263,39 @@ dmnsn_realize_global_settings(dmnsn_astnode astnode, dmnsn_scene *scene) } } +static dmnsn_pigment *dmnsn_realize_pigment(dmnsn_astnode astnode); + +static dmnsn_sky_sphere * +dmnsn_realize_sky_sphere(dmnsn_astnode astnode) +{ + dmnsn_assert(astnode.type == DMNSN_AST_SKY_SPHERE, "Expected a sky sphere."); + + dmnsn_sky_sphere *sky_sphere = dmnsn_new_sky_sphere(); + + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { + switch (item->type) { + case DMNSN_AST_PIGMENT: + { + dmnsn_pigment *pigment = dmnsn_realize_pigment(*item); + dmnsn_array_push(sky_sphere->pigments, &pigment); + break; + } + + case DMNSN_AST_TRANSFORMATION: + sky_sphere->trans = dmnsn_matrix_mul( + dmnsn_realize_transformation(*item), + sky_sphere->trans + ); + break; + + default: + dmnsn_assert(false, "Invalid sky sphere item."); + } + } + + return sky_sphere; +} + static dmnsn_camera * dmnsn_realize_camera(dmnsn_astnode astnode) { @@ -521,6 +554,49 @@ dmnsn_realize_color_map(dmnsn_astnode astnode) return color_map; } +static dmnsn_map * +dmnsn_realize_pigment_list(dmnsn_astnode astnode) +{ + dmnsn_assert(astnode.type == DMNSN_AST_PIGMENT_LIST, + "Expected a pigment list."); + + dmnsn_map *pigment_map = dmnsn_new_pigment_map(); + + double n = 0.0, i = 1.0/(dmnsn_array_size(astnode.children) - 1); + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, entry, astnode.children) { + dmnsn_pigment *pigment = dmnsn_realize_pigment(*entry); + dmnsn_add_map_entry(pigment_map, n, &pigment); + n += i; + } + + return pigment_map; +} + +static dmnsn_map * +dmnsn_realize_pigment_map(dmnsn_astnode astnode) +{ + dmnsn_assert(astnode.type == DMNSN_AST_PIGMENT_MAP, + "Expected a pigment_map."); + + dmnsn_map *pigment_map = dmnsn_new_pigment_map(); + + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, entry, astnode.children) { + dmnsn_assert(entry->type == DMNSN_AST_PIGMENT_MAP_ENTRY, + "Expected a pigment_map entry."); + + dmnsn_astnode n_node, pigment_node; + dmnsn_array_get(entry->children, 0, &n_node); + dmnsn_array_get(entry->children, 1, &pigment_node); + + double n = dmnsn_realize_float(n_node); + dmnsn_pigment *pigment = dmnsn_realize_pigment(pigment_node); + + dmnsn_add_map_entry(pigment_map, n, &pigment); + } + + return pigment_map; +} + static dmnsn_pigment * dmnsn_realize_pattern_pigment(dmnsn_astnode type, dmnsn_astnode modifiers) { @@ -528,9 +604,9 @@ dmnsn_realize_pattern_pigment(dmnsn_astnode type, dmnsn_astnode modifiers) "Expected pigment modifiers"); dmnsn_pattern *pattern = dmnsn_realize_pattern(type); - dmnsn_map *color_map = NULL; + dmnsn_map *color_map = NULL, *pigment_map = NULL; - /* Set up the color_map */ + /* Set up the map */ DMNSN_ARRAY_FOREACH_REVERSE (dmnsn_astnode *, modifier, modifiers.children) { switch (modifier->type) { case DMNSN_AST_COLOR_LIST: @@ -540,11 +616,18 @@ dmnsn_realize_pattern_pigment(dmnsn_astnode type, dmnsn_astnode modifiers) color_map = dmnsn_realize_color_map(*modifier); break; + case DMNSN_AST_PIGMENT_LIST: + pigment_map = dmnsn_realize_pigment_list(*modifier); + break; + case DMNSN_AST_PIGMENT_MAP: + pigment_map = dmnsn_realize_pigment_map(*modifier); + break; + default: break; } - if (color_map) + if (color_map || pigment_map) break; } @@ -556,17 +639,18 @@ dmnsn_realize_pattern_pigment(dmnsn_astnode type, dmnsn_astnode modifiers) switch (pattern_type.type) { case DMNSN_AST_CHECKER: /* Default checker pattern is blue and green */ - if (!color_map) + if (!color_map && !pigment_map) { color_map = dmnsn_new_color_map(); - if (dmnsn_map_size(color_map) < 1) - dmnsn_add_map_entry(color_map, 0.0, &dmnsn_blue); - if (dmnsn_map_size(color_map) < 2) - dmnsn_add_map_entry(color_map, 1.0, &dmnsn_green); + if (dmnsn_map_size(color_map) < 1) + dmnsn_add_map_entry(color_map, 0.0, &dmnsn_blue); + if (dmnsn_map_size(color_map) < 2) + dmnsn_add_map_entry(color_map, 1.0, &dmnsn_green); + } break; default: /* Default map is grayscale */ - if (!color_map) { + if (!color_map && !pigment_map) { color_map = dmnsn_new_color_map(); dmnsn_add_map_entry(color_map, 0.0, &dmnsn_black); dmnsn_add_map_entry(color_map, 1.0, &dmnsn_white); @@ -574,7 +658,14 @@ dmnsn_realize_pattern_pigment(dmnsn_astnode type, dmnsn_astnode modifiers) break; } - dmnsn_pigment *pigment = dmnsn_new_color_map_pigment(pattern, color_map); + dmnsn_pigment *pigment = NULL; + if (color_map) { + pigment = dmnsn_new_color_map_pigment(pattern, color_map); + } else if (pigment_map) { + pigment = dmnsn_new_pigment_map_pigment(pattern, pigment_map); + } else { + dmnsn_assert(false, "No appropriate map constructed."); + } return pigment; } @@ -603,6 +694,8 @@ dmnsn_realize_pigment_modifiers(dmnsn_astnode astnode, dmnsn_pigment *pigment) case DMNSN_AST_COLOR_LIST: case DMNSN_AST_COLOR_MAP: + case DMNSN_AST_PIGMENT_LIST: + case DMNSN_AST_PIGMENT_MAP: /* Already handled by dmnsn_realize_pattern_pigment() */ break; @@ -680,37 +773,6 @@ dmnsn_realize_pigment(dmnsn_astnode astnode) return pigment; } -static dmnsn_sky_sphere * -dmnsn_realize_sky_sphere(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_SKY_SPHERE, "Expected a sky sphere."); - - dmnsn_sky_sphere *sky_sphere = dmnsn_new_sky_sphere(); - - DMNSN_ARRAY_FOREACH (dmnsn_astnode *, item, astnode.children) { - switch (item->type) { - case DMNSN_AST_PIGMENT: - { - dmnsn_pigment *pigment = dmnsn_realize_pigment(*item); - dmnsn_array_push(sky_sphere->pigments, &pigment); - break; - } - - case DMNSN_AST_TRANSFORMATION: - sky_sphere->trans = dmnsn_matrix_mul( - dmnsn_realize_transformation(*item), - sky_sphere->trans - ); - break; - - default: - dmnsn_assert(false, "Invalid sky sphere item."); - } - } - - return sky_sphere; -} - static dmnsn_finish * dmnsn_realize_reflection(dmnsn_astnode astnode) { -- cgit v1.2.3