summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dimension/grammar.y64
-rw-r--r--dimension/lexer.l5
-rw-r--r--dimension/parse.h7
-rw-r--r--dimension/realize.c86
-rw-r--r--tests/dimension/demo.pov10
-rwxr-xr-xtests/dimension/demo.sh12
6 files changed, 171 insertions, 13 deletions
diff --git a/dimension/grammar.y b/dimension/grammar.y
index b7e2b19..7024180 100644
--- a/dimension/grammar.y
+++ b/dimension/grammar.y
@@ -167,7 +167,7 @@ yyerror(YYLTYPE *locp, const char *filename, void *yyscanner,
%name-prefix "dmnsn_yy"
-%expect 7
+%expect 8
%glr-parser
%parse-param {const char *filename}
@@ -232,7 +232,7 @@ yyerror(YYLTYPE *locp, const char *filename, void *yyscanner,
%token DMNSN_T_ALPHA
%token DMNSN_T_ALTITUDE
%token DMNSN_T_ALWAYS_SAMPLE
-%token DMNSN_T_AMBIENT
+%token DMNSN_T_AMBIENT "ambient"
%token DMNSN_T_AMBIENT_LIGHT
%token DMNSN_T_ANGLE "angle"
%token DMNSN_T_APERTURE
@@ -315,7 +315,7 @@ yyerror(YYLTYPE *locp, const char *filename, void *yyscanner,
%token DMNSN_T_DENTS
%token DMNSN_T_DF3
%token DMNSN_T_DIFFERENCE
-%token DMNSN_T_DIFFUSE
+%token DMNSN_T_DIFFUSE "diffuse"
%token DMNSN_T_DIMENSION_SIZE
%token DMNSN_T_DIMENSIONS
%token DMNSN_T_DIRECTION "direction"
@@ -347,7 +347,7 @@ yyerror(YYLTYPE *locp, const char *filename, void *yyscanner,
%token DMNSN_T_FILTER "filter"
%token DMNSN_T_FINAL_CLOCK
%token DMNSN_T_FINAL_FRAME
-%token DMNSN_T_FINISH
+%token DMNSN_T_FINISH "finish"
%token DMNSN_T_FISHEYE
%token DMNSN_T_FLATNESS
%token DMNSN_T_FLIP
@@ -480,8 +480,8 @@ yyerror(YYLTYPE *locp, const char *filename, void *yyscanner,
%token DMNSN_T_PERSPECTIVE "perspective"
%token DMNSN_T_PGM
%token DMNSN_T_PHASE
-%token DMNSN_T_PHONG
-%token DMNSN_T_PHONG_SIZE
+%token DMNSN_T_PHONG "phong"
+%token DMNSN_T_PHONG_SIZE "phong_size"
%token DMNSN_T_PHOTONS
%token DMNSN_T_PI
%token DMNSN_T_PIGMENT "pigment"
@@ -584,7 +584,7 @@ yyerror(YYLTYPE *locp, const char *filename, void *yyscanner,
%token DMNSN_T_TANH
%token DMNSN_T_TARGET
%token DMNSN_T_TEXT
-%token DMNSN_T_TEXTURE
+%token DMNSN_T_TEXTURE "texture"
%token DMNSN_T_TEXTURE_LIST
%token DMNSN_T_TEXTURE_MAP
%token DMNSN_T_TGA
@@ -719,6 +719,10 @@ yyerror(YYLTYPE *locp, const char *filename, void *yyscanner,
%type <astnode> PIGMENT
%type <astnode> PIGMENT_TYPE
+/* Finishes */
+%type <astnode> FINISH
+%type <astnode> FINISH_ITEMS
+
/* Floats */
%type <astnode> FLOAT
%type <astnode> FLOAT_LITERAL
@@ -943,6 +947,10 @@ TEXTURE_ITEMS: /* empty */ {
$$ = $1;
dmnsn_array_push($$.children, &$2);
}
+ | TEXTURE_ITEMS FINISH {
+ $$ = $1;
+ dmnsn_array_push($$.children, &$2);
+ }
;
/* Pigments */
@@ -961,6 +969,41 @@ PIGMENT_TYPE: /* empty */ {
| COLOR
;
+/* Finishes */
+FINISH: "finish" "{"
+ FINISH_ITEMS
+ "}"
+ { $$ = $3; }
+;
+
+FINISH_ITEMS: /* empty */ {
+ $$ = dmnsn_new_astnode(DMNSN_AST_FINISH, @$);
+ }
+ | FINISH_ITEMS "ambient" COLOR {
+ dmnsn_astnode ambient = dmnsn_new_astnode1(DMNSN_AST_AMBIENT,
+ @2, $3);
+ $$ = $1;
+ dmnsn_array_push($$.children, &ambient);
+ }
+ | FINISH_ITEMS "diffuse" FLOAT {
+ dmnsn_astnode diffuse = dmnsn_new_astnode1(DMNSN_AST_DIFFUSE,
+ @2, $3);
+ $$ = $1;
+ dmnsn_array_push($$.children, &diffuse);
+ }
+ | FINISH_ITEMS "phong" FLOAT {
+ dmnsn_astnode phong = dmnsn_new_astnode1(DMNSN_AST_PHONG, @2, $3);
+ $$ = $1;
+ dmnsn_array_push($$.children, &phong);
+ }
+ | FINISH_ITEMS "phong_size" FLOAT {
+ dmnsn_astnode phong_size
+ = dmnsn_new_astnode1(DMNSN_AST_PHONG_SIZE, @2, $3);
+ $$ = $1;
+ dmnsn_array_push($$.children, &phong_size);
+ }
+;
+
/* Floats */
FLOAT: ARITH_EXPR {
@@ -1275,8 +1318,15 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type)
dmnsn_astnode_map(DMNSN_AST_OBJECT_MODIFIERS, "object-modifiers");
dmnsn_astnode_map(DMNSN_AST_TEXTURE, "texture");
+
dmnsn_astnode_map(DMNSN_AST_PIGMENT, "pigment");
+ dmnsn_astnode_map(DMNSN_AST_FINISH, "finish");
+ dmnsn_astnode_map(DMNSN_AST_AMBIENT, "ambient");
+ dmnsn_astnode_map(DMNSN_AST_DIFFUSE, "diffuse");
+ dmnsn_astnode_map(DMNSN_AST_PHONG, "phong");
+ dmnsn_astnode_map(DMNSN_AST_PHONG_SIZE, "phong_size");
+
dmnsn_astnode_map(DMNSN_AST_FLOAT, "float");
dmnsn_astnode_map(DMNSN_AST_INTEGER, "integer");
diff --git a/dimension/lexer.l b/dimension/lexer.l
index 691467b..08712d7 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -157,6 +157,7 @@ unsigned long wchar;
}
(?# Keywords)
+"ambient" RETURN_TOKEN(DMNSN_T_AMBIENT);
"angle" RETURN_TOKEN(DMNSN_T_ANGLE);
"background" RETURN_TOKEN(DMNSN_T_BACKGROUND);
"box" RETURN_TOKEN(DMNSN_T_BOX);
@@ -165,7 +166,9 @@ unsigned long wchar;
"color" RETURN_TOKEN(DMNSN_T_COLOR);
"colour" RETURN_TOKEN(DMNSN_T_COLOR);
"direction" RETURN_TOKEN(DMNSN_T_DIRECTION);
+"diffuse" RETURN_TOKEN(DMNSN_T_DIFFUSE);
"filter" RETURN_TOKEN(DMNSN_T_FILTER);
+"finish" RETURN_TOKEN(DMNSN_T_FINISH);
"gray" RETURN_TOKEN(DMNSN_T_GRAY);
"grey" RETURN_TOKEN(DMNSN_T_GRAY);
"green" RETURN_TOKEN(DMNSN_T_GREEN);
@@ -173,6 +176,8 @@ unsigned long wchar;
"look_at" RETURN_TOKEN(DMNSN_T_LOOK_AT);
"light_source" RETURN_TOKEN(DMNSN_T_LIGHT_SOURCE);
"perspective" RETURN_TOKEN(DMNSN_T_PERSPECTIVE);
+"phong" RETURN_TOKEN(DMNSN_T_PHONG);
+"phong_size" RETURN_TOKEN(DMNSN_T_PHONG_SIZE);
"pigment" RETURN_TOKEN(DMNSN_T_PIGMENT);
"red" RETURN_TOKEN(DMNSN_T_RED);
"rgb" RETURN_TOKEN(DMNSN_T_RGB);
diff --git a/dimension/parse.h b/dimension/parse.h
index 2b2a878..7a7ded2 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -53,8 +53,15 @@ typedef enum {
DMNSN_AST_OBJECT_MODIFIERS,
DMNSN_AST_TEXTURE,
+
DMNSN_AST_PIGMENT,
+ DMNSN_AST_FINISH,
+ DMNSN_AST_AMBIENT,
+ DMNSN_AST_DIFFUSE,
+ DMNSN_AST_PHONG,
+ DMNSN_AST_PHONG_SIZE,
+
DMNSN_AST_FLOAT,
DMNSN_AST_INTEGER,
diff --git a/dimension/realize.c b/dimension/realize.c
index 5ba4c8b..7b1ce04 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -24,6 +24,7 @@
#include "utility.h"
#include <math.h>
#include <stdio.h>
+#include <stdbool.h>
static double
dmnsn_realize_float(dmnsn_astnode astnode)
@@ -374,6 +375,86 @@ dmnsn_realize_pigment(dmnsn_astnode astnode)
return pigment;
}
+
+static dmnsn_finish *
+dmnsn_realize_finish(dmnsn_astnode astnode)
+{
+ if (astnode.type != DMNSN_AST_FINISH) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Expected a finish.");
+ }
+
+ dmnsn_finish *finish = dmnsn_new_finish();
+
+ dmnsn_color ambient = dmnsn_black;
+ bool ambient_set = false;
+
+ double diffuse = 0.0;
+ bool diffuse_set = false;
+
+ double phong = 0.0;
+ double phong_size = 40.0;
+
+ unsigned int i;
+ for (i = 0; i < dmnsn_array_size(astnode.children); ++i) {
+ dmnsn_astnode item;
+ dmnsn_astnode child;
+ dmnsn_array_get(astnode.children, i, &item);
+
+ switch (item.type) {
+ case DMNSN_AST_AMBIENT:
+ dmnsn_array_get(item.children, 0, &child);
+ ambient = dmnsn_realize_color(child);
+ ambient_set = true;
+ break;
+
+ case DMNSN_AST_DIFFUSE:
+ dmnsn_array_get(item.children, 0, &child);
+ diffuse = dmnsn_realize_float(child);
+ diffuse_set = true;
+ break;
+
+ case DMNSN_AST_PHONG:
+ dmnsn_array_get(item.children, 0, &child);
+ phong = dmnsn_realize_float(child);
+ break;
+ case DMNSN_AST_PHONG_SIZE:
+ dmnsn_array_get(item.children, 0, &child);
+ phong_size = dmnsn_realize_float(child);
+ break;
+
+ default:
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Invalid finish item.");
+ }
+ }
+
+ if (ambient_set) {
+ finish = dmnsn_new_finish_combination(
+ dmnsn_new_ambient_finish(ambient),
+ finish
+ );
+ }
+
+ if (diffuse_set) {
+ finish = dmnsn_new_finish_combination(
+ dmnsn_new_diffuse_finish(diffuse),
+ finish
+ );
+ }
+
+ if (phong) {
+ finish = dmnsn_new_finish_combination(
+ dmnsn_new_phong_finish(phong, phong_size),
+ finish
+ );
+ }
+
+ if (!finish) {
+ dmnsn_error(DMNSN_SEVERITY_HIGH, "Couldn't allocate finish.");
+ }
+
+ return finish;
+}
+
static dmnsn_texture *
dmnsn_realize_texture(dmnsn_astnode astnode)
{
@@ -397,6 +478,11 @@ dmnsn_realize_texture(dmnsn_astnode astnode)
texture->pigment = dmnsn_realize_pigment(modifier);
break;
+ case DMNSN_AST_FINISH:
+ dmnsn_delete_finish(texture->finish);
+ texture->finish = dmnsn_realize_finish(modifier);
+ break;
+
default:
dmnsn_error(DMNSN_SEVERITY_HIGH, "Invalid texture item.");
}
diff --git a/tests/dimension/demo.pov b/tests/dimension/demo.pov
index bb43573..c59148a 100644
--- a/tests/dimension/demo.pov
+++ b/tests/dimension/demo.pov
@@ -46,7 +46,13 @@ box {
sphere {
<0, 0, 0>, 1.25
- pigment {
- color rgb <0, 1, 0>
+ texture {
+ pigment {
+ color rgb <0, 1, 0>
+ }
+ finish {
+ phong 0.2
+ phong_size 40.0
+ }
}
}
diff --git a/tests/dimension/demo.sh b/tests/dimension/demo.sh
index c49e0ca..05225b6 100755
--- a/tests/dimension/demo.sh
+++ b/tests/dimension/demo.sh
@@ -42,15 +42,19 @@ demo_exp=$(echo -n \
(rotate (vector (integer 45) (integer 0) (integer 0)
(integer 0) (integer 0)))
(texture
- (pigment (color (integer 0) (integer 0) (integer 1)
- (float 0.25) (float 0.25))))))
+ (pigment
+ (color (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
(texture
- (pigment (color (integer 0) (integer 1) (integer 0)
- (integer 0) (integer 0)))))))' \
+ (pigment
+ (color (integer 0) (integer 1) (integer 0) (integer 0) (integer 0)))
+ (finish
+ (phong (float 0.2))
+ (phong_size (float 40)))))))' \
| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')
if [ "$demo" != "$demo_exp" ]; then