From 51bd26d0faad306183c58bff0865b72cf99fbe90 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Wed, 5 Oct 2022 22:10:53 +0200 Subject: New math function to add small bias to zero axis In some situations the zero axis can produce problems and need to add a small bias. This function adds a small bias using the orthogonal result of the others valid axis. Reviewed By: fclem Differential Revision: https://developer.blender.org/D16158 6d --- source/blender/blenlib/BLI_math_matrix.h | 2 ++ source/blender/blenlib/intern/math_matrix.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) (limited to 'source') diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 19943614881..7e1b7c2ba56 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -367,6 +367,8 @@ void pseudoinverse_m4_m4(float inverse[4][4], const float mat[4][4], float epsil void pseudoinverse_m3_m3(float inverse[3][3], const float mat[3][3], float epsilon); bool has_zero_axis_m4(const float matrix[4][4]); +/** Fix any zero scale axis adding a small bias orthogonal to the other valid axis. */ +void zero_axis_bias_m4(float mat[4][4]); void invert_m4_m4_safe(float inverse[4][4], const float mat[4][4]); diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 221ae84e74d..d997eae26fb 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -3116,6 +3116,34 @@ bool has_zero_axis_m4(const float matrix[4][4]) len_squared_v3(matrix[2]) < FLT_EPSILON; } +void zero_axis_bias_m4(float mat[4][4]) +{ + const bool axis_x_degenerate = len_squared_v3(mat[0]) < FLT_EPSILON; + const bool axis_y_degenerate = len_squared_v3(mat[1]) < FLT_EPSILON; + const bool axis_z_degenerate = len_squared_v3(mat[2]) < FLT_EPSILON; + + /* X Axis. */ + if (axis_x_degenerate && !axis_y_degenerate && !axis_z_degenerate) { + cross_v3_v3v3(mat[0], mat[1], mat[2]); + mul_v3_fl(mat[0], FLT_EPSILON); + return; + } + + /* Y Axis. */ + if (!axis_x_degenerate && axis_y_degenerate && !axis_z_degenerate) { + cross_v3_v3v3(mat[1], mat[2], mat[0]); + mul_v3_fl(mat[1], FLT_EPSILON); + return; + } + + /* Z Axis. */ + if (!axis_x_degenerate && !axis_y_degenerate && axis_z_degenerate) { + cross_v3_v3v3(mat[2], mat[0], mat[1]); + mul_v3_fl(mat[2], FLT_EPSILON); + return; + } +} + void invert_m4_m4_safe(float inverse[4][4], const float mat[4][4]) { if (!invert_m4_m4(inverse, mat)) { -- cgit v1.2.3