+// =======================================================================
+// function : gltfParseTexturInGlbBuffer
+// purpose :
+// =======================================================================
+bool RWGltf_GltfJsonParser::gltfParseTexturInGlbBuffer (Handle(Image_Texture)& theTexture,
+ const RWGltf_JsonValue& theBinVal,
+ const TCollection_AsciiString& theBufferViewId,
+ const RWGltf_JsonValue& theBufferView)
+{
+ const RWGltf_JsonValue* aMimeTypeVal = findObjectMember (theBinVal, "mimeType");
+ //const RWGltf_JsonValue* aWidthVal = findObjectMember (theBinVal, "width");
+ //const RWGltf_JsonValue* aHeightVal = findObjectMember (theBinVal, "height");
+ (void )aMimeTypeVal;
+
+ const RWGltf_JsonValue* aBufferName = findObjectMember (theBufferView, "buffer");
+ const RWGltf_JsonValue* aByteLength = findObjectMember (theBufferView, "byteLength");
+ const RWGltf_JsonValue* aByteOffset = findObjectMember (theBufferView, "byteOffset");
+ if (aBufferName != NULL
+ && aBufferName->IsString()
+ && !IsEqual (aBufferName->GetString(), "binary_glTF"))
+ {
+ reportGltfError ("BufferView '" + theBufferViewId + "' does not define binary_glTF buffer.");
+ return false;
+ }
+
+ RWGltf_GltfBufferView aBuffView;
+ aBuffView.ByteOffset = aByteOffset != NULL && aByteOffset->IsNumber()
+ ? (int64_t )aByteOffset->GetDouble()
+ : 0;
+ aBuffView.ByteLength = aByteLength != NULL && aByteLength->IsNumber()
+ ? (int64_t )aByteLength->GetDouble()
+ : 0;
+ if (aBuffView.ByteLength <= 0)
+ {
+ reportGltfError ("BufferView '" + theBufferViewId + "' defines invalid byteLength.");
+ return false;
+ }
+ else if (aBuffView.ByteOffset < 0)
+ {
+ reportGltfError ("BufferView '" + theBufferViewId + "' defines invalid byteOffset.");
+ return false;
+ }
+
+ const int64_t anOffset = myBinBodyOffset + aBuffView.ByteOffset;
+ theTexture = new Image_Texture (myFilePath, anOffset, aBuffView.ByteLength);
+ return true;
+}
+
+// =======================================================================
+// function : gltfParseTextureInBufferView
+// purpose :
+// =======================================================================
+bool RWGltf_GltfJsonParser::gltfParseTextureInBufferView (Handle(Image_Texture)& theTexture,
+ const TCollection_AsciiString& theSourceId,
+ const TCollection_AsciiString& theBufferViewId,
+ const RWGltf_JsonValue& theBufferView)
+{
+ const RWGltf_JsonValue* aBufferName = findObjectMember (theBufferView, "buffer");
+ const RWGltf_JsonValue* aByteLength = findObjectMember (theBufferView, "byteLength");
+ const RWGltf_JsonValue* aByteOffset = findObjectMember (theBufferView, "byteOffset");
+ if (aBufferName == NULL)
+ {
+ reportGltfError ("BufferView '" + theBufferViewId + "' does not define buffer.");
+ return false;
+ }
+
+ const TCollection_AsciiString aBufferId = getKeyString (*aBufferName);
+ const RWGltf_JsonValue* aBuffer = myGltfRoots[RWGltf_GltfRootElement_Buffers].FindChild (*aBufferName);
+ if (aBuffer == NULL
+ || !aBuffer->IsObject())
+ {
+ reportGltfError ("BufferView '" + theBufferViewId + "' refers to non-existing buffer.");
+ return false;
+ }
+
+ RWGltf_GltfBufferView aBuffView;
+ aBuffView.ByteOffset = aByteOffset != NULL && aByteOffset->IsNumber()
+ ? (int64_t )aByteOffset->GetDouble()
+ : 0;
+ aBuffView.ByteLength = aByteLength != NULL && aByteLength->IsNumber()
+ ? (int64_t )aByteLength->GetDouble()
+ : 0;
+ if (aBuffView.ByteLength <= 0)
+ {
+ reportGltfError ("BufferView '" + theBufferViewId + "' defines invalid byteLength.");
+ return false;
+ }
+ else if (aBuffView.ByteOffset < 0)
+ {
+ reportGltfError ("BufferView '" + theBufferViewId + "' defines invalid byteOffset.");
+ return false;
+ }
+
+ const RWGltf_JsonValue* anUriVal = findObjectMember (*aBuffer, "uri");
+ if (anUriVal == NULL
+ || !anUriVal->IsString())
+ {
+ reportGltfError ("Buffer '" + aBufferId + "' does not define uri.");
+ return false;
+ }
+
+ const char* anUriData = anUriVal->GetString();
+ if (::strncmp (anUriData, "data:application/octet-stream;base64,", 37) == 0)
+ {
+ Handle(NCollection_Buffer) aBaseBuffer;
+ if (!myDecodedBuffers.Find (aBufferId, aBaseBuffer))
+ {
+ aBaseBuffer = FSD_Base64Decoder::Decode ((const Standard_Byte* )anUriData + 37, anUriVal->GetStringLength() - 37);
+ myDecodedBuffers.Bind (aBufferId, aBaseBuffer);
+ }
+
+ Handle(RWGltf_SubBuffer) aSubBuffer = new RWGltf_SubBuffer (aBaseBuffer, (Standard_Size )aBuffView.ByteOffset, (Standard_Size )aBuffView.ByteLength);
+ theTexture = new Image_Texture (aSubBuffer, myFilePath + "@" + theSourceId);
+ return true;
+ }
+
+ const TCollection_AsciiString anUri (anUriData);
+ if (anUri.IsEmpty())
+ {
+ reportGltfError ("Buffer '" + aBufferId + "' does not define uri.");
+ return false;
+ }
+
+ const TCollection_AsciiString aPath = myFolder + anUri;
+ bool isFileExist = false;
+ if (!myProbedFiles.Find (aPath, isFileExist))
+ {
+ isFileExist = OSD_File (aPath).Exists();
+ myProbedFiles.Bind (aPath, isFileExist);
+ }
+ if (!isFileExist)
+ {
+ reportGltfError ("Buffer '" + aBufferId + "' refers to non-existing file '" + anUri + "'.");
+ return false;
+ }
+
+ theTexture = new Image_Texture (aPath, aBuffView.ByteOffset, aBuffView.ByteLength);
+ if (myExternalFiles != NULL)
+ {
+ myExternalFiles->Add (aPath);
+ }
+ return true;
+}
+