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 | |
5 | #include "qssgutils_p.h" |
6 | |
7 | #include <QtCore/QDir> |
8 | |
9 | #include <cmath> |
10 | |
11 | QT_BEGIN_NAMESPACE |
12 | |
13 | float QSSGUtils::vec2::magnitude(const QVector2D &v) |
14 | { |
15 | return ::sqrtf(x: v.x() * v.x() + v.y() * v.y()); |
16 | } |
17 | |
18 | bool QSSGUtils::vec3::isFinite(const QVector3D &v) |
19 | { |
20 | return qIsFinite(f: v.x()) && qIsFinite(f: v.y()) && qIsFinite(f: v.z()); |
21 | } |
22 | |
23 | float QSSGUtils::vec3::magnitude(const QVector3D &v) |
24 | { |
25 | return sqrtf(x: v.x() * v.x() + v.y() * v.y() + v.z() * v.z()); |
26 | } |
27 | |
28 | float QSSGUtils::vec3::magnitudeSquared(const QVector3D &v) |
29 | { |
30 | return v.x() * v.x() + v.y() * v.y() + v.z() * v.z(); |
31 | } |
32 | |
33 | // This special normalize function normalizes a vector in place |
34 | // and returns the magnnitude (needed for compatiblity) |
35 | float QSSGUtils::vec3::normalize(QVector3D &v) |
36 | { |
37 | const float m = QSSGUtils::vec3::magnitude(v); |
38 | if (m > 0) |
39 | v /= m; |
40 | return m; |
41 | } |
42 | |
43 | QVector3D QSSGUtils::mat33::transform(const QMatrix3x3 &m, const QVector3D &v) |
44 | { |
45 | const QVector3D c0 = QVector3D(m(0, 0), m(1, 0), m(2, 0)); |
46 | const QVector3D c1 = QVector3D(m(0, 1), m(1, 1), m(2, 1)); |
47 | const QVector3D c2 = QVector3D(m(0, 2), m(1, 2), m(2, 2)); |
48 | return c0 * v.x() + c1 * v.y() + c2 * v.z(); |
49 | } |
50 | |
51 | QMatrix3x3 QSSGUtils::mat44::getUpper3x3(const QMatrix4x4 &m) |
52 | { |
53 | 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) }; |
54 | return QMatrix3x3(values); |
55 | } |
56 | |
57 | void QSSGUtils::mat44::normalize(QMatrix4x4 &m) |
58 | { |
59 | QVector4D c0 = m.column(index: 0); |
60 | QVector4D c1 = m.column(index: 1); |
61 | QVector4D c2 = m.column(index: 2); |
62 | QVector4D c3 = m.column(index: 3); |
63 | |
64 | c0.normalize(); |
65 | c1.normalize(); |
66 | c2.normalize(); |
67 | c3.normalize(); |
68 | |
69 | m.setColumn(index: 0, value: c0); |
70 | m.setColumn(index: 1, value: c1); |
71 | m.setColumn(index: 2, value: c2); |
72 | m.setColumn(index: 3, value: c3); |
73 | } |
74 | |
75 | QVector3D QSSGUtils::mat44::rotate(const QMatrix4x4 &m, const QVector3D &v) |
76 | { |
77 | const QVector4D tmp = QSSGUtils::mat44::rotate(m, v: QVector4D(v.x(), v.y(), v.z(), 1.0f)); |
78 | return QVector3D(tmp.x(), tmp.y(), tmp.z()); |
79 | } |
80 | |
81 | QVector4D QSSGUtils::mat44::rotate(const QMatrix4x4 &m, const QVector4D &v) |
82 | { |
83 | return m.column(index: 0) * v.x() + m.column(index: 1) * v.y() + m.column(index: 2) * v.z(); |
84 | } |
85 | |
86 | QVector3D QSSGUtils::mat44::transform(const QMatrix4x4 &m, const QVector3D &v) |
87 | { |
88 | const QVector4D tmp = QSSGUtils::mat44::transform(m, v: QVector4D(v.x(), v.y(), v.z(), 1.0f)); |
89 | return QVector3D(tmp.x(), tmp.y(), tmp.z()); |
90 | } |
91 | |
92 | QVector4D QSSGUtils::mat44::transform(const QMatrix4x4 &m, const QVector4D &v) |
93 | { |
94 | return m.column(index: 0) * v.x() + m.column(index: 1) * v.y() + m.column(index: 2) * v.z() + m.column(index: 3) * v.w(); |
95 | } |
96 | |
97 | QVector3D QSSGUtils::mat44::getPosition(const QMatrix4x4 &m) |
98 | { |
99 | return QVector3D(m(0, 3), m(1, 3), m(2, 3)); |
100 | } |
101 | |
102 | QVector3D QSSGUtils::mat44::getScale(const QMatrix4x4 &m) |
103 | { |
104 | const float scaleX = m.column(index: 0).length(); |
105 | const float scaleY = m.column(index: 1).length(); |
106 | const float scaleZ = m.column(index: 2).length(); |
107 | return QVector3D(scaleX, scaleY, scaleZ); |
108 | } |
109 | |
110 | bool QSSGUtils::quat::isFinite(const QQuaternion &q) |
111 | { |
112 | return qIsFinite(f: q.x()) && qIsFinite(f: q.y()) && qIsFinite(f: q.z()) && qIsFinite(f: q.scalar()); |
113 | } |
114 | |
115 | float QSSGUtils::quat::magnitude(const QQuaternion &q) |
116 | { |
117 | return std::sqrt(x: q.x() * q.x() + q.y() * q.y() + q.z() * q.z() + q.scalar() * q.scalar()); |
118 | } |
119 | |
120 | bool QSSGUtils::quat::isSane(const QQuaternion &q) |
121 | { |
122 | const float unitTolerance = float(1e-2); |
123 | return isFinite(q) && qAbs(t: magnitude(q) - 1) < unitTolerance; |
124 | } |
125 | |
126 | bool QSSGUtils::quat::isUnit(const QQuaternion &q) |
127 | { |
128 | const float unitTolerance = float(1e-4); |
129 | return isFinite(q) && qAbs(t: magnitude(q) - 1) < unitTolerance; |
130 | } |
131 | |
132 | QVector3D QSSGUtils::quat::rotated(const QQuaternion &q, const QVector3D &v) |
133 | { |
134 | const float vx = 2.0f * v.x(); |
135 | const float vy = 2.0f * v.y(); |
136 | const float vz = 2.0f * v.z(); |
137 | const float w2 = q.scalar() * q.scalar() - 0.5f; |
138 | const float dot2 = (q.x() * vx + q.y() * vy + q.z() * vz); |
139 | return QVector3D((vx * w2 + (q.y() * vz - q.z() * vy) * q.scalar() + q.x() * dot2), |
140 | (vy * w2 + (q.z() * vx - q.x() * vz) * q.scalar() + q.y() * dot2), |
141 | (vz * w2 + (q.x() * vy - q.y() * vx) * q.scalar() + q.z() * dot2)); |
142 | } |
143 | |
144 | QVector3D QSSGUtils::quat::inverseRotated(const QQuaternion &q, const QVector3D &v) |
145 | { |
146 | const float vx = 2.0f * v.x(); |
147 | const float vy = 2.0f * v.y(); |
148 | const float vz = 2.0f * v.z(); |
149 | const float w2 = q.scalar() * q.scalar() - 0.5f; |
150 | const float dot2 = (q.x() * vx + q.y() * vy + q.z() * vz); |
151 | return QVector3D((vx * w2 - (q.y() * vz - q.z() * vy) * q.scalar() + q.x() * dot2), |
152 | (vy * w2 - (q.z() * vx - q.x() * vz) * q.scalar() + q.y() * dot2), |
153 | (vz * w2 - (q.x() * vy - q.y() * vx) * q.scalar() + q.z() * dot2)); |
154 | } |
155 | |
156 | const char *nonNull(const char *src) |
157 | { |
158 | return src == nullptr ? "" : src; |
159 | } |
160 | |
161 | QVector4D QSSGUtils::color::sRGBToLinear(const QColor &color) |
162 | { |
163 | const QVector3D rgb(color.redF(), color.greenF(), color.blueF()); |
164 | const float C1 = 0.305306011f; |
165 | const QVector3D C2(0.682171111f, 0.682171111f, 0.682171111f); |
166 | const QVector3D C3(0.012522878f, 0.012522878f, 0.012522878f); |
167 | return QVector4D(rgb * (rgb * (rgb * C1 + C2) + C3), color.alphaF()); |
168 | } |
169 | |
170 | QColor QSSGUtils::color::sRGBToLinearColor(const QColor &color) |
171 | { |
172 | const QVector4D c = sRGBToLinear(color); |
173 | return QColor::fromRgbF(r: c.x(), g: c.y(), b: c.z(), a: c.w()); |
174 | } |
175 | |
176 | QT_END_NAMESPACE |
177 | |
178 | |