From 6b1252cdfa5988b77917518bc291a0cc34e5066e Mon Sep 17 00:00:00 2001 From: Ferenc Arn Date: Thu, 5 Jan 2017 11:31:39 -0600 Subject: Fix the order in which additional transformations are applied in Matrix3 and Transform. This is a part of the breaking changes proposed in PR #6865, solving the issue regarding the order of affine transformations described in #2565. This PR also fixes the affected code within Godot codebase. Includes improvements to documentation too. Another change is, Matrix3::get_scale() will now return negative scaling when the determinant of the matrix is negative. The rationale behind this is simple: when performing a polar decomposition on a basis matrix M = R.S, we have to ensure that the determinant of R is +1, such that it is a proper rotation matrix (with no reflections) which can be represented by Euler angles or a quaternion. Also replaced the few instances of float with real_t in Matrix3 and Transform. Furthermore, this PR fixes an issue introduced due to the API breakage in #6865. Namely Matrix3::get_euler() now only works with proper rotation matrices. As a result, the code that wants to get the rotation portion of a transform needs to use Matrix3::get_rotation() introduced in this commit, which complements Matrix3::get_scaled(), providing both parts of the polar decomposition. Finally, it is now possible to construct a rotation matrix from Euler angles using the new constructor Matrix3::Matrix3(const Vector3 &p_euler). --- core/math/transform.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'core/math/transform.cpp') diff --git a/core/math/transform.cpp b/core/math/transform.cpp index 8516e4afc..0dba12101 100644 --- a/core/math/transform.cpp +++ b/core/math/transform.cpp @@ -54,7 +54,8 @@ void Transform::invert() { } Transform Transform::inverse() const { - + // FIXME: this function assumes the basis is a rotation matrix, with no scaling. + // Transform::affine_inverse can handle matrices with scaling, so GDScript should eventually use that. Transform ret=*this; ret.invert(); return ret; @@ -63,12 +64,12 @@ Transform Transform::inverse() const { void Transform::rotate(const Vector3& p_axis,real_t p_phi) { - *this = *this * Transform( Matrix3( p_axis, p_phi ), Vector3() ); + *this = rotated(p_axis, p_phi); } Transform Transform::rotated(const Vector3& p_axis,real_t p_phi) const{ - return *this * Transform( Matrix3( p_axis, p_phi ), Vector3() ); + return Transform(Matrix3( p_axis, p_phi ), Vector3()) * (*this); } void Transform::rotate_basis(const Vector3& p_axis,real_t p_phi) { @@ -113,7 +114,7 @@ void Transform::set_look_at( const Vector3& p_eye, const Vector3& p_target, cons } -Transform Transform::interpolate_with(const Transform& p_transform, float p_c) const { +Transform Transform::interpolate_with(const Transform& p_transform, real_t p_c) const { /* not sure if very "efficient" but good enough? */ -- cgit v1.2.3-70-g09d2