@ -62,7 +62,7 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* 0 & 0 & 0 & 1
* \ end { pmatrix }
* @ f ]
* @ see @ ref translation ( ) , @ ref DualQuaternion : : translation ( ) ,
* @ see @ ref translation ( ) const , @ ref DualQuaternion : : translation ( ) ,
* @ ref Matrix3 : : translation ( const Vector2 < T > & ) ,
* @ ref Vector3 : : xAxis ( ) , @ ref Vector3 : : yAxis ( ) ,
* @ ref Vector3 : : zAxis ( )
@ -86,8 +86,7 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* 0 & 0 & 0 & 1
* \ end { pmatrix }
* @ f ]
* @ see @ ref rotationScaling ( ) ,
* @ ref Matrix3 : : scaling ( const Vector2 < T > & ) ,
* @ see @ ref scaling ( ) const , @ ref Matrix3 : : scaling ( const Vector2 < T > & ) ,
* @ ref Vector3 : : xScale ( ) , @ ref Vector3 : : yScale ( ) ,
* @ ref Vector3 : : zScale ( )
*/
@ -433,7 +432,7 @@ template<class T> class Matrix4: public Matrix4x4<T> {
/**
* @ brief 3 D rotation and scaling part of the matrix
*
* Upper - left 3 x3 part of the matrix . @ f [
* Unchanged u pper - left 3 x3 part of the matrix . @ f [
* \ begin { pmatrix }
* \ color { m - danger } a_x & \ color { m - success } b_x & \ color { m - info } c_x & t_x \ \
* \ color { m - danger } a_y & \ color { m - success } b_y & \ color { m - info } c_y & t_y \ \
@ -442,9 +441,16 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* \ end { pmatrix }
* @ f ]
*
* Note that an arbitrary combination of rotation and scaling can also
* represent shear and reflection . Especially when non - uniform scaling
* is involved , decomposition of the result into primary linear
* transformations may have multiple equivalent solutions . See
* @ ref Algorithms : : svd ( ) and @ ref Algorithms : : qr ( ) for further info .
* See also @ ref rotationShear ( ) , @ ref rotation ( ) const and
* @ ref scaling ( ) const for extracting further properties .
*
* @ see @ ref from ( const Matrix3x3 < T > & , const Vector3 < T > & ) ,
* @ ref rotation ( ) const , @ ref rotationNormalized ( ) ,
* @ ref uniformScaling ( ) , @ ref rotation ( Rad , const Vector3 < T > & ) ,
* @ ref rotation ( Rad , const Vector3 < T > & ) ,
* @ ref Matrix3 : : rotationScaling ( ) const
*/
constexpr Matrix3x3 < T > rotationScaling ( ) const {
@ -454,68 +460,216 @@ template<class T> class Matrix4: public Matrix4x4<T> {
}
/**
* @ brief 3 D rotation part of the matrix assuming there is no scaling
* @ brief 3 D rotation and scaling part of the matrix
*
* Similar to @ ref rotationScaling ( ) , but additionally checks that the
* base vectors are normalized . Check its documentation for caveats . @ f [
* Normalized upper - left 3 x3 part of the matrix . Assuming the following
* matrix , with the upper - left 3 x3 part represented by column vectors
* @ f $ \ boldsymbol { a } @ f $ , @ f $ \ boldsymbol { b } @ f $ and
* @ f $ \ boldsymbol { c } @ f $ : @ f [
* \ begin { pmatrix }
* \ color { m - danger } a_x & \ color { m - success } b_x & \ color { m - info } c_x & t_x \ \
* \ color { m - danger } a_y & \ color { m - success } b_y & \ color { m - info } c_y & t_y \ \
* \ color { m - danger } a_z & \ color { m - success } b_z & \ color { m - info } c_z & t_z \ \
* \ color { m - warning } a_x & \ color { m - warning } b_x & \ color { m - warning } c_x & t_x \ \
* \ color { m - warning } a_y & \ color { m - warning } b_y & \ color { m - warning } c_y & t_y \ \
* \ color { m - warning } a_z & \ color { m - warning } b_z & \ color { m - warning } c_z & t_z \ \
* \ color { m - dim } 0 & \ color { m - dim } 0 & \ color { m - dim } 0 & \ color { m - dim } 1
* \ end { pmatrix }
* @ f ]
*
* @ see @ ref rotation ( ) const , @ ref uniformScaling ( ) ,
* @ ref Matrix3 : : rotationNormalized ( )
* @ todo assert also orthogonality or this is good enough ?
* @ m_class { m - noindent }
*
* the resulting rotation is extracted as : @ f [
* \ boldsymbol { R } = \ begin { pmatrix }
* \ cfrac { \ boldsymbol { a } } { | \ boldsymbol { a } | } &
* \ cfrac { \ boldsymbol { b } } { | \ boldsymbol { b } | } &
* \ cfrac { \ boldsymbol { c } } { | \ boldsymbol { c } | }
* \ end { pmatrix }
* @ f ]
*
* This function is a counterpart to @ ref rotation ( ) const that does
* not require orthogonal input . See also @ ref rotationScaling ( ) and
* @ ref scaling ( ) const for extracting other properties . The
* @ ref Algorithms : : svd ( ) and @ ref Algorithms : : qr ( ) can be used to
* separate the rotation / shear properties .
*
* @ see @ ref from ( const Matrix3x3 < T > & , const Vector3 < T > & ) ,
* @ ref rotation ( Rad , const Vector3 < T > & ) ,
* @ ref Matrix3 : : rotationShear ( ) const
*/
Matrix3x3 < T > rotationNormalized ( ) const {
CORRADE_ASSERT ( ( * this ) [ 0 ] . xyz ( ) . isNormalized ( ) & & ( * this ) [ 1 ] . xyz ( ) . isNormalized ( ) & & ( * this ) [ 2 ] . xyz ( ) . isNormalized ( ) ,
" Math::Matrix4::rotationNormalized(): the rotation part is not normalized " , { } ) ;
return { ( * this ) [ 0 ] . xyz ( ) ,
( * this ) [ 1 ] . xyz ( ) ,
( * this ) [ 2 ] . xyz ( ) } ;
Matrix3x3 < T > rotationShear ( ) const {
return { ( * this ) [ 0 ] . xyz ( ) . normalized ( ) ,
( * this ) [ 1 ] . xyz ( ) . normalized ( ) ,
( * this ) [ 2 ] . xyz ( ) . normalized ( ) } ;
}
/**
* @ brief 3 D rotation part of the matrix
*
* Normalized upper - left 3 x3 part of the matrix . Expects uniform
* scaling . @ f [
* Normalized upper - left 3 x3 part of the matrix . Expects that the
* normalized part is orthogonal . Assuming the following matrix , with
* the upper - left 3 x3 part represented by column vectors
* @ f $ \ boldsymbol { a } @ f $ , @ f $ \ boldsymbol { b } @ f $ and
* @ f $ \ boldsymbol { c } @ f $ : @ f [
* \ begin { pmatrix }
* \ color { m - danger } a_x & \ color { m - success } b_x & \ color { m - info } c_x & t_x \ \
* \ color { m - danger } a_y & \ color { m - success } b_y & \ color { m - info } c_y & t_y \ \
* \ color { m - danger } a_z & \ color { m - success } b_z & \ color { m - info } c_z & t_z \ \
* \ color { m - warning } a_x & \ color { m - warning } b_x & \ color { m - warning } c_x & t_x \ \
* \ color { m - warning } a_y & \ color { m - warning } b_y & \ color { m - warning } c_y & t_y \ \
* \ color { m - warning } a_z & \ color { m - warning } b_z & \ color { m - warning } c_z & t_z \ \
* \ color { m - dim } 0 & \ color { m - dim } 0 & \ color { m - dim } 0 & \ color { m - dim } 1
* \ end { pmatrix }
* @ f ]
*
* @ note Extracting rotation part of a matrix this way will cause
* @ m_class { m - noindent }
*
* the resulting rotation is extracted as : @ f [
* \ boldsymbol { R } = \ begin { pmatrix }
* \ cfrac { \ boldsymbol { a } } { | \ boldsymbol { a } | } &
* \ cfrac { \ boldsymbol { b } } { | \ boldsymbol { b } | } &
* \ cfrac { \ boldsymbol { c } } { | \ boldsymbol { c } | }
* \ end { pmatrix }
* @ f ]
*
* This function is equivalent to @ ref rotationShear ( ) but with the
* added orthogonality requirement . See also @ ref rotationScaling ( ) and
* @ ref scaling ( ) const for extracting other properties .
*
* @ note Extracting rotation part of a matrix this way may cause
* assertions in case you have unsanitized input ( for example a
* model transformation loaded from an external source ) or when
* you accumulate many transformations together ( for example when
* controlling a FPS camera ) . To mitigate this , either renormalize
* the matrix using @ ref Algorithms : : gramSchmidtOrthogonalize ( ) or
* @ ref Algorithms : : svd ( ) first , use a different transformation
* controlling a FPS camera ) . To mitigate this , either first
* reorthogonalize the matrix using
* @ ref Algorithms : : gramSchmidtOrthogonalize ( ) , decompose it to
* basic linear transformations using @ ref Algorithms : : svd ( ) or
* @ ref Algorithms : : qr ( ) or use a different transformation
* representation that suffers less floating point error and can
* be easier renormalized such as @ ref DualQuaternion , or , ignore
* the error and extract combined non - uniform rotation and scaling
* with @ ref rotationScaling ( ) .
* be easier renormalized such as @ ref DualQuaternion . Another
* possibility is to ignore the error and extract combined
* rotation and scaling / shear with @ ref rotationScaling ( ) /
* @ ref rotationShear ( ) .
*
* @ see @ ref rotationNormalized ( ) , @ ref rotationScaling ( ) ,
* @ ref uniformScaling ( ) , @ ref rotation ( Rad , const Vector3 < T > & ) ,
* @ see @ ref rotationNormalized ( ) , @ ref s caling( ) const ,
* @ ref rotation ( Rad , const Vector3 < T > & ) ,
* @ ref Matrix3 : : rotation ( ) const
*/
Matrix3x3 < T > rotation ( ) const ;
/**
* @ brief 3 D rotation part of the matrix assuming there is no scaling
*
* Similar to @ ref rotation ( ) , but expects that the rotation part is
* orthogonal , saving the extra renormalization . Assuming the
* following matrix , with the upper - left 3 x3 part represented by column
* vectors @ f $ \ boldsymbol { a } @ f $ , @ f $ \ boldsymbol { b } @ f $ and
* @ f $ \ boldsymbol { c } @ f $ : @ f [
* \ begin { pmatrix }
* \ color { m - danger } a_x & \ color { m - success } b_x & \ color { m - info } c_x & t_x \ \
* \ color { m - danger } a_y & \ color { m - success } b_y & \ color { m - info } c_y & t_y \ \
* \ color { m - danger } a_z & \ color { m - success } b_z & \ color { m - info } c_z & t_z \ \
* \ color { m - dim } 0 & \ color { m - dim } 0 & \ color { m - dim } 0 & \ color { m - dim } 1
* \ end { pmatrix }
* @ f ]
*
* @ m_class { m - noindent }
*
* the resulting rotation is extracted as : @ f [
* \ boldsymbol { R } = \ begin { pmatrix }
* \ cfrac { \ boldsymbol { a } } { | \ boldsymbol { a } | } &
* \ cfrac { \ boldsymbol { b } } { | \ boldsymbol { b } | } &
* \ cfrac { \ boldsymbol { c } } { | \ boldsymbol { c } | }
* \ end { pmatrix } = \ begin { pmatrix }
* \ boldsymbol { a } &
* \ boldsymbol { b } &
* \ boldsymbol { c }
* \ end { pmatrix }
* @ f ]
*
* In particular , for an orthogonal matrix , @ ref rotationScaling ( ) ,
* @ ref rotationShear ( ) , @ ref rotation ( ) const and
* @ ref rotationNormalized ( ) all return the same value .
*
* @ see @ ref isOrthogonal ( ) , @ ref uniformScaling ( ) ,
* @ ref Matrix3 : : rotationNormalized ( )
*/
Matrix3x3 < T > rotationNormalized ( ) const ;
/**
* @ brief Non - uniform scaling part of the matrix , squared
*
* Squared length of vectors in upper - left 3 x3 part of the matrix .
* Faster alternative to @ ref scaling ( ) const , because it doesn ' t
* calculate the square root . Assuming the following matrix , with the
* upper - left 3 x3 part represented by column vectors
* @ f $ \ boldsymbol { a } @ f $ , @ f $ \ boldsymbol { b } @ f $ and
* @ f $ \ boldsymbol { c } @ f $ : @ f [
* \ begin { pmatrix }
* \ color { m - warning } a_x & \ color { m - warning } b_x & \ color { m - warning } c_x & t_x \ \
* \ color { m - warning } a_y & \ color { m - warning } b_y & \ color { m - warning } c_y & t_y \ \
* \ color { m - warning } a_z & \ color { m - warning } b_z & \ color { m - warning } c_z & t_z \ \
* \ color { m - dim } 0 & \ color { m - dim } 0 & \ color { m - dim } 0 & \ color { m - dim } 1
* \ end { pmatrix }
* @ f ]
*
* @ m_class { m - noindent }
*
* the resulting scaling vector , squared , is : @ f [
* \ boldsymbol { s } ^ 2 = \ begin { pmatrix }
* \ boldsymbol { a } \ cdot \ boldsymbol { a } \ \
* \ boldsymbol { b } \ cdot \ boldsymbol { b } \ \
* \ boldsymbol { c } \ cdot \ boldsymbol { c }
* \ end { pmatrix }
* @ f ]
*
* @ see @ ref scaling ( ) const , @ ref uniformScalingSquared ( ) ,
* @ ref rotation ( ) const , @ ref Matrix3 : : scalingSquared ( )
*/
Vector3 < T > scalingSquared ( ) const {
return { ( * this ) [ 0 ] . xyz ( ) . dot ( ) ,
( * this ) [ 1 ] . xyz ( ) . dot ( ) ,
( * this ) [ 2 ] . xyz ( ) . dot ( ) } ;
}
/**
* @ brief Non - uniform scaling part of the matrix , squared
*
* Length of vectors in upper - left 3 x3 part of the matrix . Use the
* faster alternative @ ref scalingSquared ( ) where possible . Assuming
* the following matrix , with the upper - left 3 x3 part represented by
* column vectors @ f $ \ boldsymbol { a } @ f $ , @ f $ \ boldsymbol { b } @ f $ and
* @ f $ \ boldsymbol { c } @ f $ : @ f [
* \ begin { pmatrix }
* \ color { m - warning } a_x & \ color { m - warning } b_x & \ color { m - warning } c_x & t_x \ \
* \ color { m - warning } a_y & \ color { m - warning } b_y & \ color { m - warning } c_y & t_y \ \
* \ color { m - warning } a_z & \ color { m - warning } b_z & \ color { m - warning } c_z & t_z \ \
* \ color { m - dim } 0 & \ color { m - dim } 0 & \ color { m - dim } 0 & \ color { m - dim } 1
* \ end { pmatrix }
* @ f ]
*
* @ m_class { m - noindent }
*
* the resulting scaling vector is : @ f [
* \ boldsymbol { s } = \ begin { pmatrix }
* | \ boldsymbol { a } | \ \
* | \ boldsymbol { b } | \ \
* | \ boldsymbol { c } |
* \ end { pmatrix }
* @ f ]
*
* @ see @ ref scalingSquared ( ) , @ ref uniformScaling ( ) ,
* @ ref rotation ( ) const , @ ref Matrix3 : : scaling ( ) const
*/
Vector3 < T > scaling ( ) const {
return { ( * this ) [ 0 ] . xyz ( ) . length ( ) ,
( * this ) [ 1 ] . xyz ( ) . length ( ) ,
( * this ) [ 2 ] . xyz ( ) . length ( ) } ;
}
/**
* @ brief Uniform scaling part of the matrix , squared
*
* Squared length of vectors in upper - left 3 x3 part of the matrix .
* Expects that the scaling is the same in all axes . Faster alternative
* to @ ref uniformScaling ( ) , because it doesn ' t compute the square
* root . See its documentation for caveats . @ f [
* to @ ref uniformScaling ( ) , because it doesn ' t calculate the square
* root . Assuming the following matrix , with the upper - left 3 x3 part
* represented by column vectors @ f $ \ boldsymbol { a } @ f $ ,
* @ f $ \ boldsymbol { b } @ f $ and @ f $ \ boldsymbol { c } @ f $ : @ f [
* \ begin { pmatrix }
* \ color { m - warning } a_x & \ color { m - warning } b_x & \ color { m - warning } c_x & t_x \ \
* \ color { m - warning } a_y & \ color { m - warning } b_y & \ color { m - warning } c_y & t_y \ \
@ -524,9 +678,28 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* \ end { pmatrix }
* @ f ]
*
* @ see @ ref rotationScaling ( ) , @ ref rotation ( ) const ,
* @ ref rotationNormalized ( ) , @ ref scaling ( const Vector3 < T > & ) ,
* @ ref Matrix3 : : uniformScaling ( )
* @ m_class { m - noindent }
*
* the resulting uniform scaling , squared , is : @ f [
* s ^ 2 = \ boldsymbol { a } \ cdot \ boldsymbol { a }
* = \ boldsymbol { b } \ cdot \ boldsymbol { b }
* = \ boldsymbol { c } \ cdot \ boldsymbol { c }
* @ f ]
*
* @ note Extracting uniform scaling of a matrix this way may cause
* assertions in case you have unsanitized input ( for example a
* model transformation loaded from an external source ) or when
* you accumulate many transformations together ( for example when
* controlling a FPS camera ) . To mitigate this , either first
* reorthogonalize the matrix using
* @ ref Algorithms : : gramSchmidtOrthogonalize ( ) , decompose it to
* basic linear transformations using @ ref Algorithms : : svd ( ) or
* @ ref Algorithms : : qr ( ) or extract a non - uniform scaling using
* @ ref scalingSquared ( ) .
*
* @ see @ ref rotation ( ) const , @ ref scaling ( ) const ,
* @ ref scaling ( const Vector3 < T > & ) ,
* @ ref Matrix3 : : uniformScalingSquared ( )
*/
T uniformScalingSquared ( ) const ;
@ -534,8 +707,11 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* @ brief Uniform scaling part of the matrix
*
* Length of vectors in upper - left 3 x3 part of the matrix . Expects that
* the scaling is the same in all axes . Use faster alternative
* @ ref uniformScalingSquared ( ) where possible . @ f [
* the scaling is the same in all axes . Use the faster alternative
* @ ref uniformScalingSquared ( ) where possible . Assuming the following
* matrix , with the upper - left 3 x3 part represented by column vectors
* @ f $ \ boldsymbol { a } @ f $ , @ f $ \ boldsymbol { b } @ f $ and
* @ f $ \ boldsymbol { c } @ f $ : @ f [
* \ begin { pmatrix }
* \ color { m - warning } a_x & \ color { m - warning } b_x & \ color { m - warning } c_x & t_x \ \
* \ color { m - warning } a_y & \ color { m - warning } b_y & \ color { m - warning } c_y & t_y \ \
@ -544,18 +720,25 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* \ end { pmatrix }
* @ f ]
*
* @ note Extracting uniform scaling of a matrix this way will cause
* @ m_class { m - noindent }
*
* the resulting uniform scaling is : @ f [
* s = | \ boldsymbol { a } | = | \ boldsymbol { b } | = | \ boldsymbol { c } |
* @ f ]
*
* @ note Extracting uniform scaling of a matrix this way may cause
* assertions in case you have unsanitized input ( for example a
* model transformation loaded from an external source ) or when
* you accumulate many transformations together ( for example when
* controlling a FPS camera ) . To mitigate this , either renormalize
* the matrix using @ ref Algorithms : : gramSchmidtOrthogonalize ( ) or
* @ ref Algorithms : : svd ( ) first or extract the scaling manually by
* calculating lengths of @ ref right ( ) , @ ref up ( ) and
* @ ref backward ( ) vectors .
*
* @ see @ ref rotationScaling ( ) , @ ref rotation ( ) const ,
* @ ref rotationNormalized ( ) , @ ref scaling ( const Vector3 < T > & ) ,
* controlling a FPS camera ) . To mitigate this , either first
* reorthogonalize the matrix using
* @ ref Algorithms : : gramSchmidtOrthogonalize ( ) , decompose it to
* basic linear transformations using @ ref Algorithms : : svd ( ) or
* @ ref Algorithms : : qr ( ) or extract a non - uniform scaling using
* @ ref scaling ( ) const .
*
* @ see @ ref rotation ( ) const , @ ref scaling ( ) const ,
* @ ref scaling ( const Vector3 < T > & ) ,
* @ ref Matrix3 : : uniformScaling ( )
*/
T uniformScaling ( ) const { return std : : sqrt ( uniformScalingSquared ( ) ) ; }
@ -787,13 +970,22 @@ template<class T> Matrix4<T> Matrix4<T>::lookAt(const Vector3<T>& eye, const Vec
return from ( { right , realUp , backward } , eye ) ;
}
template < class T > inline Matrix3x3 < T > Matrix4 < T > : : rotation ( ) const {
CORRADE_ASSERT ( TypeTraits < T > : : equals ( ( * this ) [ 0 ] . xyz ( ) . dot ( ) , ( * this ) [ 1 ] . xyz ( ) . dot ( ) ) & &
TypeTraits < T > : : equals ( ( * this ) [ 1 ] . xyz ( ) . dot ( ) , ( * this ) [ 2 ] . xyz ( ) . dot ( ) ) ,
" Math::Matrix4::rotation(): the matrix doesn't have uniform scaling " , { } ) ;
return { ( * this ) [ 0 ] . xyz ( ) . normalized ( ) ,
( * this ) [ 1 ] . xyz ( ) . normalized ( ) ,
( * this ) [ 2 ] . xyz ( ) . normalized ( ) } ;
template < class T > Matrix3x3 < T > Matrix4 < T > : : rotation ( ) const {
Matrix3x3 < T > rotation { ( * this ) [ 0 ] . xyz ( ) . normalized ( ) ,
( * this ) [ 1 ] . xyz ( ) . normalized ( ) ,
( * this ) [ 2 ] . xyz ( ) . normalized ( ) } ;
CORRADE_ASSERT ( rotation . isOrthogonal ( ) ,
" Math::Matrix4::rotation(): the normalized rotation part is not orthogonal " , { } ) ;
return rotation ;
}
template < class T > Matrix3x3 < T > Matrix4 < T > : : rotationNormalized ( ) const {
Matrix3x3 < T > rotation { ( * this ) [ 0 ] . xyz ( ) ,
( * this ) [ 1 ] . xyz ( ) ,
( * this ) [ 2 ] . xyz ( ) } ;
CORRADE_ASSERT ( rotation . isOrthogonal ( ) ,
" Math::Matrix4::rotationNormalized(): the rotation part is not orthogonal " , { } ) ;
return rotation ;
}
template < class T > T Matrix4 < T > : : uniformScalingSquared ( ) const {