Browse Source

Fix issue 5767: Can't load USD from memory (#5818)

* initial commit

* fix element size
Pichas 11 months ago
parent
commit
811bf2df15
1 changed files with 28 additions and 6 deletions
  1. 28 6
      code/AssetLib/USD/USDLoaderImplTinyusdz.cpp

+ 28 - 6
code/AssetLib/USD/USDLoaderImplTinyusdz.cpp

@@ -58,6 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/importerdesc.h>
 #include <assimp/IOStreamBuffer.h>
 #include <assimp/IOSystem.hpp>
+#include "assimp/MemoryIOWrapper.h"
 #include <assimp/StringUtils.h>
 #include <assimp/StreamReader.h>
 
@@ -81,7 +82,7 @@ using namespace std;
 void USDImporterImplTinyusdz::InternReadFile(
         const std::string &pFile,
         aiScene *pScene,
-        IOSystem *) {
+        IOSystem *pIOHandler) {
     // Grab filename for logging purposes
     size_t pos = pFile.find_last_of('/');
     string basePath = pFile.substr(0, pos);
@@ -91,29 +92,48 @@ void USDImporterImplTinyusdz::InternReadFile(
     ss << "InternReadFile(): model" << nameWExt;
     TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
 
+    bool is_load_from_mem{ pFile.substr(0, AI_MEMORYIO_MAGIC_FILENAME_LENGTH) == AI_MEMORYIO_MAGIC_FILENAME };
+    std::vector<uint8_t> in_mem_data;
+    if (is_load_from_mem) {
+        auto stream_closer = [pIOHandler](IOStream *pStream) {
+            pIOHandler->Close(pStream);
+        };
+        std::unique_ptr<IOStream, decltype(stream_closer)> file_stream(pIOHandler->Open(pFile, "rb"), stream_closer);
+        if (!file_stream) {
+            throw DeadlyImportError("Failed to open file ", pFile, ".");
+        }
+        size_t file_size{ file_stream->FileSize() };
+        in_mem_data.resize(file_size);
+        file_stream->Read(in_mem_data.data(), 1, file_size);
+    }
+
     bool ret{ false };
     tinyusdz::USDLoadOptions options;
     tinyusdz::Stage stage;
     std::string warn, err;
     bool is_usdz{ false };
     if (isUsdc(pFile)) {
-        ret = LoadUSDCFromFile(pFile, &stage, &warn, &err, options);
+        ret = is_load_from_mem ? LoadUSDCFromMemory(in_mem_data.data(), in_mem_data.size(), pFile, &stage, &warn, &err, options) :
+                                 LoadUSDCFromFile(pFile, &stage, &warn, &err, options);
         ss.str("");
         ss << "InternReadFile(): LoadUSDCFromFile() result: " << ret;
         TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
     } else if (isUsda(pFile)) {
-        ret = LoadUSDAFromFile(pFile, &stage, &warn, &err, options);
+        ret = is_load_from_mem ? LoadUSDAFromMemory(in_mem_data.data(), in_mem_data.size(), pFile, &stage, &warn, &err, options) :
+                                 LoadUSDAFromFile(pFile, &stage, &warn, &err, options);
         ss.str("");
         ss << "InternReadFile(): LoadUSDAFromFile() result: " << ret;
         TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
     } else if (isUsdz(pFile)) {
-        ret = LoadUSDZFromFile(pFile, &stage, &warn, &err, options);
+        ret = is_load_from_mem ? LoadUSDZFromMemory(in_mem_data.data(), in_mem_data.size(), pFile, &stage, &warn, &err, options) :
+                                 LoadUSDZFromFile(pFile, &stage, &warn, &err, options);
         is_usdz = true;
         ss.str("");
         ss << "InternReadFile(): LoadUSDZFromFile() result: " << ret;
         TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
     } else if (isUsd(pFile)) {
-        ret = LoadUSDFromFile(pFile, &stage, &warn, &err, options);
+        ret = is_load_from_mem ? LoadUSDFromMemory(in_mem_data.data(), in_mem_data.size(), pFile, &stage, &warn, &err, options) :
+                                 LoadUSDFromFile(pFile, &stage, &warn, &err, options);
         ss.str("");
         ss << "InternReadFile(): LoadUSDFromFile() result: " << ret;
         TINYUSDZLOGD(TAG, "%s", ss.str().c_str());
@@ -149,7 +169,9 @@ void USDImporterImplTinyusdz::InternReadFile(
     // NOTE: Pointer address of usdz_asset must be valid until the call of RenderSceneConverter::ConvertToRenderScene.
     tinyusdz::USDZAsset usdz_asset;
     if (is_usdz) {
-        if (!tinyusdz::ReadUSDZAssetInfoFromFile(pFile, &usdz_asset, &warn, &err)) {
+        bool is_read_USDZ_asset = is_load_from_mem ? tinyusdz::ReadUSDZAssetInfoFromMemory(in_mem_data.data(), in_mem_data.size(), false, &usdz_asset, &warn, &err) :
+                                                     tinyusdz::ReadUSDZAssetInfoFromFile(pFile, &usdz_asset, &warn, &err);
+        if (!is_read_USDZ_asset) {
             if (!warn.empty()) {
                 ss.str("");
                 ss << "InternReadFile(): ReadUSDZAssetInfoFromFile: WARNING reported: " << warn;