Skip to content

Commit

Permalink
Merge pull request #53684 from TokageItLab/orthogonal-mode
Browse files Browse the repository at this point in the history
  • Loading branch information
akien-mga authored Jan 5, 2022
2 parents bb4157a + 61759da commit 6af77c7
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 83 deletions.
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

0 comments on commit 6af77c7

Please sign in to comment.