diff options
author | Ignacio Etcheverry <neikeq@users.noreply.github.com> | 2019-02-13 02:20:55 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-13 02:20:55 +0100 |
commit | 35963eb052f35e720fb60119561e21a4f56f185a (patch) | |
tree | ffffe10eb6aa479e154506b481731623a0822bfc | |
parent | 5aff9903548c0f62d3d6aa880693d9131d2c53ac (diff) | |
parent | 06df7b0963ffeac31d2a0e4268889f0573edd7ea (diff) |
Merge pull request #25831 from aaronfranke/mono-trans-rot-scale
[Core] [Mono] Transform2D rotation and scale fixes
-rw-r--r-- | core/math/basis.cpp | 4 | ||||
-rw-r--r-- | core/math/transform_2d.cpp | 12 | ||||
-rw-r--r-- | core/math/transform_2d.h | 1 | ||||
-rw-r--r-- | modules/mono/glue/Managed/Files/Transform2D.cs | 62 |
4 files changed, 63 insertions, 16 deletions
diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 8e4eacd9a6..7f60b7962c 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -258,7 +258,7 @@ Vector3 Basis::get_scale_abs() const { } Vector3 Basis::get_scale_local() const { - real_t det_sign = determinant() > 0 ? 1 : -1; + real_t det_sign = SGN(determinant()); return det_sign * Vector3(elements[0].length(), elements[1].length(), elements[2].length()); } @@ -284,7 +284,7 @@ Vector3 Basis::get_scale() const { // matrix elements. // // The rotation part of this decomposition is returned by get_rotation* functions. - real_t det_sign = determinant() > 0 ? 1 : -1; + real_t det_sign = SGN(determinant()); return det_sign * Vector3( Vector3(elements[0][0], elements[1][0], elements[2][0]).length(), Vector3(elements[0][1], elements[1][1], elements[2][1]).length(), diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index 295e60babb..7d00158f3d 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -80,13 +80,14 @@ real_t Transform2D::get_rotation() const { } void Transform2D::set_rotation(real_t p_rot) { - + Size2 scale = get_scale(); real_t cr = Math::cos(p_rot); real_t sr = Math::sin(p_rot); elements[0][0] = cr; elements[0][1] = sr; elements[1][0] = -sr; elements[1][1] = cr; + set_scale(scale); } Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) { @@ -101,10 +102,17 @@ Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) { } Size2 Transform2D::get_scale() const { - real_t det_sign = basis_determinant() > 0 ? 1 : -1; + real_t det_sign = SGN(basis_determinant()); return Size2(elements[0].length(), det_sign * elements[1].length()); } +void Transform2D::set_scale(Size2 &p_scale) { + elements[0].normalize(); + elements[1].normalize(); + elements[0] *= p_scale.x; + elements[1] *= p_scale.y; +} + void Transform2D::scale(const Size2 &p_scale) { scale_basis(p_scale); elements[2] *= p_scale; diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 507e6a16eb..b9e7a36fb3 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -81,6 +81,7 @@ struct Transform2D { real_t basis_determinant() const; Size2 get_scale() const; + void set_scale(Size2 &p_scale); _FORCE_INLINE_ const Vector2 &get_origin() const { return elements[2]; } _FORCE_INLINE_ void set_origin(const Vector2 &p_origin) { elements[2] = p_origin; } diff --git a/modules/mono/glue/Managed/Files/Transform2D.cs b/modules/mono/glue/Managed/Files/Transform2D.cs index f89c99cff2..df7ba3402d 100644 --- a/modules/mono/glue/Managed/Files/Transform2D.cs +++ b/modules/mono/glue/Managed/Files/Transform2D.cs @@ -17,12 +17,40 @@ namespace Godot public real_t Rotation { - get { return Mathf.Atan2(y.x, origin.y); } + get + { + real_t det = BasisDeterminant(); + Transform2D t = Orthonormalized(); + if (det < 0) + { + t.ScaleBasis(new Vector2(1, -1)); + } + return Mathf.Atan2(t.x.y, t.x.x); + } + set + { + Vector2 scale = Scale; + x.x = y.y = Mathf.Cos(value); + x.y = y.x = Mathf.Sin(value); + y.x *= -1; + Scale = scale; + } } public Vector2 Scale { - get { return new Vector2(x.Length(), y.Length()); } + get + { + real_t detSign = Mathf.Sign(BasisDeterminant()); + return new Vector2(x.Length(), detSign * y.Length()); + } + set + { + x = x.Normalized(); + y = y.Normalized(); + x *= value.x; + y *= value.y; + } } public Vector2 this[int index] @@ -95,7 +123,7 @@ namespace Godot { var inv = this; - real_t det = this[0, 0] * this[1, 1] - this[1, 0] * this[0, 1]; + real_t det = BasisDeterminant(); if (det == 0) { @@ -107,20 +135,25 @@ namespace Godot ); } - real_t idet = 1.0f / det; + real_t detInv = 1.0f / det; real_t temp = this[0, 0]; this[0, 0] = this[1, 1]; this[1, 1] = temp; - this[0] *= new Vector2(idet, -idet); - this[1] *= new Vector2(-idet, idet); + this[0] *= new Vector2(detInv, -detInv); + this[1] *= new Vector2(-detInv, detInv); this[2] = BasisXform(-this[2]); return inv; } + private real_t BasisDeterminant() + { + return x.x * y.y - x.y * y.x; + } + public Vector2 BasisXform(Vector2 v) { return new Vector2(Tdotx(v), Tdoty(v)); @@ -220,6 +253,14 @@ namespace Godot return copy; } + private void ScaleBasis(Vector2 scale) + { + x.x *= scale.x; + x.y *= scale.y; + y.x *= scale.x; + y.y *= scale.y; + } + private real_t Tdotx(Vector2 with) { return this[0, 0] * with[0] + this[1, 0] * with[1]; @@ -274,12 +315,9 @@ namespace Godot public Transform2D(real_t rot, Vector2 pos) { - real_t cr = Mathf.Cos(rot); - real_t sr = Mathf.Sin(rot); - x.x = cr; - x.y = -sr; - y.x = sr; - y.y = cr; + x.x = y.y = Mathf.Cos(rot); + x.y = y.x = Mathf.Sin(rot); + y.x *= -1; origin = pos; } |