#4314 Fix model suffixes

Usecase: Unable to use the same GLB model for physics
master
Andrey Kleshchev 2025-07-08 21:32:07 +03:00 committed by Andrey Kleshchev
parent b7dbe0e49e
commit 60425f69f7
4 changed files with 50 additions and 32 deletions

View File

@ -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))
{

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
*/