|
@@ -1037,7 +1037,72 @@ inline void AssetMetadata::Read(Document& doc)
|
|
|
// Asset methods implementation
|
|
|
//
|
|
|
|
|
|
-inline void Asset::Load(const std::string& pFile)
|
|
|
+inline void Asset::ReadBinaryHeader(IOStream& stream, std::vector<char>& sceneData)
|
|
|
+{
|
|
|
+ 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 = to_string(header.version);
|
|
|
+ if (header.version != 2) {
|
|
|
+ throw DeadlyImportError("GLTF: Unsupported binary glTF version");
|
|
|
+ }
|
|
|
+
|
|
|
+ GLB_Chunk chunk;
|
|
|
+ if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
|
|
|
+ throw DeadlyImportError("GLTF: Unable to read JSON chunk");
|
|
|
+ }
|
|
|
+
|
|
|
+ AI_SWAP4(chunk.chunkLength);
|
|
|
+ AI_SWAP4(chunk.chunkType);
|
|
|
+
|
|
|
+ if (chunk.chunkType != ChunkType_JSON) {
|
|
|
+ throw DeadlyImportError("GLTF: JSON chunk missing");
|
|
|
+ }
|
|
|
+
|
|
|
+ // read the scene data
|
|
|
+
|
|
|
+ mSceneLength = chunk.chunkLength;
|
|
|
+ sceneData.resize(mSceneLength + 1);
|
|
|
+ sceneData[mSceneLength] = '\0';
|
|
|
+
|
|
|
+ if (stream.Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
|
|
|
+ throw DeadlyImportError("GLTF: Could not read the file contents");
|
|
|
+ }
|
|
|
+
|
|
|
+ uint32_t padding = ((chunk.chunkLength + 3) & ~3) - chunk.chunkLength;
|
|
|
+ if (padding > 0) {
|
|
|
+ stream.Seek(padding, aiOrigin_CUR);
|
|
|
+ }
|
|
|
+
|
|
|
+ AI_SWAP4(header.length);
|
|
|
+ mBodyOffset = 12 + 8 + chunk.chunkLength + padding + 8;
|
|
|
+ if (header.length >= mBodyOffset) {
|
|
|
+ if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
|
|
|
+ throw DeadlyImportError("GLTF: Unable to read BIN chunk");
|
|
|
+ }
|
|
|
+
|
|
|
+ AI_SWAP4(chunk.chunkLength);
|
|
|
+ AI_SWAP4(chunk.chunkType);
|
|
|
+
|
|
|
+ if (chunk.chunkType != ChunkType_BIN) {
|
|
|
+ throw DeadlyImportError("GLTF: BIN chunk missing");
|
|
|
+ }
|
|
|
+
|
|
|
+ mBodyLength = chunk.chunkLength;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ mBodyOffset = mBodyLength = 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+inline void Asset::Load(const std::string& pFile, bool isBinary)
|
|
|
{
|
|
|
mCurrentAssetDir.clear();
|
|
|
int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
|
|
@@ -1048,16 +1113,25 @@ inline void Asset::Load(const std::string& pFile)
|
|
|
throw DeadlyImportError("GLTF: Could not open file for reading");
|
|
|
}
|
|
|
|
|
|
- mSceneLength = stream->FileSize();
|
|
|
- mBodyLength = 0;
|
|
|
+ // is binary? then read the header
|
|
|
+ std::vector<char> sceneData;
|
|
|
+ if (isBinary) {
|
|
|
+ SetAsBinary(); // also creates the body buffer
|
|
|
+ ReadBinaryHeader(*stream, sceneData);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ mSceneLength = stream->FileSize();
|
|
|
+ mBodyLength = 0;
|
|
|
|
|
|
- // read the scene data
|
|
|
|
|
|
- std::vector<char> sceneData(mSceneLength + 1);
|
|
|
- sceneData[mSceneLength] = '\0';
|
|
|
+ // read the scene data
|
|
|
|
|
|
- if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
|
|
|
- throw DeadlyImportError("GLTF: Could not read the file contents");
|
|
|
+ sceneData.resize(mSceneLength + 1);
|
|
|
+ sceneData[mSceneLength] = '\0';
|
|
|
+
|
|
|
+ if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
|
|
|
+ throw DeadlyImportError("GLTF: Could not read the file contents");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1110,6 +1184,15 @@ inline void Asset::Load(const std::string& pFile)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+inline void Asset::SetAsBinary()
|
|
|
+{
|
|
|
+ if (!mBodyBuffer) {
|
|
|
+ mBodyBuffer = buffers.Create("binary_glTF");
|
|
|
+ mBodyBuffer->MarkAsSpecial();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
inline void Asset::ReadExtensionsUsed(Document& doc)
|
|
|
{
|
|
|
Value* extsUsed = FindArray(doc, "extensionsUsed");
|