diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-05-08 18:33:02 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-05-08 18:33:02 +0400 |
commit | 0ee45c9301fa100624479255b3928945ded4042e (patch) | |
tree | c8747edeed599f8d45db9a91dfa241776dffce2b /source/blender/blenlib | |
parent | f25e7d62b3023812eb594250d22e142c02533482 (diff) |
more optimal method of calculating the normal for the solidify modifier.
When adding 2 unit length vectors, the length can be used to calculate the angle.
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_math_vector.h | 3 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_vector.c | 51 |
2 files changed, 54 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 9b2d6a5ead6..17c69d22337 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -182,6 +182,9 @@ void mid_v3_v3v3(float r[3], const float a[3], const float b[3]); void mid_v2_v2v2(float r[2], const float a[2], const float b[2]); void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3]); +void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3]); +void mid_v3_angle_weighted(float r[3]); + void flip_v4_v4v4(float v[4], const float v1[4], const float v2[4]); void flip_v3_v3v3(float v[3], const float v1[3], const float v2[3]); void flip_v2_v2v2(float v[2], const float v1[2], const float v2[2]); diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 24b5d2af3db..82b295d39b2 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -130,6 +130,57 @@ void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float } /** + * Specialized function for calculating normals. + * fastpath for: + * +* \code{.c} + * add_v3_v3v3(r, a, b); + * normalize_v3(r) + * mul_v3_fl(r, angle_normalized_v3v3(a, b) / M_PI_2); + * \endcode + * + * We can use the length of (a + b) to calculate the angle. + */ +void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3]) +{ + /* trick, we want the middle of 2 normals as well as the angle between them + * avoid multiple calculations by */ + float angle; + + /* double check they are normalized */ + BLI_ASSERT_UNIT_V3(a); + BLI_ASSERT_UNIT_V3(b); + + add_v3_v3v3(r, a, b); + angle = ((float)(1.0 / (M_PI / 2.0)) * + /* normally we would only multiply by 2, + * but instead of an angle make this 0-1 factor */ + 2.0f) * + acosf(normalize_v3(r) / 2.0f); + mul_v3_fl(r, angle); +} +/** + * Same as mid_v3_v3v3_angle_weighted + * but \a r is assumed to be accumulated normals, divided by their total. + */ +void mid_v3_angle_weighted(float r[3]) +{ + /* trick, we want the middle of 2 normals as well as the angle between them + * avoid multiple calculations by */ + float angle; + + /* double check they are normalized */ + BLI_assert(len_squared_v3(r) <= 1.0f + FLT_EPSILON); + + angle = ((float)(1.0 / (M_PI / 2.0)) * + /* normally we would only multiply by 2, + * but instead of an angle make this 0-1 factor */ + 2.0f) * + acosf(normalize_v3(r)); + mul_v3_fl(r, angle); +} + +/** * Equivalent to: * interp_v3_v3v3(v, v1, v2, -1.0f); */ |