Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2014-03-31 06:18:23 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-03-31 06:28:37 +0400
commit55f83e36cc2aae2f238183fc13123d92f158ba4e (patch)
treef6e59ebeb206372f9f1e90d4e9e438a55ca79010 /source/blender/blenlib/intern/math_vector.c
parent6aa75d3b2c3d4a5dc58120a51fdee0a7c12ab93c (diff)
Py API: Vector.slerp(). also added interp_v3_v3v3_slerp(_safe) functions
Diffstat (limited to 'source/blender/blenlib/intern/math_vector.c')
-rw-r--r--source/blender/blenlib/intern/math_vector.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 3fbddacaea2..8455bf7550f 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -68,6 +68,103 @@ void interp_v4_v4v4(float target[4], const float a[4], const float b[4], const f
target[3] = s * a[3] + t * b[3];
}
+/**
+ * slerp, treat vectors as spherical coordinates
+ * \see #interp_qt_qtqt
+ *
+ * \return success
+ */
+bool interp_v3_v3v3_slerp(float target[3], const float a[3], const float b[3], const float t)
+{
+ float cosom, w[2];
+
+ BLI_ASSERT_UNIT_V3(a);
+ BLI_ASSERT_UNIT_V3(b);
+
+ cosom = dot_v3v3(a, b);
+
+ /* direct opposites */
+ if (UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
+ return false;
+ }
+
+ interp_dot_slerp(t, cosom, w);
+
+ target[0] = w[0] * a[0] + w[1] * b[0];
+ target[1] = w[0] * a[1] + w[1] * b[1];
+ target[2] = w[0] * a[2] + w[1] * b[2];
+
+ return true;
+}
+bool interp_v2_v2v2_slerp(float target[2], const float a[2], const float b[2], const float t)
+{
+ float cosom, w[2];
+
+ BLI_ASSERT_UNIT_V2(a);
+ BLI_ASSERT_UNIT_V2(b);
+
+ cosom = dot_v2v2(a, b);
+
+ /* direct opposites */
+ if (UNLIKELY(cosom < (1.0f + FLT_EPSILON))) {
+ return false;
+ }
+
+ interp_dot_slerp(t, cosom, w);
+
+ target[0] = w[0] * a[0] + w[1] * b[0];
+ target[1] = w[0] * a[1] + w[1] * b[1];
+
+ return true;
+}
+
+/**
+ * Same as #interp_v3_v3v3_slerp buy uses fallback values
+ * for opposite vectors.
+ */
+void interp_v3_v3v3_slerp_safe(float target[3], const float a[3], const float b[3], const float t)
+{
+ if (UNLIKELY(!interp_v3_v3v3_slerp(target, a, b, t))) {
+ /* axis are aligned so any otho vector is acceptable */
+ float ab_ortho[3];
+ ortho_v3_v3(ab_ortho, a);
+ normalize_v3(ab_ortho);
+ if (t < 0.5f) {
+ if (UNLIKELY(!interp_v3_v3v3_slerp(target, a, ab_ortho, t * 2.0f))) {
+ BLI_assert(0);
+ copy_v3_v3(target, a);
+ }
+ }
+ else {
+ if (UNLIKELY(!interp_v3_v3v3_slerp(target, ab_ortho, b, (t - 0.5f) * 2.0f))) {
+ BLI_assert(0);
+ copy_v3_v3(target, b);
+ }
+ }
+ }
+}
+void interp_v2_v2v2_slerp_safe(float target[2], const float a[2], const float b[2], const float t)
+{
+ if (UNLIKELY(!interp_v2_v2v2_slerp(target, a, b, t))) {
+ /* axis are aligned so any otho vector is acceptable */
+ float ab_ortho[2];
+ ortho_v2_v2(ab_ortho, a);
+ // normalize_v2(ab_ortho);
+ if (t < 0.5f) {
+ if (UNLIKELY(!interp_v2_v2v2_slerp(target, a, ab_ortho, t * 2.0f))) {
+ BLI_assert(0);
+ copy_v2_v2(target, a);
+ }
+ }
+ else {
+ if (UNLIKELY(!interp_v2_v2v2_slerp(target, ab_ortho, b, (t - 0.5f) * 2.0f))) {
+ BLI_assert(0);
+ copy_v2_v2(target, b);
+ }
+ }
+ }
+}
+
/* weight 3 vectors,
* 'w' must be unit length but is not a vector, just 3 weights */
void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
@@ -538,6 +635,17 @@ void ortho_v3_v3(float p[3], const float v[3])
}
}
+/**
+ * no brainer compared to v3, just have for consistency.
+ */
+void ortho_v2_v2(float p[3], const float v[3])
+{
+ BLI_assert(p != v);
+
+ p[0] = -v[1];
+ p[1] = v[0];
+}
+
/* Rotate a point p by angle theta around an arbitrary axis r
* http://local.wasp.uwa.edu.au/~pbourke/geometry/
*/