From cb85f91c28be53b4436d4cb4ff3ce4c87f501ba3 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 15 Apr 2010 20:21:14 -0400 Subject: Support transforming pigments and textures in dimension. --- dimension/common.nonterminals | 1 + dimension/common.rules | 16 +++++++++- dimension/grammar.epilogue | 3 +- dimension/parse.h | 1 + dimension/realize.c | 73 +++++++++++++++++++++++++++++++++---------- tests/dimension/csg.sh | 9 ++++-- tests/dimension/demo.sh | 9 ++++-- tests/dimension/directives.sh | 15 +++++---- 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 PIGMENT %type PIGMENT_TYPE +%type PIGMENT_MODIFIERS /* Finishes */ %type 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')" -- cgit v1.2.3