summaryrefslogtreecommitdiffstats
path: root/dimension/realize.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2010-06-17 09:16:20 -0600
committerTavian Barnes <tavianator@gmail.com>2010-06-17 09:16:20 -0600
commitc8667ce6ae94929e9bc06c9af51b6589bc528946 (patch)
treeb325c25f6192f51159e24ace80f2e9e5ce00b99f /dimension/realize.c
parent91cc57a4a12997a72c2ec643f3560ad998daa87b (diff)
downloaddimension-c8667ce6ae94929e9bc06c9af51b6589bc528946.tar.xz
Fully implement POV-Ray transformations.
Diffstat (limited to 'dimension/realize.c')
-rw-r--r--dimension/realize.c124
1 files changed, 83 insertions, 41 deletions
diff --git a/dimension/realize.c b/dimension/realize.c
index e558c5b..a9b9c71 100644
--- a/dimension/realize.c
+++ b/dimension/realize.c
@@ -113,6 +113,31 @@ dmnsn_realize_color(dmnsn_astnode astnode)
}
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)
{
dmnsn_assert(astnode.type == DMNSN_AST_ROTATION, "Expected a rotation.");
@@ -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