Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qssgutils.cpp
Go to the documentation of this file.
1// Copyright (C) 2008-2012 NVIDIA Corporation.
2// Copyright (C) 2019 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6
7#include "qssgutils_p.h"
8
9#include <QtCore/QDir>
10
11#include <cmath>
12
13QT_BEGIN_NAMESPACE
14
15float QSSGUtils::vec2::magnitude(const QVector2D &v)
16{
17 return ::sqrtf(v.x() * v.x() + v.y() * v.y());
18}
19
20bool QSSGUtils::vec3::isFinite(const QVector3D &v)
21{
22 return qIsFinite(v.x()) && qIsFinite(v.y()) && qIsFinite(v.z());
23}
24
25float QSSGUtils::vec3::magnitude(const QVector3D &v)
26{
27 return sqrtf(v.x() * v.x() + v.y() * v.y() + v.z() * v.z());
28}
29
30float QSSGUtils::vec3::magnitudeSquared(const QVector3D &v)
31{
32 return v.x() * v.x() + v.y() * v.y() + v.z() * v.z();
33}
34
35// This special normalize function normalizes a vector in place
36// and returns the magnnitude (needed for compatiblity)
37float QSSGUtils::vec3::normalize(QVector3D &v)
38{
39 const float m = QSSGUtils::vec3::magnitude(v);
40 if (m > 0)
41 v /= m;
42 return m;
43}
44
45QVector3D QSSGUtils::mat33::transform(const QMatrix3x3 &m, const QVector3D &v)
46{
47 const QVector3D c0 = QVector3D(m(0, 0), m(1, 0), m(2, 0));
48 const QVector3D c1 = QVector3D(m(0, 1), m(1, 1), m(2, 1));
49 const QVector3D c2 = QVector3D(m(0, 2), m(1, 2), m(2, 2));
50 return c0 * v.x() + c1 * v.y() + c2 * v.z();
51}
52
53QMatrix3x3 QSSGUtils::mat44::getUpper3x3(const QMatrix4x4 &m)
54{
55 const float values[9] = { m(0, 0), m(0, 1), m(0, 2), m(1, 0), m(1, 1), m(1, 2), m(2, 0), m(2, 1), m(2, 2) };
56 return QMatrix3x3(values);
57}
58
59void QSSGUtils::mat44::normalize(QMatrix4x4 &m)
60{
61 QVector4D c0 = m.column(0);
62 QVector4D c1 = m.column(1);
63 QVector4D c2 = m.column(2);
64 QVector4D c3 = m.column(3);
65
66 c0.normalize();
67 c1.normalize();
68 c2.normalize();
69 c3.normalize();
70
71 m.setColumn(0, c0);
72 m.setColumn(1, c1);
73 m.setColumn(2, c2);
74 m.setColumn(3, c3);
75}
76
77QVector3D QSSGUtils::mat44::rotate(const QMatrix4x4 &m, const QVector3D &v)
78{
79 const QVector4D tmp = QSSGUtils::mat44::rotate(m, QVector4D(v.x(), v.y(), v.z(), 1.0f));
80 return QVector3D(tmp.x(), tmp.y(), tmp.z());
81}
82
83QVector4D QSSGUtils::mat44::rotate(const QMatrix4x4 &m, const QVector4D &v)
84{
85 return m.column(0) * v.x() + m.column(1) * v.y() + m.column(2) * v.z();
86}
87
88QVector3D QSSGUtils::mat44::transform(const QMatrix4x4 &m, const QVector3D &v)
89{
90 const QVector4D tmp = QSSGUtils::mat44::transform(m, QVector4D(v.x(), v.y(), v.z(), 1.0f));
91 return QVector3D(tmp.x(), tmp.y(), tmp.z());
92}
93
94QVector4D QSSGUtils::mat44::transform(const QMatrix4x4 &m, const QVector4D &v)
95{
96 return m.column(0) * v.x() + m.column(1) * v.y() + m.column(2) * v.z() + m.column(3) * v.w();
97}
98
99QVector3D QSSGUtils::mat44::getPosition(const QMatrix4x4 &m)
100{
101 return QVector3D(m(0, 3), m(1, 3), m(2, 3));
102}
103
104QVector3D QSSGUtils::mat44::getScale(const QMatrix4x4 &m)
105{
106 const float scaleX = m.column(0).length();
107 const float scaleY = m.column(1).length();
108 const float scaleZ = m.column(2).length();
109 return QVector3D(scaleX, scaleY, scaleZ);
110}
111
112bool QSSGUtils::quat::isFinite(const QQuaternion &q)
113{
114 return qIsFinite(q.x()) && qIsFinite(q.y()) && qIsFinite(q.z()) && qIsFinite(q.scalar());
115}
116
117float QSSGUtils::quat::magnitude(const QQuaternion &q)
118{
119 return std::sqrt(q.x() * q.x() + q.y() * q.y() + q.z() * q.z() + q.scalar() * q.scalar());
120}
121
122bool QSSGUtils::quat::isSane(const QQuaternion &q)
123{
124 const float unitTolerance = float(1e-2);
125 return isFinite(q) && qAbs(magnitude(q) - 1) < unitTolerance;
126}
127
128bool QSSGUtils::quat::isUnit(const QQuaternion &q)
129{
130 const float unitTolerance = float(1e-4);
131 return isFinite(q) && qAbs(magnitude(q) - 1) < unitTolerance;
132}
133
134QVector3D QSSGUtils::quat::rotated(const QQuaternion &q, const QVector3D &v)
135{
136 const float vx = 2.0f * v.x();
137 const float vy = 2.0f * v.y();
138 const float vz = 2.0f * v.z();
139 const float w2 = q.scalar() * q.scalar() - 0.5f;
140 const float dot2 = (q.x() * vx + q.y() * vy + q.z() * vz);
141 return QVector3D((vx * w2 + (q.y() * vz - q.z() * vy) * q.scalar() + q.x() * dot2),
142 (vy * w2 + (q.z() * vx - q.x() * vz) * q.scalar() + q.y() * dot2),
143 (vz * w2 + (q.x() * vy - q.y() * vx) * q.scalar() + q.z() * dot2));
144}
145
146QVector3D QSSGUtils::quat::inverseRotated(const QQuaternion &q, const QVector3D &v)
147{
148 const float vx = 2.0f * v.x();
149 const float vy = 2.0f * v.y();
150 const float vz = 2.0f * v.z();
151 const float w2 = q.scalar() * q.scalar() - 0.5f;
152 const float dot2 = (q.x() * vx + q.y() * vy + q.z() * vz);
153 return QVector3D((vx * w2 - (q.y() * vz - q.z() * vy) * q.scalar() + q.x() * dot2),
154 (vy * w2 - (q.z() * vx - q.x() * vz) * q.scalar() + q.y() * dot2),
155 (vz * w2 - (q.x() * vy - q.y() * vx) * q.scalar() + q.z() * dot2));
156}
157
158const char *nonNull(const char *src)
159{
160 return src == nullptr ? "" : src;
161}
162
163QColor QSSGUtils::color::linearTosRGB(const QVector4D &linearColorFactor)
164{
165 const QVector3D S1 = QVector3D(::sqrtf(linearColorFactor.x()), ::sqrtf(linearColorFactor.y()), ::sqrtf(linearColorFactor.z()));
166 const QVector3D S2 = QVector3D(::sqrtf(S1.x()), ::sqrtf(S1.y()), ::sqrtf(S1.z()));
167 const QVector3D S3 = QVector3D(::sqrtf(S2.x()), ::sqrtf(S2.y()), ::sqrtf(S2.z()));
168 const QVector3D result(0.585122381f * S1 + 0.783140355f * S2 - 0.368262736f * S3);
169 return QColor::fromRgbF(result.x(), result.y(), result.z(), linearColorFactor.w());
170}
171
172QVector4D QSSGUtils::color::sRGBToLinear(const QColor &color)
173{
174 const QVector3D rgb(color.redF(), color.greenF(), color.blueF());
175 const float C1 = 0.305306011f;
176 const QVector3D C2(0.682171111f, 0.682171111f, 0.682171111f);
177 const QVector3D C3(0.012522878f, 0.012522878f, 0.012522878f);
178 return QVector4D(rgb * (rgb * (rgb * C1 + C2) + C3), color.alphaF());
179}
180
181QColor QSSGUtils::color::sRGBToLinearColor(const QColor &color)
182{
183 const QVector4D c = sRGBToLinear(color);
184 return QColor::fromRgbF(c.x(), c.y(), c.z(), c.w());
185}
186
187bool QSSGUtils::mat44::decompose(const QMatrix4x4 &transform, QVector3D &position, QVector3D &scale, QQuaternion &rotation)
188{
189 QMatrix4x4 m { transform };
190 QSSGUtils::mat44::normalize(m);
191
192 rotation = QQuaternion::fromRotationMatrix(QSSGUtils::mat44::getUpper3x3(m)).normalized();
193 scale = QSSGUtils::mat44::getScale(transform);
194 position = QSSGUtils::mat44::getPosition(transform);
195
196 const auto det = m.determinant();
197
198 return !qFuzzyIsNull(det);
199}
200
201QT_END_NAMESPACE
const char * nonNull(const char *src)