From b4d259f04476812dba04e7854e5989fe4e06796c Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Tue, 25 Mar 2014 21:57:34 -0300 Subject: New resolve_tri_uv_v3 util function Compute barycentric coordinates (u, v) for a point with respect to a triangle. This is needed for Cycles baking but we decided to push this independently of the upcoming main baking changes. Code adapted from Christer Ericson's Real-Time Collision Detection. Cleanup, refactoring and review from Campbell Barton. --- source/blender/blenlib/BLI_math_geom.h | 1 + source/blender/blenlib/intern/math_geom.c | 42 ++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 6889e4f2651..db32701c3ed 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -219,6 +219,7 @@ bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[ int barycentric_inside_triangle_v2(const float w[3]); void resolve_tri_uv_v2(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]); +void resolve_tri_uv_v3(float r_uv[2], const float st[3], const float st0[3], const float st1[3], const float st2[3]); void resolve_quad_uv_v2(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]); void resolve_quad_uv_v2_deriv(float r_uv[2], float r_deriv[2][2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 66fdaafa32d..72b8f1ce024 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2686,7 +2686,7 @@ void interp_cubic_v3(float x[3], float v[3], const float x1[3], const float v1[3 /** * Barycentric reverse * - * Compute coordinates (u, v) for point \a st with respect to triangle (\a st0, \a st1, \a st2)" + * Compute coordinates (u, v) for point \a st with respect to triangle (\a st0, \a st1, \a st2) */ void resolve_tri_uv_v2(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]) @@ -2698,8 +2698,9 @@ void resolve_tri_uv_v2(float r_uv[2], const float st[2], const double c = st0[1] - st2[1], d = st1[1] - st2[1]; const double det = a * d - c * b; - if (IS_ZERO(det) == 0) { /* det should never be zero since the determinant is the signed ST area of the triangle. */ - const double x[] = {st[0] - st2[0], st[1] - st2[1]}; + /* det should never be zero since the determinant is the signed ST area of the triangle. */ + if (IS_ZERO(det) == 0) { + const double x[2] = {st[0] - st2[0], st[1] - st2[1]}; r_uv[0] = (float)((d * x[0] - b * x[1]) / det); r_uv[1] = (float)(((-c) * x[0] + a * x[1]) / det); @@ -2709,6 +2710,41 @@ void resolve_tri_uv_v2(float r_uv[2], const float st[2], } } +/** + * Barycentric reverse 3d + * + * Compute coordinates (u, v) for point \a st with respect to triangle (\a st0, \a st1, \a st2) + */ +void resolve_tri_uv_v3(float r_uv[2], const float st[3], const float st0[3], const float st1[3], const float st2[3]) +{ + float v0[3], v1[3], v2[3]; + double d00, d01, d11, d20, d21, det; + + sub_v3_v3v3(v0, st1, st0); + sub_v3_v3v3(v1, st2, st0); + sub_v3_v3v3(v2, st, st0); + + d00 = dot_v3v3(v0, v0); + d01 = dot_v3v3(v0, v1); + d11 = dot_v3v3(v1, v1); + d20 = dot_v3v3(v2, v0); + d21 = dot_v3v3(v2, v1); + + det = d00 * d11 - d01 * d01; + + /* det should never be zero since the determinant is the signed ST area of the triangle. */ + if (IS_ZERO(det) == 0) { + float w; + + w = (float)((d00 * d21 - d01 * d20) / det); + r_uv[1] = (float)((d11 * d20 - d01 * d21) / det); + r_uv[0] = 1.0f - r_uv[1] - w; + } + else { + zero_v2(r_uv); + } +} + /* bilinear reverse */ void resolve_quad_uv_v2(float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]) -- cgit v1.2.3