diff options
author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2025-06-18 15:57:11 +0300 |
---|---|---|
committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2025-06-18 16:57:16 +0300 |
commit | bb45bfae0d5f3a7c4d588a2727a86172b12e7c40 (patch) | |
tree | 15aeb3d0bf2631445b533d6fa4c5fb69c55e651e | |
parent | 46aeaf48034fead1dd69060f07494d53ade1ae80 (diff) |
#4204 Fix GLTF texture loading to match DAE loader behavior
-rw-r--r-- | indra/newview/gltf/llgltfloader.cpp | 72 |
1 files changed, 61 insertions, 11 deletions
diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp index 33639cf93c..1f65435728 100644 --- a/indra/newview/gltf/llgltfloader.cpp +++ b/indra/newview/gltf/llgltfloader.cpp @@ -52,11 +52,14 @@ #include "llsdserialize.h" #include "lljoint.h" +#include "llbase64.h" +#include "lldir.h" #include "llmatrix4a.h" #include <boost/regex.hpp> #include <boost/algorithm/string/replace.hpp> +#include <fstream> static const std::string lod_suffix[LLModel::NUM_LODS] = { @@ -609,9 +612,8 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh& } else { - // Let the model preview know we need to load this texture - mNumOfFetchingTextures++; - LL_INFOS("GLTF_IMPORT") << "Adding texture to load queue: " << impMat.mDiffuseMapFilename << LL_ENDL; + // Texture will be loaded later through the callback system + LL_INFOS("GLTF_IMPORT") << "Texture needs loading: " << impMat.mDiffuseMapFilename << LL_ENDL; } } else if (image.mTexture.notNull()) @@ -623,14 +625,62 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh& else if (image.mBufferView >= 0) { // For embedded textures (no URI but has buffer data) - // Create a pseudo filename for the embedded texture - std::string pseudo_filename = "gltf_embedded_texture_" + std::to_string(sourceIndex) + ".png"; - impMat.mDiffuseMapFilename = pseudo_filename; - impMat.mDiffuseMapLabel = material->mName.empty() ? pseudo_filename : material->mName; - - // Mark for loading - mNumOfFetchingTextures++; - LL_INFOS("GLTF_IMPORT") << "Adding embedded texture to load queue: " << pseudo_filename << LL_ENDL; + // Extract the texture to a temporary file immediately + if (image.mBufferView < mGLTFAsset.mBufferViews.size()) + { + const LL::GLTF::BufferView& buffer_view = mGLTFAsset.mBufferViews[image.mBufferView]; + if (buffer_view.mBuffer < mGLTFAsset.mBuffers.size()) + { + const LL::GLTF::Buffer& buffer = mGLTFAsset.mBuffers[buffer_view.mBuffer]; + + if (buffer_view.mByteOffset + buffer_view.mByteLength <= buffer.mData.size()) + { + // Extract image data + const U8* data_ptr = &buffer.mData[buffer_view.mByteOffset]; + U32 data_size = buffer_view.mByteLength; + + // Determine the file extension + std::string extension = ".png"; // Default + if (!image.mMimeType.empty()) + { + if (image.mMimeType == "image/jpeg") + extension = ".jpg"; + else if (image.mMimeType == "image/png") + extension = ".png"; + } + else if (data_size >= 4) + { + if (data_ptr[0] == 0xFF && data_ptr[1] == 0xD8) + extension = ".jpg"; // JPEG magic bytes + else if (data_ptr[0] == 0x89 && data_ptr[1] == 0x50 && data_ptr[2] == 0x4E && data_ptr[3] == 0x47) + extension = ".png"; // PNG magic bytes + } + + // Create a temporary file + std::string temp_dir = gDirUtilp->getTempDir(); + std::string temp_filename = temp_dir + gDirUtilp->getDirDelimiter() + + "gltf_embedded_" + std::to_string(sourceIndex) + extension; + + // Write the image data to the temporary file + std::ofstream temp_file(temp_filename, std::ios::binary); + if (temp_file.is_open()) + { + temp_file.write(reinterpret_cast<const char*>(data_ptr), data_size); + temp_file.close(); + + // Use the temp file as the texture filename + impMat.mDiffuseMapFilename = temp_filename; + impMat.mDiffuseMapLabel = material->mName.empty() ? temp_filename : material->mName; + + LL_INFOS("GLTF_IMPORT") << "Extracted embedded texture to: " << temp_filename << LL_ENDL; + } + else + { + LL_WARNS("GLTF_IMPORT") << "Failed to create temporary file for embedded texture" << LL_ENDL; + } + } + } + } } } } |