summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dimension/common.nonterminals1
-rw-r--r--dimension/common.rules16
-rw-r--r--dimension/grammar.epilogue3
-rw-r--r--dimension/parse.h1
-rw-r--r--dimension/realize.c73
-rwxr-xr-xtests/dimension/csg.sh9
-rwxr-xr-xtests/dimension/demo.sh9
-rwxr-xr-xtests/dimension/directives.sh15
8 files changed, 97 insertions, 30 deletions
diff --git a/dimension/common.nonterminals b/dimension/common.nonterminals
index 9feb03b..10a7b23 100644
--- a/dimension/common.nonterminals
+++ b/dimension/common.nonterminals
@@ -60,6 +60,7 @@
/* Pigments */
%type <astnode> PIGMENT
%type <astnode> PIGMENT_TYPE
+%type <astnode> PIGMENT_MODIFIERS
/* Finishes */
%type <astnode> FINISH
diff --git a/dimension/common.rules b/dimension/common.rules
index 7a6dba1..863b288 100644
--- a/dimension/common.rules
+++ b/dimension/common.rules
@@ -303,15 +303,20 @@ TEXTURE_ITEMS: /* empty */ {
$$ = $1;
dmnsn_array_push($$.children, &$2);
}
+ | TEXTURE_ITEMS TRANSFORMATION {
+ $$ = $1;
+ dmnsn_array_push($$.children, &$2);
+ }
;
/* Pigments */
PIGMENT: "pigment" "{"
PIGMENT_TYPE
+ PIGMENT_MODIFIERS
"}"
{
- $$ = dmnsn_new_astnode1(DMNSN_AST_PIGMENT, @$, $3);
+ $$ = dmnsn_new_astnode2(DMNSN_AST_PIGMENT, @$, $3, $4);
}
;
@@ -321,6 +326,15 @@ PIGMENT_TYPE: /* empty */ {
| COLOR
;
+PIGMENT_MODIFIERS: /* empty */ {
+ $$ = dmnsn_new_astnode(DMNSN_AST_PIGMENT_MODIFIERS, @$);
+ }
+ | PIGMENT_MODIFIERS TRANSFORMATION {
+ $$ = $1;
+ dmnsn_array_push($$.children, &$2);
+ }
+;
+
/* Finishes */
FINISH: "finish" "{"
FINISH_ITEMS
diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue
index 606e9dc..ea1414f 100644
--- a/dimension/grammar.epilogue
+++ b/dimension/grammar.epilogue
@@ -145,7 +145,8 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type)
dmnsn_astnode_map(DMNSN_AST_TEXTURE, "texture");
- dmnsn_astnode_map(DMNSN_AST_PIGMENT, "pigment");
+ dmnsn_astnode_map(DMNSN_AST_PIGMENT, "pigment");
+ dmnsn_astnode_map(DMNSN_AST_PIGMENT_MODIFIERS, "pigment-modifiers");
dmnsn_astnode_map(DMNSN_AST_FINISH, "finish");
dmnsn_astnode_map(DMNSN_AST_AMBIENT, "ambient");
diff --git a/dimension/parse.h b/dimension/parse.h
index 7387fbd..9d9e84f 100644
--- a/dimension/parse.h
+++ b/dimension/parse.h
@@ -60,6 +60,7 @@ typedef enum {
DMNSN_AST_TEXTURE,
DMNSN_AST_PIGMENT,
+ DMNSN_AST_PIGMENT_MODIFIERS,
DMNSN_AST_FINISH,
DMNSN_AST_AMBIENT,
diff --git a/dimension/realize.c b/dimension/realize.c
index 8ca24cc..463c27e 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -154,6 +154,23 @@ dmnsn_realize_translation(dmnsn_astnode astnode)
return dmnsn_translation_matrix(trans);
}
+static dmnsn_matrix
+dmnsn_realize_transformation(dmnsn_astnode astnode)
+{
+ switch (astnode.type) {
+ case DMNSN_AST_ROTATION:
+ return dmnsn_realize_rotation(astnode);
+ case DMNSN_AST_SCALE:
+ return dmnsn_realize_scale(astnode);
+ case DMNSN_AST_TRANSLATION:
+ return dmnsn_realize_translation(astnode);
+
+ default:
+ dmnsn_assert(false, "Expected a transformation.");
+ return dmnsn_identity_matrix(); // Shut up compiler
+ }
+}
+
static void
dmnsn_realize_global_settings(dmnsn_astnode astnode, dmnsn_scene *scene)
{
@@ -296,13 +313,9 @@ dmnsn_realize_camera(dmnsn_astnode astnode)
/* Transformations */
case DMNSN_AST_ROTATION:
- trans = dmnsn_matrix_mul(dmnsn_realize_rotation(item), trans);
- break;
case DMNSN_AST_SCALE:
- trans = dmnsn_matrix_mul(dmnsn_realize_scale(item), trans);
- break;
case DMNSN_AST_TRANSLATION:
- trans = dmnsn_matrix_mul(dmnsn_realize_translation(item), trans);
+ trans = dmnsn_matrix_mul(dmnsn_realize_transformation(item), trans);
break;
default:
@@ -379,6 +392,33 @@ dmnsn_realize_camera(dmnsn_astnode astnode)
return camera;
}
+static void
+dmnsn_realize_pigment_modifiers(dmnsn_astnode astnode, dmnsn_pigment *pigment)
+{
+ dmnsn_assert(astnode.type == DMNSN_AST_PIGMENT_MODIFIERS,
+ "Expected pigment modifiers.");
+
+ unsigned int i;
+ for (i = 0; i < dmnsn_array_size(astnode.children); ++i) {
+ dmnsn_astnode modifier;
+ dmnsn_array_get(astnode.children, i, &modifier);
+
+ switch (modifier.type) {
+ case DMNSN_AST_ROTATION:
+ case DMNSN_AST_SCALE:
+ case DMNSN_AST_TRANSLATION:
+ pigment->trans = dmnsn_matrix_mul(
+ dmnsn_realize_transformation(modifier),
+ pigment->trans
+ );
+ break;
+
+ default:
+ dmnsn_assert(false, "Invalid pigment modifier.");
+ }
+ }
+}
+
static dmnsn_pigment *
dmnsn_realize_pigment(dmnsn_astnode astnode)
{
@@ -403,6 +443,10 @@ dmnsn_realize_pigment(dmnsn_astnode astnode)
dmnsn_assert(false, "Invalid pigment color.");
}
+ dmnsn_astnode modifiers;
+ dmnsn_array_get(astnode.children, 1, &modifiers);
+ dmnsn_realize_pigment_modifiers(modifiers, pigment);
+
return pigment;
}
@@ -550,6 +594,13 @@ dmnsn_realize_texture(dmnsn_astnode astnode)
texture->finish = dmnsn_realize_finish(item);
break;
+ case DMNSN_AST_ROTATION:
+ case DMNSN_AST_SCALE:
+ case DMNSN_AST_TRANSLATION:
+ texture->trans = dmnsn_matrix_mul(dmnsn_realize_transformation(item),
+ texture->trans);
+ break;
+
default:
dmnsn_assert(false, "Invalid texture item.");
}
@@ -597,20 +648,10 @@ dmnsn_realize_object_modifiers(dmnsn_astnode astnode, dmnsn_object *object)
switch (modifier.type) {
case DMNSN_AST_ROTATION:
- object->trans = dmnsn_matrix_mul(
- dmnsn_realize_rotation(modifier),
- object->trans
- );
- break;
case DMNSN_AST_SCALE:
- object->trans = dmnsn_matrix_mul(
- dmnsn_realize_scale(modifier),
- object->trans
- );
- break;
case DMNSN_AST_TRANSLATION:
object->trans = dmnsn_matrix_mul(
- dmnsn_realize_translation(modifier),
+ dmnsn_realize_transformation(modifier),
object->trans
);
break;
diff --git a/tests/dimension/csg.sh b/tests/dimension/csg.sh
index c27e448..325aaba 100755
--- a/tests/dimension/csg.sh
+++ b/tests/dimension/csg.sh
@@ -38,7 +38,8 @@ csg_exp="$(echo -n \
(object-modifiers
(pigment
(vector (integer 1) (integer 0) (integer 0)
- (integer 0) (integer 0))))))
+ (integer 0) (integer 0))
+ pigment-modifiers))))
object-modifiers)
(union
(array
@@ -59,7 +60,8 @@ csg_exp="$(echo -n \
(object-modifiers
(pigment
(vector (integer 0) (integer 1) (integer 0)
- (integer 0) (integer 0)))))
+ (integer 0) (integer 0))
+ pigment-modifiers)))
(light_source
(vector (integer 15) (integer 0) (integer 0) (integer 0) (integer 0))
(vector (float 0.5) (float 0.5) (float 0.5) (integer 0) (integer 0))
@@ -70,7 +72,8 @@ csg_exp="$(echo -n \
(object-modifiers
(pigment
(vector (integer 0) (integer 0) (integer 1)
- (integer 0) (integer 0))))))
+ (integer 0) (integer 0))
+ pigment-modifiers))))
(object-modifiers
(translate (vector (integer 0) (integer 20) (integer 0)
(integer 0) (integer 0))))))' \
diff --git a/tests/dimension/demo.sh b/tests/dimension/demo.sh
index 7691093..f047f55 100755
--- a/tests/dimension/demo.sh
+++ b/tests/dimension/demo.sh
@@ -47,7 +47,8 @@ demo_exp=$(echo -n \
(texture
(pigment
(vector (integer 0) (integer 0) (integer 1)
- (float 0.25) (float 0.5)))
+ (float 0.25) (float 0.5))
+ pigment-modifiers)
(finish
(reflection
(vector (float 0.5) (float 0.5) (float 0.5)
@@ -64,7 +65,8 @@ demo_exp=$(echo -n \
(texture
(pigment
(vector (integer 0) (integer 1) (integer 0)
- (integer 0) (integer 0)))
+ (integer 0) (integer 0))
+ pigment-modifiers)
(finish
(phong (float 0.2))
(phong_size (float 40)))))))
@@ -75,7 +77,8 @@ demo_exp=$(echo -n \
(object-modifiers
(pigment
(vector (integer 1) (integer 1) (integer 1)
- (integer 0) (integer 0))))))' \
+ (integer 0) (integer 0))
+ pigment-modifiers))))' \
| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')
if [ "$demo" != "$demo_exp" ]; then
diff --git a/tests/dimension/directives.sh b/tests/dimension/directives.sh
index 1e487c4..4e77822 100755
--- a/tests/dimension/directives.sh
+++ b/tests/dimension/directives.sh
@@ -77,20 +77,23 @@ $(echo -n \
(vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0))
(integer 1)
(object-modifiers
- (pigment (vector (integer 1) (integer 1) (integer 1)
- (integer 0) (integer 0)))))
+ (pigment
+ (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0))
+ pigment-modifiers)))
(sphere
(vector (integer 0) (integer 1) (integer 0) (integer 0) (integer 0))
(integer 1)
(object-modifiers
- (pigment (vector (integer 1) (integer 1) (integer 1)
- (integer 0) (integer 0)))))
+ (pigment
+ (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0))
+ pigment-modifiers)))
(box
(vector (integer -1) (integer -1) (integer -1) (integer 0) (integer 0))
(vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0))
(object-modifiers
- (pigment (vector (integer 1) (integer 1) (integer 1)
- (integer 0) (integer 0)))
+ (pigment
+ (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0))
+ pigment-modifiers)
(finish
(phong (float 0.2))))))' \
| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')"