summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2025-07-08 21:32:07 +0300
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2025-07-08 23:13:19 +0300
commit60425f69f7500f55013a6d4f1c02d0b6612a731b (patch)
tree94fce549ea578597f06238407f885bcbd41b45ca /indra
parentb7dbe0e49e49fd047f701c39006750dec4814395 (diff)
#4314 Fix model suffixes
Usecase: Unable to use the same GLB model for physics
Diffstat (limited to 'indra')
-rw-r--r--indra/llprimitive/lldaeloader.cpp3
-rw-r--r--indra/llprimitive/lldaeloader.h2
-rw-r--r--indra/newview/gltf/llgltfloader.cpp66
-rw-r--r--indra/newview/gltf/llgltfloader.h11
4 files changed, 50 insertions, 32 deletions
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index aeeca9bcfb..a11f9b5ca2 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -1682,6 +1682,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
{
materials[model->mMaterialList[i]] = LLImportMaterial();
}
+ // todo: likely a bug here, shouldn't be using suffixed label, see how it gets used in other places.
mScene[transformation].push_back(LLModelInstance(model, model->mLabel, transformation, materials));
stretch_extents(model, transformation);
}
@@ -2414,7 +2415,7 @@ std::string LLDAELoader::getElementLabel(daeElement *element)
}
// static
-size_t LLDAELoader::getSuffixPosition(std::string label)
+size_t LLDAELoader::getSuffixPosition(const std::string &label)
{
if ((label.find("_LOD") != -1) || (label.find("_PHYS") != -1))
{
diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h
index 400277d902..0335011a56 100644
--- a/indra/llprimitive/lldaeloader.h
+++ b/indra/llprimitive/lldaeloader.h
@@ -98,7 +98,7 @@ protected:
bool loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& models_out, U32 submodel_limit);
static std::string getElementLabel(daeElement *element);
- static size_t getSuffixPosition(std::string label);
+ static size_t getSuffixPosition(const std::string& label);
static std::string getLodlessLabel(daeElement *element);
static std::string preprocessDAE(std::string filename);
diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp
index c850663579..a211dad5fa 100644
--- a/indra/newview/gltf/llgltfloader.cpp
+++ b/indra/newview/gltf/llgltfloader.cpp
@@ -188,6 +188,7 @@ bool LLGLTFLoader::OpenFile(const std::string &filename)
void LLGLTFLoader::addModelToScene(
LLModel* pModel,
+ const std::string& model_name,
U32 submodel_limit,
const LLMatrix4& transformation,
const LLVolumeParams& volume_params,
@@ -239,7 +240,7 @@ void LLGLTFLoader::addModelToScene(
LLModel* next = new LLModel(volume_params, 0.f);
next->ClearFacesAndMaterials();
next->mSubmodelID = ++submodelID;
- next->mLabel = pModel->mLabel + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod];
+ next->mLabel = model_name + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod];
next->getVolumeFaces() = remainder;
next->mNormalizedScale = current_model->mNormalizedScale;
next->mNormalizedTranslation = current_model->mNormalizedTranslation;
@@ -289,7 +290,12 @@ void LLGLTFLoader::addModelToScene(
materials[model->mMaterialList[i]] = LLImportMaterial();
}
}
- mScene[transformation].push_back(LLModelInstance(model, model->mLabel, transformation, materials));
+ std::string base_name = model_name;
+ if (model->mSubmodelID > 0)
+ {
+ base_name += (char)((int)'a' + model->mSubmodelID);
+ }
+ mScene[transformation].push_back(LLModelInstance(model, base_name, transformation, materials));
stretch_extents(model, transformation);
}
}
@@ -387,7 +393,7 @@ void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map<std::string, S32>
const LL::GLTF::Mesh& mesh = mGLTFAsset.mMeshes[node.mMesh];
// Get base mesh name and track usage
- std::string base_name = mesh.mName;
+ std::string base_name = getLodlessLabel(mesh);
if (base_name.empty())
{
base_name = "mesh_" + std::to_string(node.mMesh);
@@ -395,7 +401,13 @@ void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map<std::string, S32>
S32 instance_count = mesh_name_counts[base_name]++;
- if (populateModelFromMesh(pModel, mesh, node, mats, instance_count) &&
+ // make name unique
+ if (instance_count > 0)
+ {
+ base_name = base_name + "_copy_" + std::to_string(instance_count);
+ }
+
+ if (populateModelFromMesh(pModel, base_name, mesh, node, mats) &&
(LLModel::NO_ERRORS == pModel->getStatus()) &&
validate_model(pModel))
{
@@ -443,7 +455,7 @@ void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map<std::string, S32>
mWarningsArray.append(args);
}
- addModelToScene(pModel, submodel_limit, transformation, volume_params, mats);
+ addModelToScene(pModel, base_name, submodel_limit, transformation, volume_params, mats);
mats.clear();
}
else
@@ -529,29 +541,16 @@ bool LLGLTFLoader::addJointToModelSkin(LLMeshSkinInfo& skin_info, S32 gltf_skin_
return true;
}
-bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh& mesh, const LL::GLTF::Node& nodeno, material_map& mats, S32 instance_count)
+bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const std::string& base_name, const LL::GLTF::Mesh& mesh, const LL::GLTF::Node& nodeno, material_map& mats)
{
// Set the requested label for the floater display and uploading
pModel->mRequestedLabel = gDirUtilp->getBaseFileName(mFilename, true);
+ // Set name and suffix. Suffix is nessesary for model matching logic
+ // because sometimes higher lod can be used as a lower one, so they
+ // need unique names not just in scope of one lod, but across lods.
+ pModel->mLabel = base_name + lod_suffix[mLod];
- // Create unique model name
- std::string base_name = mesh.mName;
- if (base_name.empty())
- {
- S32 mesh_index = static_cast<S32>(&mesh - &mGLTFAsset.mMeshes[0]);
- base_name = "mesh_" + std::to_string(mesh_index);
- }
-
- LL_DEBUGS("GLTF_DEBUG") << "Processing model " << base_name << LL_ENDL;
-
- if (instance_count > 0)
- {
- pModel->mLabel = base_name + "_copy_" + std::to_string(instance_count);
- }
- else
- {
- pModel->mLabel = base_name;
- }
+ LL_DEBUGS("GLTF_DEBUG") << "Processing model " << pModel->mLabel << LL_ENDL;
pModel->ClearFacesAndMaterials();
@@ -1723,3 +1722,22 @@ void LLGLTFLoader::notifyUnsupportedExtension(bool unsupported)
}
}
+size_t LLGLTFLoader::getSuffixPosition(const std::string &label)
+{
+ if ((label.find("_LOD") != -1) || (label.find("_PHYS") != -1))
+ {
+ return label.rfind('_');
+ }
+ return -1;
+}
+
+std::string LLGLTFLoader::getLodlessLabel(const LL::GLTF::Mesh& mesh)
+{
+ size_t ext_pos = getSuffixPosition(mesh.mName);
+ if (ext_pos != -1)
+ {
+ return mesh.mName.substr(0, ext_pos);
+ }
+ return mesh.mName;
+}
+
diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h
index 7486c72a95..3a9531bf7b 100644
--- a/indra/newview/gltf/llgltfloader.h
+++ b/indra/newview/gltf/llgltfloader.h
@@ -136,10 +136,10 @@ private:
void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform) const;
void processNodeHierarchy(S32 node_idx, std::map<std::string, S32>& mesh_name_counts, U32 submodel_limit, const LLVolumeParams& volume_params);
bool addJointToModelSkin(LLMeshSkinInfo& skin_info, S32 gltf_skin_idx, size_t gltf_joint_idx);
- bool populateModelFromMesh(LLModel* pModel, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats, S32 instance_count);
+ bool populateModelFromMesh(LLModel* pModel, const std::string& base_name, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats);
void populateJointsFromSkin(S32 skin_idx);
void populateJointGroups();
- void addModelToScene(LLModel* pModel, U32 submodel_limit, const LLMatrix4& transformation, const LLVolumeParams& volume_params, const material_map& mats);
+ void addModelToScene(LLModel* pModel, const std::string& model_name, U32 submodel_limit, const LLMatrix4& transformation, const LLVolumeParams& volume_params, const material_map& mats);
void buildJointGroup(LLJointData& viewer_data, const std::string& parent_group);
void buildOverrideMatrix(LLJointData& data, joints_data_map_t &gltf_nodes, joints_name_to_node_map_t &names_to_nodes, glm::mat4& parent_rest, glm::mat4& support_rest) const;
glm::mat4 buildGltfRestMatrix(S32 joint_node_index, const LL::GLTF::Skin& gltf_skin) const;
@@ -153,6 +153,9 @@ private:
void notifyUnsupportedExtension(bool unsupported);
+ static size_t getSuffixPosition(const std::string& label);
+ static std::string getLodlessLabel(const LL::GLTF::Mesh& mesh);
+
// bool mPreprocessGLTF;
/* Below inherited from dae loader - unknown if/how useful here
@@ -190,10 +193,6 @@ private:
//
bool loadModelsFromGltfMesh(gltfMesh *mesh, std::vector<LLModel *> &models_out, U32 submodel_limit);
- static std::string getElementLabel(gltfElement *element);
- static size_t getSuffixPosition(std::string label);
- static std::string getLodlessLabel(gltfElement *element);
-
static std::string preprocessGLTF(std::string filename);
*/