summaryrefslogtreecommitdiff
path: root/indra/llprimitive/llmodel.cpp
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2011-07-07 18:32:42 -0500
committerDave Parks <davep@lindenlab.com>2011-07-07 18:32:42 -0500
commit2a6e18d147a3ef3f5a8780233c1cef2f7b69af4a (patch)
tree52115ae225f5e7a9d195cf035d713d42bcaf515c /indra/llprimitive/llmodel.cpp
parent9b253ccf68718dea51dc94416b3ece28b42fc32a (diff)
SH-1774 Fix for preserving material assignments between multiple custom LoDs.
Diffstat (limited to 'indra/llprimitive/llmodel.cpp')
-rw-r--r--indra/llprimitive/llmodel.cpp77
1 files changed, 75 insertions, 2 deletions
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index d3f42c63d5..986bde0581 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1378,6 +1378,14 @@ LLSD LLModel::writeModel(
}
}
+ if (as_slm)
+ { //save material list names
+ for (U32 i = 0; i < high->mMaterialList.size(); ++i)
+ {
+ mdl["material_list"][i] = high->mMaterialList[i];
+ }
+ }
+
for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx)
{
if (model[idx] && model[idx]->getNumVolumeFaces() > 0)
@@ -1565,10 +1573,10 @@ LLSD LLModel::writeModel(
}
}
- return writeModelToStream(ostr, mdl, nowrite);
+ return writeModelToStream(ostr, mdl, nowrite, as_slm);
}
-LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
+LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BOOL as_slm)
{
U32 bytes = 0;
@@ -1576,6 +1584,11 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
LLSD header;
+ if (as_slm && mdl.has("material_list"))
+ { //save material binding names to header
+ header["material_list"] = mdl["material_list"];
+ }
+
std::string skin;
if (mdl.has("skin"))
@@ -1769,6 +1782,15 @@ bool LLModel::loadModel(std::istream& is)
}
}
+ if (header.has("material_list"))
+ { //load material list names
+ mMaterialList.clear();
+ for (U32 i = 0; i < header["material_list"].size(); ++i)
+ {
+ mMaterialList.push_back(header["material_list"][i].asString());
+ }
+ }
+
std::string nm[] =
{
"lowest_lod",
@@ -1855,6 +1877,57 @@ bool LLModel::loadModel(std::istream& is)
}
+void LLModel::matchMaterialOrder(LLModel* ref)
+{
+ llassert(ref->mMaterialList.size() == mMaterialList.size());
+
+ std::map<std::string, U32> index_map;
+
+ //build a map of material slot names to face indexes
+ bool reorder = false;
+ std::set<std::string> base_mat;
+ std::set<std::string> cur_mat;
+
+ for (U32 i = 0; i < mMaterialList.size(); i++)
+ {
+ index_map[ref->mMaterialList[i]] = i;
+ if (!reorder)
+ { //if any material name does not match reference, we need to reorder
+ reorder = ref->mMaterialList[i] != mMaterialList[i];
+ }
+ base_mat.insert(ref->mMaterialList[i]);
+ cur_mat.insert(mMaterialList[i]);
+ }
+
+
+ if (reorder &&
+ base_mat == cur_mat) //don't reorder if material name sets don't match
+ {
+ std::vector<LLVolumeFace> new_face_list;
+ new_face_list.resize(mVolumeFaces.size());
+
+ std::vector<std::string> new_material_list;
+ new_material_list.resize(mVolumeFaces.size());
+
+ //rebuild face list so materials have the same order
+ //as the reference model
+ for (U32 i = 0; i < mMaterialList.size(); ++i)
+ {
+ U32 ref_idx = index_map[mMaterialList[i]];
+ new_face_list[ref_idx] = mVolumeFaces[i];
+
+ new_material_list[ref_idx] = mMaterialList[i];
+ }
+
+ llassert(new_material_list == ref->mMaterialList);
+
+ mVolumeFaces = new_face_list;
+ }
+
+ //override material list with reference model ordering
+ mMaterialList = ref->mMaterialList;
+}
+
bool LLModel::loadSkinInfo(LLSD& header, std::istream &is)
{