载入中...
搜索中...
未找到
GltfDecode.cpp
浏览该文件的文档.
13Result<std::uint64_t> unsignedValue(const Value* value, std::string path, bool required, std::uint64_t fallback) {
31void putFloat(std::vector<std::uint8_t>& bytes, float value) { put32(bytes, std::bit_cast<std::uint32_t>(value)); }
35 if (request.documentBytes.empty() || request.documentBytes.size() > request.limits.maximumSourceBytes)
37 DiagnosticCode::InvalidArgument, "glTF document size is outside limits", {}, {}, "asset.import"));
51 Diagnostic::error(DiagnosticCode::ParseError, "GLB JSON chunk is invalid", {}, {}, "asset.import"));
62 if (binaryType != 0x004e4942 || binarySize > bytes.size() - cursor || cursor + binarySize != bytes.size())
64 Diagnostic::error(DiagnosticCode::ParseError, "GLB BIN chunk is invalid", {}, {}, "asset.import"));
89Result<std::vector<std::span<const std::uint8_t>>> resolveBuffers(const Value::Object& root, const Document& document,
103 Diagnostic::error(DiagnosticCode::ParseError, "glTF buffer must be an object", {}, {}, "asset.import"));
105 unsignedValue(member(*object, "byteLength"), "$.buffers[" + std::to_string(index) + "].byteLength");
106 if (!declared) return Result<std::vector<std::span<const std::uint8_t>>>::failure(declared.status());
112 Diagnostic::error(DiagnosticCode::Unsupported, "external glTF buffer URI is unsafe or unsupported",
123 Diagnostic::error(DiagnosticCode::ParseError, "buffer without URI requires the first GLB BIN chunk",
148Result<Accessor> accessorAt(const Value::Object& root, const std::vector<std::span<const std::uint8_t>>& buffers,
150 const auto* accessors = member(root, "accessors") ? member(root, "accessors")->getIf<Value::Array>() : nullptr;
151 const auto* views = member(root, "bufferViews") ? member(root, "bufferViews")->getIf<Value::Array>() : nullptr;
154 Diagnostic::error(DiagnosticCode::ParseError, "glTF accessor index is invalid", {}, {}, "asset.import"));
158 DiagnosticCode::Unsupported, "sparse or malformed glTF accessor is unsupported", {}, {}, "asset.import"));
162 auto accessorOffset = unsignedValue(member(*object, "byteOffset"), "accessor.byteOffset", false, 0);
165 Diagnostic::error(DiagnosticCode::ParseError, "glTF accessor fields are invalid", {}, {}, "asset.import"));
167 count.value() > std::max(limits.maximumVerticesPerPrimitive, limits.maximumIndicesPerPrimitive))
169 Diagnostic::error(DiagnosticCode::InvalidArgument, "glTF accessor exceeds limits", {}, {}, "asset.import"));
173 Diagnostic::error(DiagnosticCode::ParseError, "glTF accessor type is missing", {}, {}, "asset.import"));
191 Diagnostic::error(DiagnosticCode::ParseError, "glTF bufferView is malformed", {}, {}, "asset.import"));
193 auto viewOffset = unsignedValue(member(*view, "byteOffset"), "bufferView.byteOffset", false, 0);
195 auto byteStride = unsignedValue(member(*view, "byteStride"), "bufferView.byteStride", false, 0);
196 if (!bufferIndex || !viewOffset || !viewLength || !byteStride || bufferIndex.value() >= buffers.size())
199 const std::uint32_t elementSize = componentSize(static_cast<std::uint32_t>(component.value())) * components;
206 Diagnostic::error(DiagnosticCode::ParseError, "glTF accessor layout is invalid", {}, {}, "asset.import"));
210 Diagnostic::error(DiagnosticCode::ParseError, "glTF accessor range is truncated", {}, {}, "asset.import"));
216 {buffers[bufferIndex.value()], static_cast<std::size_t>(viewOffset.value() + accessorOffset.value()),
221Result<float> readFloat(const Accessor& accessor, std::uint32_t element, std::uint32_t component) {
225 DiagnosticCode::Unsupported, "mesh attribute must use FLOAT components", {}, {}, "asset.import"));
226 const std::size_t offset = accessor.offset + std::size_t(element) * accessor.stride + component * 4;
230 DiagnosticCode::ParseError, "mesh attribute contains non-finite values", {}, {}, "asset.import"));
237 Diagnostic::error(DiagnosticCode::ParseError, "index accessor must be SCALAR", {}, {}, "asset.import"));
239 if (accessor.componentType == 5121) return Result<std::uint32_t>::success(accessor.buffer[offset]);
243 if (accessor.componentType == 5125) return Result<std::uint32_t>::success(little32(accessor.buffer, offset));
245 Diagnostic::error(DiagnosticCode::Unsupported, "indices must use UNSIGNED_BYTE, UNSIGNED_SHORT or UNSIGNED_INT",
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
const std::string & asString() const
Return the string payload; the caller must have checked the kind.
Definition Value.cpp:87
static Result< Value > fromJson(std::string_view json)
Parse one strict JSON value into an owning Value.
Definition Value.cpp:57
const T * getIf() const noexcept
Return a typed pointer, or nullptr when the kind differs.
Definition Value.h:180
Value * find(const std::string &key) noexcept
Return an object member, or nullptr when absent.
Definition Value.cpp:124
Definition GltfAnimation.cpp:11
Result< Accessor > accessorAt(const Value::Object &root, const std::vector< std::span< const std::uint8_t > > &buffers, std::uint64_t accessorIndex, const AssetImportLimits &limits)
Validate an accessor retaining only buffer spans borrowed for this import.
Definition GltfDecode.cpp:148
Result< float > readFloat(const Accessor &accessor, std::uint32_t element, std::uint32_t component)
Read one bounded finite FLOAT component.
Definition GltfDecode.cpp:221
void put32(std::vector< std::uint8_t > &bytes, std::uint32_t value)
Append little-endian uint32 to owned storage.
Definition GltfDecode.cpp:27
Result< std::vector< std::span< const std::uint8_t > > > resolveBuffers(const Value::Object &root, const Document &document, const GltfImportRequest &request)
Resolve immutable spans borrowed from document/request; both must outlive their use.
Definition GltfDecode.cpp:89
Result< std::uint64_t > unsignedValue(const Value *value, std::string path, bool required, std::uint64_t fallback)
Validate an optional integer field. @ownership Borrowed nullable field owned by the input document....
Definition GltfDecode.cpp:13
std::uint32_t little32(std::span< const std::uint8_t > bytes, std::size_t offset)
Read a uint32 after the caller has bounded the byte range.
Definition GltfDecode.cpp:22
Result< Document > parseDocument(const GltfImportRequest &request)
Parse a bounded document into an owning result.
Definition GltfDecode.cpp:34
Result< std::uint32_t > readIndex(const Accessor &accessor, std::uint32_t element)
Read one bounded unsigned scalar index.
Definition GltfDecode.cpp:234
std::uint32_t componentSize(std::uint32_t type)
Return encoded component byte size, or zero for an unknown type.
Definition GltfDecode.cpp:141
bool safeUri(std::string_view uri, const AssetImportLimits &limits)
Definition GltfDecode.cpp:75
void putFloat(std::vector< std::uint8_t > &bytes, float value)
Append IEEE FLOAT to owned storage.
Definition GltfDecode.cpp:31
@ InvalidArgument
@ NotFound
@ Unsupported
@ ParseError
Parser and allocation budgets applied to untrusted importer inputs.
Definition AssetImporter.h:17
Untrusted .gltf/.glb input plus explicitly supplied external URI bytes.
Definition AssetImporter.h:54
Borrowed validated accessor; its source document/resources must outlive synchronous reads.
Definition GltfDecode.h:13
std::span< const std::uint8_t > buffer
Definition GltfDecode.h:14
std::uint32_t componentType
Definition GltfDecode.h:16
Owning parsed document; keep alive while resolved buffer spans are used.
Definition GltfDecode.h:8
std::vector< std::uint8_t > binaryChunk
Definition GltfDecode.h:10