1 /*
2  * DQt - D bindings for the Qt Toolkit
3  *
4  * GNU Lesser General Public License Usage
5  * This file may be used under the terms of the GNU Lesser
6  * General Public License version 3 as published by the Free Software
7  * Foundation and appearing in the file LICENSE.LGPL3 included in the
8  * packaging of this file. Please review the following information to
9  * ensure the GNU Lesser General Public License version 3 requirements
10  * will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
11  */
12 module qt.gui.vector4d;
13 extern(C++):
14 
15 import qt.config;
16 import qt.helpers;
17 version(QT_NO_VECTOR2D){}else
18 version(QT_NO_VECTOR4D){}else
19     import qt.gui.vector2d;
20 version(QT_NO_VECTOR3D){}else
21 version(QT_NO_VECTOR4D){}else
22     import qt.gui.vector3d;
23 version(QT_NO_VECTOR4D){}else
24 {
25     import qt.core.namespace;
26     import qt.core.point;
27     import qt.core.typeinfo;
28     import qt.core.variant;
29 }
30 
31 version(QT_NO_VECTOR4D)
32 {
33 extern(C++, class) struct QVector4D;
34 }
35 version(QT_NO_VECTOR4D){}else
36 {
37 
38 /// Binding for C++ class [QVector4D](https://doc.qt.io/qt-6/qvector4d.html).
39 @Q_PRIMITIVE_TYPE extern(C++, class) struct QVector4D
40 {
41 public:
42     /+pragma(inline, true) this()/+ noexcept+/
43     {
44         this.v = [0.0f, 0.0f, 0.0f, 0.0f];
45     }+/
46     /+ explicit +/this(/+ Qt:: +/qt.core.namespace.Initialization)/+ noexcept+/ {}
47     pragma(inline, true) this(float xpos, float ypos, float zpos, float wpos)/+ noexcept+/
48     {
49         this.v = [xpos, ypos, zpos, wpos];
50     }
51     /+ explicit +/pragma(inline, true) this(QPoint point)/+ noexcept+/
52     {
53         this.v = [float(point.x()), float(point.y()), 0.0f, 0.0f];
54     }
55     /+ explicit +/pragma(inline, true) this(QPointF point)/+ noexcept+/
56     {
57         this.v = [float(point.x()), float(point.y()), 0.0f, 0.0f];
58     }
59 /+ #ifndef QT_NO_VECTOR2D +/
60     version(QT_NO_VECTOR2D){}else
61     {
62         /+ /+ explicit +/this(QVector2D vector)/+ noexcept+/
63         {
64             this.v = [vector[0], vector[1], 0.0f, 0.0f];
65         }
66         this(QVector2D vector, float zpos, float wpos)/+ noexcept+/
67         {
68             this.v = [vector[0], vector[1], zpos, wpos];
69         } +/
70     }
71 /+ #endif
72 #ifndef QT_NO_VECTOR3D +/
73     version(QT_NO_VECTOR3D){}else
74     {
75         /+ /+ explicit +/this(QVector3D vector)/+ noexcept+/
76         {
77             this.v = [vector[0], vector[1], vector[2], 0.0f];
78         }
79         this(QVector3D vector, float wpos)/+ noexcept+/
80         {
81             this.v = [vector[0], vector[1], vector[2], wpos];
82         } +/
83     }
84 /+ #endif +/
85 
86     pragma(inline, true) bool isNull() const/+ noexcept+/
87     {
88         import qt.core.global;
89 
90         return qIsNull(v[0]) && qIsNull(v[1]) && qIsNull(v[2]) && qIsNull(v[3]);
91     }
92 
93     pragma(inline, true) float x() const/+ noexcept+/ { return v[0]; }
94     pragma(inline, true) float y() const/+ noexcept+/ { return v[1]; }
95     pragma(inline, true) float z() const/+ noexcept+/ { return v[2]; }
96     pragma(inline, true) float w() const/+ noexcept+/ { return v[3]; }
97 
98     pragma(inline, true) void setX(float aX)/+ noexcept+/ { v[0] = aX; }
99     pragma(inline, true) void setY(float aY)/+ noexcept+/ { v[1] = aY; }
100     pragma(inline, true) void setZ(float aZ)/+ noexcept+/ { v[2] = aZ; }
101     pragma(inline, true) void setW(float aW)/+ noexcept+/ { v[3] = aW; }
102 
103     /+pragma(inline, true) ref float operator [](int i)
104     {
105         import qt.core.global;
106 
107         (mixin(Q_ASSERT(q{uint(i) < 4u})));
108         return v[i];
109     }+/
110     /+pragma(inline, true) float operator [](int i) const
111     {
112         import qt.core.global;
113 
114         (mixin(Q_ASSERT(q{uint(i) < 4u})));
115         return v[i];
116     }+/
117 
118     /+ /+ [[nodiscard]] +/ pragma(inline, true) float length() const/+ noexcept+/
119     {
120         return qHypot(v[0], v[1], v[2], v[3]);
121     }
122     /+ [[nodiscard]] +/ pragma(inline, true) float lengthSquared() const/+ noexcept+/
123     {
124         return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
125     }
126 
127     /+ [[nodiscard]] +/ pragma(inline, true) QVector4D normalized() const/+ noexcept+/
128     {
129         import qt.core.global;
130 
131         const(float) len = length();
132         return qFuzzyIsNull(len - 1.0f) ? this : qFuzzyIsNull(len) ? QVector4D()
133             : QVector4D(v[0] / len, v[1] / len, v[2] / len, v[3] / len);
134     }
135     pragma(inline, true) void normalize()/+ noexcept+/
136     {
137         import qt.core.global;
138 
139         const(float) len = length();
140         if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
141             return;
142 
143         v[0] /= len;
144         v[1] /= len;
145         v[2] /= len;
146         v[3] /= len;
147     } +/
148 
149     /+pragma(inline, true) ref QVector4D operator +=(QVector4D vector)/+ noexcept+/
150     {
151         v[0] += vector.v[0];
152         v[1] += vector.v[1];
153         v[2] += vector.v[2];
154         v[3] += vector.v[3];
155         return this;
156     }+/
157     /+pragma(inline, true) ref QVector4D operator -=(QVector4D vector)/+ noexcept+/
158     {
159         v[0] -= vector.v[0];
160         v[1] -= vector.v[1];
161         v[2] -= vector.v[2];
162         v[3] -= vector.v[3];
163         return this;
164     }+/
165     /+pragma(inline, true) ref QVector4D operator *=(float factor)/+ noexcept+/
166     {
167         v[0] *= factor;
168         v[1] *= factor;
169         v[2] *= factor;
170         v[3] *= factor;
171         return this;
172     }+/
173     /+pragma(inline, true) ref QVector4D operator *=(QVector4D vector)/+ noexcept+/
174     {
175         v[0] *= vector.v[0];
176         v[1] *= vector.v[1];
177         v[2] *= vector.v[2];
178         v[3] *= vector.v[3];
179         return this;
180     }+/
181     /+pragma(inline, true) ref QVector4D operator /=(float divisor)
182     {
183         import qt.core.global;
184 
185         (mixin(Q_ASSERT(q{divisor < 0 || divisor > 0})));
186         v[0] /= divisor;
187         v[1] /= divisor;
188         v[2] /= divisor;
189         v[3] /= divisor;
190         return this;
191     }+/
192     /+pragma(inline, true) ref QVector4D operator /=(QVector4D vector)
193     {
194         import qt.core.global;
195 
196         (mixin(Q_ASSERT(q{vector.v[0] > 0 || vector.v[0] < 0})));
197         (mixin(Q_ASSERT(q{vector.v[1] > 0 || vector.v[1] < 0})));
198         (mixin(Q_ASSERT(q{vector.v[2] > 0 || vector.v[2] < 0})));
199         (mixin(Q_ASSERT(q{vector.v[3] > 0 || vector.v[3] < 0})));
200         v[0] /= vector.v[0];
201         v[1] /= vector.v[1];
202         v[2] /= vector.v[2];
203         v[3] /= vector.v[3];
204         return this;
205     }+/
206 
207     /+ [[nodiscard]] +/ static float dotProduct(QVector4D v1, QVector4D v2)/+ noexcept+/
208     {
209         return v1.v[0] * v2.v[0] + v1.v[1] * v2.v[1] + v1.v[2] * v2.v[2] + v1.v[3] * v2.v[3];
210     }
211 
212 /+ QT_WARNING_PUSH
213 QT_WARNING_DISABLE_FLOAT_COMPARE +/
214     /+ constexpr friend inline bool operator==(QVector4D v1, QVector4D v2) noexcept
215     {
216         return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1] && v1.v[2] == v2.v[2] && v1.v[3] == v2.v[3];
217     } +/
218 
219     /+ constexpr friend inline bool operator!=(QVector4D v1, QVector4D v2) noexcept
220     {
221         return v1.v[0] != v2.v[0] || v1.v[1] != v2.v[1] || v1.v[2] != v2.v[2] || v1.v[3] != v2.v[3];
222     } +/
223 /+ QT_WARNING_POP +/
224     /+ constexpr friend inline QVector4D operator+(QVector4D v1, QVector4D v2) noexcept
225     {
226         return QVector4D(v1.v[0] + v2.v[0], v1.v[1] + v2.v[1], v1.v[2] + v2.v[2], v1.v[3] + v2.v[3]);
227     } +/
228 
229     /+ constexpr friend inline QVector4D operator-(QVector4D v1, QVector4D v2) noexcept
230     {
231         return QVector4D(v1.v[0] - v2.v[0], v1.v[1] - v2.v[1], v1.v[2] - v2.v[2], v1.v[3] - v2.v[3]);
232     } +/
233 
234     /+ constexpr friend inline QVector4D operator*(float factor, QVector4D vector) noexcept
235     {
236         return QVector4D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor, vector.v[3] * factor);
237     } +/
238 
239     /+ constexpr friend inline QVector4D operator*(QVector4D vector, float factor) noexcept
240     {
241         return QVector4D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor, vector.v[3] * factor);
242     } +/
243 
244     /+ constexpr friend inline QVector4D operator*(QVector4D v1, QVector4D v2) noexcept
245     {
246         return QVector4D(v1.v[0] * v2.v[0], v1.v[1] * v2.v[1], v1.v[2] * v2.v[2], v1.v[3] * v2.v[3]);
247     } +/
248 
249     /+ constexpr friend inline QVector4D operator-(QVector4D vector) noexcept
250     {
251         return QVector4D(-vector.v[0], -vector.v[1], -vector.v[2], -vector.v[3]);
252     } +/
253 
254     /+ constexpr friend inline QVector4D operator/(QVector4D vector, float divisor)
255     {
256         Q_ASSERT(divisor < 0 || divisor > 0);
257         return QVector4D(vector.v[0] / divisor, vector.v[1] / divisor, vector.v[2] / divisor, vector.v[3] / divisor);
258     } +/
259 
260     /+ constexpr friend inline QVector4D operator/(QVector4D vector, QVector4D divisor)
261     {
262         Q_ASSERT(divisor.v[0] > 0 || divisor.v[0] < 0);
263         Q_ASSERT(divisor.v[1] > 0 || divisor.v[1] < 0);
264         Q_ASSERT(divisor.v[2] > 0 || divisor.v[2] < 0);
265         Q_ASSERT(divisor.v[3] > 0 || divisor.v[3] < 0);
266         return QVector4D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1],
267                          vector.v[2] / divisor.v[2], vector.v[3] / divisor.v[3]);
268     } +/
269 
270     /+ friend Q_GUI_EXPORT bool qFuzzyCompare(QVector4D v1, QVector4D v2) noexcept; +/
271 
272 /+ #ifndef QT_NO_VECTOR2D +/
273     version(QT_NO_VECTOR2D){}else
274     {
275         pragma(inline, true) QVector2D toVector2D() const/+ noexcept+/
276         {
277             return QVector2D(v[0], v[1]);
278         }
279         pragma(inline, true) QVector2D toVector2DAffine() const/+ noexcept+/
280         {
281             import qt.core.global;
282 
283             if (qIsNull(v[3]))
284                 return QVector2D();
285             return QVector2D(v[0] / v[3], v[1] / v[3]);
286         }
287     }
288 /+ #endif
289 #ifndef QT_NO_VECTOR3D +/
290     version(QT_NO_VECTOR3D){}else
291     {
292         pragma(inline, true) QVector3D toVector3D() const/+ noexcept+/
293         {
294             return QVector3D(v[0], v[1], v[2]);
295         }
296         QVector3D toVector3DAffine() const/+ noexcept+/
297         {
298             import qt.core.global;
299 
300             if (qIsNull(v[3]))
301                 return QVector3D();
302             return QVector3D(v[0] / v[3], v[1] / v[3], v[2] / v[3]);
303         }
304     }
305 /+ #endif +/
306 
307     pragma(inline, true) QPoint toPoint() const/+ noexcept+/
308     {
309         import qt.core.global;
310 
311         return QPoint(qRound(v[0]), qRound(v[1]));
312     }
313     pragma(inline, true) QPointF toPointF() const/+ noexcept+/
314     {
315         import qt.core.global;
316 
317         return QPointF(qreal(v[0]), qreal(v[1]));
318     }
319 
320     /+/+ Q_GUI_EXPORT +/ auto opCast(T : QVariant)() const;+/
321 
322 private:
323     float[4] v = [0.0f, 0.0f, 0.0f, 0.0f];
324 
325     /+ friend class QVector2D; +/
326     /+ friend class QVector3D; +/
327     /+ friend class QMatrix4x4; +/
328     static if(!defined!"QT_NO_MATRIX4X4")
329     {
330         /+ friend QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix); +/
331         /+ friend QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector); +/
332     }
333 
334     /+ template <std::size_t I,
335               typename V,
336               std::enable_if_t<(I < 4), bool> = true,
337               std::enable_if_t<std::is_same_v<std::decay_t<V>, QVector4D>, bool> = true> +/
338     /+ friend constexpr decltype(auto) get(V &&vec) noexcept
339     {
340         static if (I == 0)
341             return (std::forward<V>(vec).v[0]);
342         else static if (I == 1)
343             return (std::forward<V>(vec).v[1]);
344         else static if (I == 2)
345             return (std::forward<V>(vec).v[2]);
346         else static if (I == 3)
347             return (std::forward<V>(vec).v[3]);
348     } +/
349     mixin(CREATE_CONVENIENCE_WRAPPERS);
350 }
351 }
352