diff options
author | Tavian Barnes <tavianator@gmail.com> | 2011-09-12 21:55:37 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2011-09-12 21:56:51 -0400 |
commit | 68c7874484767e02366873a32b7420c52476fdb8 (patch) | |
tree | fa9188eb571621fec125f69f861e88ccf49a1a3f /libdimension/object.c | |
parent | 15fdb4cbe1a4843db5ef3d86b18b059f949e1d89 (diff) | |
download | dimension-68c7874484767e02366873a32b7420c52476fdb8.tar.xz |
Fix pigment_trans calculation in deeply nested objects.
Diffstat (limited to 'libdimension/object.c')
-rw-r--r-- | libdimension/object.c | 33 |
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); +} |