diff --git a/code/glTFAsset.h b/code/glTFAsset.h index 6d5ac1a71..022774779 100644 --- a/code/glTFAsset.h +++ b/code/glTFAsset.h @@ -489,6 +489,9 @@ namespace glTF bool IsSpecial() const { return mIsSpecial; } + std::string GetURI() + { return std::string(this->id) + ".bin"; } + static const char* TranslateId(Asset& r, const char* id); }; diff --git a/code/glTFAssetWriter.h b/code/glTFAssetWriter.h index 370d2c0ab..4d2d3c919 100644 --- a/code/glTFAssetWriter.h +++ b/code/glTFAssetWriter.h @@ -79,6 +79,7 @@ public: AssetWriter(Asset& asset); void WriteFile(const char* path); + void WriteGLBFile(const char* path); }; } diff --git a/code/glTFAssetWriter.inl b/code/glTFAssetWriter.inl index 415db6714..6302ab3c3 100644 --- a/code/glTFAssetWriter.inl +++ b/code/glTFAssetWriter.inl @@ -94,9 +94,6 @@ namespace glTF { inline void Write(Value& obj, Buffer& b, AssetWriter& w) { - std::string dataURI = "data:application/octet-stream;base64,"; - Util::EncodeBase64(b.GetPointer(), b.byteLength, dataURI); - const char* type; switch (b.type) { case Buffer::Type_text: @@ -107,7 +104,7 @@ namespace glTF { obj.AddMember("byteLength", static_cast(b.byteLength), w.mAl); obj.AddMember("type", StringRef(type), w.mAl); - obj.AddMember("uri", Value(dataURI, w.mAl).Move(), w.mAl); + obj.AddMember("uri", Value(b.GetURI(), w.mAl).Move(), w.mAl); } inline void Write(Value& obj, BufferView& bv, AssetWriter& w) @@ -328,39 +325,61 @@ namespace glTF { inline void AssetWriter::WriteFile(const char* path) { - bool isBinary = mAsset.extensionsUsed.KHR_binary_glTF; + std::unique_ptr jsonOutFile(mAsset.OpenFile(path, "wt", true)); - std::unique_ptr outfile - (mAsset.OpenFile(path, isBinary ? "wb" : "wt", true)); + if (jsonOutFile == 0) { + throw DeadlyExportError("Could not open output file: " + std::string(path)); + } + + StringBuffer docBuffer; + + PrettyWriter writer(docBuffer); + mDoc.Accept(writer); + + if (jsonOutFile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) { + throw DeadlyExportError("Failed to write scene data!"); + } + + // Write buffer data to separate .bin files + for (unsigned int i = 0; i < mAsset.buffers.Size(); ++i) { + Ref b = mAsset.buffers.Get(i); + + std::string binPath = b->GetURI(); + + std::unique_ptr binOutFile(mAsset.OpenFile(binPath, "wb", true)); + + if (binOutFile == 0) { + throw DeadlyExportError("Could not open output file: " + binPath); + } + + if (b->byteLength > 0) { + if (binOutFile->Write(b->GetPointer(), b->byteLength, 1) != 1) { + throw DeadlyExportError("Failed to write binary file: " + binPath); + } + } + } + } + + inline void AssetWriter::WriteGLBFile(const char* path) + { + std::unique_ptr outfile(mAsset.OpenFile(path, "wb", true)); if (outfile == 0) { throw DeadlyExportError("Could not open output file: " + std::string(path)); } - if (isBinary) { - // we will write the header later, skip its size - outfile->Seek(sizeof(GLB_Header), aiOrigin_SET); - } + // we will write the header later, skip its size + outfile->Seek(sizeof(GLB_Header), aiOrigin_SET); StringBuffer docBuffer; - - bool pretty = true; - if (!isBinary && pretty) { - PrettyWriter writer(docBuffer); - mDoc.Accept(writer); - } - else { - Writer writer(docBuffer); - mDoc.Accept(writer); - } + Writer writer(docBuffer); + mDoc.Accept(writer); if (outfile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) { - throw DeadlyExportError("Failed to write scene data!"); + throw DeadlyExportError("Failed to write scene data!"); } - if (isBinary) { - WriteBinaryData(outfile.get(), docBuffer.GetSize()); - } + WriteBinaryData(outfile.get(), docBuffer.GetSize()); } inline void AssetWriter::WriteBinaryData(IOStream* outfile, size_t sceneLength) @@ -385,7 +404,6 @@ namespace glTF { } } - // // write the header // diff --git a/code/glTFExporter.cpp b/code/glTFExporter.cpp index e333272be..e2681d0f1 100644 --- a/code/glTFExporter.cpp +++ b/code/glTFExporter.cpp @@ -137,9 +137,13 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc ExportScene(); - glTF::AssetWriter writer(*mAsset); - writer.WriteFile(filename); + + if (isBinary) { + writer.WriteGLBFile(filename); + } else { + writer.WriteFile(filename); + } } @@ -267,6 +271,15 @@ void glTFExporter::ExportMaterials() void glTFExporter::ExportMeshes() { + std::string fname = std::string(mFilename); + std::string bufferIdPrefix = fname.substr(0, fname.find(".")); + std::string bufferId = mAsset->FindUniqueID("", bufferIdPrefix.c_str()); + + Ref b = mAsset->GetBodyBuffer(); + if (!b) { + b = mAsset->buffers.Create(bufferId); + } + for (unsigned int i = 0; i < mScene->mNumMeshes; ++i) { const aiMesh* aim = mScene->mMeshes[i]; @@ -277,13 +290,6 @@ void glTFExporter::ExportMeshes() p.material = mAsset->materials.Get(aim->mMaterialIndex); - std::string bufferId = mAsset->FindUniqueID(meshId, "buffer"); - - Ref b = mAsset->GetBodyBuffer(); - if (!b) { - b = mAsset->buffers.Create(bufferId); - } - Ref v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); if (v) p.attributes.position.push_back(v);