diff options
Diffstat (limited to 'indra/llprimitive/llmodel.cpp')
-rw-r--r-- | indra/llprimitive/llmodel.cpp | 199 |
1 files changed, 134 insertions, 65 deletions
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 204ff63712..fbd97b3de7 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -31,12 +31,12 @@ #include "llconvexdecomposition.h" #include "llsdserialize.h" #include "llvector4a.h" -#include "llmd5.h" +#include "hbxxh.h" #ifdef LL_USESYSTEMLIBS # include <zlib.h> #else -# include "zlib/zlib.h" +# include "zlib-ng/zlib.h" #endif std::string model_names[] = @@ -107,6 +107,14 @@ void LLModel::offsetMesh( const LLVector3& pivotPoint ) } } +void LLModel::remapVolumeFaces() +{ + for (U32 i = 0; i < getNumVolumeFaces(); ++i) + { + mVolumeFaces[i].remap(); + } +} + void LLModel::optimizeVolumeFaces() { for (U32 i = 0; i < getNumVolumeFaces(); ++i) @@ -371,6 +379,8 @@ void LLModel::setVolumeFaceData( U32 num_verts, U32 num_indices) { + llassert(num_indices % 3 == 0); + LLVolumeFace& face = mVolumeFaces[f]; face.resizeVertices(num_verts); @@ -822,55 +832,69 @@ LLSD LLModel::writeModel( if (skinning) { - //write out skin weights - - //each influence list entry is up to 4 24-bit values - // first 8 bits is bone index - // last 16 bits is bone influence weight - // a bone index of 0xFF signifies no more influences for this vertex - - std::stringstream ostr; - - for (U32 j = 0; j < face.mNumVertices; ++j) - { - LLVector3 pos(face.mPositions[j].getF32ptr()); - - weight_list& weights = high->getJointInfluences(pos); - - S32 count = 0; - for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter) - { - // Note joint index cannot exceed 255. - if (iter->mJointIdx < 255 && iter->mJointIdx >= 0) - { - U8 idx = (U8) iter->mJointIdx; - ostr.write((const char*) &idx, 1); - - U16 influence = (U16) (iter->mWeight*65535); - ostr.write((const char*) &influence, 2); - - ++count; - } - } - U8 end_list = 0xFF; - if (count < 4) - { - ostr.write((const char*) &end_list, 1); - } - } - - //copy ostr to binary buffer - std::string data = ostr.str(); - const U8* buff = (U8*) data.data(); - U32 bytes = data.size(); - - LLSD::Binary w(bytes); - for (U32 j = 0; j < bytes; ++j) - { - w[j] = buff[j]; - } - - mdl[model_names[idx]][i]["Weights"] = w; + if (!model[idx]->mSkinWeights.empty()) + { + //write out skin weights + + //each influence list entry is up to 4 24-bit values + // first 8 bits is bone index + // last 16 bits is bone influence weight + // a bone index of 0xFF signifies no more influences for this vertex + + std::stringstream ostr; + for (U32 j = 0; j < face.mNumVertices; ++j) + { + LLVector3 pos(face.mPositions[j].getF32ptr()); + + weight_list& weights = model[idx]->getJointInfluences(pos); + + S32 count = 0; + for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter) + { + // Note joint index cannot exceed 255. + if (iter->mJointIdx < 255 && iter->mJointIdx >= 0) + { + U8 idx = (U8)iter->mJointIdx; + ostr.write((const char*)&idx, 1); + + U16 influence = (U16)(iter->mWeight * 65535); + ostr.write((const char*)&influence, 2); + + ++count; + } + } + U8 end_list = 0xFF; + if (count < 4) + { + ostr.write((const char*)&end_list, 1); + } + } + + //copy ostr to binary buffer + std::string data = ostr.str(); + const U8* buff = (U8*)data.data(); + U32 bytes = data.size(); + + LLSD::Binary w(bytes); + for (U32 j = 0; j < bytes; ++j) + { + w[j] = buff[j]; + } + + mdl[model_names[idx]][i]["Weights"] = w; + } + else + { + if (idx == LLModel::LOD_PHYSICS) + { + // Ex: using "bounding box" + LL_DEBUGS("MESHSKININFO") << "Using physics model without skin weights" << LL_ENDL; + } + else + { + LL_WARNS("MESHSKININFO") << "Attempting to use skinning without having skin weights" << LL_ENDL; + } + } } } } @@ -881,8 +905,6 @@ LLSD LLModel::writeModel( LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BOOL as_slm) { - U32 bytes = 0; - std::string::size_type cur_offset = 0; LLSD header; @@ -904,7 +926,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO header["skin"]["offset"] = (LLSD::Integer) cur_offset; header["skin"]["size"] = (LLSD::Integer) size; cur_offset += size; - bytes += size; } } @@ -920,7 +941,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset; header["physics_convex"]["size"] = (LLSD::Integer) size; cur_offset += size; - bytes += size; } } @@ -942,7 +962,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO header[model_names[i]]["offset"] = (LLSD::Integer) cur_offset; header[model_names[i]]["size"] = (LLSD::Integer) size; cur_offset += size; - bytes += size; } } @@ -977,6 +996,8 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) //1. If a vertex has been weighted then we'll find it via pos and return its weight list weight_map::iterator iterPos = mSkinWeights.begin(); weight_map::iterator iterEnd = mSkinWeights.end(); + + llassert(!mSkinWeights.empty()); for ( ; iterPos!=iterEnd; ++iterPos ) { @@ -1381,6 +1402,16 @@ LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin): fromLLSD(skin); } +LLMeshSkinInfo::LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& skin) : + mMeshID(mesh_id), + mPelvisOffset(0.0), + mLockScaleIfJointPosition(false), + mInvalidJointsScrubbed(false), + mJointNumsInitialized(false) +{ + fromLLSD(skin); +} + void LLMeshSkinInfo::fromLLSD(LLSD& skin) { if (skin.has("joint_names")) @@ -1516,7 +1547,7 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_positi void LLMeshSkinInfo::updateHash() { // get hash of data relevant to render batches - LLMD5 hash; + HBXXH64 hash; //mJointNames for (auto& name : mJointNames) @@ -1525,24 +1556,38 @@ void LLMeshSkinInfo::updateHash() } //mJointNums - hash.update((U8*)&(mJointNums[0]), sizeof(S32) * mJointNums.size()); + hash.update((const void*)mJointNums.data(), sizeof(S32) * mJointNums.size()); //mInvBindMatrix F32* src = mInvBindMatrix[0].getF32ptr(); - for (int i = 0; i < mInvBindMatrix.size() * 16; ++i) + for (size_t i = 0, count = mInvBindMatrix.size() * 16; i < count; ++i) { S32 t = llround(src[i] * 10000.f); - hash.update((U8*)&t, sizeof(S32)); + hash.update((const void*)&t, sizeof(S32)); } - //hash.update((U8*)&(mInvBindMatrix[0]), sizeof(LLMatrix4a) * mInvBindMatrix.size()); + //hash.update((const void*)mInvBindMatrix.data(), sizeof(LLMatrix4a) * mInvBindMatrix.size()); - hash.finalize(); + mHash = hash.digest(); +} + +U32 LLMeshSkinInfo::sizeBytes() const +{ + U32 res = sizeof(LLUUID); // mMeshID + + res += sizeof(std::vector<std::string>) + sizeof(std::string) * mJointNames.size(); + for (U32 i = 0; i < mJointNames.size(); ++i) + { + res += mJointNames[i].size(); // actual size, not capacity + } - U64 digest[2]; - hash.raw_digest((U8*) digest); + res += sizeof(std::vector<S32>) + sizeof(S32) * mJointNums.size(); + res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mInvBindMatrix.size(); + res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mAlternateBindMatrix.size(); + res += 16 * sizeof(float); //mBindShapeMatrix + res += sizeof(float) + 3 * sizeof(bool); - mHash = digest[0]; + return res; } LLModel::Decomposition::Decomposition(LLSD& data) @@ -1651,6 +1696,30 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp) } } +U32 LLModel::Decomposition::sizeBytes() const +{ + U32 res = sizeof(LLUUID); // mMeshID + + res += sizeof(LLModel::convex_hull_decomposition) + sizeof(std::vector<LLVector3>) * mHull.size(); + for (U32 i = 0; i < mHull.size(); ++i) + { + res += mHull[i].size() * sizeof(LLVector3); + } + + res += sizeof(LLModel::hull) + sizeof(LLVector3) * mBaseHull.size(); + + res += sizeof(std::vector<LLModel::PhysicsMesh>) + sizeof(std::vector<LLModel::PhysicsMesh>) * mMesh.size(); + for (U32 i = 0; i < mMesh.size(); ++i) + { + res += mMesh[i].sizeBytes(); + } + + res += sizeof(std::vector<LLModel::PhysicsMesh>) * 2; + res += mBaseHullMesh.sizeBytes() + mPhysicsShapeMesh.sizeBytes(); + + return res; +} + bool LLModel::Decomposition::hasHullList() const { return !mHull.empty() ; |