Fix create Rotation from scaled matrix
Support for creation of Rotation from matrices which is a combination of non uniform scale and a rotation Fixes according to review Scale -1 is Uniform, Not NoScaling Fix hasScale() when negative scale
This commit is contained in:
@@ -833,34 +833,43 @@ ScaleType Matrix4D::hasScale(double tol) const
|
||||
if (tol == 0.0)
|
||||
tol = 1e-9;
|
||||
|
||||
// check if the absolute values are proportionally close or equal
|
||||
auto closeAbs = [&](double a, double b) {
|
||||
double c = fabs(a);
|
||||
double d = fabs(b);
|
||||
if (d>c) return (d-c)/d <= tol;
|
||||
else if (c>d) return (c-d)/c <= tol;
|
||||
return true;
|
||||
};
|
||||
|
||||
// get column vectors
|
||||
double dx = Vector3d(dMtrx4D[0][0],dMtrx4D[1][0],dMtrx4D[2][0]).Sqr();
|
||||
double dy = Vector3d(dMtrx4D[0][1],dMtrx4D[1][1],dMtrx4D[2][1]).Sqr();
|
||||
double dz = Vector3d(dMtrx4D[0][2],dMtrx4D[1][2],dMtrx4D[2][2]).Sqr();
|
||||
double dx = getCol(0).Sqr();
|
||||
double dy = getCol(1).Sqr();
|
||||
double dz = getCol(2).Sqr();
|
||||
double dxyz = sqrt(dx * dy * dz);
|
||||
|
||||
// get row vectors
|
||||
double du = Vector3d(dMtrx4D[0][0],dMtrx4D[0][1],dMtrx4D[0][2]).Sqr();
|
||||
double dv = Vector3d(dMtrx4D[1][0],dMtrx4D[1][1],dMtrx4D[1][2]).Sqr();
|
||||
double dw = Vector3d(dMtrx4D[2][0],dMtrx4D[2][1],dMtrx4D[2][2]).Sqr();
|
||||
double du = getRow(0).Sqr();
|
||||
double dv = getRow(1).Sqr();
|
||||
double dw = getRow(2).Sqr();
|
||||
double duvw = sqrt(du * dv * dw);
|
||||
|
||||
double d3 = determinant3();
|
||||
|
||||
// This could be e.g. a projection, a shearing,... matrix
|
||||
if (fabs(dxyz - d3) > tol && fabs(duvw - d3) > tol) {
|
||||
if (!closeAbs(dxyz, d3) && !closeAbs(duvw, d3)) {
|
||||
return ScaleType::Other;
|
||||
}
|
||||
|
||||
if (fabs(duvw - d3) <= tol && (fabs(du - dv) > tol || fabs(dv - dw) > tol)) {
|
||||
if (closeAbs(duvw, d3) && (!closeAbs(du, dv) || !closeAbs(dv, dw))) {
|
||||
return ScaleType::NonUniformLeft;
|
||||
}
|
||||
|
||||
if (fabs(dxyz - d3) <= tol && (fabs(dx - dy) > tol || fabs(dy - dz) > tol)) {
|
||||
if (closeAbs(dxyz, d3) && (!closeAbs(dx, dy) || !closeAbs(dy, dz))) {
|
||||
return ScaleType::NonUniformRight;
|
||||
}
|
||||
|
||||
if (fabs(dx - 1.0) > tol) {
|
||||
if (fabs(d3 - 1.0) > tol) {
|
||||
return ScaleType::Uniform;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user