diff options
author | Leyla Farazha <leyla@lindenlab.com> | 2011-03-29 16:33:47 -0700 |
---|---|---|
committer | Leyla Farazha <leyla@lindenlab.com> | 2011-03-29 16:33:47 -0700 |
commit | ac4e4607b8bde0fa05af75da5f873ef42e3c5918 (patch) | |
tree | d7c4e24a69d2b4e3a8d5bbe333795db98c4cb156 /indra | |
parent | e69aa18c0dfbef2fa3bbefeba08fa1c258c69fb3 (diff) | |
parent | 1aecac62eb88125546057be2a2a70a6b2eba1a57 (diff) |
Merge
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llmath/llvolume.cpp | 50 | ||||
-rw-r--r-- | indra/llmath/llvolume.h | 2 | ||||
-rwxr-xr-x | indra/llprimitive/llmodel.cpp | 464 | ||||
-rwxr-xr-x | indra/llprimitive/llmodel.h | 79 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 16 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.h | 2 | ||||
-rwxr-xr-x | indra/newview/llfloatermodelpreview.cpp | 134 | ||||
-rw-r--r-- | indra/newview/llfloatermodelpreview.h | 3 | ||||
-rw-r--r-- | indra/newview/llfloatermodelwizard.cpp | 1 | ||||
-rwxr-xr-x | indra/newview/llmeshrepository.cpp | 332 | ||||
-rw-r--r-- | indra/newview/llmeshrepository.h | 40 | ||||
-rw-r--r-- | indra/newview/llspatialpartition.cpp | 51 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 1 | ||||
-rw-r--r-- | indra/newview/skins/minimal/xui/de/menu_inspect_self_gear.xml | 2 | ||||
-rw-r--r-- | indra/newview/skins/minimal/xui/es/menu_inspect_self_gear.xml | 2 | ||||
-rw-r--r-- | indra/newview/skins/minimal/xui/fr/menu_inspect_self_gear.xml | 2 | ||||
-rw-r--r-- | indra/newview/skins/minimal/xui/pt/menu_inspect_self_gear.xml | 2 |
18 files changed, 643 insertions, 545 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 7a2f06da8f..dc360818d6 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2143,56 +2143,6 @@ bool LLVolumeFace::VertexData::compareNormal(const LLVolumeFace::VertexData& rhs return retval;
}
-BOOL LLVolume::createVolumeFacesFromFile(const std::string& file_name)
-{
- std::ifstream is;
-
- is.open(file_name.c_str(), std::ifstream::in | std::ifstream::binary);
-
- BOOL success = createVolumeFacesFromStream(is);
-
- is.close();
-
- return success;
-}
-
-BOOL LLVolume::createVolumeFacesFromStream(std::istream& is)
-{
- mSculptLevel = -1; // default is an error occured
-
- LLSD header;
- {
- if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024))
- {
- llwarns << "Mesh header parse error. Not a valid mesh asset!" << llendl;
- return FALSE;
- }
- }
-
- std::string nm[] =
- {
- "lowest_lod",
- "low_lod",
- "medium_lod",
- "high_lod",
- "physics_shape",
- };
-
- const S32 MODEL_LODS = 5;
-
- S32 lod = llclamp((S32) mDetail, 0, MODEL_LODS);
-
- if (header[nm[lod]]["offset"].asInteger() == -1 ||
- header[nm[lod]]["size"].asInteger() == 0 )
- { //cannot load requested LOD
- return FALSE;
- }
-
- is.seekg(header[nm[lod]]["offset"].asInteger(), std::ios_base::cur);
-
- return unpackVolumeFaces(is, header[nm[lod]]["size"].asInteger());
-}
-
bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
{
//input stream is now pointing at a zlib compressed block of LLSD
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 60b64b1285..01bfbd858b 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1048,8 +1048,6 @@ protected: BOOL generate(); void createVolumeFaces(); public: - virtual BOOL createVolumeFacesFromFile(const std::string& file_name); - virtual BOOL createVolumeFacesFromStream(std::istream& is); virtual bool unpackVolumeFaces(std::istream& is, S32 size); virtual void makeTetrahedron(); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 3669fef0dc..595f9aa307 100755 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -775,43 +775,6 @@ BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh) return FALSE; } - -BOOL LLModel::createVolumeFacesFromFile(const std::string& file_name) -{ - DAE dae; - domCOLLADA* dom = dae.open(file_name); - if (dom) - { - daeDatabase* db = dae.getDatabase(); - - daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH); - - mVolumeFaces.clear(); - mMaterialList.clear(); - - for (daeInt idx = 0; idx < count; ++idx) - { - domMesh* mesh = NULL; - - db->getElement((daeElement**) &mesh, idx, NULL, COLLADA_TYPE_MESH); - - if (mesh) - { - addVolumeFacesFromDomMesh(mesh); - } - } - - if (getNumVolumeFaces() > 0) - { - optimizeVolumeFaces(); - normalizeVolumeFaces(); - return TRUE; - } - } - - return FALSE; -} - void LLModel::offsetMesh( const LLVector3& pivotPoint ) { LLVector4a pivot( pivotPoint[VX], pivotPoint[VY], pivotPoint[VZ] ); @@ -1352,16 +1315,6 @@ std::string LLModel::getElementLabel(daeElement *element) } //static -LLModel* LLModel::loadModelFromDae(std::string filename) -{ - LLVolumeParams volume_params; - volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - LLModel* ret = new LLModel(volume_params, 0.f); - ret->createVolumeFacesFromFile(filename); - return ret; -} - -//static LLModel* LLModel::loadModelFromDomMesh(domMesh *mesh) { LLVolumeParams volume_params; @@ -1473,49 +1426,7 @@ LLSD LLModel::writeModel( if (skinning) { //write skinning block - if (high->mJointList.size() != high->mInvBindMatrix.size()) - { - llerrs << "WTF?" << llendl; - } - - for (U32 i = 0; i < high->mJointList.size(); ++i) - { - mdl["skin"]["joint_names"][i] = high->mJointList[i]; - - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - mdl["skin"]["inverse_bind_matrix"][i][j*4+k] = high->mInvBindMatrix[i].mMatrix[j][k]; - } - } - } - - for (U32 i = 0; i < 4; i++) - { - for (U32 j = 0; j < 4; j++) - { - mdl["skin"]["bind_shape_matrix"][i*4+j] = high->mBindShapeMatrix.mMatrix[i][j]; - } - } - - - if ( upload_joints && high->mAlternateBindMatrix.size() > 0 ) - { - for (U32 i = 0; i < high->mJointList.size(); ++i) - { - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - mdl["skin"]["alt_inverse_bind_matrix"][i][j*4+k] = high->mAlternateBindMatrix[i].mMatrix[j][k]; - } - } - } - - mdl["skin"]["pelvis_offset"] = high->mPelvisOffset; - } - + mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints); } if (!decomp.empty() || !base_hull.empty()) @@ -1897,12 +1808,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite) return header; } -//static -LLModel* LLModel::loadModelFromAsset(std::string filename, S32 lod) -{ - return NULL; -} - LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) { weight_map::iterator iter = mSkinWeights.find(pos); @@ -1976,27 +1881,380 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) void LLModel::setConvexHullDecomposition( const LLModel::convex_hull_decomposition& decomp) { - mConvexHullDecomp = decomp; + mPhysics.mHull = decomp; + mPhysics.mMesh.clear(); + updateHullCenters(); +} - mHullCenter.resize(mConvexHullDecomp.size()); +void LLModel::updateHullCenters() +{ + mHullCenter.resize(mPhysics.mHull.size()); mHullPoints = 0; mCenterOfHullCenters.clear(); - for (U32 i = 0; i < decomp.size(); ++i) + for (U32 i = 0; i < mPhysics.mHull.size(); ++i) { LLVector3 cur_center; - for (U32 j = 0; j < decomp[i].size(); ++j) + for (U32 j = 0; j < mPhysics.mHull[i].size(); ++j) { - cur_center += decomp[i][j]; + cur_center += mPhysics.mHull[i][j]; } mCenterOfHullCenters += cur_center; - cur_center *= 1.f/decomp[i].size(); + cur_center *= 1.f/mPhysics.mHull[i].size(); mHullCenter[i] = cur_center; - mHullPoints += decomp[i].size(); + mHullPoints += mPhysics.mHull[i].size(); } mCenterOfHullCenters *= 1.f / mHullPoints; } +bool LLModel::loadModel(std::istream& is)
+{
+ mSculptLevel = -1; // default is an error occured
+
+ LLSD header;
+ {
+ if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024))
+ {
+ llwarns << "Mesh header parse error. Not a valid mesh asset!" << llendl;
+ return false;
+ }
+ }
+
+ std::string nm[] =
+ {
+ "lowest_lod",
+ "low_lod",
+ "medium_lod",
+ "high_lod",
+ "physics_shape",
+ };
+
+ const S32 MODEL_LODS = 5;
+
+ S32 lod = llclamp((S32) mDetail, 0, MODEL_LODS);
+
+ if (header[nm[lod]]["offset"].asInteger() == -1 ||
+ header[nm[lod]]["size"].asInteger() == 0 )
+ { //cannot load requested LOD
+ return false;
+ }
+
+ bool has_skin = header["skin"]["offset"].asInteger() >=0 &&
+ header["skin"]["size"].asInteger() > 0;
+
+ if (lod == LLModel::LOD_HIGH)
+ { //try to load skin info and decomp info
+ std::ios::pos_type cur_pos = is.tellg();
+ loadSkinInfo(header, is);
+ is.seekg(cur_pos);
+ }
+
+ if (lod == LLModel::LOD_PHYSICS)
+ {
+ std::ios::pos_type cur_pos = is.tellg();
+ loadDecomposition(header, is);
+ is.seekg(cur_pos);
+ }
+
+ is.seekg(header[nm[lod]]["offset"].asInteger(), std::ios_base::cur);
+
+ if (unpackVolumeFaces(is, header[nm[lod]]["size"].asInteger()))
+ {
+ if (has_skin)
+ {
+ //build out mSkinWeight from face info
+ for (S32 i = 0; i < getNumVolumeFaces(); ++i)
+ {
+ const LLVolumeFace& face = getVolumeFace(i);
+
+ if (face.mWeights)
+ {
+ for (S32 j = 0; j < face.mNumVertices; ++j)
+ {
+ LLVector4a& w = face.mWeights[j];
+
+ std::vector<JointWeight> wght;
+
+ for (S32 k = 0; k < 4; ++k)
+ {
+ S32 idx = (S32) w[k];
+ F32 f = w[k] - idx;
+ if (f > 0.f)
+ {
+ wght.push_back(JointWeight(idx, f));
+ }
+ }
+
+ if (!wght.empty())
+ {
+ LLVector3 pos(face.mPositions[j].getF32ptr());
+ mSkinWeights[pos] = wght;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ return false;
+
+}
+ + +bool LLModel::loadSkinInfo(LLSD& header, std::istream &is) +{ + S32 offset = header["skin"]["offset"].asInteger(); + S32 size = header["skin"]["size"].asInteger(); + + if (offset >= 0 && size > 0) + { + is.seekg(offset, std::ios_base::cur); + + LLSD skin_data; + + if (unzip_llsd(skin_data, is, size)) + { + mSkinInfo.fromLLSD(skin_data); + return true; + } + } + + return false; +} + +bool LLModel::loadDecomposition(LLSD& header, std::istream& is) +{ + S32 offset = header["decomposition"]["offset"].asInteger(); + S32 size = header["decomposition"]["size"].asInteger(); + + if (offset >= 0 && size > 0) + { + is.seekg(offset, std::ios_base::cur); + + LLSD data; + + if (unzip_llsd(data, is, size)) + { + mPhysics.fromLLSD(data); + updateHullCenters(); + } + } + + return true; +} + + +LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin) +{ + fromLLSD(skin); +} + +void LLMeshSkinInfo::fromLLSD(LLSD& skin) +{ + if (skin.has("joint_names")) + { + for (U32 i = 0; i < skin["joint_names"].size(); ++i) + { + mJointNames.push_back(skin["joint_names"][i]); + } + } + + if (skin.has("inverse_bind_matrix")) + { + for (U32 i = 0; i < skin["inverse_bind_matrix"].size(); ++i) + { + LLMatrix4 mat; + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + mat.mMatrix[j][k] = skin["inverse_bind_matrix"][i][j*4+k].asReal(); + } + } + + mInvBindMatrix.push_back(mat); + } + } + + if (skin.has("bind_shape_matrix")) + { + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + mBindShapeMatrix.mMatrix[j][k] = skin["bind_shape_matrix"][j*4+k].asReal(); + } + } + } + + if (skin.has("alt_inverse_bind_matrix")) + { + for (U32 i = 0; i < skin["alt_inverse_bind_matrix"].size(); ++i) + { + LLMatrix4 mat; + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + mat.mMatrix[j][k] = skin["alt_inverse_bind_matrix"][i][j*4+k].asReal(); + } + } + + mAlternateBindMatrix.push_back(mat); + } + } + + if (skin.has("pelvis_offset")) + { + mPelvisOffset = skin["pelvis_offset"].asReal(); + } +} + +LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const +{ + LLSD ret; + + for (U32 i = 0; i < mJointNames.size(); ++i) + { + ret["joint_names"][i] = mJointNames[i]; + + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + ret["inverse_bind_matrix"][i][j*4+k] = mInvBindMatrix[i].mMatrix[j][k]; + } + } + } + + for (U32 i = 0; i < 4; i++) + { + for (U32 j = 0; j < 4; j++) + { + ret["bind_shape_matrix"][i*4+j] = mBindShapeMatrix.mMatrix[i][j]; + } + } + + if ( include_joints && mAlternateBindMatrix.size() > 0 ) + { + for (U32 i = 0; i < mJointNames.size(); ++i) + { + for (U32 j = 0; j < 4; j++) + { + for (U32 k = 0; k < 4; k++) + { + ret["alt_inverse_bind_matrix"][i][j*4+k] = mAlternateBindMatrix[i].mMatrix[j][k]; + } + } + } + + ret["pelvis_offset"] = mPelvisOffset; + } + + return ret; +} + +LLModel::Decomposition::Decomposition(LLSD& data) +{ + fromLLSD(data); +} + +void LLModel::Decomposition::fromLLSD(LLSD& decomp) +{ + if (decomp.has("HullList")) + { + // updated for const-correctness. gcc is picky about this type of thing - Nyx + const LLSD::Binary& hulls = decomp["HullList"].asBinary(); + const LLSD::Binary& position = decomp["Position"].asBinary(); + + U16* p = (U16*) &position[0]; + + mHull.resize(hulls.size()); + + LLVector3 min; + LLVector3 max; + LLVector3 range; + + min.setValue(decomp["Min"]); + max.setValue(decomp["Max"]); + range = max-min; + + for (U32 i = 0; i < hulls.size(); ++i) + { + U16 count = (hulls[i] == 0) ? 256 : hulls[i]; + + for (U32 j = 0; j < count; ++j) + { + mHull[i].push_back(LLVector3( + (F32) p[0]/65535.f*range.mV[0]+min.mV[0], + (F32) p[1]/65535.f*range.mV[1]+min.mV[1], + (F32) p[2]/65535.f*range.mV[2]+min.mV[2])); + p += 3; + } + + } + } + + if (decomp.has("Hull")) + { + const LLSD::Binary& position = decomp["Hull"].asBinary(); + + U16* p = (U16*) &position[0]; + + LLVector3 min; + LLVector3 max; + LLVector3 range; + + min.setValue(decomp["Min"]); + max.setValue(decomp["Max"]); + range = max-min; + + U16 count = position.size()/6; + + for (U32 j = 0; j < count; ++j) + { + mBaseHull.push_back(LLVector3( + (F32) p[0]/65535.f*range.mV[0]+min.mV[0], + (F32) p[1]/65535.f*range.mV[1]+min.mV[1], + (F32) p[2]/65535.f*range.mV[2]+min.mV[2])); + p += 3; + } + } + else + { + //empty base hull mesh to indicate decomposition has been loaded + //but contains no base hull + mBaseHullMesh.clear();; + } + +} + +void LLModel::Decomposition::merge(const LLModel::Decomposition* rhs) +{ + if (!rhs) + { + return; + } + + if (mMeshID != rhs->mMeshID) + { + llerrs << "Attempted to merge with decomposition of some other mesh." << llendl; + } + + if (mBaseHull.empty()) + { //take base hull and decomposition from rhs + mHull = rhs->mHull; + mBaseHull = rhs->mBaseHull; + mMesh = rhs->mMesh; + mBaseHullMesh = rhs->mBaseHullMesh; + } + + if (mPhysicsShapeMesh.empty()) + { //take physics shape mesh from rhs + mPhysicsShapeMesh = rhs->mPhysicsShapeMesh; + } +} diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index addf527d8d..e9450d2967 100755 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -27,6 +27,7 @@ #ifndef LL_LLMODEL_H #define LL_LLMODEL_H +#include "llpointer.h" #include "llvolume.h" #include "v4math.h" #include "m4math.h" @@ -36,6 +37,24 @@ class domMesh; #define MAX_MODEL_FACES 8 + +class LLMeshSkinInfo +{ +public: + LLUUID mMeshID; + std::vector<std::string> mJointNames; + std::vector<LLMatrix4> mInvBindMatrix; + std::vector<LLMatrix4> mAlternateBindMatrix; + std::map<std::string, U32> mJointMap; + + LLMeshSkinInfo() { } + LLMeshSkinInfo(LLSD& data); + void fromLLSD(LLSD& data); + LLSD asLLSD(bool include_joints) const; + LLMatrix4 mBindShapeMatrix; + float mPelvisOffset; +}; + class LLModel : public LLVolume { public: @@ -58,6 +77,9 @@ public: LLModel(LLVolumeParams& params, F32 detail); ~LLModel(); + bool loadModel(std::istream& is); + bool loadSkinInfo(LLSD& header, std::istream& is); + bool loadDecomposition(LLSD& header, std::istream& is); static LLSD writeModel( std::string filename, LLModel* physics, @@ -98,8 +120,6 @@ public: LLSD& mdl, BOOL nowrite = FALSE); - static LLModel* loadModelFromAsset(std::string filename, S32 lod); - static LLModel* loadModelFromDae(std::string filename); static LLModel* loadModelFromDomMesh(domMesh* mesh); static std::string getElementLabel(daeElement* element); std::string getName() const; @@ -177,17 +197,8 @@ public: //get list of weight influences closest to given position weight_list& getJointInfluences(const LLVector3& pos); - //should always be true that mJointList[mJointMap["foo"]] == "foo" - - //map of joint names to joint index - std::map<std::string, U32> mJointMap; - - //list of joint names - std::vector<std::string> mJointList; - - LLMatrix4 mBindShapeMatrix; - std::vector<LLMatrix4> mInvBindMatrix; - std::vector<LLMatrix4> mAlternateBindMatrix; + LLMeshSkinInfo mSkinInfo; + std::string mRequestedLabel; // name requested in UI, if any. std::string mLabel; // name computed from dae. @@ -197,9 +208,10 @@ public: float mPelvisOffset; // convex hull decomposition S32 mDecompID; - convex_hull_decomposition mConvexHullDecomp; + void setConvexHullDecomposition( const convex_hull_decomposition& decomp); + void updateHullCenters(); LLVector3 mCenterOfHullCenters; std::vector<LLVector3> mHullCenter; @@ -208,9 +220,46 @@ public: //ID for storing this model in a .slm file S32 mLocalID; + class PhysicsMesh + { + public: + std::vector<LLVector3> mPositions; + std::vector<LLVector3> mNormals; + + void clear() + { + mPositions.clear(); + mNormals.clear(); + } + + bool empty() const + { + return mPositions.empty(); + } + }; + + class Decomposition + { + public: + Decomposition() { } + Decomposition(LLSD& data); + void fromLLSD(LLSD& data); + + void merge(const Decomposition* rhs); + + LLUUID mMeshID; + LLModel::convex_hull_decomposition mHull; + LLModel::hull mBaseHull; + + std::vector<LLModel::PhysicsMesh> mMesh; + LLModel::PhysicsMesh mBaseHullMesh; + LLModel::PhysicsMesh mPhysicsShapeMesh; + }; + + Decomposition mPhysics; + protected: void addVolumeFacesFromDomMesh(domMesh* mesh); - virtual BOOL createVolumeFacesFromFile(const std::string& file_name); virtual BOOL createVolumeFacesFromDomMesh(domMesh *mesh); }; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 0d3f5b81bc..73efbfc999 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -236,6 +236,22 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) } } +//static +void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm) +{ + U32 count = pos.size(); + llassert(norm.size() >= pos.size()); + + unbind(); + + setupClientArrays(MAP_VERTEX | MAP_NORMAL); + + glVertexPointer(3, GL_FLOAT, 0, pos[0].mV); + glNormalPointer(GL_FLOAT, 0, norm[0].mV); + + glDrawArrays(sGLMode[mode], 0, count); +} + void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const { if (start >= (U32) mRequestedNumVerts || diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 2bbc17fb12..6c0895512e 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -97,6 +97,8 @@ public: static void initClass(bool use_vbo, bool no_vbo_mapping); static void cleanupClass(); static void setupClientArrays(U32 data_mask); + static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm); + static void clientCopy(F64 max_time = 0.005); //copy data from client to GL static void unbind(); //unbind any bound vertex buffer diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 4d498840fe..a2a25105bc 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -389,7 +389,11 @@ LLFloaterModelPreview::~LLFloaterModelPreview() gAgentAvatarp->resetJointPositions(); } + + if ( mModelPreview ) + { delete mModelPreview; + } if (mGLName) { @@ -1326,17 +1330,19 @@ bool LLModelLoader::doLoadModel() { //get bind shape matrix domFloat4x4& dom_value = bind_mat->getValue(); + LLMeshSkinInfo& skin_info = model->mSkinInfo; + for (int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) { - model->mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4]; + skin_info.mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4]; } } LLMatrix4 trans = normalized_transformation; - trans *= model->mBindShapeMatrix; - model->mBindShapeMatrix = trans; + trans *= skin_info.mBindShapeMatrix; + skin_info.mBindShapeMatrix = trans; } @@ -1475,7 +1481,7 @@ bool LLModelLoader::doLoadModel() xsNMTOKEN semantic = input->getSemantic(); if (strcmp(semantic, COMMON_PROFILE_INPUT_JOINT) == 0) - { //found joint source, fill model->mJointMap and model->mJointList + { //found joint source, fill model->mJointMap and model->mSkinInfo.mJointNames daeElement* elem = input->getSource().getElement(); domSource* source = daeSafeCast<domSource>(elem); @@ -1496,8 +1502,8 @@ bool LLModelLoader::doLoadModel() { name = mJointMap[name]; } - model->mJointList.push_back(name); - model->mJointMap[name] = j; + model->mSkinInfo.mJointNames.push_back(name); + model->mSkinInfo.mJointMap[name] = j; } } else @@ -1514,8 +1520,8 @@ bool LLModelLoader::doLoadModel() { name = mJointMap[name]; } - model->mJointList.push_back(name); - model->mJointMap[name] = j; + model->mSkinInfo.mJointNames.push_back(name); + model->mSkinInfo.mJointMap[name] = j; } } } @@ -1544,7 +1550,7 @@ bool LLModelLoader::doLoadModel() } } - model->mInvBindMatrix.push_back(mat); + model->mSkinInfo.mInvBindMatrix.push_back(mat); } } } @@ -1555,8 +1561,8 @@ bool LLModelLoader::doLoadModel() //(which means we have all the joints that are required for an avatar versus //a skinned asset attached to a node in a file that contains an entire skeleton, //but does not use the skeleton). - mPreview->setRigValid( doesJointArrayContainACompleteRig( model->mJointList ) ); - if ( !skeletonWithNoRootNode && !model->mJointList.empty() && mPreview->isRigValid() ) + mPreview->setRigValid( doesJointArrayContainACompleteRig( model->mSkinInfo.mJointNames ) ); + if ( !skeletonWithNoRootNode && !model->mSkinInfo.mJointNames.empty() && mPreview->isRigValid() ) { mResetJoints = true; } @@ -1596,8 +1602,8 @@ bool LLModelLoader::doLoadModel() //in the same order as they were stored in the joint buffer. The joints associated //with the skeleton are not stored in the same order as they are in the exported joint buffer. //This remaps the skeletal joints to be in the same order as the joints stored in the model. - std::vector<std::string> :: const_iterator jointIt = model->mJointList.begin(); - const int jointCnt = model->mJointList.size(); + std::vector<std::string> :: const_iterator jointIt = model->mSkinInfo.mJointNames.begin(); + const int jointCnt = model->mSkinInfo.mJointNames.size(); for ( int i=0; i<jointCnt; ++i, ++jointIt ) { std::string lookingForJoint = (*jointIt).c_str(); @@ -1606,9 +1612,9 @@ bool LLModelLoader::doLoadModel() if ( jointTransforms.find( lookingForJoint ) != jointTransforms.end() ) { LLMatrix4 jointTransform = jointTransforms[lookingForJoint]; - LLMatrix4 newInverse = model->mInvBindMatrix[i]; + LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i]; newInverse.setTranslation( jointTransforms[lookingForJoint].getTranslation() ); - model->mAlternateBindMatrix.push_back( newInverse ); + model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse ); } else { @@ -1813,10 +1819,15 @@ bool LLModelLoader::loadFromSLM(const std::string& filename) { std::stringstream str(mesh[i].asString()); LLPointer<LLModel> loaded_model = new LLModel(volume_params, (F32) lod); - if (loaded_model->createVolumeFacesFromStream(str)) + if (loaded_model->loadModel(str)) { loaded_model->mLocalID = i; model[lod].push_back(loaded_model); + + if (lod == LLModel::LOD_HIGH && !loaded_model->mSkinInfo.mJointNames.empty()) + { //check to see if rig is valid + mPreview->setRigValid( doesJointArrayContainACompleteRig( loaded_model->mSkinInfo.mJointNames ) ); + } } else { @@ -1878,8 +1889,6 @@ void LLModelLoader::loadModelCallback() { //wait until this thread is stopped before deleting self apr_sleep(100); } - - delete this; } void LLModelLoader::handlePivotPoint( daeElement* pRoot ) @@ -2455,6 +2464,7 @@ LLModelPreview::~LLModelPreview() { if (mModelLoader) { + delete mModelLoader; mModelLoader->mPreview = NULL; } //*HACK : *TODO : turn this back on when we understand why this crashes @@ -2510,8 +2520,8 @@ U32 LLModelPreview::calcResourceCost() LLModel::convex_hull_decomposition& decomp = instance.mLOD[LLModel::LOD_PHYSICS] ? - instance.mLOD[LLModel::LOD_PHYSICS]->mConvexHullDecomp : - instance.mModel->mConvexHullDecomp; + instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics.mHull : + instance.mModel->mPhysics.mHull; LLSD ret = LLModel::writeModel( "", @@ -2729,8 +2739,8 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw LLModel::convex_hull_decomposition& decomp = instance.mLOD[LLModel::LOD_PHYSICS].notNull() ? - instance.mLOD[LLModel::LOD_PHYSICS]->mConvexHullDecomp : - instance.mModel->mConvexHullDecomp; + instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics.mHull : + instance.mModel->mPhysics.mHull; LLModel::writeModel(str, instance.mLOD[LLModel::LOD_PHYSICS], @@ -2901,6 +2911,9 @@ void LLModelPreview::loadModelCallback(S32 lod) mBaseModel.clear(); mBaseScene.clear(); + bool skin_weights = false; + bool joint_positions = false; + for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) { //for each LoD @@ -2934,11 +2947,39 @@ void LLModelPreview::loadModelCallback(S32 lod) } mModel[lod][idx] = list_iter->mModel; + if (!list_iter->mModel->mSkinWeights.empty()) + { + skin_weights = true; + + if (!list_iter->mModel->mSkinInfo.mAlternateBindMatrix.empty()) + { + joint_positions = true; + } + } } } } } + if (mFMP) + { + LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) mFMP; + + if (skin_weights) + { //enable uploading/previewing of skin weights if present in .slm file + fmp->enableViewOption("show_skin_weight"); + mViewOption["show_skin_weight"] = true; + fmp->childSetValue("upload_skin", true); + } + + if (joint_positions) + { + fmp->enableViewOption("show_joint_positions"); + mViewOption["show_joint_positions"] = true; + fmp->childSetValue("upload_joints", true); + } + } + //copy high lod to base scene for LoD generation mBaseScene = mScene[LLModel::LOD_HIGH]; mBaseModel = mModel[LLModel::LOD_HIGH]; @@ -2952,14 +2993,8 @@ void LLModelPreview::loadModelCallback(S32 lod) mScene[lod] = mModelLoader->mScene; mVertexBuffer[lod].clear(); - if (lod == LLModel::LOD_PHYSICS) - { - mPhysicsMesh.clear(); - } - setPreviewLOD(lod); - if (lod == LLModel::LOD_HIGH) { //save a copy of the highest LOD for automatic LOD manipulation if (mBaseModel.empty()) @@ -3082,11 +3117,6 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim return; } - if (which_lod == LLModel::LOD_PHYSICS) - { //clear physics mesh map - mPhysicsMesh.clear(); - } - LLVertexBuffer::unbind(); stop_gloderror(); @@ -3415,11 +3445,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim //of an open problem). target_model->mPosition = base->mPosition; target_model->mSkinWeights = base->mSkinWeights; - target_model->mJointMap = base->mJointMap; - target_model->mJointList = base->mJointList; - target_model->mInvBindMatrix = base->mInvBindMatrix; - target_model->mBindShapeMatrix = base->mBindShapeMatrix; - target_model->mAlternateBindMatrix = base->mAlternateBindMatrix; + target_model->mSkinInfo = base->mSkinInfo; //copy material list target_model->mMaterialList = base->mMaterialList; @@ -3639,7 +3665,7 @@ void LLModelPreview::updateStatusMessages() LLModel* model = mModel[LLModel::LOD_PHYSICS][i]; S32 cur_submeshes = model->getNumVolumeFaces(); - LLModel::convex_hull_decomposition& decomp = model->mConvexHullDecomp; + LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull; if (!decomp.empty()) { @@ -4276,12 +4302,17 @@ BOOL LLModelPreview::render() { LLMutexLock(decomp->mMutex); - std::map<LLPointer<LLModel>, std::vector<LLPointer<LLVertexBuffer> > >::iterator iter = - mPhysicsMesh.find(model); - if (iter != mPhysicsMesh.end()) + LLModel::Decomposition& physics = model->mPhysics; + + if (physics.mMesh.empty()) + { //build vertex buffer for physics mesh + gMeshRepo.buildPhysicsMesh(physics); + } + + if (!physics.mMesh.empty()) { //render hull instead of mesh render_mesh = false; - for (U32 i = 0; i < iter->second.size(); ++i) + for (U32 i = 0; i < physics.mMesh.size(); ++i) { if (explode > 0.f) { @@ -4300,14 +4331,8 @@ BOOL LLModelPreview::render() hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255)); } - LLVertexBuffer* buff = iter->second[i]; - if (buff) - { - buff->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL); - glColor4ubv(hull_colors[i].mV); - buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts()); - } + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals); if (explode > 0.f) { @@ -4391,12 +4416,12 @@ BOOL LLModelPreview::render() //build matrix palette LLMatrix4 mat[64]; - for (U32 j = 0; j < model->mJointList.size(); ++j) + for (U32 j = 0; j < model->mSkinInfo.mJointNames.size(); ++j) { - LLJoint* joint = avatar->getJoint(model->mJointList[j]); + LLJoint* joint = avatar->getJoint(model->mSkinInfo.mJointNames[j]); if (joint) { - mat[j] = model->mInvBindMatrix[j]; + mat[j] = model->mSkinInfo.mInvBindMatrix[j]; mat[j] *= joint->getWorldMatrix(); } } @@ -4437,7 +4462,7 @@ BOOL LLModelPreview::render() //VECTORIZE THIS LLVector3 v(face.mPositions[j].getF32ptr()); - v = v * model->mBindShapeMatrix; + v = v * model->mSkinInfo.mBindShapeMatrix; v = v * final_mat; position[j] = v; @@ -4687,7 +4712,6 @@ void LLFloaterModelPreview::DecompRequest::completed() { if (sInstance->mModelPreview) { - sInstance->mModelPreview->mPhysicsMesh[mModel] = mHullMesh; sInstance->mModelPreview->mDirty = true; LLFloaterModelPreview::sInstance->mModelPreview->refresh(); } diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 68fa0fa4c1..6542ed4fbe 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -358,8 +358,7 @@ public: U32 mGroup; std::map<LLPointer<LLModel>, U32> mObject; U32 mMaxTriangleLimit; - std::map<LLPointer<LLModel>, std::vector<LLPointer<LLVertexBuffer> > > mPhysicsMesh; - + LLMeshUploadThread::instance_list mUploadData; std::set<LLViewerFetchedTexture* > mTextureSet; diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp index 9751b87b4c..532c6789bb 100644 --- a/indra/newview/llfloatermodelwizard.cpp +++ b/indra/newview/llfloatermodelwizard.cpp @@ -485,7 +485,6 @@ void LLFloaterModelWizard::DecompRequest::completed() { if (sInstance->mModelPreview) { - sInstance->mModelPreview->mPhysicsMesh[mModel] = mHullMesh; sInstance->mModelPreview->mDirty = true; LLFloaterModelWizard::sInstance->mModelPreview->refresh(); } diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index a2792bcdc6..752e4c8744 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -108,19 +108,13 @@ U32 get_volume_memory_size(const LLVolume* volume) return indices*2+vertices*11+sizeof(LLVolume)+sizeof(LLVolumeFace)*volume->getNumVolumeFaces(); } -LLVertexBuffer* get_vertex_buffer_from_mesh(LLCDMeshData& mesh, F32 scale = 1.f) +void get_vertex_buffer_from_mesh(LLCDMeshData& mesh, LLModel::PhysicsMesh& res, F32 scale = 1.f) { - LLVertexBuffer* buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL, 0); - buff->allocateBuffer(mesh.mNumTriangles*3, 0, true); - - LLStrider<LLVector3> pos; - LLStrider<LLVector3> norm; + res.mPositions.clear(); + res.mNormals.clear(); - buff->getVertexStrider(pos); - buff->getNormalStrider(norm); - const F32* v = mesh.mVertexBase; - + if (mesh.mIndexType == LLCDMeshData::INT_16) { U16* idx = (U16*) mesh.mIndexBase; @@ -139,13 +133,13 @@ LLVertexBuffer* get_vertex_buffer_from_mesh(LLCDMeshData& mesh, F32 scale = 1.f) LLVector3 n = (v1-v0)%(v2-v0); n.normalize(); - *pos++ = v0*scale; - *pos++ = v1*scale; - *pos++ = v2*scale; + res.mPositions.push_back(v0*scale); + res.mPositions.push_back(v1*scale); + res.mPositions.push_back(v2*scale); - *norm++ = n; - *norm++ = n; - *norm++ = n; + res.mNormals.push_back(n); + res.mNormals.push_back(n); + res.mNormals.push_back(n); } } else @@ -166,17 +160,15 @@ LLVertexBuffer* get_vertex_buffer_from_mesh(LLCDMeshData& mesh, F32 scale = 1.f) LLVector3 n = (v1-v0)%(v2-v0); n.normalize(); - *(pos++) = v0*scale; - *(pos++) = v1*scale; - *(pos++) = v2*scale; + res.mPositions.push_back(v0*scale); + res.mPositions.push_back(v1*scale); + res.mPositions.push_back(v2*scale); - *(norm++) = n; - *(norm++) = n; - *(norm++) = n; + res.mNormals.push_back(n); + res.mNormals.push_back(n); + res.mNormals.push_back(n); } } - - return buff; } S32 LLMeshRepoThread::sActiveHeaderRequests = 0; @@ -1111,66 +1103,9 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat } { - LLMeshSkinInfo info; + LLMeshSkinInfo info(skin); info.mMeshID = mesh_id; - if (skin.has("joint_names")) - { - for (U32 i = 0; i < skin["joint_names"].size(); ++i) - { - info.mJointNames.push_back(skin["joint_names"][i]); - } - } - - if (skin.has("inverse_bind_matrix")) - { - for (U32 i = 0; i < skin["inverse_bind_matrix"].size(); ++i) - { - LLMatrix4 mat; - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - mat.mMatrix[j][k] = skin["inverse_bind_matrix"][i][j*4+k].asReal(); - } - } - - info.mInvBindMatrix.push_back(mat); - } - } - - if (skin.has("bind_shape_matrix")) - { - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - info.mBindShapeMatrix.mMatrix[j][k] = skin["bind_shape_matrix"][j*4+k].asReal(); - } - } - } - - if (skin.has("alt_inverse_bind_matrix")) - { - for (U32 i = 0; i < skin["alt_inverse_bind_matrix"].size(); ++i) - { - LLMatrix4 mat; - for (U32 j = 0; j < 4; j++) - { - for (U32 k = 0; k < 4; k++) - { - mat.mMatrix[j][k] = skin["alt_inverse_bind_matrix"][i][j*4+k].asReal(); - } - } - - info.mAlternateBindMatrix.push_back(mat); - } - } - - if (skin.has("pelvis_offset")) - { - info.mPelvisOffset = skin["pelvis_offset"].asReal(); - } //llinfos<<"info pelvis offset"<<info.mPelvisOffset<<llendl; mSkinInfoQ.push(info); } @@ -1196,119 +1131,8 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 } { - LLMeshDecomposition* d = new LLMeshDecomposition(); + LLModel::Decomposition* d = new LLModel::Decomposition(decomp); d->mMeshID = mesh_id; - - if (decomp.has("HullList")) - { - // updated for const-correctness. gcc is picky about this type of thing - Nyx - const LLSD::Binary& hulls = decomp["HullList"].asBinary(); - const LLSD::Binary& position = decomp["Position"].asBinary(); - - U16* p = (U16*) &position[0]; - - d->mHull.resize(hulls.size()); - - LLVector3 min; - LLVector3 max; - LLVector3 range; - - min.setValue(decomp["Min"]); - max.setValue(decomp["Max"]); - range = max-min; - - for (U32 i = 0; i < hulls.size(); ++i) - { - U16 count = (hulls[i] == 0) ? 256 : hulls[i]; - - for (U32 j = 0; j < count; ++j) - { - d->mHull[i].push_back(LLVector3( - (F32) p[0]/65535.f*range.mV[0]+min.mV[0], - (F32) p[1]/65535.f*range.mV[1]+min.mV[1], - (F32) p[2]/65535.f*range.mV[2]+min.mV[2])); - p += 3; - } - - } - - //get mesh for decomposition - for (U32 i = 0; i < d->mHull.size(); ++i) - { - LLCDHull hull; - hull.mNumVertices = d->mHull[i].size(); - hull.mVertexBase = d->mHull[i][0].mV; - hull.mVertexStrideBytes = 12; - - LLCDMeshData mesh; - LLCDResult res = LLCD_OK; - if (LLConvexDecomposition::getInstance() != NULL) - { - res = LLConvexDecomposition::getInstance()->getMeshFromHull(&hull, &mesh); - } - if (res != LLCD_OK) - { - llwarns << "could not get mesh from hull from convex decomposition lib." << llendl; - return false; - } - - - d->mMesh.push_back(get_vertex_buffer_from_mesh(mesh)); - } - } - - if (decomp.has("Hull")) - { - const LLSD::Binary& position = decomp["Hull"].asBinary(); - - U16* p = (U16*) &position[0]; - - LLVector3 min; - LLVector3 max; - LLVector3 range; - - min.setValue(decomp["Min"]); - max.setValue(decomp["Max"]); - range = max-min; - - U16 count = position.size()/6; - - for (U32 j = 0; j < count; ++j) - { - d->mBaseHull.push_back(LLVector3( - (F32) p[0]/65535.f*range.mV[0]+min.mV[0], - (F32) p[1]/65535.f*range.mV[1]+min.mV[1], - (F32) p[2]/65535.f*range.mV[2]+min.mV[2])); - p += 3; - } - - //get mesh for decomposition - LLCDHull hull; - hull.mNumVertices = d->mBaseHull.size(); - hull.mVertexBase = d->mBaseHull[0].mV; - hull.mVertexStrideBytes = 12; - - LLCDMeshData mesh; - LLCDResult res = LLCD_OK; - if (LLConvexDecomposition::getInstance() != NULL) - { - res = LLConvexDecomposition::getInstance()->getMeshFromHull(&hull, &mesh); - } - if (res != LLCD_OK) - { - llwarns << "could not get mesh from hull from convex decomposition lib." << llendl; - return false; - } - - d->mBaseHullMesh = get_vertex_buffer_from_mesh(mesh); - } - else - { - //empty vertex buffer to indicate decomposition has been fetched - //but contains no base hull - d->mBaseHullMesh = new LLVertexBuffer(0, 0); - } - mDecompositionQ.push(d); } @@ -1319,12 +1143,12 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 { LLSD physics_shape; - LLMeshDecomposition* d = new LLMeshDecomposition(); + LLModel::Decomposition* d = new LLModel::Decomposition(); d->mMeshID = mesh_id; if (data == NULL) { //no data, no physics shape exists - d->mPhysicsShapeMesh = new LLVertexBuffer(0,0); + d->mPhysicsShapeMesh.clear(); } else { @@ -1348,33 +1172,22 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 index_count += face.mNumIndices; } - d->mPhysicsShapeMesh = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, 0); - - d->mPhysicsShapeMesh->allocateBuffer(vertex_count, index_count, true); - - LLStrider<LLVector3> pos; - LLStrider<U16> idx; + d->mPhysicsShapeMesh.clear(); - d->mPhysicsShapeMesh->getVertexStrider(pos); - d->mPhysicsShapeMesh->getIndexStrider(idx); + std::vector<LLVector3>& pos = d->mPhysicsShapeMesh.mPositions; + std::vector<LLVector3>& norm = d->mPhysicsShapeMesh.mNormals; - S32 idx_offset = 0; for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) { const LLVolumeFace& face = volume->getVolumeFace(i); - if (idx_offset + face.mNumIndices > 65535) - { //avoid 16-bit index overflow - continue; - } - - LLVector4a::memcpyNonAliased16(pos[idx_offset].mV, face.mPositions[0].getF32ptr(), face.mNumVertices*sizeof(LLVector4a)); for (S32 i = 0; i < face.mNumIndices; ++i) { - *idx++ = face.mIndices[i] + idx_offset; - } + U16 idx = face.mIndices[i]; - idx_offset += face.mNumVertices; + pos.push_back(LLVector3(face.mPositions[idx].getF32ptr())); + norm.push_back(LLVector3(face.mNormals[idx].getF32ptr())); + } } } } @@ -2485,33 +2298,7 @@ void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info) mLoadingSkins.erase(info.mMeshID); } -void LLMeshDecomposition::merge(const LLMeshDecomposition* rhs) -{ - if (!rhs) - { - return; - } - - if (mMeshID != rhs->mMeshID) - { - llerrs << "Attempted to merge with decomposition of some other mesh." << llendl; - } - - if (mBaseHull.empty()) - { //take base hull and decomposition from rhs - mHull = rhs->mHull; - mBaseHull = rhs->mBaseHull; - mMesh = rhs->mMesh; - mBaseHullMesh = rhs->mBaseHullMesh; - } - - if (mPhysicsShapeMesh.isNull()) - { //take physics shape mesh from rhs - mPhysicsShapeMesh = rhs->mPhysicsShapeMesh; - } -} - -void LLMeshRepository::notifyDecompositionReceived(LLMeshDecomposition* decomp) +void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decomp) { decomposition_map::iterator iter = mDecompositionMap.find(decomp->mMeshID); if (iter == mDecompositionMap.end()) @@ -2653,7 +2440,7 @@ void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id) { if (mesh_id.notNull()) { - LLMeshDecomposition* decomp = NULL; + LLModel::Decomposition* decomp = NULL; decomposition_map::iterator iter = mDecompositionMap.find(mesh_id); if (iter != mDecompositionMap.end()) { @@ -2661,7 +2448,7 @@ void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id) } //decomposition block hasn't been fetched yet - if (!decomp || decomp->mPhysicsShapeMesh.isNull()) + if (!decomp || decomp->mPhysicsShapeMesh.empty()) { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes @@ -2676,9 +2463,9 @@ void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id) } -const LLMeshDecomposition* LLMeshRepository::getDecomposition(const LLUUID& mesh_id) +LLModel::Decomposition* LLMeshRepository::getDecomposition(const LLUUID& mesh_id) { - LLMeshDecomposition* ret = NULL; + LLModel::Decomposition* ret = NULL; if (mesh_id.notNull()) { @@ -2689,7 +2476,7 @@ const LLMeshDecomposition* LLMeshRepository::getDecomposition(const LLUUID& mesh } //decomposition block hasn't been fetched yet - if (!ret || ret->mBaseHullMesh.isNull()) + if (!ret || ret->mBaseHullMesh.empty()) { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes @@ -2792,8 +2579,8 @@ void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data) LLModel::convex_hull_decomposition& decomp = data.mModel[LLModel::LOD_PHYSICS].notNull() ? - data.mModel[LLModel::LOD_PHYSICS]->mConvexHullDecomp : - data.mBaseModel->mConvexHullDecomp; + data.mModel[LLModel::LOD_PHYSICS]->mPhysics.mHull : + data.mBaseModel->mPhysics.mHull; LLModel::hull dummy_hull; @@ -2893,8 +2680,8 @@ void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data) LLModel::convex_hull_decomposition& decomp = data.mModel[LLModel::LOD_PHYSICS].notNull() ? - data.mModel[LLModel::LOD_PHYSICS]->mConvexHullDecomp : - data.mBaseModel->mConvexHullDecomp; + data.mModel[LLModel::LOD_PHYSICS]->mPhysics.mHull : + data.mBaseModel->mPhysics.mHull; LLModel::writeModel( ostr, @@ -3412,7 +3199,7 @@ void LLPhysicsDecomp::doDecomposition() // if LLConvexDecomposition is a stub, num_hulls should have been set to 0 above, and we should not reach this code LLConvexDecomposition::getInstance()->getMeshFromStage(stage, i, &mesh); - mCurRequest->mHullMesh[i] = get_vertex_buffer_from_mesh(mesh); + get_vertex_buffer_from_mesh(mesh, mCurRequest->mHullMesh[i]); mMutex->lock(); mCurRequest->mHull[i] = p; @@ -3685,3 +3472,46 @@ LLSD LLImportMaterial::asLLSD() return ret; } + +void LLMeshRepository::buildPhysicsMesh(LLModel::Decomposition& decomp) +{ + decomp.mMesh.resize(decomp.mHull.size());
+
+ for (U32 i = 0; i < decomp.mHull.size(); ++i)
+ {
+ LLCDHull hull; + hull.mNumVertices = decomp.mHull[i].size(); + hull.mVertexBase = decomp.mHull[i][0].mV; + hull.mVertexStrideBytes = 12; + + LLCDMeshData mesh; + LLCDResult res = LLCD_OK; + if (LLConvexDecomposition::getInstance() != NULL) + { + res = LLConvexDecomposition::getInstance()->getMeshFromHull(&hull, &mesh); + } + if (res == LLCD_OK) + { + get_vertex_buffer_from_mesh(mesh, decomp.mMesh[i]);
+ }
+ } + + if (!decomp.mBaseHull.empty() && decomp.mBaseHullMesh.empty()) + { //get mesh for base hull + LLCDHull hull; + hull.mNumVertices = decomp.mBaseHull.size(); + hull.mVertexBase = decomp.mBaseHull[0].mV; + hull.mVertexStrideBytes = 12; + + LLCDMeshData mesh; + LLCDResult res = LLCD_OK; + if (LLConvexDecomposition::getInstance() != NULL) + { + res = LLConvexDecomposition::getInstance()->getMeshFromHull(&hull, &mesh); + } + if (res == LLCD_OK) + { + get_vertex_buffer_from_mesh(mesh, decomp.mBaseHullMesh); + } + } +} diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 4e349a1270..31c2049c32 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -132,34 +132,6 @@ public: LLSD asLLSD(); }; -class LLMeshSkinInfo -{ -public: - LLUUID mMeshID; - std::vector<std::string> mJointNames; - std::vector<LLMatrix4> mInvBindMatrix; - std::vector<LLMatrix4> mAlternateBindMatrix; - - LLMatrix4 mBindShapeMatrix; - float mPelvisOffset; -}; - -class LLMeshDecomposition -{ -public: - LLMeshDecomposition() { } - - void merge(const LLMeshDecomposition* rhs); - - LLUUID mMeshID; - LLModel::convex_hull_decomposition mHull; - LLModel::hull mBaseHull; - - std::vector<LLPointer<LLVertexBuffer> > mMesh; - LLPointer<LLVertexBuffer> mBaseHullMesh; - LLPointer<LLVertexBuffer> mPhysicsShapeMesh; -}; - class LLPhysicsDecomp : public LLThread { public: @@ -178,7 +150,7 @@ public: //output state std::string mStatusMessage; - std::vector<LLPointer<LLVertexBuffer> > mHullMesh; + std::vector<LLModel::PhysicsMesh> mHullMesh; LLModel::convex_hull_decomposition mHull; //status message callback, called from decomposition thread @@ -313,7 +285,7 @@ public: std::set<LLUUID> mPhysicsShapeRequests; //queue of completed Decomposition info requests - std::queue<LLMeshDecomposition*> mDecompositionQ; + std::queue<LLModel::Decomposition*> mDecompositionQ; //queue of requested headers std::queue<HeaderRequest> mHeaderReqQ; @@ -477,17 +449,19 @@ public: void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume); void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod); void notifySkinInfoReceived(LLMeshSkinInfo& info); - void notifyDecompositionReceived(LLMeshDecomposition* info); + void notifyDecompositionReceived(LLModel::Decomposition* info); S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); U32 calcResourceCost(LLSD& header); U32 getResourceCost(const LLUUID& mesh_params); const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id); - const LLMeshDecomposition* getDecomposition(const LLUUID& mesh_id); + LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id); void fetchPhysicsShape(const LLUUID& mesh_id); bool hasPhysicsShape(const LLUUID& mesh_id); void buildHull(const LLVolumeParams& params, S32 detail); + void buildPhysicsMesh(LLModel::Decomposition& decomp); + const LLSD& getMeshHeader(const LLUUID& mesh_id); void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, @@ -501,7 +475,7 @@ public: typedef std::map<LLUUID, LLMeshSkinInfo> skin_map; skin_map mSkinMap; - typedef std::map<LLUUID, LLMeshDecomposition*> decomposition_map; + typedef std::map<LLUUID, LLModel::Decomposition*> decomposition_map; decomposition_map mDecompositionMap; LLMutex* mMeshMutex; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 5e7af6bbb3..65f7d299bc 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2961,31 +2961,21 @@ S32 get_physics_detail(const LLVolumeParams& volume_params, const LLVector3& sca void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLColor4& line_color) { LLUUID mesh_id = volume->getVolume()->getParams().getSculptID(); - const LLMeshDecomposition* decomp = gMeshRepo.getDecomposition(mesh_id); + LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id); const LLVector3 center(0,0,0); const LLVector3 size(0.25f,0.25f,0.25f); if (decomp) { - LLVertexBuffer* buff = decomp->mBaseHullMesh; - - if (buff && buff->getNumVerts() > 0) + if (!decomp->mBaseHullMesh.empty()) { - buff->setBuffer(data_mask); - - /* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glColor4fv(line_color.mV); - buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts()); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);*/ - - { - glColor4fv(color.mV); - buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts()); - } + glColor4fv(color.mV); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions, decomp->mBaseHullMesh.mNormals); } else { + gMeshRepo.buildPhysicsMesh(*decomp); gGL.color3f(0,1,1); drawBoxOutline(center, size); } @@ -2998,19 +2988,16 @@ void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLCo } } -void render_hull(LLVertexBuffer* buff, U32 data_mask, const LLColor4& color, const LLColor4& line_color) +void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color, const LLColor4& line_color) { - buff->setBuffer(data_mask); - glColor4fv(color.mV); - buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts()); - + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions, mesh.mNormals); LLGLEnable offset(GL_POLYGON_OFFSET_LINE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glPolygonOffset(3.f, 3.f); glLineWidth(3.f); glColor4fv(line_color.mV); - buff->drawArrays(LLRender::TRIANGLES, 0, buff->getNumVerts()); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions, mesh.mNormals); glLineWidth(1.f); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } @@ -3075,7 +3062,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_MESH) { LLUUID mesh_id = volume->getVolume()->getParams().getSculptID(); - const LLMeshDecomposition* decomp = gMeshRepo.getDecomposition(mesh_id); + LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id); if (decomp) { //render a physics based mesh @@ -3084,27 +3071,33 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) if (!decomp->mHull.empty()) { //decomposition exists, use that - for (U32 i = 0; i < decomp->mHull.size(); ++i) + + if (decomp->mMesh.empty()) + { + gMeshRepo.buildPhysicsMesh(*decomp); + } + + for (U32 i = 0; i < decomp->mMesh.size(); ++i) { - render_hull(decomp->mMesh[i], data_mask, color, line_color); + render_hull(decomp->mMesh[i], color, line_color); } } - else if (decomp->mPhysicsShapeMesh.notNull() && decomp->mPhysicsShapeMesh->getNumVerts() > 0) + else if (!decomp->mPhysicsShapeMesh.empty()) { //decomp has physics mesh, render that mesh glColor4fv(color.mV); - pushBufferVerts(decomp->mPhysicsShapeMesh, data_mask); - + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions, decomp->mPhysicsShapeMesh.mNormals); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glColor4fv(line_color.mV); - pushBufferVerts(decomp->mPhysicsShapeMesh, data_mask); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions, decomp->mPhysicsShapeMesh.mNormals); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { //no mesh or decomposition, render base hull renderMeshBaseHull(volume, data_mask, color, line_color); - if (decomp->mPhysicsShapeMesh.isNull()) + if (decomp->mPhysicsShapeMesh.empty()) { //attempt to fetch physics shape mesh if available gMeshRepo.fetchPhysicsShape(mesh_id); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 7468281f65..71706f0146 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -762,6 +762,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mPelvisOffset = LLVector3(0.0f,0.0f,0.0f);
mLastPelvisToFoot = 0.0f;
mPelvisFixup = 0.0f;
+ mLastPelvisFixup = 0.0f;
}
//------------------------------------------------------------------------
@@ -3805,6 +3806,7 @@ void LLVOAvatar::setPelvisOffset( bool hasOffset, const LLVector3& offsetAmount, //Store off last pelvis to foot value
mLastPelvisToFoot = mPelvisToFoot;
mPelvisOffset = offsetAmount;
+ mLastPelvisFixup = mPelvisFixup;
mPelvisFixup = pelvisFixup;
}
}
@@ -3825,6 +3827,7 @@ void LLVOAvatar::postPelvisSetRecalc( void ) void LLVOAvatar::setPelvisOffset( F32 pelvisFixupAmount )
{
mHasPelvisOffset = true;
+ mLastPelvisFixup = mPelvisFixup;
mPelvisFixup = pelvisFixupAmount;
}
//------------------------------------------------------------------------
@@ -4965,6 +4968,7 @@ void LLVOAvatar::resetJointPositions( void ) mSkeleton[i].setId( LLUUID::null );
}
mHasPelvisOffset = false;
+ mPelvisFixup = mLastPelvisFixup;
}
//-----------------------------------------------------------------------------
// resetSpecificJointPosition
@@ -5024,6 +5028,7 @@ void LLVOAvatar::resetJointPositionsToDefault( void ) }
//make sure we don't apply the joint offset
mHasPelvisOffset = false;
+ mPelvisFixup = mLastPelvisFixup;
postPelvisSetRecalc();
}
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 1552532a97..edec1b480a 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -301,6 +301,7 @@ public: LLVector3 mPelvisOffset;
F32 mLastPelvisToFoot;
F32 mPelvisFixup;
+ F32 mLastPelvisFixup;
LLVector3 mHeadOffset; // current head position
LLViewerJoint mRoot;
diff --git a/indra/newview/skins/minimal/xui/de/menu_inspect_self_gear.xml b/indra/newview/skins/minimal/xui/de/menu_inspect_self_gear.xml index 19264db598..443092319b 100644 --- a/indra/newview/skins/minimal/xui/de/menu_inspect_self_gear.xml +++ b/indra/newview/skins/minimal/xui/de/menu_inspect_self_gear.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Gear Menu"> +<toggleable_menu name="Self Pie"> <menu_item_call label="Hinsetzen" name="Sit Down Here"/> <menu_item_call label="Aufstehen" name="Stand Up"/> <menu_item_call label="Meine Freunde" name="Friends..."/> diff --git a/indra/newview/skins/minimal/xui/es/menu_inspect_self_gear.xml b/indra/newview/skins/minimal/xui/es/menu_inspect_self_gear.xml index 6b76137114..1a49efb9d0 100644 --- a/indra/newview/skins/minimal/xui/es/menu_inspect_self_gear.xml +++ b/indra/newview/skins/minimal/xui/es/menu_inspect_self_gear.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Gear Menu"> +<toggleable_menu name="Self Pie"> <menu_item_call label="Sentarme" name="Sit Down Here"/> <menu_item_call label="Levantarme" name="Stand Up"/> <menu_item_call label="Mis amigos" name="Friends..."/> diff --git a/indra/newview/skins/minimal/xui/fr/menu_inspect_self_gear.xml b/indra/newview/skins/minimal/xui/fr/menu_inspect_self_gear.xml index 7a79c00123..fd48aa4f7d 100644 --- a/indra/newview/skins/minimal/xui/fr/menu_inspect_self_gear.xml +++ b/indra/newview/skins/minimal/xui/fr/menu_inspect_self_gear.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Gear Menu"> +<toggleable_menu name="Self Pie"> <menu_item_call label="M'asseoir" name="Sit Down Here"/> <menu_item_call label="Me lever" name="Stand Up"/> <menu_item_call label="Mes amis" name="Friends..."/> diff --git a/indra/newview/skins/minimal/xui/pt/menu_inspect_self_gear.xml b/indra/newview/skins/minimal/xui/pt/menu_inspect_self_gear.xml index e514d2f4f5..c1f27e765d 100644 --- a/indra/newview/skins/minimal/xui/pt/menu_inspect_self_gear.xml +++ b/indra/newview/skins/minimal/xui/pt/menu_inspect_self_gear.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<toggleable_menu name="Gear Menu"> +<toggleable_menu name="Self Pie"> <menu_item_call label="Sentar" name="Sit Down Here"/> <menu_item_call label="Ficar de pé" name="Stand Up"/> <menu_item_call label="Meus amigos" name="Friends..."/> |