Added support for generating glb2 (binary glTF 2)
parent
949375e695
commit
31a4ccaebb
|
@ -92,6 +92,7 @@ void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperti
|
||||||
void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneGLTF2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneGLTF2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
void ExportSceneGLB2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
@ -151,6 +152,8 @@ Exporter::ExportFormatEntry gExporters[] =
|
||||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||||
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf2", &ExportSceneGLTF2,
|
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf2", &ExportSceneGLTF2,
|
||||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||||
|
Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2", "glb2", &ExportSceneGLB2,
|
||||||
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
||||||
|
@ -420,7 +423,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
|
||||||
|
|
||||||
pimpl->mError = std::string("Found no exporter to handle this file format: ") + pFormatId;
|
pimpl->mError = std::string("Found no exporter to handle this file format: ") + pFormatId;
|
||||||
ASSIMP_END_EXCEPTION_REGION(aiReturn);
|
ASSIMP_END_EXCEPTION_REGION(aiReturn);
|
||||||
|
|
||||||
return AI_FAILURE;
|
return AI_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ public:
|
||||||
AssetWriter(Asset& asset);
|
AssetWriter(Asset& asset);
|
||||||
|
|
||||||
void WriteFile(const char* path);
|
void WriteFile(const char* path);
|
||||||
|
void WriteGLBFile(const char* path);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -561,6 +561,98 @@ namespace glTF2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void AssetWriter::WriteGLBFile(const char* path)
|
||||||
|
{
|
||||||
|
std::unique_ptr<IOStream> outfile(mAsset.OpenFile(path, "wb", true));
|
||||||
|
|
||||||
|
if (outfile == 0) {
|
||||||
|
throw DeadlyExportError("Could not open output file: " + std::string(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Padding with zeros make a invalid JSON for the gltf online validator
|
||||||
|
uint8_t padding[] = { '\n', '\n', '\n' };
|
||||||
|
|
||||||
|
// Adapt JSON so that it is not pointing to an external file,
|
||||||
|
// as this is required by the GLB spec'.
|
||||||
|
mDoc["buffers"][0].RemoveMember("uri");
|
||||||
|
|
||||||
|
//
|
||||||
|
// JSON chunk
|
||||||
|
//
|
||||||
|
|
||||||
|
StringBuffer docBuffer;
|
||||||
|
Writer<StringBuffer> writer(docBuffer);
|
||||||
|
mDoc.Accept(writer);
|
||||||
|
|
||||||
|
uint32_t jsonChunkLength = (docBuffer.GetSize() + 3) & ~3; // Round up to next multiple of 4
|
||||||
|
auto paddingLength = jsonChunkLength - docBuffer.GetSize();
|
||||||
|
std::cout << paddingLength << std::endl;
|
||||||
|
|
||||||
|
GLB_Chunk jsonChunk;
|
||||||
|
jsonChunk.chunkLength = jsonChunkLength;
|
||||||
|
jsonChunk.chunkType = ChunkType_JSON;
|
||||||
|
AI_SWAP4(jsonChunk.chunkLength);
|
||||||
|
|
||||||
|
outfile->Seek(sizeof(GLB_Header), aiOrigin_SET);
|
||||||
|
if (outfile->Write(&jsonChunk, 1, sizeof(GLB_Chunk)) != sizeof(GLB_Chunk)) {
|
||||||
|
throw DeadlyExportError("Failed to write scene data header!");
|
||||||
|
}
|
||||||
|
if (outfile->Write(docBuffer.GetString(), 1, docBuffer.GetSize()) != docBuffer.GetSize()) {
|
||||||
|
throw DeadlyExportError("Failed to write scene data!");
|
||||||
|
}
|
||||||
|
if (paddingLength && outfile->Write(padding, 1, paddingLength) != paddingLength) {
|
||||||
|
throw DeadlyExportError("Failed to write scene data padding!");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Binary chunk
|
||||||
|
//
|
||||||
|
|
||||||
|
uint32_t binaryChunkLength = 0;
|
||||||
|
if (mAsset.buffers.Size() > 0) {
|
||||||
|
Ref<Buffer> b = mAsset.buffers.Get(0u);
|
||||||
|
if (b->byteLength > 0) {
|
||||||
|
binaryChunkLength = (b->byteLength + 3) & ~3; // Round up to next multiple of 4
|
||||||
|
auto paddingLength = binaryChunkLength - b->byteLength;
|
||||||
|
|
||||||
|
GLB_Chunk binaryChunk;
|
||||||
|
binaryChunk.chunkLength = binaryChunkLength;
|
||||||
|
binaryChunk.chunkType = ChunkType_BIN;
|
||||||
|
AI_SWAP4(binaryChunk.chunkLength);
|
||||||
|
|
||||||
|
size_t bodyOffset = sizeof(GLB_Header) + sizeof(GLB_Chunk) + jsonChunk.chunkLength;
|
||||||
|
outfile->Seek(bodyOffset, aiOrigin_SET);
|
||||||
|
if (outfile->Write(&binaryChunk, 1, sizeof(GLB_Chunk)) != sizeof(GLB_Chunk)) {
|
||||||
|
throw DeadlyExportError("Failed to write body data header!");
|
||||||
|
}
|
||||||
|
if (outfile->Write(b->GetPointer(), 1, b->byteLength) != b->byteLength) {
|
||||||
|
throw DeadlyExportError("Failed to write body data!");
|
||||||
|
}
|
||||||
|
if (paddingLength && outfile->Write(padding, 1, paddingLength) != paddingLength) {
|
||||||
|
throw DeadlyExportError("Failed to write body data padding!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Header
|
||||||
|
//
|
||||||
|
|
||||||
|
GLB_Header header;
|
||||||
|
memcpy(header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic));
|
||||||
|
|
||||||
|
header.version = 2;
|
||||||
|
AI_SWAP4(header.version);
|
||||||
|
|
||||||
|
header.length = uint32_t(sizeof(GLB_Header) + 2 * sizeof(GLB_Chunk) + jsonChunkLength + binaryChunkLength);
|
||||||
|
AI_SWAP4(header.length);
|
||||||
|
|
||||||
|
outfile->Seek(0, aiOrigin_SET);
|
||||||
|
if (outfile->Write(&header, 1, sizeof(GLB_Header)) != sizeof(GLB_Header)) {
|
||||||
|
throw DeadlyExportError("Failed to write the header!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void AssetWriter::WriteMetadata()
|
inline void AssetWriter::WriteMetadata()
|
||||||
{
|
{
|
||||||
Value asset;
|
Value asset;
|
||||||
|
|
|
@ -77,6 +77,14 @@ namespace Assimp {
|
||||||
glTF2Exporter exporter(pFile, pIOSystem, pScene, pProperties, false);
|
glTF2Exporter exporter(pFile, pIOSystem, pScene, pProperties, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Worker function for exporting a scene to GLB. Prototyped and registered in Exporter.cpp
|
||||||
|
void ExportSceneGLB2(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
|
{
|
||||||
|
// invoke the exporter
|
||||||
|
glTF2Exporter exporter(pFile, pIOSystem, pScene, pProperties, true);
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene,
|
glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene,
|
||||||
|
@ -118,7 +126,11 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai
|
||||||
|
|
||||||
AssetWriter writer(*mAsset);
|
AssetWriter writer(*mAsset);
|
||||||
|
|
||||||
writer.WriteFile(filename);
|
if (isBinary) {
|
||||||
|
writer.WriteGLBFile(filename);
|
||||||
|
} else {
|
||||||
|
writer.WriteFile(filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue