Export glTF buffers as separate .bin files
parent
c98915e382
commit
3c827f29f6
|
@ -489,6 +489,9 @@ namespace glTF
|
||||||
bool IsSpecial() const
|
bool IsSpecial() const
|
||||||
{ return mIsSpecial; }
|
{ return mIsSpecial; }
|
||||||
|
|
||||||
|
std::string GetURI()
|
||||||
|
{ return std::string(this->id) + ".bin"; }
|
||||||
|
|
||||||
static const char* TranslateId(Asset& r, const char* id);
|
static const char* TranslateId(Asset& r, const char* id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
AssetWriter(Asset& asset);
|
AssetWriter(Asset& asset);
|
||||||
|
|
||||||
void WriteFile(const char* path);
|
void WriteFile(const char* path);
|
||||||
|
void WriteGLBFile(const char* path);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,9 +94,6 @@ namespace glTF {
|
||||||
|
|
||||||
inline void Write(Value& obj, Buffer& b, AssetWriter& w)
|
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;
|
const char* type;
|
||||||
switch (b.type) {
|
switch (b.type) {
|
||||||
case Buffer::Type_text:
|
case Buffer::Type_text:
|
||||||
|
@ -107,7 +104,7 @@ namespace glTF {
|
||||||
|
|
||||||
obj.AddMember("byteLength", static_cast<uint64_t>(b.byteLength), w.mAl);
|
obj.AddMember("byteLength", static_cast<uint64_t>(b.byteLength), w.mAl);
|
||||||
obj.AddMember("type", StringRef(type), 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)
|
inline void Write(Value& obj, BufferView& bv, AssetWriter& w)
|
||||||
|
@ -328,39 +325,61 @@ namespace glTF {
|
||||||
|
|
||||||
inline void AssetWriter::WriteFile(const char* path)
|
inline void AssetWriter::WriteFile(const char* path)
|
||||||
{
|
{
|
||||||
bool isBinary = mAsset.extensionsUsed.KHR_binary_glTF;
|
std::unique_ptr<IOStream> jsonOutFile(mAsset.OpenFile(path, "wt", true));
|
||||||
|
|
||||||
std::unique_ptr<IOStream> outfile
|
if (jsonOutFile == 0) {
|
||||||
(mAsset.OpenFile(path, isBinary ? "wb" : "wt", true));
|
throw DeadlyExportError("Could not open output file: " + std::string(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuffer docBuffer;
|
||||||
|
|
||||||
|
PrettyWriter<StringBuffer> 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<Buffer> b = mAsset.buffers.Get(i);
|
||||||
|
|
||||||
|
std::string binPath = b->GetURI();
|
||||||
|
|
||||||
|
std::unique_ptr<IOStream> 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<IOStream> outfile(mAsset.OpenFile(path, "wb", true));
|
||||||
|
|
||||||
if (outfile == 0) {
|
if (outfile == 0) {
|
||||||
throw DeadlyExportError("Could not open output file: " + std::string(path));
|
throw DeadlyExportError("Could not open output file: " + std::string(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBinary) {
|
// we will write the header later, skip its size
|
||||||
// we will write the header later, skip its size
|
outfile->Seek(sizeof(GLB_Header), aiOrigin_SET);
|
||||||
outfile->Seek(sizeof(GLB_Header), aiOrigin_SET);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuffer docBuffer;
|
StringBuffer docBuffer;
|
||||||
|
Writer<StringBuffer> writer(docBuffer);
|
||||||
bool pretty = true;
|
mDoc.Accept(writer);
|
||||||
if (!isBinary && pretty) {
|
|
||||||
PrettyWriter<StringBuffer> writer(docBuffer);
|
|
||||||
mDoc.Accept(writer);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Writer<StringBuffer> writer(docBuffer);
|
|
||||||
mDoc.Accept(writer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outfile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) {
|
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)
|
inline void AssetWriter::WriteBinaryData(IOStream* outfile, size_t sceneLength)
|
||||||
|
@ -385,7 +404,6 @@ namespace glTF {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// write the header
|
// write the header
|
||||||
//
|
//
|
||||||
|
|
|
@ -137,9 +137,13 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
|
||||||
|
|
||||||
ExportScene();
|
ExportScene();
|
||||||
|
|
||||||
|
|
||||||
glTF::AssetWriter writer(*mAsset);
|
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()
|
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<Buffer> b = mAsset->GetBodyBuffer();
|
||||||
|
if (!b) {
|
||||||
|
b = mAsset->buffers.Create(bufferId);
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mScene->mNumMeshes; ++i) {
|
for (unsigned int i = 0; i < mScene->mNumMeshes; ++i) {
|
||||||
const aiMesh* aim = mScene->mMeshes[i];
|
const aiMesh* aim = mScene->mMeshes[i];
|
||||||
|
|
||||||
|
@ -277,13 +290,6 @@ void glTFExporter::ExportMeshes()
|
||||||
|
|
||||||
p.material = mAsset->materials.Get(aim->mMaterialIndex);
|
p.material = mAsset->materials.Get(aim->mMaterialIndex);
|
||||||
|
|
||||||
std::string bufferId = mAsset->FindUniqueID(meshId, "buffer");
|
|
||||||
|
|
||||||
Ref<Buffer> b = mAsset->GetBodyBuffer();
|
|
||||||
if (!b) {
|
|
||||||
b = mAsset->buffers.Create(bufferId);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
|
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
|
||||||
if (v) p.attributes.position.push_back(v);
|
if (v) p.attributes.position.push_back(v);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue