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 d4c63cd936b3f3cc37ef84ec279a994f5a32a850
parent b87fe14f77b8ecbac7b06cdf3c1e309b7d069ffb
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Mon, 22 Jun 2026 15:31:42 +0200

Fix threshold preventing difficult but possible tracking

The previous threshold seemed too high; the new one is low enough to
accommodate a real-world situation that triggered this fix.

Diffstat:
Msrc/sanim_node.c | 23++++++++++++++---------
Msrc/test_sanim_node_pivot.c | 2+-
2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/src/sanim_node.c b/src/sanim_node.c @@ -24,6 +24,11 @@ #include <math.h> +/* This constant is used as a minimum length for the 2D projection of normalized + * 3D vectors: a shorter length means that computations on the 2D projections + * can no longer be performed. */ +#define MIN_2D_PROJ 0.05 + /******************************************************************************* * Helper functions ******************************************************************************/ @@ -267,7 +272,7 @@ pivot_solve_single_axis_sun d33_muld3(local_in, inv, in_dir); /* solve in the YZ plane */ - if (d2_normalize(local_in_2D, local_in + 1) < 0.25) { + if (d2_normalize(local_in_2D, local_in + 1) < MIN_2D_PROJ) { /* not really in the YZ-plane */ return RES_BAD_ARG; } @@ -314,7 +319,7 @@ pivot_solve_single_axis_line(struct sanim_node* node, const double in_dir[3]) d33_transpose(inv, mat); /* no scale factors: inverse is transpose */ d33_muld3(local_in, inv, in_dir); /* solve in the YZ plane */ - if (d2_normalize(local_in_2D, local_in + 1) < 0.25) { + if (d2_normalize(local_in_2D, local_in + 1) < MIN_2D_PROJ) { /* not really in the YZ-plane */ return RES_BAD_ARG; } @@ -356,7 +361,7 @@ pivot_solve_single_axis_line(struct sanim_node* node, const double in_dir[3]) double pivot[4]; /* compute 2D normal after rotation */ d2_sub(local_out_2D, local_target_2D, ref_point_2D); - if (d2_normalize(local_out_2D, local_out_2D) < 0.25) { + if (d2_normalize(local_out_2D, local_out_2D) < MIN_2D_PROJ) { /* not really in the YZ-plane */ return RES_BAD_ARG; } @@ -380,7 +385,7 @@ pivot_solve_single_axis_line(struct sanim_node* node, const double in_dir[3]) if (d2) { /* only if ref_point is not the rotation point - * the heuristic is to amortize algorithm's oscillations */ + * the heuristic is to amortize algorithm's oscillations */ sign_dA = sign(previous_angle - angle); if (prev_sign_dA != sign_dA) kA *= 0.9; @@ -407,9 +412,9 @@ pivot_solve_single_axis_dir { double mat[12], inv[12]; double local_in[3], local_out[3]; - double local_in_2D[2] = {0, 0}; - double rotated_n_2D[2] = {0, 0}; - double local_out_2D[2] = {0, 0}; + double local_in_2D[2]; + double rotated_n_2D[2]; + double local_out_2D[2]; const double* ref_normal_2D; struct pivot_data* pivot_data; ASSERT(node && node->data && in_dir); @@ -431,11 +436,11 @@ pivot_solve_single_axis_dir d33_muld3(local_out, inv, pivot_data->tracking.data.out_dir.u); /* solve in the YZ plane */ - if (d2_normalize(local_in_2D, local_in + 1) < 0.25) { + if (d2_normalize(local_in_2D, local_in + 1) < MIN_2D_PROJ) { /* not really in the YZ-plane */ return RES_BAD_ARG; } - if (d2_normalize(local_out_2D, local_out + 1) < 0.25) { + if (d2_normalize(local_out_2D, local_out + 1) < MIN_2D_PROJ) { /* not really in the YZ-plane */ return RES_BAD_ARG; } diff --git a/src/test_sanim_node_pivot.c b/src/test_sanim_node_pivot.c @@ -67,7 +67,7 @@ main(int argc, char** argv) CHK(my_type_set_translation(t2, transl) == RES_OK); CHK(my_type_set_translation(t3, transl) == RES_OK); - d3(in_dir, 0, 0.99, -0.1); + d3(in_dir, 0, 0.9999, -0.01); /* rotation axis is Y after positioning: cannot accomodate in_dir */ CHK(my_type_solve_pivot(t2, in_dir) == RES_BAD_ARG);