summaryrefslogtreecommitdiffstats
path: root/libdimension
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2011-09-12 21:55:37 -0400
committerTavian Barnes <tavianator@gmail.com>2011-09-12 21:56:51 -0400
commit68c7874484767e02366873a32b7420c52476fdb8 (patch)
treefa9188eb571621fec125f69f861e88ccf49a1a3f /libdimension
parent15fdb4cbe1a4843db5ef3d86b18b059f949e1d89 (diff)
downloaddimension-68c7874484767e02366873a32b7420c52476fdb8.tar.xz
Fix pigment_trans calculation in deeply nested objects.
Diffstat (limited to 'libdimension')
-rw-r--r--libdimension/object.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/libdimension/object.c b/libdimension/object.c
index 7736880..66c5166 100644
--- a/libdimension/object.c
+++ b/libdimension/object.c
@@ -64,9 +64,10 @@ dmnsn_delete_object(dmnsn_object *object)
}
}
-/* Precompute object properties */
-void
-dmnsn_initialize_object(dmnsn_object *object)
+/** Recursively initialize objects. */
+static void
+dmnsn_initialize_object_recursive(dmnsn_object *object,
+ dmnsn_matrix pigment_trans)
{
dmnsn_assert(!object->initialized, "Object double-initialized.");
object->initialized = true;
@@ -77,22 +78,24 @@ dmnsn_initialize_object(dmnsn_object *object)
}
/* Precalculate object values */
- object->pigment_trans = dmnsn_matrix_inverse(object->trans);
+ object->pigment_trans = pigment_trans;
object->trans = dmnsn_matrix_mul(object->trans, object->intrinsic_trans);
/* Initialize the object's children */
DMNSN_ARRAY_FOREACH (dmnsn_object **, child, object->children) {
(*child)->trans = dmnsn_matrix_mul(object->trans, (*child)->trans);
- bool pigment_cascaded =
- (*child)->texture == NULL || (*child)->texture->pigment == NULL;
+
+ dmnsn_matrix child_pigment_trans;
+ if ((*child)->texture == NULL || (*child)->texture->pigment == NULL) {
+ /* Don't transform cascaded pigments with the child object */
+ child_pigment_trans = pigment_trans;
+ } else {
+ child_pigment_trans = dmnsn_matrix_inverse((*child)->trans);
+ }
dmnsn_texture_cascade(object->texture, &(*child)->texture);
dmnsn_interior_cascade(object->interior, &(*child)->interior);
- dmnsn_initialize_object(*child);
-
- if (pigment_cascaded) {
- (*child)->pigment_trans = object->pigment_trans;
- }
+ dmnsn_initialize_object_recursive(*child, child_pigment_trans);
}
/* Initialization callback */
@@ -105,3 +108,11 @@ dmnsn_initialize_object(dmnsn_object *object)
= dmnsn_transform_bounding_box(object->trans, object->bounding_box);
object->trans_inv = dmnsn_matrix_inverse(object->trans);
}
+
+/* Precompute object properties */
+void
+dmnsn_initialize_object(dmnsn_object *object)
+{
+ dmnsn_matrix pigment_trans = dmnsn_matrix_inverse(object->trans);
+ dmnsn_initialize_object_recursive(object, pigment_trans);
+}