diff options
author | Dave Parks <davep@lindenlab.com> | 2011-07-07 18:32:42 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2011-07-07 18:32:42 -0500 |
commit | 2a6e18d147a3ef3f5a8780233c1cef2f7b69af4a (patch) | |
tree | 52115ae225f5e7a9d195cf035d713d42bcaf515c /indra/llprimitive | |
parent | 9b253ccf68718dea51dc94416b3ece28b42fc32a (diff) |
SH-1774 Fix for preserving material assignments between multiple custom LoDs.
Diffstat (limited to 'indra/llprimitive')
-rw-r--r-- | indra/llprimitive/llmodel.cpp | 77 | ||||
-rw-r--r-- | indra/llprimitive/llmodel.h | 7 |
2 files changed, 81 insertions, 3 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) { diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 1ece877f0f..3f58eba07d 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -143,7 +143,7 @@ public: static LLSD writeModelToStream( std::ostream& ostr, LLSD& mdl, - BOOL nowrite = FALSE); + BOOL nowrite = FALSE, BOOL as_slm = FALSE); static LLModel* loadModelFromDomMesh(domMesh* mesh); static std::string getElementLabel(daeElement* element); @@ -172,6 +172,11 @@ public: void optimizeVolumeFaces(); void offsetMesh( const LLVector3& pivotPoint ); void getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out); + + //reorder face list based on mMaterialList in this and reference so + //order matches that of reference (material ordering touchup) + void matchMaterialOrder(LLModel* reference); + std::vector<std::string> mMaterialList; //data used for skin weights |