summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dimension/common.nonterminals2
-rw-r--r--dimension/common.rules13
-rw-r--r--dimension/common.terminals2
-rw-r--r--dimension/grammar.epilogue1
-rw-r--r--dimension/lexer.l1
-rw-r--r--dimension/parse.h1
-rw-r--r--dimension/realize.c25
-rw-r--r--tests/dimension/demo.pov7
-rwxr-xr-xtests/dimension/demo.sh9
9 files changed, 59 insertions, 2 deletions
diff --git a/dimension/common.nonterminals b/dimension/common.nonterminals
index 768e075..9feb03b 100644
--- a/dimension/common.nonterminals
+++ b/dimension/common.nonterminals
@@ -39,6 +39,8 @@
%type <astnode> FINITE_SOLID_OBJECT
%type <astnode> BOX
%type <astnode> SPHERE
+%type <astnode> INFINITE_SOLID_OBJECT
+%type <astnode> PLANE
%type <astnode> CSG_OBJECT
%type <astnode> UNION
%type <astnode> INTERSECTION
diff --git a/dimension/common.rules b/dimension/common.rules
index c5f9eea..7a6dba1 100644
--- a/dimension/common.rules
+++ b/dimension/common.rules
@@ -111,6 +111,7 @@ CAMERA_MODIFIER: "angle" FLOAT {
/* Objects */
OBJECT: FINITE_SOLID_OBJECT
+ | INFINITE_SOLID_OBJECT
| CSG_OBJECT
| LIGHT_SOURCE
| "object" "{"
@@ -194,6 +195,18 @@ SPHERE: "sphere" "{"
}
;
+INFINITE_SOLID_OBJECT: PLANE
+;
+
+PLANE: "plane" "{"
+ VECTOR "," FLOAT
+ OBJECT_MODIFIERS
+ "}"
+ {
+ $$ = dmnsn_new_astnode3(DMNSN_AST_PLANE, @$, $3, $5, $6);
+ }
+;
+
CSG_OBJECT: UNION
| INTERSECTION
| DIFFERENCE
diff --git a/dimension/common.terminals b/dimension/common.terminals
index 4458af3..c125489 100644
--- a/dimension/common.terminals
+++ b/dimension/common.terminals
@@ -335,7 +335,7 @@
%token DMNSN_T_PIGMENT_MAP
%token DMNSN_T_PIGMENT_PATTERN
%token DMNSN_T_PLANAR
-%token DMNSN_T_PLANE
+%token DMNSN_T_PLANE "plane"
%token DMNSN_T_PNG
%token DMNSN_T_POINT_AT
%token DMNSN_T_POLY
diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue
index 275e03d..606e9dc 100644
--- a/dimension/grammar.epilogue
+++ b/dimension/grammar.epilogue
@@ -137,6 +137,7 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type)
dmnsn_astnode_map(DMNSN_AST_INTERSECTION, "intersection");
dmnsn_astnode_map(DMNSN_AST_LIGHT_SOURCE, "light_source");
dmnsn_astnode_map(DMNSN_AST_MERGE, "merge");
+ dmnsn_astnode_map(DMNSN_AST_PLANE, "plane");
dmnsn_astnode_map(DMNSN_AST_SPHERE, "sphere");
dmnsn_astnode_map(DMNSN_AST_UNION, "union");
diff --git a/dimension/lexer.l b/dimension/lexer.l
index cc5fef5..5039bef 100644
--- a/dimension/lexer.l
+++ b/dimension/lexer.l
@@ -222,6 +222,7 @@ unsigned long wchar;
"phong_size" RETURN_TOKEN(DMNSN_T_PHONG_SIZE);
"pi" RETURN_TOKEN(DMNSN_T_PI);
"pigment" RETURN_TOKEN(DMNSN_T_PIGMENT);
+"plane" RETURN_TOKEN(DMNSN_T_PLANE);
"pow" RETURN_TOKEN(DMNSN_T_POW);
"radians" RETURN_TOKEN(DMNSN_T_RADIANS);
"red" RETURN_TOKEN(DMNSN_T_RED);
diff --git a/dimension/parse.h b/dimension/parse.h
index 64fbf25..7387fbd 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -51,6 +51,7 @@ typedef enum {
DMNSN_AST_INTERSECTION,
DMNSN_AST_LIGHT_SOURCE,
DMNSN_AST_MERGE,
+ DMNSN_AST_PLANE,
DMNSN_AST_SPHERE,
DMNSN_AST_UNION,
diff --git a/dimension/realize.c b/dimension/realize.c
index b5c6066..8ca24cc 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -771,6 +771,28 @@ dmnsn_realize_sphere(dmnsn_astnode astnode)
return sphere;
}
+static dmnsn_object *
+dmnsn_realize_plane(dmnsn_astnode astnode)
+{
+ dmnsn_assert(astnode.type == DMNSN_AST_PLANE, "Expected a plane.");
+
+ dmnsn_astnode normal, distance;
+ dmnsn_array_get(astnode.children, 0, &normal);
+ dmnsn_array_get(astnode.children, 1, &distance);
+
+ dmnsn_vector n = dmnsn_vector_normalize(dmnsn_realize_vector(normal));
+ double d = dmnsn_realize_float(distance);
+
+ dmnsn_object *plane = dmnsn_new_plane(n);
+ plane->trans = dmnsn_translation_matrix(dmnsn_vector_mul(d, n));
+
+ dmnsn_astnode modifiers;
+ dmnsn_array_get(astnode.children, 2, &modifiers);
+ dmnsn_realize_object_modifiers(modifiers, plane);
+
+ return plane;
+}
+
typedef dmnsn_object *dmnsn_csg_object_fn(dmnsn_object *a, dmnsn_object *b);
/* Generalized CSG realizer */
@@ -857,6 +879,8 @@ dmnsn_realize_object(dmnsn_astnode astnode, dmnsn_array *lights)
return dmnsn_realize_intersection(astnode, lights);
case DMNSN_AST_MERGE:
return dmnsn_realize_merge(astnode, lights);
+ case DMNSN_AST_PLANE:
+ return dmnsn_realize_plane(astnode);
case DMNSN_AST_SPHERE:
return dmnsn_realize_sphere(astnode);
case DMNSN_AST_UNION:
@@ -925,6 +949,7 @@ dmnsn_realize_astree(const dmnsn_astree *astree)
case DMNSN_AST_DIFFERENCE:
case DMNSN_AST_INTERSECTION:
case DMNSN_AST_MERGE:
+ case DMNSN_AST_PLANE:
case DMNSN_AST_SPHERE:
case DMNSN_AST_UNION:
object = dmnsn_realize_object(astnode, scene->lights);
diff --git a/tests/dimension/demo.pov b/tests/dimension/demo.pov
index d14cebb..4f558c5 100644
--- a/tests/dimension/demo.pov
+++ b/tests/dimension/demo.pov
@@ -70,3 +70,10 @@ difference {
}
}
}
+
+plane {
+ y, -2
+ pigment {
+ color rgb 1
+ }
+}
diff --git a/tests/dimension/demo.sh b/tests/dimension/demo.sh
index 7e9306a..7691093 100755
--- a/tests/dimension/demo.sh
+++ b/tests/dimension/demo.sh
@@ -68,7 +68,14 @@ demo_exp=$(echo -n \
(finish
(phong (float 0.2))
(phong_size (float 40)))))))
- object-modifiers))' \
+ object-modifiers)
+ (plane
+ (vector (integer 0) (integer 1) (integer 0) (integer 0) (integer 0))
+ (integer -2)
+ (object-modifiers
+ (pigment
+ (vector (integer 1) (integer 1) (integer 1)
+ (integer 0) (integer 0))))))' \
| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')
if [ "$demo" != "$demo_exp" ]; then