Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed some Transform3DGizmo behavior to make more consistent #53684

Merged
merged 1 commit into from
Jan 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions core/math/basis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,18 @@ Basis Basis::orthonormalized() const {
return c;
}

void Basis::orthogonalize() {
Vector3 scl = get_scale();
orthonormalize();
scale_local(scl);
}

Basis Basis::orthogonalized() const {
Basis c = *this;
c.orthogonalize();
return c;
}

bool Basis::is_orthogonal() const {
Basis identity;
Basis m = (*this) * transposed();
Expand Down Expand Up @@ -237,6 +249,24 @@ void Basis::scale_local(const Vector3 &p_scale) {
*this = scaled_local(p_scale);
}

void Basis::scale_orthogonal(const Vector3 &p_scale) {
*this = scaled_orthogonal(p_scale);
}

Basis Basis::scaled_orthogonal(const Vector3 &p_scale) const {
Basis m = *this;
Vector3 s = Vector3(-1, -1, -1) + p_scale;
Vector3 dots;
Basis b;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
dots[j] += s[i] * abs(m.get_axis(i).normalized().dot(b.get_axis(j)));
}
}
m.scale_local(Vector3(1, 1, 1) + dots);
return m;
}

float Basis::get_uniform_scale() const {
return (elements[0].length() + elements[1].length() + elements[2].length()) / 3.0;
}
Expand Down Expand Up @@ -931,6 +961,15 @@ void Basis::_set_diagonal(const Vector3 &p_diag) {
elements[2][2] = p_diag.z;
}

Basis Basis::lerp(const Basis &p_to, const real_t &p_weight) const {
Basis b;
b.elements[0] = elements[0].lerp(p_to.elements[0], p_weight);
b.elements[1] = elements[1].lerp(p_to.elements[1], p_weight);
b.elements[2] = elements[2].lerp(p_to.elements[2], p_weight);

return b;
}

Basis Basis::slerp(const Basis &p_to, const real_t &p_weight) const {
//consider scale
Quaternion from(*this);
Expand Down
7 changes: 7 additions & 0 deletions core/math/basis.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ class Basis {
void scale_local(const Vector3 &p_scale);
Basis scaled_local(const Vector3 &p_scale) const;

void scale_orthogonal(const Vector3 &p_scale);
Basis scaled_orthogonal(const Vector3 &p_scale) const;

void make_scale_uniform();
float get_uniform_scale() const;

Expand Down Expand Up @@ -168,6 +171,7 @@ class Basis {
bool is_diagonal() const;
bool is_rotation() const;

Basis lerp(const Basis &p_to, const real_t &p_weight) const;
Basis slerp(const Basis &p_to, const real_t &p_weight) const;
void rotate_sh(real_t *p_values);

Expand Down Expand Up @@ -233,6 +237,9 @@ class Basis {
void orthonormalize();
Basis orthonormalized() const;

void orthogonalize();
Basis orthogonalized() const;

#ifdef MATH_CHECKS
bool is_symmetric() const;
#endif
Expand Down
24 changes: 22 additions & 2 deletions core/math/transform_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ void Transform3D::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, con
origin = p_eye;
}

Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t p_c) const {
Transform3D Transform3D::sphere_interpolate_with(const Transform3D &p_transform, real_t p_c) const {
/* not sure if very "efficient" but good enough? */

Transform3D interp;

Vector3 src_scale = basis.get_scale();
Quaternion src_rot = basis.get_rotation_quaternion();
Vector3 src_loc = origin;
Expand All @@ -91,13 +93,21 @@ Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t
Quaternion dst_rot = p_transform.basis.get_rotation_quaternion();
Vector3 dst_loc = p_transform.origin;

Transform3D interp;
interp.basis.set_quaternion_scale(src_rot.slerp(dst_rot, p_c).normalized(), src_scale.lerp(dst_scale, p_c));
interp.origin = src_loc.lerp(dst_loc, p_c);

return interp;
}

Transform3D Transform3D::interpolate_with(const Transform3D &p_transform, real_t p_c) const {
Transform3D interp;

interp.basis = basis.lerp(p_transform.basis, p_c);
interp.origin = origin.lerp(p_transform.origin, p_c);

return interp;
}

void Transform3D::scale(const Vector3 &p_scale) {
basis.scale(p_scale);
origin *= p_scale;
Expand Down Expand Up @@ -139,6 +149,16 @@ Transform3D Transform3D::orthonormalized() const {
return _copy;
}

void Transform3D::orthogonalize() {
basis.orthogonalize();
}

Transform3D Transform3D::orthogonalized() const {
Transform3D _copy = *this;
_copy.orthogonalize();
return _copy;
}

bool Transform3D::is_equal_approx(const Transform3D &p_transform) const {
return basis.is_equal_approx(p_transform.basis) && origin.is_equal_approx(p_transform.origin);
}
Expand Down
3 changes: 3 additions & 0 deletions core/math/transform_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class Transform3D {

void orthonormalize();
Transform3D orthonormalized() const;
void orthogonalize();
Transform3D orthogonalized() const;
bool is_equal_approx(const Transform3D &p_transform) const;

bool operator==(const Transform3D &p_transform) const;
Expand Down Expand Up @@ -99,6 +101,7 @@ class Transform3D {
void operator*=(const real_t p_val);
Transform3D operator*(const real_t p_val) const;

Transform3D sphere_interpolate_with(const Transform3D &p_transform, real_t p_c) const;
Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const;

_FORCE_INLINE_ Transform3D inverse_xform(const Transform3D &t) const {
Expand Down
2 changes: 1 addition & 1 deletion core/variant/variant_setget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2120,7 +2120,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case BASIS: {
r_dst = Transform3D(*a._data._basis).interpolate_with(Transform3D(*b._data._basis), c).basis;
r_dst = a._data._basis->lerp(*b._data._basis, c);
}
return;
case TRANSFORM3D: {
Expand Down
Loading