11using namespace QSSGGltf;
15
16
17
18
19
20
21
22namespace QSSGGltfAccessorReader {
29 const char *data =
nullptr;
33DataView viewForAccessor(
const QSSGGltfDocument &document,
const Accessor &accessor)
35 if (accessor.bufferView < 0)
37 const BufferView &view = document.bufferViews.at(accessor.bufferView);
38 const Buffer &buffer = document.buffers.at(view.buffer);
40 result.stride = view.byteStride > 0 ? view.byteStride : accessor.elementByteSize();
41 result.data = buffer.data.constData() + view.byteOffset + accessor.byteOffset;
45quint32 readIndexValue(
const char *data, Accessor::ComponentType componentType)
47 switch (componentType) {
48 case Accessor::ComponentType::UnsignedByte:
49 return *
reinterpret_cast<
const quint8 *>(data);
50 case Accessor::ComponentType::UnsignedShort: {
52 std::memcpy(&value, data,
sizeof(value));
55 case Accessor::ComponentType::UnsignedInt: {
57 std::memcpy(&value, data,
sizeof(value));
66void applySparse(
const QSSGGltfDocument &document,
const Accessor &accessor, QByteArray &packed)
68 const Accessor::Sparse &sparse = *accessor.sparse;
69 const qsizetype elementSize = accessor.elementByteSize();
71 const BufferView &indicesView = document.bufferViews.at(sparse.indicesBufferView);
72 const Buffer &indicesBuffer = document.buffers.at(indicesView.buffer);
73 const char *indices = indicesBuffer.data.constData() + indicesView.byteOffset + sparse.indicesByteOffset;
74 const qsizetype indexSize = Accessor::componentByteSize(sparse.indicesComponentType);
76 const BufferView &valuesView = document.bufferViews.at(sparse.valuesBufferView);
77 const Buffer &valuesBuffer = document.buffers.at(valuesView.buffer);
78 const char *values = valuesBuffer.data.constData() + valuesView.byteOffset + sparse.valuesByteOffset;
80 for (qint64 i = 0; i < sparse.count; ++i) {
81 const quint32 targetElement = readIndexValue(indices + i * indexSize, sparse.indicesComponentType);
82 if (qint64(targetElement) >= accessor.count)
84 std::memcpy(packed.data() + qsizetype(targetElement) * elementSize, values + i * elementSize, elementSize);
88float componentToFloat(
const char *data, Accessor::ComponentType componentType,
bool normalized)
90 switch (componentType) {
91 case Accessor::ComponentType::Byte: {
92 const qint8 value = *
reinterpret_cast<
const qint8 *>(data);
93 return normalized ? std::max(value / 127.0f, -1.0f) :
float(value);
95 case Accessor::ComponentType::UnsignedByte: {
96 const quint8 value = *
reinterpret_cast<
const quint8 *>(data);
97 return normalized ? value / 255.0f :
float(value);
99 case Accessor::ComponentType::Short: {
101 std::memcpy(&value, data,
sizeof(value));
102 return normalized ? std::max(value / 32767.0f, -1.0f) :
float(value);
104 case Accessor::ComponentType::UnsignedShort: {
106 std::memcpy(&value, data,
sizeof(value));
107 return normalized ? value / 65535.0f :
float(value);
109 case Accessor::ComponentType::UnsignedInt: {
111 std::memcpy(&value, data,
sizeof(value));
114 case Accessor::ComponentType::Float: {
116 std::memcpy(&value, data,
sizeof(value));
126
127
128
129
130
133 if (accessorIndex < 0 || accessorIndex >= document.accessors.size())
135 const Accessor &accessor = document.accessors.at(accessorIndex);
136 const qsizetype elementSize = accessor.elementByteSize();
138 QByteArray packed(accessor.count * elementSize,
'\0');
139 const DataView view = viewForAccessor(document, accessor);
141 if (view.stride == elementSize) {
142 std::memcpy(packed.data(), view.data, packed.size());
147 const qint64 count = packed.size() / elementSize;
148 for (qint64 i = 0; i < count; ++i)
149 std::memcpy(packed.data() + i * elementSize, view.data + i * view.stride, elementSize);
153 if (accessor.sparse.has_value())
154 applySparse(document, accessor, packed);
160
161
162
163
164
165
166
167
170 if (accessorIndex < 0 || accessorIndex >= document.accessors.size())
172 const Accessor &accessor = document.accessors.at(accessorIndex);
173 const QByteArray packed = readPacked(document, accessorIndex);
174 const int components = Accessor::componentCount(accessor.type);
175 const int componentSize = Accessor::componentByteSize(accessor.componentType);
177 QList<
float> result(accessor.count * components);
178 const char *element = packed.constData();
179 for (qsizetype i = 0; i < result.size(); ++i)
180 result[i] = componentToFloat(element + i * componentSize, accessor.componentType, accessor.normalized);
185
186
187
188
189
192 if (accessorIndex < 0 || accessorIndex >= document.accessors.size())
194 const Accessor &accessor = document.accessors.at(accessorIndex);
195 const QByteArray packed = readPacked(document, accessorIndex);
196 const qsizetype componentSize = Accessor::componentByteSize(accessor.componentType);
198 QList<quint32> result(accessor.count);
199 for (qint64 i = 0; i < accessor.count; ++i)
200 result[i] = readIndexValue(packed.constData() + i * componentSize, accessor.componentType);
QList< float > readAsFloats(const QSSGGltfDocument &document, int accessorIndex)
QList< quint32 > readIndices(const QSSGGltfDocument &document, int accessorIndex)
QByteArray readPacked(const QSSGGltfDocument &document, int accessorIndex)