diff options
author | Tavian Barnes <tavianator@gmail.com> | 2011-06-12 02:37:51 -0600 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2011-06-13 00:16:06 -0600 |
commit | 7acd8ea6673b7a90ed4041408ccf1b024b8a007a (patch) | |
tree | d52199dd7c58e0217bfd1a74e7601d739ad333f5 /libdimension/csg.c | |
parent | 066261810c2fca192677c5c1c01c91d6ecec65a0 (diff) | |
download | dimension-7acd8ea6673b7a90ed4041408ccf1b024b8a007a.tar.xz |
Vast libdimension API and internals improvements.
Couldn't really do these while I was trying to be POV-Ray compatible,
'cause they would've broken compatibility.
Diffstat (limited to 'libdimension/csg.c')
-rw-r--r-- | libdimension/csg.c | 124 |
1 files changed, 29 insertions, 95 deletions
diff --git a/libdimension/csg.c b/libdimension/csg.c index 0222b8b..1b2e36f 100644 --- a/libdimension/csg.c +++ b/libdimension/csg.c @@ -26,21 +26,6 @@ #include "dimension-impl.h" #include <stdlib.h> -/** Apply the properties of \p csg to its children. */ -static void -dmnsn_csg_cascade(const dmnsn_object *csg, dmnsn_object *object) -{ - if (!object->texture && csg->texture) { - object->texture = csg->texture; - } - - if (!object->interior && csg->interior) { - object->interior = csg->interior; - } - - object->trans = dmnsn_matrix_mul(csg->trans, object->trans); -} - /* * Unions */ @@ -67,10 +52,6 @@ dmnsn_csg_union_inside_fn(const dmnsn_object *csg, dmnsn_vector point) static void dmnsn_csg_union_initialize_fn(dmnsn_object *csg) { - DMNSN_ARRAY_FOREACH (dmnsn_object **, child, csg->children) { - dmnsn_csg_cascade(csg, *child); - dmnsn_initialize_object(*child); - } csg->trans = dmnsn_identity_matrix(); dmnsn_prtree *prtree = dmnsn_new_prtree(csg->children); @@ -92,10 +73,9 @@ dmnsn_new_csg_union(const dmnsn_array *objects) dmnsn_object *csg = dmnsn_new_object(); DMNSN_ARRAY_FOREACH (dmnsn_object **, object, objects) { - DMNSN_INCREF(*object); dmnsn_array_push(csg->children, object); } - + csg->split_children = true; csg->ptr = NULL; csg->intersection_fn = dmnsn_csg_union_intersection_fn; csg->inside_fn = dmnsn_csg_union_inside_fn; @@ -105,16 +85,6 @@ dmnsn_new_csg_union(const dmnsn_array *objects) return csg; } -/** Generic CSG destruction callback. */ -static void -dmnsn_csg_free_fn(void *ptr) -{ - dmnsn_object **params = ptr; - dmnsn_delete_object(params[1]); - dmnsn_delete_object(params[0]); - dmnsn_free(ptr); -} - /** * Generic CSG intersection callback. * @param[in] csg The CSG object. @@ -131,11 +101,12 @@ dmnsn_csg_intersection_fn(const dmnsn_object *csg, dmnsn_line line, dmnsn_intersection *intersection, bool inside1, bool inside2) { - const dmnsn_object **params = csg->ptr; + const dmnsn_object *A = *(dmnsn_object **)dmnsn_array_first(csg->children); + const dmnsn_object *B = *(dmnsn_object **)dmnsn_array_last(csg->children); dmnsn_intersection i1, i2; - bool is_i1 = dmnsn_object_intersection(params[0], line, &i1); - bool is_i2 = dmnsn_object_intersection(params[1], line, &i2); + bool is_i1 = dmnsn_object_intersection(A, line, &i1); + bool is_i2 = dmnsn_object_intersection(B, line, &i2); double oldt = 0.0; while (is_i1) { @@ -144,11 +115,11 @@ dmnsn_csg_intersection_fn(const dmnsn_object *csg, dmnsn_line line, oldt = i1.t + dmnsn_epsilon; dmnsn_vector point = dmnsn_line_point(i1.ray, i1.t); - if (inside2 ^ dmnsn_object_inside(params[1], point)) { + if (inside2 ^ dmnsn_object_inside(B, point)) { dmnsn_line newline = line; newline.x0 = dmnsn_line_point(line, i1.t); newline = dmnsn_line_add_epsilon(newline); - is_i1 = dmnsn_object_intersection(params[0], newline, &i1); + is_i1 = dmnsn_object_intersection(A, newline, &i1); } else { break; } @@ -161,11 +132,11 @@ dmnsn_csg_intersection_fn(const dmnsn_object *csg, dmnsn_line line, oldt = i2.t + dmnsn_epsilon; dmnsn_vector point = dmnsn_line_point(i2.ray, i2.t); - if (inside1 ^ dmnsn_object_inside(params[0], point)) { + if (inside1 ^ dmnsn_object_inside(A, point)) { dmnsn_line newline = line; newline.x0 = dmnsn_line_point(line, i2.t); newline = dmnsn_line_add_epsilon(newline); - is_i2 = dmnsn_object_intersection(params[1], newline, &i2); + is_i2 = dmnsn_object_intersection(B, newline, &i2); } else { break; } @@ -205,24 +176,17 @@ dmnsn_csg_intersection_intersection_fn(const dmnsn_object *csg, static bool dmnsn_csg_intersection_inside_fn(const dmnsn_object *csg, dmnsn_vector point) { - dmnsn_object **params = csg->ptr; - return dmnsn_object_inside(params[0], point) - && dmnsn_object_inside(params[1], point); + const dmnsn_object *A = *(dmnsn_object **)dmnsn_array_first(csg->children); + const dmnsn_object *B = *(dmnsn_object **)dmnsn_array_last(csg->children); + return dmnsn_object_inside(A, point) && dmnsn_object_inside(B, point); } /** CSG intersection initialization callback. */ static void dmnsn_csg_intersection_initialize_fn(dmnsn_object *csg) { - dmnsn_object **params = csg->ptr; - dmnsn_object *A = params[0]; - dmnsn_object *B = params[1]; - - dmnsn_csg_cascade(csg, A); - dmnsn_csg_cascade(csg, B); - - dmnsn_initialize_object(A); - dmnsn_initialize_object(B); + dmnsn_object *A = *(dmnsn_object **)dmnsn_array_first(csg->children); + dmnsn_object *B = *(dmnsn_object **)dmnsn_array_last(csg->children); csg->trans = dmnsn_identity_matrix(); csg->bounding_box.min @@ -236,17 +200,12 @@ dmnsn_new_csg_intersection(dmnsn_object *A, dmnsn_object *B) { dmnsn_object *csg = dmnsn_new_object(); - DMNSN_INCREF(A); - DMNSN_INCREF(B); - dmnsn_object **params = dmnsn_malloc(2*sizeof(dmnsn_object *)); - params[0] = A; - params[1] = B; + dmnsn_array_push(csg->children, &A); + dmnsn_array_push(csg->children, &B); - csg->ptr = params; csg->intersection_fn = dmnsn_csg_intersection_intersection_fn; csg->inside_fn = dmnsn_csg_intersection_inside_fn; csg->initialize_fn = dmnsn_csg_intersection_initialize_fn; - csg->free_fn = dmnsn_csg_free_fn; return csg; } @@ -268,24 +227,16 @@ dmnsn_csg_difference_intersection_fn(const dmnsn_object *csg, static bool dmnsn_csg_difference_inside_fn(const dmnsn_object *csg, dmnsn_vector point) { - dmnsn_object **params = csg->ptr; - return dmnsn_object_inside(params[0], point) - && !dmnsn_object_inside(params[1], point); + const dmnsn_object *A = *(dmnsn_object **)dmnsn_array_first(csg->children); + const dmnsn_object *B = *(dmnsn_object **)dmnsn_array_last(csg->children); + return dmnsn_object_inside(A, point) && !dmnsn_object_inside(B, point); } /** CSG difference initialization callback. */ static void dmnsn_csg_difference_initialize_fn(dmnsn_object *csg) { - dmnsn_object **params = csg->ptr; - dmnsn_object *A = params[0]; - dmnsn_object *B = params[1]; - - dmnsn_csg_cascade(csg, A); - dmnsn_csg_cascade(csg, B); - - dmnsn_initialize_object(A); - dmnsn_initialize_object(B); + dmnsn_object *A = *(dmnsn_object **)dmnsn_array_first(csg->children); csg->trans = dmnsn_identity_matrix(); csg->bounding_box = A->bounding_box; @@ -296,17 +247,12 @@ dmnsn_new_csg_difference(dmnsn_object *A, dmnsn_object *B) { dmnsn_object *csg = dmnsn_new_object(); - DMNSN_INCREF(A); - DMNSN_INCREF(B); - dmnsn_object **params = dmnsn_malloc(2*sizeof(dmnsn_object *)); - params[0] = A; - params[1] = B; + dmnsn_array_push(csg->children, &A); + dmnsn_array_push(csg->children, &B); - csg->ptr = params; csg->intersection_fn = dmnsn_csg_difference_intersection_fn; csg->inside_fn = dmnsn_csg_difference_inside_fn; csg->initialize_fn = dmnsn_csg_difference_initialize_fn; - csg->free_fn = dmnsn_csg_free_fn; return csg; } @@ -328,24 +274,17 @@ dmnsn_csg_merge_intersection_fn(const dmnsn_object *csg, static bool dmnsn_csg_merge_inside_fn(const dmnsn_object *csg, dmnsn_vector point) { - dmnsn_object **params = csg->ptr; - return dmnsn_object_inside(params[0], point) - || dmnsn_object_inside(params[1], point); + const dmnsn_object *A = *(dmnsn_object **)dmnsn_array_first(csg->children); + const dmnsn_object *B = *(dmnsn_object **)dmnsn_array_last(csg->children); + return dmnsn_object_inside(A, point) || dmnsn_object_inside(B, point); } /** CSG merge initialization callback. */ static void dmnsn_csg_merge_initialize_fn(dmnsn_object *csg) { - dmnsn_object **params = csg->ptr; - dmnsn_object *A = params[0]; - dmnsn_object *B = params[1]; - - dmnsn_csg_cascade(csg, A); - dmnsn_csg_cascade(csg, B); - - dmnsn_initialize_object(A); - dmnsn_initialize_object(B); + dmnsn_object *A = *(dmnsn_object **)dmnsn_array_first(csg->children); + dmnsn_object *B = *(dmnsn_object **)dmnsn_array_last(csg->children); csg->trans = dmnsn_identity_matrix(); csg->bounding_box.min @@ -359,17 +298,12 @@ dmnsn_new_csg_merge(dmnsn_object *A, dmnsn_object *B) { dmnsn_object *csg = dmnsn_new_object(); - DMNSN_INCREF(A); - DMNSN_INCREF(B); - dmnsn_object **params = dmnsn_malloc(2*sizeof(dmnsn_object *)); - params[0] = A; - params[1] = B; + dmnsn_array_push(csg->children, &A); + dmnsn_array_push(csg->children, &B); - csg->ptr = params; csg->intersection_fn = dmnsn_csg_merge_intersection_fn; csg->inside_fn = dmnsn_csg_merge_inside_fn; csg->initialize_fn = dmnsn_csg_merge_initialize_fn; - csg->free_fn = dmnsn_csg_free_fn; return csg; } |