solstice-anim

Geometry animation library of the solstice app
git clone git://git.meso-star.com/solstice-anim.git
Log | Files | Refs | README | LICENSE

commit c4634a135d9778d5457718a4b93bf253b7ad8963
parent 297250ada07784787724b90a135c349752497744
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Tue, 18 Oct 2016 17:12:06 +0200

BugFix: 1 axis pivot pointing computations

The computations were not really in the YZ plane.
Adapt pivot testing to catch this.

Diffstat:
Msrc/sanim_node.c | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/test_sanim_node_pivot.c | 20+++++++++-----------
2 files changed, 69 insertions(+), 40 deletions(-)

diff --git a/src/sanim_node.c b/src/sanim_node.c @@ -72,7 +72,11 @@ set_pivot_transform(const double angles[3], double transform[12]) { } static double* -set_node_transform(struct sanim_node* node, const char include_pivot, double transform[12]) { +set_node_transform + (struct sanim_node* node, + const char include_pivot, + double transform[12]) +{ double tmp[12]; ASSERT(node && node->data && transform); if (include_pivot && node->data->pivot_data) { @@ -103,7 +107,10 @@ compose_node_transform(struct sanim_node* node, double transform[12]) { } static void -node_get_transform(struct sanim_node* node, const char include_own_pivot, double transform[12]) +node_get_transform + (struct sanim_node* node, + const char include_own_pivot, + double transform[12]) { struct sanim_node* ptr; ASSERT(node && node->data && transform); @@ -115,26 +122,21 @@ node_get_transform(struct sanim_node* node, const char include_own_pivot, double } } -static res_T +static void compute_single_axis_angle -(const double ref_normal[3], - const double rotated_n[3], - double* angle ) + (const double ref_normal[3], + const double rotated_n[3], + double* angle ) { ASSERT(ref_normal && rotated_n && angle); ASSERT(d3_is_normalized(rotated_n)); ASSERT(d3_is_normalized(ref_normal)); - ASSERT(ref_normal[0] == 0); /* ref_normal in the YZ plane */ - if (fabs(rotated_n[0]) > 0.9) { - /* cannot be obtained by X-rotate */ - return RES_BAD_ARG; - } - /* solve in the YZ plane */ + /* normals should be in the YZ plane */ + ASSERT(ref_normal[0] == 0); + ASSERT(rotated_n[0] == 0); *angle = atan2(-(ref_normal[2] * rotated_n[1] - ref_normal[1] * rotated_n[2]), ref_normal[1] * rotated_n[1] + ref_normal[2] * rotated_n[2]); - - return RES_OK; } static res_T @@ -161,11 +163,18 @@ pivot_solve_single_axis_sun d33_transpose(inv, mat); /* no scale factors: inverse is transpose */ d33_muld3(local_in, inv, in_dir); + /* solve in the YZ plane */ + local_in[0] = 0; + if (d3_normalize(local_in, local_in) < 0.25) { + /* not really in the YZ-plane */ + return RES_BAD_ARG; + } + /* rotated_n = -local_in */ d3_muld(rotated_n, local_in, -1); - ASSERT(d3_is_normalized(rotated_n)); - return compute_single_axis_angle(ref_normal, rotated_n, angle); + compute_single_axis_angle(ref_normal, rotated_n, angle); + return RES_OK; } FINLINE res_T @@ -173,7 +182,6 @@ pivot_solve_single_axis_line (struct sanim_node* node, const double in_dir[3]) { - res_T res = RES_OK; double mat[12], inv[9]; double local_in[3], rotated_n[3], local_out[3], local_target[3], ref_point[3]; const double* ref_normal; @@ -209,19 +217,29 @@ pivot_solve_single_axis_line double pivot[12]; /* compute rotated_n */ d3_sub(local_out, local_target, ref_point); - if (0 == d3_normalize(local_out, local_out)) { - /* cannot target so close to the device */ + + /* solve in the YZ plane */ + local_in[0] = 0; + if (d3_normalize(local_in, local_in) < 0.25) { + /* not really in the YZ-plane */ return RES_BAD_ARG; } - /* compute rotated_n = bisectrix of local_in and out_dir */ + local_out[0] = 0; + if (d3_normalize(local_out, local_out) < 0.25) { + /* not really in the YZ-plane */ + return RES_BAD_ARG; + } + + /* rotated_n = bisectrix of local_in and out_dir */ d3_sub(rotated_n, local_out, local_in); - if (0 == d3_normalize(rotated_n, rotated_n)) { - /* cannot be obtained by X-rotate */ + if (d3_normalize(rotated_n, rotated_n) < 1e-4) { + /* tangent rays */ return RES_BAD_ARG; } + ASSERT(rotated_n[0] == 0); + previous_angle = angles[0]; - res = compute_single_axis_angle(ref_normal, rotated_n, angles); /* X-rotate */ - if (res != RES_OK) return res; + compute_single_axis_angle(ref_normal, rotated_n, angles); /* X-rotate */ delta = fabs(previous_angle - angles[0]); if (delta < 1e-10 || ++cpt == 25) break; set_pivot_transform(angles, pivot); @@ -259,17 +277,30 @@ pivot_solve_single_axis_dir d33_transpose(inv, mat); /* no scale factors: inverse is transpose */ d33_muld3(local_in, inv, in_dir); d33_muld3(local_out, inv, node->data->pivot_data->tracking.data.out_dir.u); - ASSERT(d3_is_normalized(local_out)); - /* compute rotated_n = bisectrix of local_in and out_dir */ + /* solve in the YZ plane */ + local_in[0] = 0; + if (d3_normalize(local_in, local_in) < 0.25) { + /* not really in the YZ-plane */ + return RES_BAD_ARG; + } + local_out[0] = 0; + if (d3_normalize(local_out, local_out) < 0.25) { + /* not really in the YZ-plane */ + return RES_BAD_ARG; + } + + /* rotated_n = bisectrix of local_in and out_dir */ d3_sub(rotated_n, local_out, local_in); - if (0 == d3_normalize(rotated_n, rotated_n)) { - /* cannot be obtained by X-rotate */ + if (d3_normalize(rotated_n, rotated_n) < 1e-4) { + /* tangent rays */ return RES_BAD_ARG; } + ASSERT(rotated_n[0] == 0); angle = &node->data->pivot_data->pivot_angles[0]; /* X-rotate */ - return compute_single_axis_angle(ref_normal, rotated_n, angle); + compute_single_axis_angle(ref_normal, rotated_n, angle); + return RES_OK; } FINLINE res_T diff --git a/src/test_sanim_node_pivot.c b/src/test_sanim_node_pivot.c @@ -68,12 +68,11 @@ main(int argc, char** argv) /* rotation axis is Y after positioning: cannot accomodate in_dir */ CHECK(sanim_node_solve_pivot(&t2.node, in_dir), RES_BAD_ARG); - d3(in_dir, 1, 0, -1); + d3(in_dir, 1, 0.2, -1); CHECK(sanim_node_solve_pivot(&t2.node, in_dir), RES_OK); CHECK(my_type_get_transform(&t3, transform), RES_OK); - d3(n, 0, 0, 1); - d33_muld3(n, transform, n); - CHECK(eq_eps(d3_dot(in_dir, n), -d3_normalize(tmp, in_dir), 1e-10), 1); + d33_muld3(n, transform, pivot1.data.pivot1.ref_normal); + CHECK(d3_eq_eps(n, d3(tmp, -sqrt(2) / 2, 0, +sqrt(2) / 2), 1e-10), 1); CHECK(d3_eq_eps(transform + 9, d3(tmp, -sqrt(2), 3, 2), 1e-10), 1); CHECK(my_type_release(&t1), RES_OK); @@ -124,13 +123,12 @@ main(int argc, char** argv) CHECK(my_type_set_translation(&t2, transl), RES_OK); CHECK(my_type_set_translation(&t3, transl), RES_OK); - d3(in_dir, 1, 0, -1); + d3(in_dir, 1, -0.3, -1); CHECK(sanim_node_solve_pivot(&t2.node, in_dir), RES_OK); CHECK(my_type_get_transform(&t3, transform), RES_OK); - d3(n, 0, 0, 1); - d33_muld3(tmp, transform, n); - CHECK(d3_eq_eps(n, tmp, 1e-10), 1); - CHECK(d3_eq_eps(transform + 9, d3(tmp, -1, 3, 3), 1e-10), 1); + d33_muld3(n, transform, pivot1.data.pivot1.ref_normal); + CHECK(d3_eq_eps(pivot1.data.pivot1.ref_normal, n, 1e-10), 1); + CHECK(d3_eq_eps(transform + 9, d3(n, -1, 3, 3), 1e-10), 1); CHECK(my_type_release(&t1), RES_OK); CHECK(my_type_release(&t2), RES_OK); @@ -157,7 +155,7 @@ main(int argc, char** argv) CHECK(my_type_set_translation(&t2, transl), RES_OK); CHECK(my_type_set_translation(&t3, transl), RES_OK); - d3(in_dir, 1, 0, 0); + d3(in_dir, 1, 0.1, 0); CHECK(sanim_node_solve_pivot(&t2.node, in_dir), RES_OK); CHECK(my_type_get_transform(&t3, transform), RES_OK); d3(n, 0, 0, 1); @@ -189,7 +187,7 @@ main(int argc, char** argv) CHECK(my_type_set_translation(&t2, transl), RES_OK); CHECK(my_type_set_translation(&t3, transl), RES_OK); - d3(in_dir, 1, 0, 0); + d3(in_dir, 1, -0.5, 0); CHECK(sanim_node_solve_pivot(&t2.node, in_dir), RES_OK); CHECK(my_type_get_transform(&t3, transform), RES_OK); d3(n, 0, 0, 1);