I opened a source code of getScaling and saw how scaling is calculated there: https://glmatrix.net/docs/mat4.js.html#line1197
export function getScaling(out, mat) {
let m11 = mat[0];
let m12 = mat[1];
let m13 = mat[2];
let m21 = mat[4];
let m22 = mat[5];
let m23 = mat[6];
let m31 = mat[8];
let m32 = mat[9];
let m33 = mat[10];
out[0] = Math.hypot(m11, m12, m13);
out[1] = Math.hypot(m21, m22, m23);
out[2] = Math.hypot(m31, m32, m33);
return out;
}
I made the same with qHypot
#include <QtGui/QMatrix3x3>
#include <QtGui/QMatrix4x4>
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QQuaternion>
#include <QtMath>
#include <QtOpenGL/QOpenGLWindow>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
class OpenGLWindow : public QOpenGLWindow, private QOpenGLFunctions
{
public:
OpenGLWindow()
{
setTitle("OpenGL ES 2.0, Qt6, C++");
resize(350, 350);
QMatrix4x4 matrix;
matrix.translate(20.f, 80.f, 0.f);
matrix.rotate(-90.f, QVector3D(0.f, 0.f, 1.f));
matrix.scale(20.f, 20.f);
qDebug() << "Transformation matrix: " << matrix;
// Output: 0, 20, 0, 20,
// -20, 0, 0, 80,
// 0, 0, 1, 0,
// 0, 0, 0, 1
// "QMatrix4x4" has a row-major order
// Get scaling
float sx = qHypot(matrix.row(0)[0], matrix.row(1)[0], matrix.row(2)[0]);
float sy = qHypot(matrix.row(0)[1], matrix.row(1)[1], matrix.row(2)[1]);
float sz = qHypot(matrix.row(0)[2], matrix.row(1)[2], matrix.row(2)[2]);
QVector3D scaling(sx, sy, sz);
qDebug() << "Scaling:" << scaling;
// Output: QVector3D(20, 20, 1)
// Get rotation
QMatrix3x3 rotationMatrix;
rotationMatrix.data()[0] = matrix.column(0)[0] / sx;
rotationMatrix.data()[1] = matrix.column(0)[1] / sy;
rotationMatrix.data()[2] = matrix.column(0)[2] / sz;
rotationMatrix.data()[3] = matrix.column(1)[0] / sx;
rotationMatrix.data()[4] = matrix.column(1)[1] / sy;
rotationMatrix.data()[5] = matrix.column(1)[2] / sz;
rotationMatrix.data()[6] = matrix.column(2)[0] / sx;
rotationMatrix.data()[7] = matrix.column(2)[1] / sy;
rotationMatrix.data()[8] = matrix.column(2)[2] / sz;
QQuaternion rotation = QQuaternion::fromRotationMatrix(rotationMatrix);
qDebug() << "Rotation:" << rotation;
// Output: QQuaternion(scalar:0.707107, vector:(0, 0, -0.707107))
// Get translation
float tx = matrix.row(0)[3];
float ty = matrix.row(1)[3];
float tz = matrix.row(2)[3];
QVector3D translation(tx, ty, tz);
qDebug() << "Translation:" << translation;
// Output: QVector3D(20, 80, 0)
}
void initializeGL() override
{
initializeOpenGLFunctions();
glClearColor(0.2f, 0.2f, 0.2f, 1.f);
}
void paintGL() override
{
glClear(GL_COLOR_BUFFER_BIT);
}
};
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
QApplication app(argc, argv);
OpenGLWindow w;
w.show();
return app.exec();
}
QT += core gui opengl widgets
win32: LIBS += -lopengl32
CONFIG += c++17
SOURCES += \
main.cpp
P.S. The QMatrix4x4 constructor uses row-major order. The glMatrix fromValues method uses column-major order.