1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QVECTOR3D_H
41#define QVECTOR3D_H
42
43#include <QtGui/qtguiglobal.h>
44#include <QtCore/qpoint.h>
45#include <QtCore/qmetatype.h>
46
47QT_BEGIN_NAMESPACE
48
49
50class QMatrix4x4;
51class QVector2D;
52class QVector4D;
53class QRect;
54
55#ifndef QT_NO_VECTOR3D
56
57class Q_GUI_EXPORT QVector3D
58{
59public:
60 constexpr QVector3D();
61 explicit QVector3D(Qt::Initialization) {}
62 constexpr QVector3D(float xpos, float ypos, float zpos) : v{xpos, ypos, zpos} {}
63
64 constexpr explicit QVector3D(const QPoint& point);
65 constexpr explicit QVector3D(const QPointF& point);
66#ifndef QT_NO_VECTOR2D
67 QVector3D(const QVector2D& vector);
68 QVector3D(const QVector2D& vector, float zpos);
69#endif
70#ifndef QT_NO_VECTOR4D
71 explicit QVector3D(const QVector4D& vector);
72#endif
73
74 bool isNull() const;
75
76 constexpr float x() const;
77 constexpr float y() const;
78 constexpr float z() const;
79
80 void setX(float x);
81 void setY(float y);
82 void setZ(float z);
83
84 float &operator[](int i);
85 float operator[](int i) const;
86
87 float length() const;
88 float lengthSquared() const;
89
90 QVector3D normalized() const;
91 void normalize();
92
93 QVector3D &operator+=(const QVector3D &vector);
94 QVector3D &operator-=(const QVector3D &vector);
95 QVector3D &operator*=(float factor);
96 QVector3D &operator*=(const QVector3D& vector);
97 QVector3D &operator/=(float divisor);
98 inline QVector3D &operator/=(const QVector3D &vector);
99
100 static float dotProduct(const QVector3D& v1, const QVector3D& v2); //In Qt 6 convert to inline and constexpr
101 static QVector3D crossProduct(const QVector3D& v1, const QVector3D& v2); //in Qt 6 convert to inline and constexpr
102
103 static QVector3D normal(const QVector3D& v1, const QVector3D& v2);
104 static QVector3D normal
105 (const QVector3D& v1, const QVector3D& v2, const QVector3D& v3);
106
107 QVector3D project(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport) const;
108 QVector3D unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport) const;
109
110 float distanceToPoint(const QVector3D& point) const;
111 float distanceToPlane(const QVector3D& plane, const QVector3D& normal) const;
112 float distanceToPlane(const QVector3D& plane1, const QVector3D& plane2, const QVector3D& plane3) const;
113 float distanceToLine(const QVector3D& point, const QVector3D& direction) const;
114
115 constexpr friend inline bool operator==(const QVector3D &v1, const QVector3D &v2);
116 constexpr friend inline bool operator!=(const QVector3D &v1, const QVector3D &v2);
117 constexpr friend inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2);
118 constexpr friend inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2);
119 constexpr friend inline const QVector3D operator*(float factor, const QVector3D &vector);
120 constexpr friend inline const QVector3D operator*(const QVector3D &vector, float factor);
121 constexpr friend const QVector3D operator*(const QVector3D &v1, const QVector3D& v2);
122 constexpr friend inline const QVector3D operator-(const QVector3D &vector);
123 constexpr friend inline const QVector3D operator/(const QVector3D &vector, float divisor);
124 constexpr friend inline const QVector3D operator/(const QVector3D &vector, const QVector3D &divisor);
125
126 constexpr friend inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2);
127
128#ifndef QT_NO_VECTOR2D
129 QVector2D toVector2D() const;
130#endif
131#ifndef QT_NO_VECTOR4D
132 QVector4D toVector4D() const;
133#endif
134
135 constexpr QPoint toPoint() const;
136 constexpr QPointF toPointF() const;
137
138 operator QVariant() const;
139
140private:
141 float v[3];
142
143 friend class QVector2D;
144 friend class QVector4D;
145#ifndef QT_NO_MATRIX4X4
146 friend QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix);
147 friend QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector);
148#endif
149};
150
151Q_DECLARE_TYPEINFO(QVector3D, Q_PRIMITIVE_TYPE);
152
153constexpr inline QVector3D::QVector3D() : v{0.0f, 0.0f, 0.0f} {}
154
155constexpr inline QVector3D::QVector3D(const QPoint& point) : v{float(point.x()), float(point.y()), float(0.0f)} {}
156
157constexpr inline QVector3D::QVector3D(const QPointF& point) : v{float(point.x()), float(point.y()), 0.0f} {}
158
159inline bool QVector3D::isNull() const
160{
161 return qIsNull(v[0]) && qIsNull(v[1]) && qIsNull(v[2]);
162}
163
164constexpr inline float QVector3D::x() const { return v[0]; }
165constexpr inline float QVector3D::y() const { return v[1]; }
166constexpr inline float QVector3D::z() const { return v[2]; }
167
168inline void QVector3D::setX(float aX) { v[0] = aX; }
169inline void QVector3D::setY(float aY) { v[1] = aY; }
170inline void QVector3D::setZ(float aZ) { v[2] = aZ; }
171
172inline float &QVector3D::operator[](int i)
173{
174 Q_ASSERT(uint(i) < 3u);
175 return v[i];
176}
177
178inline float QVector3D::operator[](int i) const
179{
180 Q_ASSERT(uint(i) < 3u);
181 return v[i];
182}
183
184inline QVector3D &QVector3D::operator+=(const QVector3D &vector)
185{
186 v[0] += vector.v[0];
187 v[1] += vector.v[1];
188 v[2] += vector.v[2];
189 return *this;
190}
191
192inline QVector3D &QVector3D::operator-=(const QVector3D &vector)
193{
194 v[0] -= vector.v[0];
195 v[1] -= vector.v[1];
196 v[2] -= vector.v[2];
197 return *this;
198}
199
200inline QVector3D &QVector3D::operator*=(float factor)
201{
202 v[0] *= factor;
203 v[1] *= factor;
204 v[2] *= factor;
205 return *this;
206}
207
208inline QVector3D &QVector3D::operator*=(const QVector3D& vector)
209{
210 v[0] *= vector.v[0];
211 v[1] *= vector.v[1];
212 v[2] *= vector.v[2];
213 return *this;
214}
215
216inline QVector3D &QVector3D::operator/=(float divisor)
217{
218 v[0] /= divisor;
219 v[1] /= divisor;
220 v[2] /= divisor;
221 return *this;
222}
223
224inline QVector3D &QVector3D::operator/=(const QVector3D &vector)
225{
226 v[0] /= vector.v[0];
227 v[1] /= vector.v[1];
228 v[2] /= vector.v[2];
229 return *this;
230}
231
232QT_WARNING_PUSH
233QT_WARNING_DISABLE_FLOAT_COMPARE
234
235constexpr inline bool operator==(const QVector3D &v1, const QVector3D &v2)
236{
237 return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1] && v1.v[2] == v2.v[2];
238}
239
240constexpr inline bool operator!=(const QVector3D &v1, const QVector3D &v2)
241{
242 return v1.v[0] != v2.v[0] || v1.v[1] != v2.v[1] || v1.v[2] != v2.v[2];
243}
244QT_WARNING_POP
245
246constexpr inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2)
247{
248 return QVector3D(v1.v[0] + v2.v[0], v1.v[1] + v2.v[1], v1.v[2] + v2.v[2]);
249}
250
251constexpr inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2)
252{
253 return QVector3D(v1.v[0] - v2.v[0], v1.v[1] - v2.v[1], v1.v[2] - v2.v[2]);
254}
255
256constexpr inline const QVector3D operator*(float factor, const QVector3D &vector)
257{
258 return QVector3D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor);
259}
260
261constexpr inline const QVector3D operator*(const QVector3D &vector, float factor)
262{
263 return QVector3D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor);
264}
265
266constexpr inline const QVector3D operator*(const QVector3D &v1, const QVector3D& v2)
267{
268 return QVector3D(v1.v[0] * v2.v[0], v1.v[1] * v2.v[1], v1.v[2] * v2.v[2]);
269}
270
271constexpr inline const QVector3D operator-(const QVector3D &vector)
272{
273 return QVector3D(-vector.v[0], -vector.v[1], -vector.v[2]);
274}
275
276constexpr inline const QVector3D operator/(const QVector3D &vector, float divisor)
277{
278 return QVector3D(vector.v[0] / divisor, vector.v[1] / divisor, vector.v[2] / divisor);
279}
280
281constexpr inline const QVector3D operator/(const QVector3D &vector, const QVector3D &divisor)
282{
283 return QVector3D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1], vector.v[2] / divisor.v[2]);
284}
285
286constexpr inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2)
287{
288 return qFuzzyCompare(v1.v[0], v2.v[0]) &&
289 qFuzzyCompare(v1.v[1], v2.v[1]) &&
290 qFuzzyCompare(v1.v[2], v2.v[2]);
291}
292
293constexpr inline QPoint QVector3D::toPoint() const
294{
295 return QPoint(qRound(v[0]), qRound(v[1]));
296}
297
298constexpr inline QPointF QVector3D::toPointF() const
299{
300 return QPointF(qreal(v[0]), qreal(v[1]));
301}
302
303#ifndef QT_NO_DEBUG_STREAM
304Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QVector3D &vector);
305#endif
306
307#ifndef QT_NO_DATASTREAM
308Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QVector3D &);
309Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QVector3D &);
310#endif
311
312#endif
313
314QT_END_NAMESPACE
315
316#endif
317