summaryrefslogtreecommitdiff
path: root/src/mesh/assimp-master/code/AssetLib/glTF/glTFAsset.inl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesh/assimp-master/code/AssetLib/glTF/glTFAsset.inl')
-rw-r--r--src/mesh/assimp-master/code/AssetLib/glTF/glTFAsset.inl1316
1 files changed, 0 insertions, 1316 deletions
diff --git a/src/mesh/assimp-master/code/AssetLib/glTF/glTFAsset.inl b/src/mesh/assimp-master/code/AssetLib/glTF/glTFAsset.inl
deleted file mode 100644
index 2b76a30..0000000
--- a/src/mesh/assimp-master/code/AssetLib/glTF/glTFAsset.inl
+++ /dev/null
@@ -1,1316 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2022, assimp team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-#include <assimp/MemoryIOWrapper.h>
-#include <assimp/StringUtils.h>
-#include <iomanip>
-
-// Header files, Assimp
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/Base64.hpp>
-
-#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
-// Header files, Open3DGC.
-#include <Open3DGC/o3dgcSC3DMCDecoder.h>
-#endif
-
-using namespace Assimp;
-using namespace glTFCommon;
-
-namespace glTF {
-
-#if _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4706)
-#endif // _MSC_VER
-
-//
-// LazyDict methods
-//
-
-template <class T>
-inline LazyDict<T>::LazyDict(Asset &asset, const char *dictId, const char *extId) :
- mDictId(dictId), mExtId(extId), mDict(0), mAsset(asset) {
- asset.mDicts.push_back(this); // register to the list of dictionaries
-}
-
-template <class T>
-inline LazyDict<T>::~LazyDict() {
- for (size_t i = 0; i < mObjs.size(); ++i) {
- delete mObjs[i];
- }
-}
-
-template <class T>
-inline void LazyDict<T>::AttachToDocument(Document &doc) {
- Value *container = 0;
-
- if (mExtId) {
- if (Value *exts = FindObject(doc, "extensions")) {
- container = FindObject(*exts, mExtId);
- }
- } else {
- container = &doc;
- }
-
- if (container) {
- mDict = FindObject(*container, mDictId);
- }
-}
-
-template <class T>
-inline void LazyDict<T>::DetachFromDocument() {
- mDict = 0;
-}
-
-template <class T>
-Ref<T> LazyDict<T>::Get(unsigned int i) {
- return Ref<T>(mObjs, i);
-}
-
-template <class T>
-Ref<T> LazyDict<T>::Get(const char *id) {
- id = T::TranslateId(mAsset, id);
-
- typename Dict::iterator it = mObjsById.find(id);
- if (it != mObjsById.end()) { // already created?
- return Ref<T>(mObjs, it->second);
- }
-
- // read it from the JSON object
- if (!mDict) {
- throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
- }
-
- Value::MemberIterator obj = mDict->FindMember(id);
- if (obj == mDict->MemberEnd()) {
- throw DeadlyImportError("GLTF: Missing object with id \"", id, "\" in \"", mDictId, "\"");
- }
- if (!obj->value.IsObject()) {
- throw DeadlyImportError("GLTF: Object with id \"", id, "\" is not a JSON object");
- }
-
- // create an instance of the given type
- T *inst = new T();
- inst->id = id;
- ReadMember(obj->value, "name", inst->name);
- inst->Read(obj->value, mAsset);
- return Add(inst);
-}
-
-template <class T>
-Ref<T> LazyDict<T>::Add(T *obj) {
- unsigned int idx = unsigned(mObjs.size());
- mObjs.push_back(obj);
- mObjsById[obj->id] = idx;
- mAsset.mUsedIds[obj->id] = true;
- return Ref<T>(mObjs, idx);
-}
-
-template <class T>
-Ref<T> LazyDict<T>::Create(const char *id) {
- Asset::IdMap::iterator it = mAsset.mUsedIds.find(id);
- if (it != mAsset.mUsedIds.end()) {
- throw DeadlyImportError("GLTF: two objects with the same ID exist");
- }
- T *inst = new T();
- inst->id = id;
- return Add(inst);
-}
-
-//
-// glTF dictionary objects methods
-//
-
-inline Buffer::Buffer() :
- byteLength(0), type(Type_arraybuffer), EncodedRegion_Current(nullptr), mIsSpecial(false) {}
-
-inline Buffer::~Buffer() {
- for (SEncodedRegion *reg : EncodedRegion_List)
- delete reg;
-}
-
-inline const char *Buffer::TranslateId(Asset &r, const char *id) {
- // Compatibility with old spec
- if (r.extensionsUsed.KHR_binary_glTF && strcmp(id, "KHR_binary_glTF") == 0) {
- return "binary_glTF";
- }
-
- return id;
-}
-
-inline void Buffer::Read(Value &obj, Asset &r) {
- size_t statedLength = MemberOrDefault<size_t>(obj, "byteLength", 0);
- byteLength = statedLength;
-
- Value *it = FindString(obj, "uri");
- if (!it) {
- if (statedLength > 0) {
- throw DeadlyImportError("GLTF: buffer with non-zero length missing the \"uri\" attribute");
- }
- return;
- }
-
- const char *uri = it->GetString();
-
- glTFCommon::Util::DataURI dataURI;
- if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
- if (dataURI.base64) {
- uint8_t *data = 0;
- this->byteLength = Base64::Decode(dataURI.data, dataURI.dataLength, data);
- this->mData.reset(data, std::default_delete<uint8_t[]>());
-
- if (statedLength > 0 && this->byteLength != statedLength) {
- throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", ai_to_string(statedLength),
- " bytes, but found ", ai_to_string(dataURI.dataLength));
- }
- } else { // assume raw data
- if (statedLength != dataURI.dataLength) {
- throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", ai_to_string(statedLength),
- " bytes, but found ", ai_to_string(dataURI.dataLength));
- }
-
- this->mData.reset(new uint8_t[dataURI.dataLength], std::default_delete<uint8_t[]>());
- memcpy(this->mData.get(), dataURI.data, dataURI.dataLength);
- }
- } else { // Local file
- if (byteLength > 0) {
- std::string dir = !r.mCurrentAssetDir.empty() ? (
- r.mCurrentAssetDir.back() == '/' ?
- r.mCurrentAssetDir :
- r.mCurrentAssetDir + '/') :
- "";
-
- IOStream *file = r.OpenFile(dir + uri, "rb");
- if (file) {
- bool ok = LoadFromStream(*file, byteLength);
- delete file;
-
- if (!ok)
- throw DeadlyImportError("GLTF: error while reading referenced file \"", uri, "\"");
- } else {
- throw DeadlyImportError("GLTF: could not open referenced file \"", uri, "\"");
- }
- }
- }
-}
-
-inline bool Buffer::LoadFromStream(IOStream &stream, size_t length, size_t baseOffset) {
- byteLength = length ? length : stream.FileSize();
-
- if (baseOffset) {
- stream.Seek(baseOffset, aiOrigin_SET);
- }
-
- mData.reset(new uint8_t[byteLength], std::default_delete<uint8_t[]>());
-
- if (stream.Read(mData.get(), byteLength, 1) != 1) {
- return false;
- }
- return true;
-}
-
-inline void Buffer::EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID) {
- // Check pointer to data
- if (pDecodedData == nullptr) throw DeadlyImportError("GLTF: for marking encoded region pointer to decoded data must be provided.");
-
- // Check offset
- if (pOffset > byteLength) {
- const uint8_t val_size = 32;
-
- char val[val_size];
-
- ai_snprintf(val, val_size, AI_SIZEFMT, pOffset);
- throw DeadlyImportError("GLTF: incorrect offset value (", val, ") for marking encoded region.");
- }
-
- // Check length
- if ((pOffset + pEncodedData_Length) > byteLength) {
- const uint8_t val_size = 64;
-
- char val[val_size];
-
- ai_snprintf(val, val_size, AI_SIZEFMT "/" AI_SIZEFMT, pOffset, pEncodedData_Length);
- throw DeadlyImportError("GLTF: encoded region with offset/length (", val, ") is out of range.");
- }
-
- // Add new region
- EncodedRegion_List.push_back(new SEncodedRegion(pOffset, pEncodedData_Length, pDecodedData, pDecodedData_Length, pID));
- // And set new value for "byteLength"
- byteLength += (pDecodedData_Length - pEncodedData_Length);
-}
-
-inline void Buffer::EncodedRegion_SetCurrent(const std::string &pID) {
- if ((EncodedRegion_Current != nullptr) && (EncodedRegion_Current->ID == pID)) return;
-
- for (SEncodedRegion *reg : EncodedRegion_List) {
- if (reg->ID == pID) {
- EncodedRegion_Current = reg;
-
- return;
- }
- }
-
- throw DeadlyImportError("GLTF: EncodedRegion with ID: \"", pID, "\" not found.");
-}
-
-inline bool Buffer::ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t *pReplace_Data, const size_t pReplace_Count) {
- const size_t new_data_size = byteLength + pReplace_Count - pBufferData_Count;
-
- uint8_t *new_data;
-
- if ((pBufferData_Count == 0) || (pReplace_Count == 0) || (pReplace_Data == nullptr)) return false;
-
- new_data = new uint8_t[new_data_size];
- // Copy data which place before replacing part.
- memcpy(new_data, mData.get(), pBufferData_Offset);
- // Copy new data.
- memcpy(&new_data[pBufferData_Offset], pReplace_Data, pReplace_Count);
- // Copy data which place after replacing part.
- memcpy(&new_data[pBufferData_Offset + pReplace_Count], &mData.get()[pBufferData_Offset + pBufferData_Count], pBufferData_Offset);
- // Apply new data
- mData.reset(new_data, std::default_delete<uint8_t[]>());
- byteLength = new_data_size;
-
- return true;
-}
-
-inline size_t Buffer::AppendData(uint8_t *data, size_t length) {
- size_t offset = this->byteLength;
- Grow(length);
- memcpy(mData.get() + offset, data, length);
- return offset;
-}
-
-inline void Buffer::Grow(size_t amount) {
- if (amount <= 0) return;
- if (capacity >= byteLength + amount) {
- byteLength += amount;
- return;
- }
-
- // Shift operation is standard way to divide integer by 2, it doesn't cast it to float back and forth, also works for odd numbers,
- // originally it would look like: static_cast<size_t>(capacity * 1.5f)
- capacity = std::max(capacity + (capacity >> 1), byteLength + amount);
-
- uint8_t *b = new uint8_t[capacity];
- if (mData) memcpy(b, mData.get(), byteLength);
- mData.reset(b, std::default_delete<uint8_t[]>());
- byteLength += amount;
-}
-
-//
-// struct BufferView
-//
-
-inline void BufferView::Read(Value &obj, Asset &r) {
- const char *bufferId = MemberOrDefault<const char *>(obj, "buffer", 0);
- if (bufferId) {
- buffer = r.buffers.Get(bufferId);
- }
-
- byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
- byteLength = MemberOrDefault(obj, "byteLength", 0u);
-}
-
-//
-// struct Accessor
-//
-
-inline void Accessor::Read(Value &obj, Asset &r) {
- const char *bufferViewId = MemberOrDefault<const char *>(obj, "bufferView", 0);
- if (bufferViewId) {
- bufferView = r.bufferViews.Get(bufferViewId);
- }
-
- byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
- byteStride = MemberOrDefault(obj, "byteStride", 0u);
- componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
- count = MemberOrDefault(obj, "count", 0u);
-
- const char *typestr;
- type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
-}
-
-inline unsigned int Accessor::GetNumComponents() {
- return AttribType::GetNumComponents(type);
-}
-
-inline unsigned int Accessor::GetBytesPerComponent() {
- return int(ComponentTypeSize(componentType));
-}
-
-inline unsigned int Accessor::GetElementSize() {
- return GetNumComponents() * GetBytesPerComponent();
-}
-
-inline uint8_t *Accessor::GetPointer() {
- if (!bufferView || !bufferView->buffer) return 0;
- uint8_t *basePtr = bufferView->buffer->GetPointer();
- if (!basePtr) return 0;
-
- size_t offset = byteOffset + bufferView->byteOffset;
-
- // Check if region is encoded.
- if (bufferView->buffer->EncodedRegion_Current != nullptr) {
- const size_t begin = bufferView->buffer->EncodedRegion_Current->Offset;
- const size_t end = begin + bufferView->buffer->EncodedRegion_Current->DecodedData_Length;
-
- if ((offset >= begin) && (offset < end))
- return &bufferView->buffer->EncodedRegion_Current->DecodedData[offset - begin];
- }
-
- return basePtr + offset;
-}
-
-namespace {
-inline void CopyData(size_t count,
- const uint8_t *src, size_t src_stride,
- uint8_t *dst, size_t dst_stride) {
- if (src_stride == dst_stride) {
- memcpy(dst, src, count * src_stride);
- } else {
- size_t sz = std::min(src_stride, dst_stride);
- for (size_t i = 0; i < count; ++i) {
- memcpy(dst, src, sz);
- if (sz < dst_stride) {
- memset(dst + sz, 0, dst_stride - sz);
- }
- src += src_stride;
- dst += dst_stride;
- }
- }
-}
-} // namespace
-
-template <class T>
-bool Accessor::ExtractData(T *&outData) {
- uint8_t *data = GetPointer();
- if (!data) return false;
-
- const size_t elemSize = GetElementSize();
- const size_t totalSize = elemSize * count;
-
- const size_t stride = byteStride ? byteStride : elemSize;
-
- const size_t targetElemSize = sizeof(T);
- ai_assert(elemSize <= targetElemSize);
-
- ai_assert(count * stride <= bufferView->byteLength);
-
- outData = new T[count];
- if (stride == elemSize && targetElemSize == elemSize) {
- memcpy(outData, data, totalSize);
- } else {
- for (size_t i = 0; i < count; ++i) {
- memcpy(outData + i, data + i * stride, elemSize);
- }
- }
-
- return true;
-}
-
-inline void Accessor::WriteData(size_t cnt, const void *src_buffer, size_t src_stride) {
- uint8_t *buffer_ptr = bufferView->buffer->GetPointer();
- size_t offset = byteOffset + bufferView->byteOffset;
-
- size_t dst_stride = GetNumComponents() * GetBytesPerComponent();
-
- const uint8_t *src = reinterpret_cast<const uint8_t *>(src_buffer);
- uint8_t *dst = reinterpret_cast<uint8_t *>(buffer_ptr + offset);
-
- ai_assert(dst + count * dst_stride <= buffer_ptr + bufferView->buffer->byteLength);
- CopyData(cnt, src, src_stride, dst, dst_stride);
-}
-
-inline Accessor::Indexer::Indexer(Accessor &acc) :
- accessor(acc), data(acc.GetPointer()), elemSize(acc.GetElementSize()), stride(acc.byteStride ? acc.byteStride : elemSize) {
-}
-
-//! Accesses the i-th value as defined by the accessor
-template <class T>
-T Accessor::Indexer::GetValue(int i) {
- ai_assert(data);
- ai_assert(i * stride < accessor.bufferView->byteLength);
- T value = T();
- memcpy(&value, data + i * stride, elemSize);
- //value >>= 8 * (sizeof(T) - elemSize);
- return value;
-}
-
-inline Image::Image() :
- width(0), height(0), mDataLength(0) {
-}
-
-inline void Image::Read(Value &obj, Asset &r) {
- // Check for extensions first (to detect binary embedded data)
- if (Value *extensions = FindObject(obj, "extensions")) {
- if (r.extensionsUsed.KHR_binary_glTF) {
- if (Value *ext = FindObject(*extensions, "KHR_binary_glTF")) {
-
- width = MemberOrDefault(*ext, "width", 0);
- height = MemberOrDefault(*ext, "height", 0);
-
- ReadMember(*ext, "mimeType", mimeType);
-
- const char *bufferViewId;
- if (ReadMember(*ext, "bufferView", bufferViewId)) {
- Ref<BufferView> bv = r.bufferViews.Get(bufferViewId);
- if (bv) {
- mDataLength = bv->byteLength;
- mData.reset(new uint8_t[mDataLength]);
- memcpy(mData.get(), bv->buffer->GetPointer() + bv->byteOffset, mDataLength);
- }
- }
- }
- }
- }
-
- if (!mDataLength) {
- Value *curUri = FindString(obj, "uri");
- if (nullptr != curUri) {
- const char *uristr = curUri->GetString();
-
- glTFCommon::Util::DataURI dataURI;
- if (ParseDataURI(uristr, curUri->GetStringLength(), dataURI)) {
- mimeType = dataURI.mediaType;
- if (dataURI.base64) {
- uint8_t *ptr = nullptr;
- mDataLength = Base64::Decode(dataURI.data, dataURI.dataLength, ptr);
- mData.reset(ptr);
- }
- } else {
- this->uri = uristr;
- }
- }
- }
-}
-
-inline uint8_t *Image::StealData() {
- mDataLength = 0;
- return mData.release();
-}
-
-inline void Image::SetData(uint8_t *data, size_t length, Asset &r) {
- Ref<Buffer> b = r.GetBodyBuffer();
- if (b) { // binary file: append to body
- std::string bvId = r.FindUniqueID(this->id, "imgdata");
- bufferView = r.bufferViews.Create(bvId);
-
- bufferView->buffer = b;
- bufferView->byteLength = length;
- bufferView->byteOffset = b->AppendData(data, length);
- } else { // text file: will be stored as a data uri
- uint8_t *temp = new uint8_t[length];
- memcpy(temp, data, length);
- this->mData.reset(temp);
- this->mDataLength = length;
- }
-}
-
-inline void Sampler::Read(Value &obj, Asset & /*r*/) {
- SetDefaults();
-
- ReadMember(obj, "magFilter", magFilter);
- ReadMember(obj, "minFilter", minFilter);
- ReadMember(obj, "wrapS", wrapS);
- ReadMember(obj, "wrapT", wrapT);
-}
-
-inline void Sampler::SetDefaults() {
- magFilter = SamplerMagFilter_Linear;
- minFilter = SamplerMinFilter_Linear;
- wrapS = SamplerWrap_Repeat;
- wrapT = SamplerWrap_Repeat;
-}
-
-inline void Texture::Read(Value &obj, Asset &r) {
- const char *sourcestr;
- if (ReadMember(obj, "source", sourcestr)) {
- source = r.images.Get(sourcestr);
- }
-
- const char *samplerstr;
- if (ReadMember(obj, "sampler", samplerstr)) {
- sampler = r.samplers.Get(samplerstr);
- }
-}
-
-namespace {
-inline void ReadMaterialProperty(Asset &r, Value &vals, const char *propName, TexProperty &out) {
- if (Value *prop = FindMember(vals, propName)) {
- if (prop->IsString()) {
- out.texture = r.textures.Get(prop->GetString());
- } else {
- ReadValue(*prop, out.color);
- }
- }
-}
-} // namespace
-
-inline void Material::Read(Value &material, Asset &r) {
- SetDefaults();
-
- if (Value *values = FindObject(material, "values")) {
- ReadMaterialProperty(r, *values, "ambient", this->ambient);
- ReadMaterialProperty(r, *values, "diffuse", this->diffuse);
- ReadMaterialProperty(r, *values, "specular", this->specular);
-
- ReadMember(*values, "transparency", transparency);
- ReadMember(*values, "shininess", shininess);
- }
-
- if (Value *extensions = FindObject(material, "extensions")) {
- if (r.extensionsUsed.KHR_materials_common) {
- if (Value *ext = FindObject(*extensions, "KHR_materials_common")) {
- if (Value *tnq = FindString(*ext, "technique")) {
- const char *t = tnq->GetString();
- if (strcmp(t, "BLINN") == 0)
- technique = Technique_BLINN;
- else if (strcmp(t, "PHONG") == 0)
- technique = Technique_PHONG;
- else if (strcmp(t, "LAMBERT") == 0)
- technique = Technique_LAMBERT;
- else if (strcmp(t, "CONSTANT") == 0)
- technique = Technique_CONSTANT;
- }
-
- if (Value *values = FindObject(*ext, "values")) {
- ReadMaterialProperty(r, *values, "ambient", this->ambient);
- ReadMaterialProperty(r, *values, "diffuse", this->diffuse);
- ReadMaterialProperty(r, *values, "specular", this->specular);
-
- ReadMember(*values, "doubleSided", doubleSided);
- ReadMember(*values, "transparent", transparent);
- ReadMember(*values, "transparency", transparency);
- ReadMember(*values, "shininess", shininess);
- }
- }
- }
- }
-}
-
-namespace {
-void SetVector(vec4 &v, float x, float y, float z, float w) {
- v[0] = x;
- v[1] = y;
- v[2] = z;
- v[3] = w;
-}
-} // namespace
-
-inline void Material::SetDefaults() {
- SetVector(ambient.color, 0, 0, 0, 1);
- SetVector(diffuse.color, 0, 0, 0, 1);
- SetVector(specular.color, 0, 0, 0, 1);
- SetVector(emission.color, 0, 0, 0, 1);
-
- doubleSided = false;
- transparent = false;
- transparency = 1.0;
- shininess = 0.0;
-
- technique = Technique_undefined;
-}
-
-namespace {
-
-template <int N>
-inline int Compare(const char *attr, const char (&str)[N]) {
- return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
-}
-
-inline bool GetAttribVector(Mesh::Primitive &p, const char *attr, Mesh::AccessorList *&v, int &pos) {
- if ((pos = Compare(attr, "POSITION"))) {
- v = &(p.attributes.position);
- } else if ((pos = Compare(attr, "NORMAL"))) {
- v = &(p.attributes.normal);
- } else if ((pos = Compare(attr, "TEXCOORD"))) {
- v = &(p.attributes.texcoord);
- } else if ((pos = Compare(attr, "COLOR"))) {
- v = &(p.attributes.color);
- } else if ((pos = Compare(attr, "JOINT"))) {
- v = &(p.attributes.joint);
- } else if ((pos = Compare(attr, "JOINTMATRIX"))) {
- v = &(p.attributes.jointmatrix);
- } else if ((pos = Compare(attr, "WEIGHT"))) {
- v = &(p.attributes.weight);
- } else
- return false;
- return true;
-}
-} // namespace
-
-inline void Mesh::Read(Value &pJSON_Object, Asset &pAsset_Root) {
- /****************** Mesh primitives ******************/
- Value *curPrimitives = FindArray(pJSON_Object, "primitives");
- if (nullptr != curPrimitives) {
- this->primitives.resize(curPrimitives->Size());
- for (unsigned int i = 0; i < curPrimitives->Size(); ++i) {
- Value &primitive = (*curPrimitives)[i];
-
- Primitive &prim = this->primitives[i];
- prim.mode = MemberOrDefault(primitive, "mode", PrimitiveMode_TRIANGLES);
-
- if (Value *attrs = FindObject(primitive, "attributes")) {
- for (Value::MemberIterator it = attrs->MemberBegin(); it != attrs->MemberEnd(); ++it) {
- if (!it->value.IsString()) continue;
- const char *attr = it->name.GetString();
- // Valid attribute semantics include POSITION, NORMAL, TEXCOORD, COLOR, JOINT, JOINTMATRIX,
- // and WEIGHT.Attribute semantics can be of the form[semantic]_[set_index], e.g., TEXCOORD_0, TEXCOORD_1, etc.
-
- int undPos = 0;
- Mesh::AccessorList *vec = 0;
- if (GetAttribVector(prim, attr, vec, undPos)) {
- size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
- if ((*vec).size() <= idx) (*vec).resize(idx + 1);
- (*vec)[idx] = pAsset_Root.accessors.Get(it->value.GetString());
- }
- }
- }
-
- if (Value *indices = FindString(primitive, "indices")) {
- prim.indices = pAsset_Root.accessors.Get(indices->GetString());
- }
-
- if (Value *material = FindString(primitive, "material")) {
- prim.material = pAsset_Root.materials.Get(material->GetString());
- }
- }
- }
-
- /****************** Mesh extensions ******************/
- Value *json_extensions = FindObject(pJSON_Object, "extensions");
-
- if (json_extensions == nullptr) goto mr_skip_extensions;
-
-#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
- for (Value::MemberIterator it_memb = json_extensions->MemberBegin(); it_memb != json_extensions->MemberEnd(); it_memb++) {
- if (it_memb->name.GetString() == std::string("Open3DGC-compression")) {
- // Search for compressed data.
- // Compressed data contain description of part of "buffer" which is encoded. This part must be decoded and
- // new data will replace old encoded part by request. In fact \"compressedData\" is kind of "accessor" structure.
- Value *comp_data = FindObject(it_memb->value, "compressedData");
-
- if (comp_data == nullptr) throw DeadlyImportError("GLTF: \"Open3DGC-compression\" must has \"compressedData\".");
-
- ASSIMP_LOG_INFO("GLTF: Decompressing Open3DGC data.");
-
-/************** Read data from JSON-document **************/
-#define MESH_READ_COMPRESSEDDATA_MEMBER(pFieldName, pOut) \
- if (!ReadMember(*comp_data, pFieldName, pOut)) { \
- throw DeadlyImportError("GLTF: \"compressedData\" must has \"", pFieldName, "\"."); \
- }
-
- const char *mode_str;
- const char *type_str;
- ComponentType component_type;
- SCompression_Open3DGC *ext_o3dgc = new SCompression_Open3DGC;
-
- MESH_READ_COMPRESSEDDATA_MEMBER("buffer", ext_o3dgc->Buffer);
- MESH_READ_COMPRESSEDDATA_MEMBER("byteOffset", ext_o3dgc->Offset);
- MESH_READ_COMPRESSEDDATA_MEMBER("componentType", component_type);
- MESH_READ_COMPRESSEDDATA_MEMBER("type", type_str);
- MESH_READ_COMPRESSEDDATA_MEMBER("count", ext_o3dgc->Count);
- MESH_READ_COMPRESSEDDATA_MEMBER("mode", mode_str);
- MESH_READ_COMPRESSEDDATA_MEMBER("indicesCount", ext_o3dgc->IndicesCount);
- MESH_READ_COMPRESSEDDATA_MEMBER("verticesCount", ext_o3dgc->VerticesCount);
-
-#undef MESH_READ_COMPRESSEDDATA_MEMBER
-
- // Check some values
- if (strcmp(type_str, "SCALAR")) throw DeadlyImportError("GLTF: only \"SCALAR\" type is supported for compressed data.");
- if (component_type != ComponentType_UNSIGNED_BYTE) throw DeadlyImportError("GLTF: only \"UNSIGNED_BYTE\" component type is supported for compressed data.");
-
- // Set read/write data mode.
- if (strcmp(mode_str, "binary") == 0)
- ext_o3dgc->Binary = true;
- else if (strcmp(mode_str, "ascii") == 0)
- ext_o3dgc->Binary = false;
- else
- throw DeadlyImportError("GLTF: for compressed data supported modes is: \"ascii\", \"binary\". Not the: \"", mode_str, "\".");
-
- /************************ Decoding ************************/
- Decode_O3DGC(*ext_o3dgc, pAsset_Root);
- Extension.push_back(ext_o3dgc); // store info in mesh extensions list.
- } // if(it_memb->name.GetString() == "Open3DGC-compression")
- else {
- throw DeadlyImportError("GLTF: Unknown mesh extension: \"", it_memb->name.GetString(), "\".");
- }
- } // for(Value::MemberIterator it_memb = json_extensions->MemberBegin(); it_memb != json_extensions->MemberEnd(); json_extensions++)
-#endif
-
-mr_skip_extensions:
-
- return; // After label some operators must be present.
-}
-
-#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
-inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DGC, Asset &pAsset_Root) {
- typedef unsigned short IndicesType; ///< \sa glTFExporter::ExportMeshes.
-
- o3dgc::SC3DMCDecoder<IndicesType> decoder;
- o3dgc::IndexedFaceSet<IndicesType> ifs;
- o3dgc::BinaryStream bstream;
- uint8_t *decoded_data;
- size_t decoded_data_size = 0;
- Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
-
- // Read data from buffer and place it in BinaryStream for decoder.
- // Just "Count" because always is used type equivalent to uint8_t.
- bstream.LoadFromBuffer(&buf->GetPointer()[pCompression_Open3DGC.Offset], static_cast<unsigned long>(pCompression_Open3DGC.Count));
-
- // After decoding header we can get size of primitives.
- if (decoder.DecodeHeader(ifs, bstream) != o3dgc::O3DGC_OK) throw DeadlyImportError("GLTF: can not decode Open3DGC header.");
-
- /****************** Get sizes of arrays and check sizes ******************/
- // Note. See "Limitations for meshes when using Open3DGC-compression".
-
- // Indices
- size_t size_coordindex = ifs.GetNCoordIndex() * 3; // See float attributes note.
-
- if (primitives[0].indices->count != size_coordindex)
- throw DeadlyImportError("GLTF: Open3DGC. Compressed indices count (", ai_to_string(size_coordindex),
- ") not equal to uncompressed (", ai_to_string(primitives[0].indices->count), ").");
-
- size_coordindex *= sizeof(IndicesType);
- // Coordinates
- size_t size_coord = ifs.GetNCoord(); // See float attributes note.
-
- if (primitives[0].attributes.position[0]->count != size_coord)
- throw DeadlyImportError("GLTF: Open3DGC. Compressed positions count (", ai_to_string(size_coord),
- ") not equal to uncompressed (", ai_to_string(primitives[0].attributes.position[0]->count), ").");
-
- size_coord *= 3 * sizeof(float);
- // Normals
- size_t size_normal = ifs.GetNNormal(); // See float attributes note.
-
- if (primitives[0].attributes.normal[0]->count != size_normal)
- throw DeadlyImportError("GLTF: Open3DGC. Compressed normals count (", ai_to_string(size_normal),
- ") not equal to uncompressed (", ai_to_string(primitives[0].attributes.normal[0]->count), ").");
-
- size_normal *= 3 * sizeof(float);
- // Additional attributes.
- std::vector<size_t> size_floatattr;
- std::vector<size_t> size_intattr;
-
- size_floatattr.resize(ifs.GetNumFloatAttributes());
- size_intattr.resize(ifs.GetNumIntAttributes());
-
- decoded_data_size = size_coordindex + size_coord + size_normal;
- for (size_t idx = 0, idx_end = size_floatattr.size(), idx_texcoord = 0; idx < idx_end; idx++) {
- // size = number_of_elements * components_per_element * size_of_component.
- // Note. But as you can see above, at first we are use this variable in meaning "count". After checking count of objects...
- size_t tval = ifs.GetNFloatAttribute(static_cast<unsigned long>(idx));
-
- switch (ifs.GetFloatAttributeType(static_cast<unsigned long>(idx))) {
- case o3dgc::O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_TEXCOORD:
- // Check situation when encoded data contain texture coordinates but primitive not.
- if (idx_texcoord < primitives[0].attributes.texcoord.size()) {
- if (primitives[0].attributes.texcoord[idx]->count != tval)
- throw DeadlyImportError("GLTF: Open3DGC. Compressed texture coordinates count (", ai_to_string(tval),
- ") not equal to uncompressed (", ai_to_string(primitives[0].attributes.texcoord[idx]->count), ").");
-
- idx_texcoord++;
- } else {
- ifs.SetNFloatAttribute(static_cast<unsigned long>(idx), 0ul); // Disable decoding this attribute.
- }
-
- break;
- default:
- throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: ", ai_to_string(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx))));
- }
-
- tval *= ifs.GetFloatAttributeDim(static_cast<unsigned long>(idx)) * sizeof(o3dgc::Real); // After checking count of objects we can get size of array.
- size_floatattr[idx] = tval;
- decoded_data_size += tval;
- }
-
- for (size_t idx = 0, idx_end = size_intattr.size(); idx < idx_end; idx++) {
- // size = number_of_elements * components_per_element * size_of_component. See float attributes note.
- size_t tval = ifs.GetNIntAttribute(static_cast<unsigned long>(idx));
- switch (ifs.GetIntAttributeType(static_cast<unsigned long>(idx))) {
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_UNKOWN:
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX:
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_JOINT_ID:
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX_BUFFER_ID:
- break;
-
- default:
- throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: ", ai_to_string(ifs.GetIntAttributeType(static_cast<unsigned long>(idx))));
- }
-
- tval *= ifs.GetIntAttributeDim(static_cast<unsigned long>(idx)) * sizeof(long); // See float attributes note.
- size_intattr[idx] = tval;
- decoded_data_size += tval;
- }
-
- // Create array for decoded data.
- decoded_data = new uint8_t[decoded_data_size];
-
- /****************** Set right array regions for decoder ******************/
-
- auto get_buf_offset = [](Ref<Accessor> &pAccessor) -> size_t { return pAccessor->byteOffset + pAccessor->bufferView->byteOffset; };
-
- // Indices
- ifs.SetCoordIndex((IndicesType *const)(decoded_data + get_buf_offset(primitives[0].indices)));
- // Coordinates
- ifs.SetCoord((o3dgc::Real *const)(decoded_data + get_buf_offset(primitives[0].attributes.position[0])));
- // Normals
- if (size_normal) {
- ifs.SetNormal((o3dgc::Real *const)(decoded_data + get_buf_offset(primitives[0].attributes.normal[0])));
- }
-
- for (size_t idx = 0, idx_end = size_floatattr.size(), idx_texcoord = 0; idx < idx_end; idx++) {
- switch (ifs.GetFloatAttributeType(static_cast<unsigned long>(idx))) {
- case o3dgc::O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_TEXCOORD:
- if (idx_texcoord < primitives[0].attributes.texcoord.size()) {
- // See above about absent attributes.
- ifs.SetFloatAttribute(static_cast<unsigned long>(idx), (o3dgc::Real *const)(decoded_data + get_buf_offset(primitives[0].attributes.texcoord[idx])));
- idx_texcoord++;
- }
-
- break;
- default:
- throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: ", ai_to_string(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx))));
- }
- }
-
- for (size_t idx = 0, idx_end = size_intattr.size(); idx < idx_end; idx++) {
- switch (ifs.GetIntAttributeType(static_cast<unsigned int>(idx))) {
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_UNKOWN:
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX:
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_JOINT_ID:
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX_BUFFER_ID:
- break;
-
- // ifs.SetIntAttribute(idx, (long* const)(decoded_data + get_buf_offset(primitives[0].attributes.joint)));
- default:
- throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: ", ai_to_string(ifs.GetIntAttributeType(static_cast<unsigned long>(idx))));
- }
- }
-
- //
- // Decode data
- //
- if (decoder.DecodePayload(ifs, bstream) != o3dgc::O3DGC_OK) {
- throw DeadlyImportError("GLTF: can not decode Open3DGC data.");
- }
-
- // Set encoded region for "buffer".
- buf->EncodedRegion_Mark(pCompression_Open3DGC.Offset, pCompression_Open3DGC.Count, decoded_data, decoded_data_size, id);
- // No. Do not delete "output_data". After calling "EncodedRegion_Mark" bufferView is owner of "output_data".
- // "delete [] output_data;"
-}
-#endif
-
-inline void Camera::Read(Value &obj, Asset & /*r*/) {
- type = MemberOrDefault(obj, "type", Camera::Perspective);
-
- const char *subobjId = (type == Camera::Orthographic) ? "orthographic" : "perspective";
-
- Value *it = FindObject(obj, subobjId);
- if (!it) throw DeadlyImportError("GLTF: Camera missing its parameters");
-
- if (type == Camera::Perspective) {
- perspective.aspectRatio = MemberOrDefault(*it, "aspectRatio", 0.f);
- perspective.yfov = MemberOrDefault(*it, "yfov", 3.1415f / 2.f);
- perspective.zfar = MemberOrDefault(*it, "zfar", 100.f);
- perspective.znear = MemberOrDefault(*it, "znear", 0.01f);
- } else {
- ortographic.xmag = MemberOrDefault(*it, "xmag", 1.f);
- ortographic.ymag = MemberOrDefault(*it, "ymag", 1.f);
- ortographic.zfar = MemberOrDefault(*it, "zfar", 100.f);
- ortographic.znear = MemberOrDefault(*it, "znear", 0.01f);
- }
-}
-
-inline void Light::Read(Value &obj, Asset & /*r*/) {
- SetDefaults();
-
- Value *curType = FindString(obj, "type");
- if (nullptr != curType) {
- const char *t = curType->GetString();
- if (strcmp(t, "ambient") == 0)
- this->type = Type_ambient;
- else if (strcmp(t, "directional") == 0)
- this->type = Type_directional;
- else if (strcmp(t, "point") == 0)
- this->type = Type_point;
- else if (strcmp(t, "spot") == 0)
- this->type = Type_spot;
-
- if (this->type != Type_undefined) {
- if (Value *vals = FindString(obj, t)) {
- ReadMember(*vals, "color", color);
-
- ReadMember(*vals, "constantAttenuation", constantAttenuation);
- ReadMember(*vals, "linearAttenuation", linearAttenuation);
- ReadMember(*vals, "quadraticAttenuation", quadraticAttenuation);
- ReadMember(*vals, "distance", distance);
-
- ReadMember(*vals, "falloffAngle", falloffAngle);
- ReadMember(*vals, "falloffExponent", falloffExponent);
- }
- }
- }
-}
-
-inline void Light::SetDefaults() {
-#ifndef M_PI
- const float M_PI = 3.14159265358979323846f;
-#endif
-
- type = Type_undefined;
-
- SetVector(color, 0.f, 0.f, 0.f, 1.f);
-
- constantAttenuation = 0.f;
- linearAttenuation = 1.f;
- quadraticAttenuation = 1.f;
- distance = 0.f;
-
- falloffAngle = static_cast<float>(M_PI / 2.f);
- falloffExponent = 0.f;
-}
-
-inline void Node::Read(Value &obj, Asset &r) {
- if (name.empty()) {
- name = id;
- }
-
- Value *curChildren = FindArray(obj, "children");
- if (nullptr != curChildren) {
- this->children.reserve(curChildren->Size());
- for (unsigned int i = 0; i < curChildren->Size(); ++i) {
- Value &child = (*curChildren)[i];
- if (child.IsString()) {
- // get/create the child node
- Ref<Node> chn = r.nodes.Get(child.GetString());
- if (chn) this->children.push_back(chn);
- }
- }
- }
-
- Value *curMatrix = FindArray(obj, "matrix");
- if (nullptr != curMatrix) {
- ReadValue(*curMatrix, this->matrix);
- } else {
- ReadMember(obj, "translation", translation);
- ReadMember(obj, "scale", scale);
- ReadMember(obj, "rotation", rotation);
- }
-
- Value *curMeshes = FindArray(obj, "meshes");
- if (nullptr != curMeshes) {
- unsigned int numMeshes = (unsigned int)curMeshes->Size();
-
- std::vector<unsigned int> meshList;
-
- this->meshes.reserve(numMeshes);
- for (unsigned i = 0; i < numMeshes; ++i) {
- if ((*curMeshes)[i].IsString()) {
- Ref<Mesh> mesh = r.meshes.Get((*curMeshes)[i].GetString());
- if (mesh) {
- this->meshes.push_back(mesh);
- }
- }
- }
- }
-
- Value *curCamera = FindString(obj, "camera");
- if (nullptr != curCamera) {
- this->camera = r.cameras.Get(curCamera->GetString());
- if (this->camera) {
- this->camera->id = this->id;
- }
- }
-
- // TODO load "skeletons", "skin", "jointName"
-
- if (Value *extensions = FindObject(obj, "extensions")) {
- if (r.extensionsUsed.KHR_materials_common) {
-
- if (Value *ext = FindObject(*extensions, "KHR_materials_common")) {
- Value *curLight = FindString(*ext, "light");
- if (nullptr != curLight) {
- this->light = r.lights.Get(curLight->GetString());
- }
- }
- }
- }
-}
-
-inline void Scene::Read(Value &obj, Asset &r) {
- if (Value *array = FindArray(obj, "nodes")) {
- for (unsigned int i = 0; i < array->Size(); ++i) {
- if (!(*array)[i].IsString()) continue;
- Ref<Node> node = r.nodes.Get((*array)[i].GetString());
- if (node)
- this->nodes.push_back(node);
- }
- }
-}
-
-inline void AssetMetadata::Read(Document &doc) {
- // read the version, etc.
- if (Value *obj = FindObject(doc, "asset")) {
- ReadMember(*obj, "copyright", copyright);
- ReadMember(*obj, "generator", generator);
-
- premultipliedAlpha = MemberOrDefault(*obj, "premultipliedAlpha", false);
-
- if (Value *versionString = FindString(*obj, "version")) {
- version = versionString->GetString();
- } else if (Value *versionNumber = FindNumber(*obj, "version")) {
- char buf[4];
-
- ai_snprintf(buf, 4, "%.1f", versionNumber->GetDouble());
-
- version = buf;
- }
-
- Value *curProfile = FindObject(*obj, "profile");
- if (nullptr != curProfile) {
- ReadMember(*curProfile, "api", this->profile.api);
- ReadMember(*curProfile, "version", this->profile.version);
- }
- }
-
- if (version.empty() || version[0] != '1') {
- throw DeadlyImportError("GLTF: Unsupported glTF version: ", version);
- }
-}
-
-//
-// Asset methods implementation
-//
-
-inline void Asset::ReadBinaryHeader(IOStream &stream) {
- GLB_Header header;
- if (stream.Read(&header, sizeof(header), 1) != 1) {
- throw DeadlyImportError("GLTF: Unable to read the file header");
- }
-
- if (strncmp((char *)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) {
- throw DeadlyImportError("GLTF: Invalid binary glTF file");
- }
-
- AI_SWAP4(header.version);
- asset.version = ai_to_string(header.version);
- if (header.version != 1) {
- throw DeadlyImportError("GLTF: Unsupported binary glTF version");
- }
-
- AI_SWAP4(header.sceneFormat);
- if (header.sceneFormat != SceneFormat_JSON) {
- throw DeadlyImportError("GLTF: Unsupported binary glTF scene format");
- }
-
- AI_SWAP4(header.length);
- AI_SWAP4(header.sceneLength);
-
- static_assert(std::numeric_limits<uint32_t>::max() <= std::numeric_limits<size_t>::max(), "size_t must be at least 32bits");
- mSceneLength = static_cast<size_t>(header.sceneLength); // Can't be larger than 4GB (max. uint32_t)
-
- mBodyOffset = sizeof(header) + mSceneLength;
- mBodyOffset = (mBodyOffset + 3) & ~3; // Round up to next multiple of 4
-
- mBodyLength = header.length - mBodyOffset;
-}
-
-inline void Asset::Load(const std::string &pFile, bool isBinary) {
- mCurrentAssetDir.clear();
-
- /*int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
- if (pos != int(std::string::npos)) mCurrentAssetDir = pFile.substr(0, pos + 1);*/
- if (0 != strncmp(pFile.c_str(), AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH)) {
- mCurrentAssetDir = getCurrentAssetDir(pFile);
- }
-
- shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
- if (!stream) {
- throw DeadlyImportError("GLTF: Could not open file for reading");
- }
-
- // is binary? then read the header
- if (isBinary) {
- SetAsBinary(); // also creates the body buffer
- ReadBinaryHeader(*stream);
- } else {
- mSceneLength = stream->FileSize();
- mBodyLength = 0;
- }
-
- // Smallest legal JSON file is "{}" Smallest loadable glTF file is larger than that but catch it later
- if (mSceneLength < 2) {
- throw DeadlyImportError("GLTF: No JSON file contents");
- }
-
- // Binary format only supports up to 4GB of JSON so limit it there to avoid extreme memory allocation
- if (mSceneLength >= std::numeric_limits<uint32_t>::max()) {
- throw DeadlyImportError("GLTF: JSON size greater than 4GB");
- }
-
- // read the scene data, ensure null termination
- std::vector<char> sceneData(mSceneLength + 1);
- sceneData[mSceneLength] = '\0';
-
- if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
- throw DeadlyImportError("GLTF: Could not read the file contents");
- }
-
- // parse the JSON document
-
- Document doc;
- doc.ParseInsitu(&sceneData[0]);
-
- if (doc.HasParseError()) {
- char buffer[32];
- ai_snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
- throw DeadlyImportError("GLTF: JSON parse error, offset ", buffer, ": ", GetParseError_En(doc.GetParseError()));
- }
-
- if (!doc.IsObject()) {
- throw DeadlyImportError("GLTF: JSON document root must be a JSON object");
- }
-
- // Fill the buffer instance for the current file embedded contents
- if (mBodyLength > 0) {
- if (!mBodyBuffer->LoadFromStream(*stream, mBodyLength, mBodyOffset)) {
- throw DeadlyImportError("GLTF: Unable to read gltf file");
- }
- }
-
- // Load the metadata
- asset.Read(doc);
- ReadExtensionsUsed(doc);
-
- // Prepare the dictionaries
- for (size_t i = 0; i < mDicts.size(); ++i) {
- mDicts[i]->AttachToDocument(doc);
- }
-
- // Read the "scene" property, which specifies which scene to load
- // and recursively load everything referenced by it
- Value *curScene = FindString(doc, "scene");
- if (nullptr != curScene) {
- this->scene = scenes.Get(curScene->GetString());
- }
-
- // Clean up
- for (size_t i = 0; i < mDicts.size(); ++i) {
- mDicts[i]->DetachFromDocument();
- }
-}
-
-inline void Asset::SetAsBinary() {
- if (!extensionsUsed.KHR_binary_glTF) {
- extensionsUsed.KHR_binary_glTF = true;
- mBodyBuffer = buffers.Create("binary_glTF");
- mBodyBuffer->MarkAsSpecial();
- }
-}
-
-inline void Asset::ReadExtensionsUsed(Document &doc) {
- Value *extsUsed = FindArray(doc, "extensionsUsed");
- if (!extsUsed) return;
-
- std::gltf_unordered_map<std::string, bool> exts;
-
- for (unsigned int i = 0; i < extsUsed->Size(); ++i) {
- if ((*extsUsed)[i].IsString()) {
- exts[(*extsUsed)[i].GetString()] = true;
- }
- }
-
- CHECK_EXT(KHR_binary_glTF);
- CHECK_EXT(KHR_materials_common);
-
-#undef CHECK_EXT
-}
-
-inline IOStream *Asset::OpenFile(const std::string &path, const char *mode, bool absolute) {
-#ifdef ASSIMP_API
- (void)absolute;
- return mIOSystem->Open(path, mode);
-#else
- if (path.size() < 2) return 0;
- if (!absolute && path[1] != ':' && path[0] != '/') { // relative?
- path = mCurrentAssetDir + path;
- }
- FILE *f = fopen(path.c_str(), mode);
- return f ? new IOStream(f) : 0;
-#endif
-}
-
-inline std::string Asset::FindUniqueID(const std::string &str, const char *suffix) {
- std::string id = str;
-
- if (!id.empty()) {
- if (mUsedIds.find(id) == mUsedIds.end())
- return id;
-
- id += "_";
- }
-
- id += suffix;
-
- Asset::IdMap::iterator it = mUsedIds.find(id);
- if (it == mUsedIds.end())
- return id;
-
- char buffer[1024];
- int offset = ai_snprintf(buffer, sizeof(buffer), "%s_", id.c_str());
- for (int i = 0; it != mUsedIds.end(); ++i) {
- ai_snprintf(buffer + offset, sizeof(buffer) - offset, "%d", i);
- id = buffer;
- it = mUsedIds.find(id);
- }
-
- return id;
-}
-
-#if _MSC_VER
-#pragma warning(pop)
-#endif // _MSC_VER
-
-} // namespace glTF