summaryrefslogtreecommitdiffstats
path: root/dimension
diff options
context:
space:
mode:
Diffstat (limited to 'dimension')
-rw-r--r--dimension/common.terminals2
-rw-r--r--dimension/grammar.epilogue1
-rw-r--r--dimension/grammar.nonterminals2
-rw-r--r--dimension/grammar.rules22
-rw-r--r--dimension/lexer.l1
-rw-r--r--dimension/parse.h1
-rw-r--r--dimension/realize.c35
7 files changed, 63 insertions, 1 deletions
diff --git a/dimension/common.terminals b/dimension/common.terminals
index 5a0d778..4e8e6d1 100644
--- a/dimension/common.terminals
+++ b/dimension/common.terminals
@@ -394,7 +394,7 @@
%token DMNSN_T_SINH "sinh"
%token DMNSN_T_SIZE
%token DMNSN_T_SKY "sky"
-%token DMNSN_T_SKY_SPHERE
+%token DMNSN_T_SKY_SPHERE "sky_sphere"
%token DMNSN_T_SLICE
%token DMNSN_T_SLOPE
%token DMNSN_T_SLOPE_MAP
diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue
index 0eace5e..77a782a 100644
--- a/dimension/grammar.epilogue
+++ b/dimension/grammar.epilogue
@@ -126,6 +126,7 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type)
dmnsn_astnode_map(DMNSN_AST_MAX_TRACE_LEVEL, "max_trace_level");
dmnsn_astnode_map(DMNSN_AST_BACKGROUND, "background");
+ dmnsn_astnode_map(DMNSN_AST_SKY_SPHERE, "sky_sphere");
dmnsn_astnode_map(DMNSN_AST_CAMERA, "camera");
dmnsn_astnode_map(DMNSN_AST_PERSPECTIVE, "perspective");
diff --git a/dimension/grammar.nonterminals b/dimension/grammar.nonterminals
index 9ab8ee1..912b660 100644
--- a/dimension/grammar.nonterminals
+++ b/dimension/grammar.nonterminals
@@ -31,3 +31,5 @@
/* Atmospheric effects */
%type <astnode> ATMOSPHERIC_EFFECT
%type <astnode> BACKGROUND
+%type <astnode> SKY_SPHERE
+%type <astnode> SKY_SPHERE_ITEMS
diff --git a/dimension/grammar.rules b/dimension/grammar.rules
index 0e9d6f1..8b110c0 100644
--- a/dimension/grammar.rules
+++ b/dimension/grammar.rules
@@ -94,9 +94,31 @@ GLOBAL_CHARSET: "ascii" {
/* Atmospheric effects */
ATMOSPHERIC_EFFECT: BACKGROUND
+ | SKY_SPHERE
;
BACKGROUND: "background" "{" COLOR "}" {
$$ = dmnsn_new_astnode1(DMNSN_AST_BACKGROUND, @$, $3);
}
;
+
+SKY_SPHERE: "sky_sphere" "{"
+ SKY_SPHERE_ITEMS
+ "}"
+ {
+ $$ = $3;
+ }
+;
+
+SKY_SPHERE_ITEMS: /* empty */ {
+ $$ = dmnsn_new_astnode(DMNSN_AST_SKY_SPHERE, @$);
+ }
+ | SKY_SPHERE_ITEMS PIGMENT {
+ $$ = $1;
+ dmnsn_array_push($$.children, &$2);
+ }
+ | SKY_SPHERE_ITEMS TRANSFORMATION {
+ $$ = $1;
+ dmnsn_array_push($$.children, &$2);
+ }
+;
diff --git a/dimension/lexer.l b/dimension/lexer.l
index 5e1afa2..c5eeca7 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -258,6 +258,7 @@ unsigned long wchar;
"sin" RETURN_TOKEN(DMNSN_T_SIN);
"sinh" RETURN_TOKEN(DMNSN_T_SINH);
"sky" RETURN_TOKEN(DMNSN_T_SKY);
+"sky_sphere" RETURN_TOKEN(DMNSN_T_SKY_SPHERE);
"sphere" RETURN_TOKEN(DMNSN_T_SPHERE);
"sqrt" RETURN_TOKEN(DMNSN_T_SQRT);
"strcmp" RETURN_TOKEN(DMNSN_T_STRCMP);
diff --git a/dimension/parse.h b/dimension/parse.h
index 38e4eef..7bff5ba 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -40,6 +40,7 @@ typedef enum {
DMNSN_AST_MAX_INTERSECTIONS,
DMNSN_AST_BACKGROUND,
+ DMNSN_AST_SKY_SPHERE,
DMNSN_AST_CAMERA,
DMNSN_AST_PERSPECTIVE,
diff --git a/dimension/realize.c b/dimension/realize.c
index d4b45cb..2f74ce0 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -680,6 +680,37 @@ 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)
{
@@ -1295,6 +1326,10 @@ dmnsn_realize_astree(const dmnsn_astree *astree)
dmnsn_array_get(astnode->children, 0, &child);
scene->background = dmnsn_realize_color(child);
break;
+ case DMNSN_AST_SKY_SPHERE:
+ dmnsn_delete_sky_sphere(scene->sky_sphere);
+ scene->sky_sphere = dmnsn_realize_sky_sphere(*astnode);
+ break;
case DMNSN_AST_CAMERA:
dmnsn_delete_camera(scene->camera);