diff options
-rw-r--r-- | dimension/common.nonterminals | 2 | ||||
-rw-r--r-- | dimension/common.rules | 20 | ||||
-rw-r--r-- | dimension/common.terminals | 4 | ||||
-rw-r--r-- | dimension/grammar.epilogue | 1 | ||||
-rw-r--r-- | dimension/lexer.l | 2 | ||||
-rw-r--r-- | dimension/parse.h | 1 | ||||
-rw-r--r-- | dimension/realize.c | 47 | ||||
-rw-r--r-- | tests/dimension/demo.pov | 8 | ||||
-rwxr-xr-x | tests/dimension/demo.sh | 14 |
9 files changed, 97 insertions, 2 deletions
diff --git a/dimension/common.nonterminals b/dimension/common.nonterminals index 5f915c5..09a4f5f 100644 --- a/dimension/common.nonterminals +++ b/dimension/common.nonterminals @@ -40,6 +40,8 @@ %type <astnode> OBJECT %type <astnode> FINITE_SOLID_OBJECT %type <astnode> BOX +%type <astnode> CYLINDER +%type <astnode> MAYBE_OPEN %type <astnode> SPHERE %type <astnode> INFINITE_SOLID_OBJECT %type <astnode> PLANE diff --git a/dimension/common.rules b/dimension/common.rules index 89b7ab8..e5e6543 100644 --- a/dimension/common.rules +++ b/dimension/common.rules @@ -283,6 +283,7 @@ OBJECT: FINITE_SOLID_OBJECT ; FINITE_SOLID_OBJECT: BOX + | CYLINDER | SPHERE ; @@ -296,6 +297,25 @@ BOX: "box" "{" } ; +CYLINDER: "cylinder" "{" + VECTOR "," VECTOR "," FLOAT + MAYBE_OPEN + OBJECT_MODIFIERS + "}" + { + dmnsn_astnode object + = dmnsn_new_astnode4(DMNSN_AST_CYLINDER, @$, $3, $5, $7, $8); + $$ = dmnsn_new_astnode2(DMNSN_AST_OBJECT, @$, object, $9); + } +; + +MAYBE_OPEN: /* empty */ { + $$ = dmnsn_new_ast_integer(false); + } + | "open" { + $$ = dmnsn_new_ast_integer(true); + } + SPHERE: "sphere" "{" VECTOR "," FLOAT OBJECT_MODIFIERS diff --git a/dimension/common.terminals b/dimension/common.terminals index 7ccc8cb..af75bb4 100644 --- a/dimension/common.terminals +++ b/dimension/common.terminals @@ -152,7 +152,7 @@ %token DMNSN_T_CUBIC_SPLINE %token DMNSN_T_CUBIC_WAVE %token DMNSN_T_CUTAWAY_TEXTURES -%token DMNSN_T_CYLINDER +%token DMNSN_T_CYLINDER "cylinder" %token DMNSN_T_CYLINDRICAL %token DMNSN_T_DEFINED %token DMNSN_T_DEGREES "degrees" @@ -315,7 +315,7 @@ %token DMNSN_T_ON "on" %token DMNSN_T_ONCE %token DMNSN_T_ONION -%token DMNSN_T_OPEN +%token DMNSN_T_OPEN "open" %token DMNSN_T_ORIENT %token DMNSN_T_ORIENTATION %token DMNSN_T_ORTHOGRAPHIC diff --git a/dimension/grammar.epilogue b/dimension/grammar.epilogue index 25d678a..d766a07 100644 --- a/dimension/grammar.epilogue +++ b/dimension/grammar.epilogue @@ -134,6 +134,7 @@ dmnsn_astnode_string(dmnsn_astnode_type astnode_type) dmnsn_astnode_map(DMNSN_AST_OBJECT, "object"); dmnsn_astnode_map(DMNSN_AST_BOX, "box"); + dmnsn_astnode_map(DMNSN_AST_CYLINDER, "cylinder"); dmnsn_astnode_map(DMNSN_AST_DIFFERENCE, "difference"); dmnsn_astnode_map(DMNSN_AST_INTERSECTION, "intersection"); dmnsn_astnode_map(DMNSN_AST_LIGHT_SOURCE, "light_source"); diff --git a/dimension/lexer.l b/dimension/lexer.l index ea98c07..190acb0 100644 --- a/dimension/lexer.l +++ b/dimension/lexer.l @@ -186,6 +186,7 @@ unsigned long wchar; "colour" RETURN_TOKEN(DMNSN_T_COLOR); "cos" RETURN_TOKEN(DMNSN_T_COS); "cosh" RETURN_TOKEN(DMNSN_T_COSH); +"cylinder" RETURN_TOKEN(DMNSN_T_CYLINDER); "degrees" RETURN_TOKEN(DMNSN_T_DEGREES); "difference" RETURN_TOKEN(DMNSN_T_DIFFERENCE); "diffuse" RETURN_TOKEN(DMNSN_T_DIFFUSE); @@ -224,6 +225,7 @@ unsigned long wchar; "object" RETURN_TOKEN(DMNSN_T_OBJECT); "off" RETURN_TOKEN(DMNSN_T_OFF); "on" RETURN_TOKEN(DMNSN_T_ON); +"open" RETURN_TOKEN(DMNSN_T_OPEN); "perspective" RETURN_TOKEN(DMNSN_T_PERSPECTIVE); "phong" RETURN_TOKEN(DMNSN_T_PHONG); "phong_size" RETURN_TOKEN(DMNSN_T_PHONG_SIZE); diff --git a/dimension/parse.h b/dimension/parse.h index e81f76e..d9b9195 100644 --- a/dimension/parse.h +++ b/dimension/parse.h @@ -48,6 +48,7 @@ typedef enum { DMNSN_AST_OBJECT, DMNSN_AST_BOX, + DMNSN_AST_CYLINDER, DMNSN_AST_DIFFERENCE, DMNSN_AST_INTERSECTION, DMNSN_AST_LIGHT_SOURCE, diff --git a/dimension/realize.c b/dimension/realize.c index ad6630f..15eb334 100644 --- a/dimension/realize.c +++ b/dimension/realize.c @@ -843,6 +843,50 @@ dmnsn_realize_box(dmnsn_astnode astnode) } static dmnsn_object * +dmnsn_realize_cylinder(dmnsn_astnode astnode) +{ + dmnsn_assert(astnode.type == DMNSN_AST_CYLINDER, "Expected a cylinder."); + + dmnsn_astnode pnode1, pnode2, radius, open; + dmnsn_array_get(astnode.children, 0, &pnode1); + dmnsn_array_get(astnode.children, 1, &pnode2); + dmnsn_array_get(astnode.children, 2, &radius); + dmnsn_array_get(astnode.children, 3, &open); + + dmnsn_vector p1 = dmnsn_realize_vector(pnode1); + dmnsn_vector p2 = dmnsn_realize_vector(pnode2); + double r = dmnsn_realize_float(radius); + + dmnsn_vector dir = dmnsn_vector_sub(p2, p1); + double l = dmnsn_vector_norm(dir); + + double theta1 = dmnsn_vector_axis_angle(dmnsn_y, dir, dmnsn_x); + double theta2 = dmnsn_vector_axis_angle(dmnsn_y, dir, dmnsn_z); + + dmnsn_object *cylinder = dmnsn_new_cylinder(dmnsn_realize_integer(open)); + /* Transformations: lift the cylinder to start at the origin, scale, rotate, + and translate properly */ + cylinder->trans = dmnsn_translation_matrix(dmnsn_new_vector(0.0, 1.0, 0.0)); + cylinder->trans = dmnsn_matrix_mul( + dmnsn_scale_matrix(dmnsn_new_vector(r, l/2.0, r)), + cylinder->trans + ); + cylinder->trans = dmnsn_matrix_mul( + dmnsn_rotation_matrix(dmnsn_new_vector(theta1, 0.0, 0.0)), + cylinder->trans + ); + cylinder->trans = dmnsn_matrix_mul( + dmnsn_rotation_matrix(dmnsn_new_vector(0.0, 0.0, theta2)), + cylinder->trans + ); + cylinder->trans = dmnsn_matrix_mul( + dmnsn_translation_matrix(p1), + cylinder->trans + ); + return cylinder; +} + +static dmnsn_object * dmnsn_realize_sphere(dmnsn_astnode astnode) { dmnsn_assert(astnode.type == DMNSN_AST_SPHERE, "Expected a sphere."); @@ -989,6 +1033,9 @@ dmnsn_realize_object(dmnsn_astnode astnode, dmnsn_array *lights) case DMNSN_AST_BOX: object = dmnsn_realize_box(onode); break; + case DMNSN_AST_CYLINDER: + object = dmnsn_realize_cylinder(onode); + break; case DMNSN_AST_DIFFERENCE: object = dmnsn_realize_difference(onode, modifiers, lights); break; diff --git a/tests/dimension/demo.pov b/tests/dimension/demo.pov index 4e8ba4d..69c9d4e 100644 --- a/tests/dimension/demo.pov +++ b/tests/dimension/demo.pov @@ -71,6 +71,14 @@ difference { } } +cylinder { + -1.25*y, 1.25*y, 0.1 + pigment { + color rgb <1, 0, 0> + } + rotate -45*x +} + plane { y, -2 pigment { diff --git a/tests/dimension/demo.sh b/tests/dimension/demo.sh index a5f05a5..2bf21b9 100755 --- a/tests/dimension/demo.sh +++ b/tests/dimension/demo.sh @@ -77,6 +77,20 @@ demo_exp=$(echo -n \ (phong_size (float 40))))))) object-modifiers) (object + (cylinder + (vector (float 0) (float -1.25) (float 0) (float 0) (float 0)) + (vector (float 0) (float 1.25) (float 0) (float 0) (float 0)) + (float 0.1) + (integer 0)) + (object-modifiers + (pigment + (vector (integer 1) (integer 0) (integer 0) + (integer 0) (integer 0)) + pigment-modifiers) + (transformation + (rotation (vector (integer -45) (integer 0) (integer 0) + (integer 0) (integer 0)))))) + (object (plane (vector (integer 0) (integer 1) (integer 0) (integer 0) (integer 0)) (integer -2)) |