From c8667ce6ae94929e9bc06c9af51b6589bc528946 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 17 Jun 2010 09:16:20 -0600 Subject: Fully implement POV-Ray transformations. --- dimension/common.nonterminals | 2 + dimension/common.rules | 108 ++++++++++++++++++++++++++++++- dimension/common.terminals | 6 +- dimension/directives.rules | 7 +- dimension/grammar.epilogue | 9 ++- dimension/lexer.l | 3 + dimension/parse.h | 3 + dimension/realize.c | 124 ++++++++++++++++++++++++------------ tests/dimension/Makefile.am | 2 + tests/dimension/csg.sh | 5 +- tests/dimension/demo.sh | 10 +-- tests/dimension/transformations.pov | 39 ++++++++++++ tests/dimension/transformations.sh | 63 ++++++++++++++++++ 13 files changed, 324 insertions(+), 57 deletions(-) create mode 100644 tests/dimension/transformations.pov create mode 100755 tests/dimension/transformations.sh diff --git a/dimension/common.nonterminals b/dimension/common.nonterminals index 1d39424..5f915c5 100644 --- a/dimension/common.nonterminals +++ b/dimension/common.nonterminals @@ -25,6 +25,8 @@ /* Transformations */ %type TRANSFORMATION +%type TRANSFORMATION_ITEMS +%type TRANSFORMATION_ITEM /* The camera */ %type CAMERA diff --git a/dimension/common.rules b/dimension/common.rules index d897eb3..77830a6 100644 --- a/dimension/common.rules +++ b/dimension/common.rules @@ -43,14 +43,116 @@ STRING: "string" { /* Transformations */ TRANSFORMATION: "rotate" VECTOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_ROTATION, @$, $2); + dmnsn_astnode rotation + = dmnsn_new_astnode1(DMNSN_AST_ROTATION, @$, $2); + $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSFORMATION, @$, rotation); } | "scale" VECTOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_SCALE, @$, $2); + dmnsn_astnode scale + = dmnsn_new_astnode1(DMNSN_AST_SCALE, @$, $2); + $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSFORMATION, @$, scale); } | "translate" VECTOR { - $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSLATION, @$, $2); + dmnsn_astnode translation + = dmnsn_new_astnode1(DMNSN_AST_TRANSLATION, @$, $2); + $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSFORMATION, @$, + translation); } + | "matrix" "<" FLOAT "," FLOAT "," FLOAT "," + FLOAT "," FLOAT "," FLOAT "," + FLOAT "," FLOAT "," FLOAT "," + FLOAT "," FLOAT "," FLOAT ">" + { + dmnsn_astnode matrix = dmnsn_new_astnode(DMNSN_AST_MATRIX, @$); + + dmnsn_array_push(matrix.children, &$3); + dmnsn_array_push(matrix.children, &$5); + dmnsn_array_push(matrix.children, &$7); + + dmnsn_array_push(matrix.children, &$9); + dmnsn_array_push(matrix.children, &$11); + dmnsn_array_push(matrix.children, &$13); + + dmnsn_array_push(matrix.children, &$15); + dmnsn_array_push(matrix.children, &$17); + dmnsn_array_push(matrix.children, &$19); + + dmnsn_array_push(matrix.children, &$21); + dmnsn_array_push(matrix.children, &$23); + dmnsn_array_push(matrix.children, &$25); + + $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSFORMATION, @$, matrix); + } + | "transform" IDENTIFIER { + dmnsn_astnode *trans = dmnsn_find_symbol(symtable, $2.ptr); + if (!trans) { + dmnsn_diagnostic(@2, "unbound identifier '%s'", + (const char *)$2.ptr); + dmnsn_delete_astnode($2); + YYERROR; + } + if (trans->type != DMNSN_AST_TRANSFORMATION) { + dmnsn_diagnostic( + @2, "identifier '%s' is a %s; expected a %s", + (const char *)$2.ptr, + dmnsn_astnode_string(trans->type), + dmnsn_astnode_string(DMNSN_AST_TRANSFORMATION) + ); + dmnsn_delete_astnode($2); + YYERROR; + } + + $$ = dmnsn_new_astnode(DMNSN_AST_TRANSFORMATION, @$); + dmnsn_copy_children($$, *trans); + dmnsn_delete_astnode($2); + } + | "transform" "{" + TRANSFORMATION_ITEMS + "}" + { + $$ = $3; + } +; + +TRANSFORMATION_ITEMS: TRANSFORMATION_ITEM { + $$ = dmnsn_new_astnode1(DMNSN_AST_TRANSFORMATION, @$, $1); + } + | TRANSFORMATION_ITEMS TRANSFORMATION_ITEM { + $$ = $1; + dmnsn_array_push($$.children, &$2); + } +; + +TRANSFORMATION_ITEM: IDENTIFIER { + dmnsn_astnode *trans = dmnsn_find_symbol(symtable, $1.ptr); + if (!trans) { + dmnsn_diagnostic(@1, "unbound identifier '%s'", + (const char *)$1.ptr); + dmnsn_delete_astnode($1); + YYERROR; + } + if (trans->type != DMNSN_AST_TRANSFORMATION) { + dmnsn_diagnostic( + @1, "identifier '%s' is a %s; expected a %s", + (const char *)$1.ptr, + dmnsn_astnode_string(trans->type), + dmnsn_astnode_string(DMNSN_AST_TRANSFORMATION) + ); + dmnsn_delete_astnode($1); + YYERROR; + } + + dmnsn_array_get(trans->children, 0, &$$); + ++*$$.refcount; + } + | TRANSFORMATION { + dmnsn_array_get($1.children, 0, &$$); + ++*$$.refcount; + dmnsn_delete_astnode($1); + } + | "inverse" { + $$ = dmnsn_new_astnode(DMNSN_AST_INVERSE, @$); + } ; /* Cameras */ diff --git a/dimension/common.terminals b/dimension/common.terminals index fd62320..7ccc8cb 100644 --- a/dimension/common.terminals +++ b/dimension/common.terminals @@ -240,7 +240,7 @@ %token DMNSN_T_INTERPOLATE %token DMNSN_T_INTERSECTION "intersection" %token DMNSN_T_INTERVALS -%token DMNSN_T_INVERSE +%token DMNSN_T_INVERSE "inverse" %token DMNSN_T_IOR "ior" %token DMNSN_T_IRID %token DMNSN_T_IRID_WAVELENGTH @@ -270,7 +270,7 @@ %token DMNSN_T_MARBLE %token DMNSN_T_MATERIAL %token DMNSN_T_MATERIAL_MAP -%token DMNSN_T_MATRIX +%token DMNSN_T_MATRIX "matrix" %token DMNSN_T_MAX "max" %token DMNSN_T_MAX_EXTENT %token DMNSN_T_MAX_GRADIENT @@ -445,7 +445,7 @@ %token DMNSN_T_TOROIDAL %token DMNSN_T_TORUS %token DMNSN_T_TRACE -%token DMNSN_T_TRANSFORM +%token DMNSN_T_TRANSFORM "transform" %token DMNSN_T_TRANSLATE "translate" %token DMNSN_T_TRANSMIT "transmit" %token DMNSN_T_TRIANGLE diff --git a/dimension/directives.rules b/dimension/directives.rules index 84358f6..a3c53d2 100644 --- a/dimension/directives.rules +++ b/dimension/directives.rules @@ -115,7 +115,12 @@ RVALUE: ARITH_EXPR ";" %dprec 2 { | FINISH | INTERIOR | CAMERA - | TRANSFORMATION + | "transform" "{" + TRANSFORMATION_ITEMS + "}" + { + $$ = $3; + } ; DECL_PARAMS: /* empty */ { diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue index 7b004e3..073f412 100644 --- a/dimension/grammar.epilogue +++ b/dimension/grammar.epilogue @@ -163,9 +163,12 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type) dmnsn_astnode_map(DMNSN_AST_INTERIOR, "interior"); dmnsn_astnode_map(DMNSN_AST_IOR, "ior"); - dmnsn_astnode_map(DMNSN_AST_ROTATION, "rotate"); - dmnsn_astnode_map(DMNSN_AST_SCALE, "scale"); - dmnsn_astnode_map(DMNSN_AST_TRANSLATION, "translate"); + dmnsn_astnode_map(DMNSN_AST_TRANSFORMATION, "transformation"); + dmnsn_astnode_map(DMNSN_AST_ROTATION, "rotation"); + dmnsn_astnode_map(DMNSN_AST_SCALE, "scale"); + dmnsn_astnode_map(DMNSN_AST_TRANSLATION, "translation"); + dmnsn_astnode_map(DMNSN_AST_MATRIX, "matrix"); + dmnsn_astnode_map(DMNSN_AST_INVERSE, "inverse"); 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 85c3fda..ea98c07 100644 --- a/dimension/lexer.l +++ b/dimension/lexer.l @@ -207,12 +207,14 @@ unsigned long wchar; "int" RETURN_TOKEN(DMNSN_T_INT); "interior" RETURN_TOKEN(DMNSN_T_INTERIOR); "intersection" RETURN_TOKEN(DMNSN_T_INTERSECTION); +"inverse" RETURN_TOKEN(DMNSN_T_INVERSE); "ior" RETURN_TOKEN(DMNSN_T_IOR); "ln" RETURN_TOKEN(DMNSN_T_LN); "location" RETURN_TOKEN(DMNSN_T_LOCATION); "log" RETURN_TOKEN(DMNSN_T_LOG); "look_at" RETURN_TOKEN(DMNSN_T_LOOK_AT); "light_source" RETURN_TOKEN(DMNSN_T_LIGHT_SOURCE); +"matrix" RETURN_TOKEN(DMNSN_T_MATRIX); "max" RETURN_TOKEN(DMNSN_T_MAX); "max_trace_level" RETURN_TOKEN(DMNSN_T_MAX_TRACE_LEVEL); "merge" RETURN_TOKEN(DMNSN_T_MERGE); @@ -251,6 +253,7 @@ unsigned long wchar; "tan" RETURN_TOKEN(DMNSN_T_TAN); "tanh" RETURN_TOKEN(DMNSN_T_TANH); "texture" RETURN_TOKEN(DMNSN_T_TEXTURE); +"transform" RETURN_TOKEN(DMNSN_T_TRANSFORM); "translate" RETURN_TOKEN(DMNSN_T_TRANSLATE); "transmit" RETURN_TOKEN(DMNSN_T_TRANSMIT); "true" RETURN_TOKEN(DMNSN_T_TRUE); diff --git a/dimension/parse.h b/dimension/parse.h index b4bd8fe..fd78665 100644 --- a/dimension/parse.h +++ b/dimension/parse.h @@ -77,9 +77,12 @@ typedef enum { DMNSN_AST_INTERIOR, DMNSN_AST_IOR, + DMNSN_AST_TRANSFORMATION, DMNSN_AST_ROTATION, DMNSN_AST_SCALE, DMNSN_AST_TRANSLATION, + DMNSN_AST_MATRIX, + DMNSN_AST_INVERSE, DMNSN_AST_FLOAT, DMNSN_AST_INTEGER, diff --git a/dimension/realize.c b/dimension/realize.c index e558c5b..a9b9c71 100644 --- a/dimension/realize.c +++ b/dimension/realize.c @@ -112,6 +112,31 @@ dmnsn_realize_color(dmnsn_astnode astnode) return color; } +static dmnsn_matrix +dmnsn_realize_translation(dmnsn_astnode astnode) +{ + dmnsn_assert(astnode.type == DMNSN_AST_TRANSLATION, + "Expected a translation."); + + dmnsn_astnode trans_node; + dmnsn_array_get(astnode.children, 0, &trans_node); + dmnsn_vector trans = dmnsn_realize_vector(trans_node); + + return dmnsn_translation_matrix(trans); +} + +static dmnsn_matrix +dmnsn_realize_scale(dmnsn_astnode astnode) +{ + dmnsn_assert(astnode.type == DMNSN_AST_SCALE, "Expected a scale."); + + dmnsn_astnode scale_node; + dmnsn_array_get(astnode.children, 0, &scale_node); + dmnsn_vector scale = dmnsn_realize_vector(scale_node); + + return dmnsn_scale_matrix(scale); +} + static dmnsn_matrix dmnsn_realize_rotation(dmnsn_astnode astnode) { @@ -143,45 +168,72 @@ dmnsn_realize_rotation(dmnsn_astnode astnode) } static dmnsn_matrix -dmnsn_realize_scale(dmnsn_astnode astnode) +dmnsn_realize_matrix(dmnsn_astnode astnode) { - dmnsn_assert(astnode.type == DMNSN_AST_SCALE, "Expected a scale."); + dmnsn_assert(astnode.type == DMNSN_AST_MATRIX, "Expected a matrix."); - dmnsn_astnode scale_node; - dmnsn_array_get(astnode.children, 0, &scale_node); - dmnsn_vector scale = dmnsn_realize_vector(scale_node); + dmnsn_astnode *children = dmnsn_array_first(astnode.children); + dmnsn_matrix trans; - return dmnsn_scale_matrix(scale); -} + trans.n[0][0] = dmnsn_realize_float(children[0]); + trans.n[0][1] = dmnsn_realize_float(children[1]); + trans.n[0][2] = dmnsn_realize_float(children[2]); + trans.n[0][3] = dmnsn_realize_float(children[9]); -static dmnsn_matrix -dmnsn_realize_translation(dmnsn_astnode astnode) -{ - dmnsn_assert(astnode.type == DMNSN_AST_TRANSLATION, - "Expected a translation."); + trans.n[1][0] = dmnsn_realize_float(children[3]); + trans.n[1][1] = dmnsn_realize_float(children[4]); + trans.n[1][2] = dmnsn_realize_float(children[5]); + trans.n[1][3] = dmnsn_realize_float(children[10]); - dmnsn_astnode trans_node; - dmnsn_array_get(astnode.children, 0, &trans_node); - dmnsn_vector trans = dmnsn_realize_vector(trans_node); + trans.n[2][0] = dmnsn_realize_float(children[6]); + trans.n[2][1] = dmnsn_realize_float(children[7]); + trans.n[2][2] = dmnsn_realize_float(children[8]); + trans.n[2][3] = dmnsn_realize_float(children[11]); - return dmnsn_translation_matrix(trans); + trans.n[3][0] = 0.0; + trans.n[3][1] = 0.0; + trans.n[3][2] = 0.0; + trans.n[3][3] = 1.0; + + return 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); + dmnsn_assert(astnode.type == DMNSN_AST_TRANSFORMATION, + "Expected a transformation."); - default: - dmnsn_assert(false, "Expected a transformation."); - return dmnsn_identity_matrix(); /* Shut up compiler */ + dmnsn_matrix trans = dmnsn_identity_matrix(); + + DMNSN_ARRAY_FOREACH (dmnsn_astnode *, child, astnode.children) { + switch (child->type) { + case DMNSN_AST_TRANSLATION: + trans = dmnsn_matrix_mul(trans, dmnsn_realize_translation(*child)); + break; + case DMNSN_AST_SCALE: + trans = dmnsn_matrix_mul(trans, dmnsn_realize_scale(*child)); + break; + case DMNSN_AST_ROTATION: + trans = dmnsn_matrix_mul(trans, dmnsn_realize_rotation(*child)); + break; + case DMNSN_AST_MATRIX: + trans = dmnsn_matrix_mul(trans, dmnsn_realize_matrix(*child)); + break; + case DMNSN_AST_INVERSE: + trans = dmnsn_matrix_inverse(trans); + break; + case DMNSN_AST_TRANSFORMATION: + trans = dmnsn_matrix_mul(trans, dmnsn_realize_transformation(*child)); + break; + + default: + dmnsn_assert(false, "Invalid transformation type."); + break; + } } + + return trans; } static void @@ -320,9 +372,7 @@ dmnsn_realize_camera(dmnsn_astnode astnode) } /* Transformations */ - case DMNSN_AST_ROTATION: - case DMNSN_AST_SCALE: - case DMNSN_AST_TRANSLATION: + case DMNSN_AST_TRANSFORMATION: trans = dmnsn_matrix_mul(dmnsn_realize_transformation(*item), trans); break; @@ -408,9 +458,7 @@ dmnsn_realize_pigment_modifiers(dmnsn_astnode astnode, dmnsn_pigment *pigment) DMNSN_ARRAY_FOREACH(dmnsn_astnode *, modifier, astnode.children) { switch (modifier->type) { - case DMNSN_AST_ROTATION: - case DMNSN_AST_SCALE: - case DMNSN_AST_TRANSLATION: + case DMNSN_AST_TRANSFORMATION: pigment->trans = dmnsn_matrix_mul( dmnsn_realize_transformation(*modifier), pigment->trans @@ -621,9 +669,7 @@ 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: + case DMNSN_AST_TRANSFORMATION: texture->trans = dmnsn_matrix_mul( dmnsn_realize_transformation(*item), texture->trans @@ -673,9 +719,7 @@ dmnsn_realize_object_modifiers(dmnsn_astnode astnode, dmnsn_object *object) DMNSN_ARRAY_FOREACH (dmnsn_astnode *, modifier, astnode.children) { switch (modifier->type) { - case DMNSN_AST_ROTATION: - case DMNSN_AST_SCALE: - case DMNSN_AST_TRANSLATION: + case DMNSN_AST_TRANSFORMATION: object->trans = dmnsn_matrix_mul( dmnsn_realize_transformation(*modifier), object->trans @@ -728,9 +772,7 @@ dmnsn_realize_light_source_modifiers(dmnsn_astnode astnode, dmnsn_light *light) DMNSN_ARRAY_FOREACH (dmnsn_astnode *, modifier, astnode.children) { switch (modifier->type) { - case DMNSN_AST_ROTATION: - case DMNSN_AST_SCALE: - case DMNSN_AST_TRANSLATION: + case DMNSN_AST_TRANSFORMATION: light->x0 = dmnsn_transform_vector( dmnsn_realize_transformation(*modifier), light->x0 diff --git a/tests/dimension/Makefile.am b/tests/dimension/Makefile.am index d13b56e..bdb94ed 100644 --- a/tests/dimension/Makefile.am +++ b/tests/dimension/Makefile.am @@ -25,6 +25,7 @@ TESTS = punctuation.sh \ labels.sh \ directives.sh \ arithexp.sh \ + transformations.sh \ csg.sh \ demo.sh TESTS_ENVIRONMENT = top_builddir=$(top_builddir) @@ -40,6 +41,7 @@ EXTRA_DIST = $(TESTS) \ directives.inc \ directives.pov \ arithexp.pov \ + transformations.pov \ csg.pov \ demo.pov diff --git a/tests/dimension/csg.sh b/tests/dimension/csg.sh index 7f4732c..360398c 100755 --- a/tests/dimension/csg.sh +++ b/tests/dimension/csg.sh @@ -75,8 +75,9 @@ csg_exp="$(echo -n \ (integer 0) (integer 0)) pigment-modifiers)))) (object-modifiers - (translate (vector (integer 0) (integer 20) (integer 0) - (integer 0) (integer 0))))))' \ + (transformation + (translation (vector (integer 0) (integer 20) (integer 0) + (integer 0) (integer 0)))))))' \ | tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')" if [ "$csg" != "$csg_exp" ]; then diff --git a/tests/dimension/demo.sh b/tests/dimension/demo.sh index 22308dc..18f1c05 100755 --- a/tests/dimension/demo.sh +++ b/tests/dimension/demo.sh @@ -28,8 +28,9 @@ demo_exp=$(echo -n \ (right (vector (float 1.6) (integer 0) (integer 0) (integer 0) (integer 0))) (look_at (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0))) - (rotate (vector (integer 0) (integer 53) (integer 0) - (integer 0) (integer 0)))) + (transformation + (rotation (vector (integer 0) (integer 53) (integer 0) + (integer 0) (integer 0))))) (background (vector (integer 0) (float 0.1) (float 0.2) (float 0.1) (integer 0))) (light_source @@ -42,8 +43,9 @@ demo_exp=$(echo -n \ (vector (integer -1) (integer -1) (integer -1) (integer 0) (integer 0)) (vector (integer 1) (integer 1) (integer 1) (integer 0) (integer 0)) (object-modifiers - (rotate (vector (integer 45) (integer 0) (integer 0) - (integer 0) (integer 0))) + (transformation + (rotation (vector (integer 45) (integer 0) (integer 0) + (integer 0) (integer 0)))) (texture (pigment (vector (integer 0) (integer 0) (integer 1) diff --git a/tests/dimension/transformations.pov b/tests/dimension/transformations.pov new file mode 100644 index 0000000..4b56c3f --- /dev/null +++ b/tests/dimension/transformations.pov @@ -0,0 +1,39 @@ +/************************************************************************* + * Copyright (C) 2009-2010 Tavian Barnes * + * * + * This file is part of The Dimension Test Suite. * + * * + * The Dimension Test Suite is free software; you can redistribute it * + * and/or modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + * The Dimension Test Suite is distributed in the hope that it will be * + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +// Test transformations + +#declare Trans = transform { translate 1*z } + +sphere { + 0, 0 + translate -1*x + rotate 90*y + scale 2 + transform Trans + matrix <1, 1, 0, + 0, 1, 0, + 0, 0, 1, + 0, 0, 0> + transform { + Trans + rotate 45*z + inverse + } +} diff --git a/tests/dimension/transformations.sh b/tests/dimension/transformations.sh new file mode 100755 index 0000000..3e6b8e2 --- /dev/null +++ b/tests/dimension/transformations.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +######################################################################### +# Copyright (C) 2009-2010 Tavian Barnes # +# # +# This file is part of The Dimension Test Suite. # +# # +# The Dimension Test Suite is free software; you can redistribute it # +# and/or modify it under the terms of the GNU General Public License as # +# published by the Free Software Foundation; either version 3 of the # +# License, or (at your option) any later version. # +# # +# The Dimension Test Suite is distributed in the hope that it will be # +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # +# General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +######################################################################### + +transformations=$(${top_builddir}/dimension/dimension --parse ${srcdir}/transformations.pov) +transformations_exp="$(echo -n \ +'((sphere + (vector (integer 0) (integer 0) (integer 0) (integer 0) (integer 0)) + (integer 0) + (object-modifiers + (transformation + (translation + (vector (integer -1) (integer 0) (integer 0) + (integer 0) (integer 0)))) + (transformation + (rotation + (vector (integer 0) (integer 90) (integer 0) + (integer 0) (integer 0)))) + (transformation + (scale + (vector (integer 2) (integer 2) (integer 2) (integer 2) (integer 2)))) + (transformation + (translation + (vector (integer 0) (integer 0) (integer 1) (integer 0) (integer 0)))) + (transformation + (matrix + (integer 1) (integer 1) (integer 0) + (integer 0) (integer 1) (integer 0) + (integer 0) (integer 0) (integer 1) + (integer 0) (integer 0) (integer 0))) + (transformation + (translation + (vector (integer 0) (integer 0) (integer 1) (integer 0) (integer 0))) + (rotation + (vector (integer 0) (integer 0) (integer 45) + (integer 0) (integer 0))) + inverse))))' \ +| tr '\n' ' ' | sed -r 's/[[:space:]]+/ /g')" + +if [ "$transformations" != "$transformations_exp" ]; then + echo "transformations.pov parsed as \"$transformations\"" >&2 + echo " -- expected \"$transformations_exp\"" >&2 + exit 1 +fi + +${top_builddir}/dimension/dimension -w1 -h1 -o /dev/null ${srcdir}/transformations.pov -- cgit v1.2.3