summaryrefslogtreecommitdiffstats
path: root/dimension
diff options
context:
space:
mode:
Diffstat (limited to 'dimension')
-rw-r--r--dimension/common.nonterminals5
-rw-r--r--dimension/common.rules73
-rw-r--r--dimension/common.terminals2
-rw-r--r--dimension/directives.declarations2
-rw-r--r--dimension/grammar.declarations2
-rw-r--r--dimension/grammar.epilogue3
-rw-r--r--dimension/lexer.l1
-rw-r--r--dimension/parse.h3
-rw-r--r--dimension/realize.c144
9 files changed, 177 insertions, 58 deletions
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 <astnode> PIGMENT
+%type <astnode> PIGMENT_BODY
%type <astnode> PIGMENT_TYPE
%type <astnode> PIGMENT_MODIFIERS
%type <astnode> COLOR_LIST2
%type <astnode> COLOR_MAP
%type <astnode> COLOR_MAP_ENTRIES
%type <astnode> COLOR_MAP_ENTRY
+%type <astnode> PIGMENT_LIST2
+%type <astnode> PIGMENT_MAP
+%type <astnode> PIGMENT_MAP_ENTRIES
+%type <astnode> PIGMENT_MAP_ENTRY
%type <astnode> 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)
{