Skip to content

Commit 63134f7

Browse files
committed
#4204 Cache processed materials
1 parent 07d0fbe commit 63134f7

File tree

2 files changed

+109
-85
lines changed

2 files changed

+109
-85
lines changed

indra/newview/gltf/llgltfloader.cpp

Lines changed: 105 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ LLGLTFLoader::~LLGLTFLoader() {}
126126

127127
bool LLGLTFLoader::OpenFile(const std::string &filename)
128128
{
129+
// Clear the material cache for new file
130+
mMaterialCache.clear();
131+
129132
tinygltf::TinyGLTF loader;
130133
std::string filename_lc(filename);
131134
LLStringUtil::toLower(filename_lc);
@@ -562,6 +565,106 @@ bool LLGLTFLoader::addJointToModelSkin(LLMeshSkinInfo& skin_info, S32 gltf_skin_
562565
return true;
563566
}
564567

568+
LLImportMaterial LLGLTFLoader::processMaterial(S32 material_index)
569+
{
570+
// Check cache first
571+
auto cached = mMaterialCache.find(material_index);
572+
if (cached != mMaterialCache.end())
573+
{
574+
return cached->second;
575+
}
576+
577+
LLImportMaterial impMat;
578+
impMat.mDiffuseColor = LLColor4::white; // Default color
579+
580+
// Process material if available
581+
if (material_index >= 0 && material_index < mGLTFAsset.mMaterials.size())
582+
{
583+
LL::GLTF::Material* material = &mGLTFAsset.mMaterials[material_index];
584+
585+
// Set diffuse color from base color factor
586+
impMat.mDiffuseColor = LLColor4(
587+
material->mPbrMetallicRoughness.mBaseColorFactor[0],
588+
material->mPbrMetallicRoughness.mBaseColorFactor[1],
589+
material->mPbrMetallicRoughness.mBaseColorFactor[2],
590+
material->mPbrMetallicRoughness.mBaseColorFactor[3]
591+
);
592+
593+
// Process base color texture if it exists
594+
if (material->mPbrMetallicRoughness.mBaseColorTexture.mIndex >= 0)
595+
{
596+
S32 texIndex = material->mPbrMetallicRoughness.mBaseColorTexture.mIndex;
597+
if (texIndex < mGLTFAsset.mTextures.size())
598+
{
599+
S32 sourceIndex = mGLTFAsset.mTextures[texIndex].mSource;
600+
if (sourceIndex >= 0 && sourceIndex < mGLTFAsset.mImages.size())
601+
{
602+
LL::GLTF::Image& image = mGLTFAsset.mImages[sourceIndex];
603+
604+
// Use URI as texture file name
605+
if (!image.mUri.empty())
606+
{
607+
// URI might be a remote URL or a local path
608+
std::string filename = image.mUri;
609+
610+
// Extract just the filename from the URI
611+
size_t pos = filename.find_last_of("/\\");
612+
if (pos != std::string::npos)
613+
{
614+
filename = filename.substr(pos + 1);
615+
}
616+
617+
// Store the texture filename
618+
impMat.mDiffuseMapFilename = filename;
619+
impMat.mDiffuseMapLabel = material->mName.empty() ? filename : material->mName;
620+
621+
LL_INFOS("GLTF_IMPORT") << "Found texture: " << impMat.mDiffuseMapFilename
622+
<< " for material: " << material->mName << LL_ENDL;
623+
624+
LLSD args;
625+
args["Message"] = "TextureFound";
626+
args["TEXTURE_NAME"] = impMat.mDiffuseMapFilename;
627+
args["MATERIAL_NAME"] = material->mName;
628+
mWarningsArray.append(args);
629+
630+
// If the image has a texture loaded already, use it
631+
if (image.mTexture.notNull())
632+
{
633+
impMat.setDiffuseMap(image.mTexture->getID());
634+
LL_INFOS("GLTF_IMPORT") << "Using existing texture ID: " << image.mTexture->getID().asString() << LL_ENDL;
635+
}
636+
else
637+
{
638+
// Texture will be loaded later through the callback system
639+
LL_INFOS("GLTF_IMPORT") << "Texture needs loading: " << impMat.mDiffuseMapFilename << LL_ENDL;
640+
}
641+
}
642+
else if (image.mTexture.notNull())
643+
{
644+
// No URI but we have a texture, use it directly
645+
impMat.setDiffuseMap(image.mTexture->getID());
646+
LL_INFOS("GLTF_IMPORT") << "Using existing texture ID without URI: " << image.mTexture->getID().asString() << LL_ENDL;
647+
}
648+
else if (image.mBufferView >= 0)
649+
{
650+
// For embedded textures (no URI but has buffer data)
651+
std::string temp_filename = extractTextureToTempFile(texIndex, "base_color");
652+
if (!temp_filename.empty())
653+
{
654+
impMat.mDiffuseMapFilename = temp_filename;
655+
impMat.mDiffuseMapLabel = material->mName.empty() ? temp_filename : material->mName;
656+
}
657+
}
658+
}
659+
}
660+
}
661+
}
662+
663+
// Cache the processed material
664+
mMaterialCache[material_index] = impMat;
665+
return impMat;
666+
}
667+
565668
bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const std::string& base_name, const LL::GLTF::Mesh& mesh, const LL::GLTF::Node& nodeno, material_map& mats)
566669
{
567670
// Set the requested label for the floater display and uploading
@@ -623,91 +726,8 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const std::string& bas
623726
LLVolumeFace face;
624727
std::vector<GLTFVertex> vertices;
625728

626-
LLImportMaterial impMat;
627-
impMat.mDiffuseColor = LLColor4::white; // Default color
628-
629-
// Process material if available
630-
if (prim.mMaterial >= 0 && prim.mMaterial < mGLTFAsset.mMaterials.size())
631-
{
632-
LL::GLTF::Material* material = &mGLTFAsset.mMaterials[prim.mMaterial];
633-
634-
// Set diffuse color from base color factor
635-
impMat.mDiffuseColor = LLColor4(
636-
material->mPbrMetallicRoughness.mBaseColorFactor[0],
637-
material->mPbrMetallicRoughness.mBaseColorFactor[1],
638-
material->mPbrMetallicRoughness.mBaseColorFactor[2],
639-
material->mPbrMetallicRoughness.mBaseColorFactor[3]
640-
);
641-
642-
// Process base color texture if it exists
643-
if (material->mPbrMetallicRoughness.mBaseColorTexture.mIndex >= 0)
644-
{
645-
S32 texIndex = material->mPbrMetallicRoughness.mBaseColorTexture.mIndex;
646-
if (texIndex < mGLTFAsset.mTextures.size())
647-
{
648-
S32 sourceIndex = mGLTFAsset.mTextures[texIndex].mSource;
649-
if (sourceIndex >= 0 && sourceIndex < mGLTFAsset.mImages.size())
650-
{
651-
LL::GLTF::Image& image = mGLTFAsset.mImages[sourceIndex];
652-
653-
// Use URI as texture file name
654-
if (!image.mUri.empty())
655-
{
656-
// URI might be a remote URL or a local path
657-
std::string filename = image.mUri;
658-
659-
// Extract just the filename from the URI
660-
size_t pos = filename.find_last_of("/\\");
661-
if (pos != std::string::npos)
662-
{
663-
filename = filename.substr(pos + 1);
664-
}
665-
666-
// Store the texture filename
667-
impMat.mDiffuseMapFilename = filename;
668-
impMat.mDiffuseMapLabel = material->mName.empty() ? filename : material->mName;
669-
670-
LL_INFOS("GLTF_IMPORT") << "Found texture: " << impMat.mDiffuseMapFilename
671-
<< " for material: " << material->mName << LL_ENDL;
672-
673-
LLSD args;
674-
args["Message"] = "TextureFound";
675-
args["TEXTURE_NAME"] = impMat.mDiffuseMapFilename;
676-
args["MATERIAL_NAME"] = material->mName;
677-
mWarningsArray.append(args);
678-
679-
// If the image has a texture loaded already, use it
680-
if (image.mTexture.notNull())
681-
{
682-
impMat.setDiffuseMap(image.mTexture->getID());
683-
LL_INFOS("GLTF_IMPORT") << "Using existing texture ID: " << image.mTexture->getID().asString() << LL_ENDL;
684-
}
685-
else
686-
{
687-
// Texture will be loaded later through the callback system
688-
LL_INFOS("GLTF_IMPORT") << "Texture needs loading: " << impMat.mDiffuseMapFilename << LL_ENDL;
689-
}
690-
}
691-
else if (image.mTexture.notNull())
692-
{
693-
// No URI but we have a texture, use it directly
694-
impMat.setDiffuseMap(image.mTexture->getID());
695-
LL_INFOS("GLTF_IMPORT") << "Using existing texture ID without URI: " << image.mTexture->getID().asString() << LL_ENDL;
696-
}
697-
else if (image.mBufferView >= 0)
698-
{
699-
// For embedded textures (no URI but has buffer data)
700-
std::string temp_filename = extractTextureToTempFile(texIndex, "base_color");
701-
if (!temp_filename.empty())
702-
{
703-
impMat.mDiffuseMapFilename = temp_filename;
704-
impMat.mDiffuseMapLabel = material->mName.empty() ? temp_filename : material->mName;
705-
}
706-
}
707-
}
708-
}
709-
}
710-
}
729+
// Use cached material processing
730+
LLImportMaterial impMat = processMaterial(prim.mMaterial);
711731

712732
if (prim.getIndexCount() % 3 != 0)
713733
{

indra/newview/gltf/llgltfloader.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,15 @@ class LLGLTFLoader : public LLModelLoader
131131
// per skin joint count, needs to be tracked for the sake of limits check.
132132
std::vector<S32> mValidJointsCount;
133133

134+
// Material cache to avoid duplicate processing
135+
std::map<S32, LLImportMaterial> mMaterialCache;
136+
134137
private:
135138
bool parseMeshes();
136139
void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform) const;
137140
void processNodeHierarchy(S32 node_idx, std::map<std::string, S32>& mesh_name_counts, U32 submodel_limit, const LLVolumeParams& volume_params);
138141
bool addJointToModelSkin(LLMeshSkinInfo& skin_info, S32 gltf_skin_idx, size_t gltf_joint_idx);
142+
LLImportMaterial processMaterial(S32 material_index);
139143
bool populateModelFromMesh(LLModel* pModel, const std::string& base_name, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats);
140144
void populateJointsFromSkin(S32 skin_idx);
141145
void populateJointGroups();

0 commit comments

Comments
 (0)