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:
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);