diff --git a/code/glTFExporter.cpp b/code/glTFExporter.cpp index 6e878165c..eb133cccb 100644 --- a/code/glTFExporter.cpp +++ b/code/glTFExporter.cpp @@ -233,12 +233,12 @@ public: children.SetArray(); for (unsigned int i = 0; i < n->mNumChildren; ++i) { std::string id = AddNode(nodes, n->mChildren[i]); - children.PushBack(Value(id, mAl), mAl); + children.PushBack(Value(id, mAl).Move(), mAl); } node.AddMember("children", children, mAl); } - nodes.AddMember(Value(nodeId, mAl), node, mAl); + nodes.AddMember(Value(nodeId, mAl).Move(), node, mAl); return nodeId; } @@ -247,7 +247,7 @@ public: { const char* sceneName = "defaultScene"; - mDoc.AddMember("scene", Value(sceneName, mAl), mAl); + mDoc.AddMember("scene", Value(sceneName, mAl).Move(), mAl); Value scenes; scenes.SetObject(); @@ -264,7 +264,7 @@ public: scene.AddMember("nodes", nodes, mAl); } - scenes.AddMember(Value(sceneName, mAl), scene, mAl); + scenes.AddMember(Value(sceneName, mAl).Move(), scene, mAl); } mDoc.AddMember("scenes", scenes, mAl); } @@ -275,29 +275,29 @@ public: IdMap::iterator it; - if (!id.empty()) { + do { + if (!id.empty()) { + it = mUsedIds.find(id); + if (it == mUsedIds.end()) break; + + id += "-"; + } + + id += suffix; + it = mUsedIds.find(id); - if (it == mUsedIds.end()) goto found; + if (it == mUsedIds.end()) break; - id += "-"; - } + char buffer[256]; + int offset = sprintf(buffer, "%s-", id.c_str()); + for (int i = 0; it == mUsedIds.end(); ++i) { + ASSIMP_itoa10(buffer + offset, sizeof(buffer), i); - id += suffix; + id = buffer; + it = mUsedIds.find(id); + } + } while (false); // fake loop to allow using "break" - it = mUsedIds.find(id); - if (it == mUsedIds.end()) goto found; - - char buffer[256]; - int offset = sprintf(buffer, "%s-", id.c_str()); - for (int i = 0; ; ++i) { - ASSIMP_itoa10(buffer + offset, sizeof(buffer), i); - - id = buffer; - it = mUsedIds.find(id); - if (it == mUsedIds.end()) goto found; - } - - found: mUsedIds[id] = true; return id; } diff --git a/code/glTFImporter.cpp b/code/glTFImporter.cpp index 719c53b75..2df1ea458 100644 --- a/code/glTFImporter.cpp +++ b/code/glTFImporter.cpp @@ -79,10 +79,8 @@ typedef rapidjson::Value::MemberIterator MemIt; // JSON Value reading helpers // -inline static void Getf(const Value& v, float& out) -{ - if (v.IsNumber()) out = static_cast(v.GetDouble()); -} + +#define GETF(VAL, OUT) { if ((VAL).IsNumber()) (OUT) = static_cast((VAL).GetDouble()); } template struct ReadHelper { }; @@ -109,28 +107,28 @@ template<> struct ReadHelper { static bool Read(Value& val, std::st template<> struct ReadHelper { static bool Read(Value& v, aiColor3D& out) { if (!v.IsArray() || v.Size() < 3) return false; - Getf(v[0], out.r); Getf(v[1], out.g); Getf(v[2], out.b); + GETF(v[0], out.r); GETF(v[1], out.g); GETF(v[2], out.b); return true; }}; template<> struct ReadHelper { static bool Read(Value& v, aiVector3D& out) { if (!v.IsArray() || v.Size() != 3) return false; - Getf(v[0], out.x); Getf(v[1], out.y); Getf(v[2], out.z); + GETF(v[0], out.x); GETF(v[1], out.y); GETF(v[2], out.z); return true; }}; template<> struct ReadHelper { static bool Read(Value& v, aiQuaternion& out) { if (!v.IsArray() || v.Size() != 4) return false; - Getf(v[0], out.x); Getf(v[1], out.y); Getf(v[2], out.z); Getf(v[3], out.w); + GETF(v[0], out.x); GETF(v[1], out.y); GETF(v[2], out.z); GETF(v[3], out.w); return true; }}; template<> struct ReadHelper { static bool Read(Value& v, aiMatrix4x4& o) { if (!v.IsArray() || v.Size() != 16) return false; - Getf(v[ 0], o.a1); Getf(v[ 1], o.b1); Getf(v[ 2], o.c1); Getf(v[ 3], o.d1); - Getf(v[ 4], o.a2); Getf(v[ 5], o.b2); Getf(v[ 6], o.c2); Getf(v[ 7], o.d2); - Getf(v[ 8], o.a3); Getf(v[ 9], o.b3); Getf(v[10], o.c3); Getf(v[11], o.d3); - Getf(v[12], o.a4); Getf(v[13], o.b4); Getf(v[14], o.c4); Getf(v[15], o.d4); + GETF(v[ 0], o.a1); GETF(v[ 1], o.b1); GETF(v[ 2], o.c1); GETF(v[ 3], o.d1); + GETF(v[ 4], o.a2); GETF(v[ 5], o.b2); GETF(v[ 6], o.c2); GETF(v[ 7], o.d2); + GETF(v[ 8], o.a3); GETF(v[ 9], o.b3); GETF(v[10], o.c3); GETF(v[11], o.d3); + GETF(v[12], o.a4); GETF(v[13], o.b4); GETF(v[14], o.c4); GETF(v[15], o.d4); return true; }}; @@ -167,34 +165,32 @@ typedef std::pair Range; // glTFReader class // -class glTFReader; - //! Manages lazy loading of the glTF top-level objects, and keeps a reference to them by ID -template +template< class T, class INST, T(INST::*FACTORY_FN)(const char*, Value&)> class LazyDict { typedef typename std::gltf_unordered_map Map; Value* mDict; //! JSON dictionary object const char* mDictId; //! ID of the dictionary object - glTFReader& mInstance; //! The glTFReader instance + INST& mInstance; //! The reader object instance Map mReadObjs; //! The read objects public: - LazyDict(glTFReader& instance, const char* dictId) + LazyDict(INST& instance, const char* dictId) : mDictId(dictId), mInstance(instance) { Document& doc = mInstance.GetDocument(); MemIt it = doc.FindMember(dictId); - mDict = (it != doc.MemberEnd() && it->value.IsObject()) ? &it->value : nullptr; + mDict = (it != doc.MemberEnd() && it->value.IsObject()) ? &it->value : 0; } T Get(const char* id) { if (!mDict) return T(); // section was missing - Map::iterator it = mReadObjs.find(id); + typename Map::iterator it = mReadObjs.find(id); if (it != mReadObjs.end()) { // already created? return it->second; } @@ -249,22 +245,22 @@ class glTFReader typedef glTFReader T; // (to shorten next declarations) - LazyDict, &T::LoadAccessor> mAccessors; - //LazyDict mAnimations; - //LazyDict mAssets; - LazyDict, &T::LoadBuffer> mBuffers; - LazyDict, &T::LoadBufferView> mBufferViews; - //LazyDict mCameras; - LazyDict, &T::LoadImage> mImages; - LazyDict mMaterials; - LazyDict mMeshes; - LazyDict mNodes; - //LazyDict, &T::LoadProgram> mPrograms; - //LazyDict, &T::LoadSampler> mSamplers; - //LazyDict, &T::LoadShader> mShaders; - //LazyDict, &T::LoadSkin> mSkins; - //LazyDict,&T::LoadTechnique> mTechniques; - LazyDict, &T::LoadTexture> mTextures; + LazyDict, T, &T::LoadAccessor> mAccessors; + //LazyDict mAnimations; + //LazyDict mAssets; + LazyDict, T, &T::LoadBuffer> mBuffers; + LazyDict, T, &T::LoadBufferView> mBufferViews; + //LazyDict mCameras; + LazyDict, T, &T::LoadImage> mImages; + LazyDict mMaterials; + LazyDict mMeshes; + LazyDict mNodes; + //LazyDict, T, &T::LoadProgram> mPrograms; + //LazyDict, T, &T::LoadSampler> mSamplers; + //LazyDict, T, &T::LoadShader> mShaders; + //LazyDict, T, &T::LoadSkin> mSkins; + //LazyDict,T, &T::LoadTechnique> mTechniques; + LazyDict, T, &T::LoadTexture> mTextures; void LoadScene(Value& scene) @@ -477,7 +473,8 @@ Ptr glTFReader::LoadBuffer(const char* id, Value& obj) if (isBase64) { uint8_t* data; std::size_t dataLen = DecodeBase64(comma + 1, data); - b = new Buffer(shared_ptr(data), dataLen); + shared_ptr dataptr(data); + b = new Buffer(dataptr, dataLen); } } else if (uri) { // Local file @@ -581,7 +578,8 @@ struct Accessor if (outComponents) *outComponents = numComponents; } - template + //! Gets the i-th value as defined by the accessor + template T GetValue(int i) { ai_assert(data); @@ -590,7 +588,13 @@ struct Accessor memcpy(&value, data + i*byteStride, elemSize); //value >>= 8 * (sizeof(T) - elemSize); return value; - } + } + + //! Gets the i-th value as defined by the accessor + unsigned int GetUInt(int i) + { + return GetValue(i); + } }; Ptr glTFReader::LoadAccessor(const char* id, Value& obj) @@ -742,7 +746,7 @@ Range glTFReader::LoadMesh(const char* id, Value& mesh) nFaces = acc->count; faces = new aiFace[nFaces]; for (unsigned int i = 0; i < acc->count; ++i) { - setFace(faces[i], acc->GetValue(i)); + setFace(faces[i], acc->GetUInt(i)); } break; } @@ -751,7 +755,7 @@ Range glTFReader::LoadMesh(const char* id, Value& mesh) nFaces = acc->count / 2; faces = new aiFace[nFaces]; for (unsigned int i = 0; i < acc->count; i += 2) { - setFace(faces[i / 2], acc->GetValue(i), acc->GetValue(i + 1)); + setFace(faces[i / 2], acc->GetUInt(i), acc->GetUInt(i + 1)); } break; } @@ -760,9 +764,9 @@ Range glTFReader::LoadMesh(const char* id, Value& mesh) case PrimitiveMode_LINE_STRIP: { nFaces = acc->count - ((primitiveMode == PrimitiveMode_LINE_STRIP) ? 1 : 0); faces = new aiFace[nFaces]; - setFace(faces[0], acc->GetValue(0), acc->GetValue(1)); + setFace(faces[0], acc->GetUInt(0), acc->GetUInt(1)); for (unsigned int i = 2; i < acc->count; ++i) { - setFace(faces[i - 1], faces[i - 2].mIndices[1], acc->GetValue(i)); + setFace(faces[i - 1], faces[i - 2].mIndices[1], acc->GetUInt(i)); } if (primitiveMode == PrimitiveMode_LINE_LOOP) { // close the loop setFace(faces[acc->count - 1], faces[acc->count - 2].mIndices[1], faces[0].mIndices[0]); @@ -774,25 +778,25 @@ Range glTFReader::LoadMesh(const char* id, Value& mesh) nFaces = acc->count / 3; faces = new aiFace[nFaces]; for (unsigned int i = 0; i < acc->count; i += 3) { - setFace(faces[i / 3], acc->GetValue(i), acc->GetValue(i + 1), acc->GetValue(i + 2)); + setFace(faces[i / 3], acc->GetUInt(i), acc->GetUInt(i + 1), acc->GetUInt(i + 2)); } break; } case PrimitiveMode_TRIANGLE_STRIP: { nFaces = acc->count - 2; faces = new aiFace[nFaces]; - setFace(faces[0], acc->GetValue(0), acc->GetValue(1), acc->GetValue(2)); + setFace(faces[0], acc->GetUInt(0), acc->GetUInt(1), acc->GetUInt(2)); for (unsigned int i = 3; i < acc->count; ++i) { - setFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], acc->GetValue(i)); + setFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], acc->GetUInt(i)); } break; } case PrimitiveMode_TRIANGLE_FAN: nFaces = acc->count - 2; faces = new aiFace[nFaces]; - setFace(faces[0], acc->GetValue(0), acc->GetValue(1), acc->GetValue(2)); + setFace(faces[0], acc->GetUInt(0), acc->GetUInt(1), acc->GetUInt(2)); for (unsigned int i = 3; i < acc->count; ++i) { - setFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], acc->GetValue(i)); + setFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], acc->GetUInt(i)); } break; }