summaryrefslogtreecommitdiff
path: root/indra/llprimitive/llmodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llprimitive/llmodel.cpp')
-rw-r--r--indra/llprimitive/llmodel.cpp199
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() ;