diff options
Diffstat (limited to 'dimension')
-rw-r--r-- | dimension/common.terminals | 2 | ||||
-rw-r--r-- | dimension/grammar.epilogue | 1 | ||||
-rw-r--r-- | dimension/grammar.nonterminals | 2 | ||||
-rw-r--r-- | dimension/grammar.rules | 22 | ||||
-rw-r--r-- | dimension/lexer.l | 1 | ||||
-rw-r--r-- | dimension/parse.h | 1 | ||||
-rw-r--r-- | dimension/realize.c | 35 |
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); |