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