Merge pull request #25831 from aaronfranke/mono-trans-rot-scale
[Core] [Mono] Transform2D rotation and scale fixes
This commit is contained in:
commit
35963eb052
4 changed files with 63 additions and 16 deletions
|
@ -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(),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue