From e0efc5ef27039f03be4783d593508ea7480aa4d0 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sun, 15 Aug 2010 00:22:47 -0600 Subject: Add cylinder support to dimension. --- dimension/common.nonterminals | 2 ++ dimension/common.rules | 20 ++++++++++++++++++ dimension/common.terminals | 4 ++-- dimension/grammar.epilogue | 1 + dimension/lexer.l | 2 ++ dimension/parse.h | 1 + dimension/realize.c | 47 +++++++++++++++++++++++++++++++++++++++++++ tests/dimension/demo.pov | 8 ++++++++ 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 OBJECT %type FINITE_SOLID_OBJECT %type BOX +%type CYLINDER +%type MAYBE_OPEN %type SPHERE %type INFINITE_SOLID_OBJECT %type 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 @@ -842,6 +842,50 @@ dmnsn_realize_box(dmnsn_astnode astnode) return box; } +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) { @@ -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 @@ -76,6 +76,20 @@ demo_exp=$(echo -n \ (phong (float 0.2)) (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)) -- cgit v1.2.3