diff options
author | Kostadin Damyanov <maxmight@gmail.com> | 2015-06-26 21:35:47 +0300 |
---|---|---|
committer | Kostadin Damyanov <maxmight@gmail.com> | 2015-06-26 21:35:47 +0300 |
commit | e0e54ea7d456c0fabd8f3f9b2667a69ff520f852 (patch) | |
tree | 9ce4e0b6db40ac2ab07b8582e57282fe63130165 /core/math/math_2d.cpp | |
parent | f61eb5fd8e13642c82364f8ee66a0f6c791a4511 (diff) | |
parent | a67486a39ee629acac068a6d014015944cf83bb3 (diff) |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'core/math/math_2d.cpp')
-rw-r--r-- | core/math/math_2d.cpp | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp index 0a3963f88f..88717723ce 100644 --- a/core/math/math_2d.cpp +++ b/core/math/math_2d.cpp @@ -622,9 +622,39 @@ float Matrix32::basis_determinant() const { } Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) const { + + //extract parameters + Vector2 p1 = get_origin(); + Vector2 p2 = p_transform.get_origin(); + + real_t r1 = get_rotation(); + real_t r2 = p_transform.get_rotation(); + + Vector2 s1 = get_scale(); + Vector2 s2 = p_transform.get_scale(); + + //slerp rotation + Vector2 v1(Math::cos(r1), Math::sin(r1)); + Vector2 v2(Math::cos(r2), Math::sin(r2)); + + real_t dot = v1.dot(v2); + + dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1] + + Vector2 v; - - return Matrix32(); + if (dot > 0.9995) { + v = Vector2::linear_interpolate(v1, v2, p_c).normalized(); //linearly interpolate to avoid numerical precision issues + } else { + real_t angle = p_c*Math::acos(dot); + Vector2 v3 = (v2 - v1*dot).normalized(); + v = v1*Math::cos(angle) + v3*Math::sin(angle); + } + + //construct matrix + Matrix32 res(Math::atan2(v.y, v.x), Vector2::linear_interpolate(p1, p2, p_c)); + res.scale_basis(Vector2::linear_interpolate(s1, s2, p_c)); + return res; } Matrix32::operator String() const { |