@@ -126,6 +126,9 @@ LLGLTFLoader::~LLGLTFLoader() {}
126126
127127bool 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+
565668bool 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 {
0 commit comments