1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquick3dparticleshapedatautils_p.h"
5#include <QtCore/QRect>
6#include <QtGui/QVector2D>
7#include <QtGui/QVector3D>
8#include <QtGui/QVector4D>
9#include <QtGui/QQuaternion>
10#include <QtGui/QColor>
11
12QT_BEGIN_NAMESPACE
13
14// This file contains useful methods to read & write shape
15// CBOR binary files and understand the format.
16
17// Read property 'type' value from CBOR and return it as QVariant.
18QVariant QQuick3DParticleShapeDataUtils::readValue(QCborStreamReader &reader, QMetaType::Type type)
19{
20 switch (type) {
21 case QMetaType::Bool: {
22 bool b = reader.toBool();
23 reader.next();
24 return QVariant(b);
25 }
26 case QMetaType::Int: {
27 int i = reader.toInteger();
28 reader.next();
29 return QVariant(i);
30 }
31 case QMetaType::Float: {
32 float f = reader.toFloat();
33 reader.next();
34 return QVariant(f);
35 }
36 case QMetaType::Double: {
37 double d = reader.toDouble();
38 reader.next();
39 return QVariant(d);
40 }
41 case QMetaType::QString: {
42 QString s = reader.readString().data;
43 return QVariant(s);
44 }
45 case QMetaType::QVector2D: {
46 QVector2D v;
47 v.setX(reader.toFloat());
48 reader.next();
49 v.setY(reader.toFloat());
50 reader.next();
51 return QVariant(v);
52 }
53 case QMetaType::QVector3D: {
54 QVector3D v;
55 v.setX(reader.toFloat());
56 reader.next();
57 v.setY(reader.toFloat());
58 reader.next();
59 v.setZ(reader.toFloat());
60 reader.next();
61 return QVariant(v);
62 }
63 case QMetaType::QVector4D: {
64 QVector4D v;
65 v.setX(reader.toFloat());
66 reader.next();
67 v.setY(reader.toFloat());
68 reader.next();
69 v.setZ(reader.toFloat());
70 reader.next();
71 v.setW(reader.toFloat());
72 reader.next();
73 return QVariant(v);
74 }
75 case QMetaType::QQuaternion: {
76 QQuaternion q;
77 q.setScalar(reader.toFloat());
78 reader.next();
79 q.setX(reader.toFloat());
80 reader.next();
81 q.setY(reader.toFloat());
82 reader.next();
83 q.setZ(reader.toFloat());
84 reader.next();
85 return QVariant(q);
86 }
87 case QMetaType::QColor: {
88 QColor c;
89 c.setRed(reader.toInteger());
90 reader.next();
91 c.setGreen(reader.toInteger());
92 reader.next();
93 c.setBlue(reader.toInteger());
94 reader.next();
95 c.setAlpha(reader.toInteger());
96 reader.next();
97 return QVariant(c);
98 }
99 case QMetaType::QRect: {
100 QRect r;
101 r.setX(reader.toInteger());
102 reader.next();
103 r.setY(reader.toInteger());
104 reader.next();
105 r.setWidth(reader.toInteger());
106 reader.next();
107 r.setHeight(reader.toInteger());
108 reader.next();
109 return QVariant(r);
110 }
111 default: {
112 qWarning() << "Property type not handled:" << type;
113 }
114 }
115
116 return QVariant();
117}
118
119// Read a string from CBOR.
120QString QQuick3DParticleShapeDataUtils::readString(QCborStreamReader &reader)
121{
122 QString result;
123 auto r = reader.readString();
124 while (r.status == QCborStreamReader::Ok) {
125 result += r.data;
126 r = reader.readString();
127 }
128
129 if (r.status == QCborStreamReader::Error) {
130 // handle error condition
131 result.clear();
132 }
133 return result;
134}
135
136// Read a real (double or float) from CBOR.
137double QQuick3DParticleShapeDataUtils::readReal(QCborStreamReader &reader)
138{
139 double result = 0.0;
140 if (reader.isDouble()) {
141 result = reader.toDouble();
142 reader.next();
143 } else if (reader.isFloat()) {
144 result = reader.toFloat();
145 reader.next();
146 }
147 return result;
148}
149
150// Read shape file header and return the version.
151// If header is not valid, -1 is returned.
152int QQuick3DParticleShapeDataUtils::readShapeHeader(QCborStreamReader &reader)
153{
154 int version = -1;
155 if (reader.lastError() == QCborError::NoError && reader.isArray()) {
156 // Start root array
157 reader.enterContainer();
158 if (reader.isString()) {
159 QString header = readString(reader);
160 if (header == QStringLiteral("QQ3D_SHAPE")) {
161 if (reader.isInteger()) {
162 version = reader.toInteger();
163 reader.next();
164 } else {
165 qWarning() << "Invalid shape version";
166 }
167 } else {
168 qWarning() << "Invalid shape header";
169 }
170 } else {
171 qWarning() << "Invalid shape container";
172 }
173 }
174 return version;
175}
176
177#if QT_CONFIG(cborstreamwriter)
178void QQuick3DParticleShapeDataUtils::writeShapeHeader(QCborStreamWriter &writer, int version)
179{
180 // Root array
181 writer.startArray();
182 // header name
183 writer.append(str: "QQ3D_SHAPE");
184 // file version
185 writer.append(i: version);
186}
187
188// Write QVariant value into CBOR in correct type.
189void QQuick3DParticleShapeDataUtils::writeValue(QCborStreamWriter &writer, const QVariant &value)
190{
191 const QMetaType type = value.metaType();
192 switch (type.id()) {
193 case QMetaType::Bool: {
194 bool b = value.toBool();
195 writer.append(b);
196 break;
197 }
198 case QMetaType::Int: {
199 int i = value.toInt();
200 writer.append(i);
201 break;
202 }
203 case QMetaType::Float: {
204 float f = value.toFloat();
205 writer.append(f);
206 break;
207 }
208 case QMetaType::Double: {
209 double d = value.toDouble();
210 writer.append(d);
211 break;
212 }
213 case QMetaType::QVector2D: {
214 QVector2D v = value.value<QVector2D>();
215 writer.append(f: v.x());
216 writer.append(f: v.y());
217 break;
218 }
219 case QMetaType::QVector3D: {
220 QVector3D v = value.value<QVector3D>();
221 writer.append(f: v.x());
222 writer.append(f: v.y());
223 writer.append(f: v.z());
224 break;
225 }
226 case QMetaType::QVector4D: {
227 QVector4D v = value.value<QVector4D>();
228 writer.append(f: v.x());
229 writer.append(f: v.y());
230 writer.append(f: v.z());
231 writer.append(f: v.w());
232 break;
233 }
234 case QMetaType::QQuaternion: {
235 QQuaternion q = value.value<QQuaternion>();
236 writer.append(f: q.scalar());
237 writer.append(f: q.x());
238 writer.append(f: q.y());
239 writer.append(f: q.z());
240 break;
241 }
242 case QMetaType::QColor: {
243 QColor c = value.value<QColor>();
244 writer.append(i: c.red());
245 writer.append(i: c.green());
246 writer.append(i: c.blue());
247 writer.append(i: c.alpha());
248 break;
249 }
250 case QMetaType::QRect: {
251 QRect r = value.value<QRect>();
252 writer.append(i: r.x());
253 writer.append(i: r.y());
254 writer.append(i: r.width());
255 writer.append(i: r.height());
256 break;
257 }
258 default: {
259 qDebug() << "Not able to add:" << value << "of type:" << type.name();
260 qDebug() << "Please add support for this type into generator.";
261 break;
262 }
263 }
264}
265#endif
266
267QT_END_NAMESPACE
268

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtquick3d/src/quick3dparticles/qquick3dparticleshapedatautils.cpp