From 2ea8df0593d520b86bcf958263622218f76ac113 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 26 Aug 2015 10:49:02 -0400 Subject: SL-205 WIP - support for 152-joint rigged meshes with both hardware and software skinning. --- indra/llprimitive/llmodel.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index ed903146ef..7290fa5f83 100755 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1762,6 +1762,7 @@ LLSD LLModel::writeModel( S32 count = 0; for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter) { + // BENTO JOINT COUNT LIMIT 255? if (iter->mJointIdx < 255 && iter->mJointIdx >= 0) { U8 idx = (U8) iter->mJointIdx; -- cgit v1.3 From ebad0c6868b924ba607a1b2256ae7621cab62bf4 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 1 Oct 2015 11:05:29 -0400 Subject: DRTVWR-412 WIP - more work for importer merge from viewer-release --- indra/llprimitive/lldaeloader.cpp | 18 +++++----- indra/llprimitive/lldaeloader.h | 11 +++--- indra/llprimitive/llmodelloader.cpp | 63 ++++++++++++--------------------- indra/llprimitive/llmodelloader.h | 27 +++++++------- indra/newview/llfloatermodelpreview.cpp | 25 +++++++++++++ indra/newview/llfloatermodelpreview.h | 3 +- 6 files changed, 80 insertions(+), 67 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index c1b74b1fd7..6ff9613c80 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -801,15 +801,16 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac // LLDAELoader //----------------------------------------------------------------------------- LLDAELoader::LLDAELoader( - std::string filename, - S32 lod, + std::string filename, + S32 lod, load_callback_t load_cb, joint_lookup_func_t joint_lookup_func, texture_load_func_t texture_load_func, - state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointMap, - JointSet& jointsFromNodes, + state_callback_t state_cb, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + JointNameSet& legalJointNames, U32 modelLimit) : LLModelLoader( filename, @@ -819,8 +820,9 @@ LLDAELoader::LLDAELoader( texture_load_func, state_cb, opaque_userdata, - jointMap, - jointsFromNodes), + jointTransformMap, + jointsFromNodes, + legalJointNames), mGeneratedModelLimit(modelLimit) { } diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 7d91a6063b..896451320c 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -47,15 +47,16 @@ public: dae_model_map mModelsMap; LLDAELoader( - std::string filename, - S32 lod, + std::string filename, + S32 lod, LLModelLoader::load_callback_t load_cb, LLModelLoader::joint_lookup_func_t joint_lookup_func, LLModelLoader::texture_load_func_t texture_load_func, LLModelLoader::state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointMap, - JointSet& jointsFromNodes, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + JointNameSet& legalJointNames, U32 modelLimit); virtual ~LLDAELoader() ; diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index 81d92d151b..9cf0f10a7e 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -102,16 +102,17 @@ void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3& // LLModelLoader //----------------------------------------------------------------------------- LLModelLoader::LLModelLoader( - std::string filename, - S32 lod, + std::string filename, + S32 lod, load_callback_t load_cb, joint_lookup_func_t joint_lookup_func, texture_load_func_t texture_load_func, - state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointMap, - JointSet& jointsFromNodes ) -: mJointList( jointMap ) + state_callback_t state_cb, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + JointNameSet& legalJointNames) +: mJointList( jointTransformMap ) , mJointsFromNode( jointsFromNodes ) , LLThread("Model Loader") , mFilename(filename) @@ -127,33 +128,15 @@ LLModelLoader::LLModelLoader( , mNoOptimize(false) , mCacheOnlyHitIfRigged(false) { - mJointMap["mPelvis"] = "mPelvis"; - mJointMap["mTorso"] = "mTorso"; - mJointMap["mChest"] = "mChest"; - mJointMap["mNeck"] = "mNeck"; - mJointMap["mHead"] = "mHead"; - mJointMap["mSkull"] = "mSkull"; - mJointMap["mEyeRight"] = "mEyeRight"; - mJointMap["mEyeLeft"] = "mEyeLeft"; - mJointMap["mCollarLeft"] = "mCollarLeft"; - mJointMap["mShoulderLeft"] = "mShoulderLeft"; - mJointMap["mElbowLeft"] = "mElbowLeft"; - mJointMap["mWristLeft"] = "mWristLeft"; - mJointMap["mCollarRight"] = "mCollarRight"; - mJointMap["mShoulderRight"] = "mShoulderRight"; - mJointMap["mElbowRight"] = "mElbowRight"; - mJointMap["mWristRight"] = "mWristRight"; - mJointMap["mHipRight"] = "mHipRight"; - mJointMap["mKneeRight"] = "mKneeRight"; - mJointMap["mAnkleRight"] = "mAnkleRight"; - mJointMap["mFootRight"] = "mFootRight"; - mJointMap["mToeRight"] = "mToeRight"; - mJointMap["mHipLeft"] = "mHipLeft"; - mJointMap["mKneeLeft"] = "mKneeLeft"; - mJointMap["mAnkleLeft"] = "mAnkleLeft"; - mJointMap["mFootLeft"] = "mFootLeft"; - mJointMap["mToeLeft"] = "mToeLeft"; - + // Recognize all names we've been told are legal. + for (JointNameSet::iterator joint_name_it = legalJointNames.begin(); + joint_name_it != legalJointNames.end(); ++joint_name_it) + { + const std::string& name = *joint_name_it; + mJointMap[name] = name; + } + + // Also support various legacy aliases for commonly used joints mJointMap["avatar_mPelvis"] = "mPelvis"; mJointMap["avatar_mTorso"] = "mTorso"; mJointMap["avatar_mChest"] = "mChest"; @@ -501,8 +484,8 @@ void LLModelLoader::critiqueJointToNodeMappingFromScene( void ) //Do the actual nodes back the joint listing from the dae? //if yes then this is a fully rigged asset, otherwise it's just a partial rig - JointSet::iterator jointsFromNodeIt = mJointsFromNode.begin(); - JointSet::iterator jointsFromNodeEndIt = mJointsFromNode.end(); + JointNameSet::iterator jointsFromNodeIt = mJointsFromNode.begin(); + JointNameSet::iterator jointsFromNodeEndIt = mJointsFromNode.end(); bool result = true; if ( !mJointsFromNode.empty() ) @@ -547,8 +530,8 @@ bool LLModelLoader::isRigLegacy( const std::vector &jointListFromAs bool result = false; - JointSet :: const_iterator masterJointIt = mMasterLegacyJointList.begin(); - JointSet :: const_iterator masterJointEndIt = mMasterLegacyJointList.end(); + JointNameSet :: const_iterator masterJointIt = mMasterLegacyJointList.begin(); + JointNameSet :: const_iterator masterJointEndIt = mMasterLegacyJointList.end(); std::vector :: const_iterator modelJointIt = jointListFromAsset.begin(); std::vector :: const_iterator modelJointItEnd = jointListFromAsset.end(); @@ -581,8 +564,8 @@ bool LLModelLoader::isRigSuitableForJointPositionUpload( const std::vector :: const_iterator modelJointIt = jointListFromAsset.begin(); std::vector :: const_iterator modelJointItEnd = jointListFromAsset.end(); diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index bb4d06dca3..894de2c76f 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -34,10 +34,10 @@ class LLJoint; -typedef std::map JointTransformMap; -typedef std::map:: iterator JointTransformMapIt; -typedef std::map JointMap; -typedef std::deque JointSet; +typedef std::map JointTransformMap; +typedef std::map::iterator JointTransformMapIt; +typedef std::map JointMap; +typedef std::deque JointNameSet; const S32 SLM_SUPPORTED_VERSION = 3; const S32 NUM_LOD = 4; @@ -116,18 +116,19 @@ public: //map of avatar joints as named in COLLADA assets to internal joint names JointMap mJointMap; JointTransformMap& mJointList; - JointSet& mJointsFromNode; + JointNameSet& mJointsFromNode; LLModelLoader( - std::string filename, - S32 lod, + std::string filename, + S32 lod, LLModelLoader::load_callback_t load_cb, LLModelLoader::joint_lookup_func_t joint_lookup_func, LLModelLoader::texture_load_func_t texture_load_func, LLModelLoader::state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointMap, - JointSet& jointsFromNodes); + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + JointNameSet& legalJointNames); virtual ~LLModelLoader() ; virtual void setNoNormalize() { mNoNormalize = true; } @@ -189,7 +190,7 @@ protected: LLModelLoader::joint_lookup_func_t mJointLookupFunc; LLModelLoader::texture_load_func_t mTextureLoadFunc; LLModelLoader::state_callback_t mStateCallback; - void* mOpaqueData; + void* mOpaqueData; bool mRigParityWithScene; bool mRigValidJointUpload; @@ -198,8 +199,8 @@ protected: bool mNoNormalize; bool mNoOptimize; - JointSet mMasterJointList; - JointSet mMasterLegacyJointList; + JointNameSet mMasterJointList; + JointNameSet mMasterLegacyJointList; JointTransformMap mJointTransformMap; static std::list sActiveLoaderList; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index a64685f699..18a2729398 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1708,6 +1708,21 @@ void LLModelPreview::clearModel(S32 lod) mScene[lod].clear(); } +void LLModelPreview::getLegalJointNames(JointNameSet& legal_joint_names) +{ + // Get all standard skeleton joints from the preview avatar. + LLVOAvatar *av = getPreviewAvatar(); + const LLVOAvatar::avatar_joint_list_t &skel = av->getSkeleton(); + for (S32 i=0; igetName()); + } + } +} + void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable_slm) { assert_main_thread(); @@ -1750,6 +1765,10 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable clearGLODGroup(); } + + JointNameSet legal_joint_names; + getLegalJointNames(legal_joint_names); + mModelLoader = new LLDAELoader( filename, lod, @@ -1760,6 +1779,7 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable this, mJointTransformMap, mJointsFromNode, + legal_joint_names, gSavedSettings.getU32("ImporterModelLimit")); if (force_disable_slm) @@ -3689,6 +3709,11 @@ BOOL LLModelPreview::render() } } + if (regen) + { + genBuffers(mPreviewLOD, skin_weight); + } + if (!skin_weight) { for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 7a518c798b..25c650a725 100755 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -259,6 +259,7 @@ public: virtual BOOL needsRender() { return mNeedsUpdate; } void setPreviewLOD(S32 lod); void clearModel(S32 lod); + void getLegalJointNames(JointNameSet& legal_joint_names); void loadModel(std::string filename, S32 lod, bool force_disable_slm = false); void loadModelCallback(S32 lod); void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false); @@ -405,7 +406,7 @@ private: bool mLastJointUpdate; - JointSet mJointsFromNode; + JointNameSet mJointsFromNode; JointTransformMap mJointTransformMap; LLPointer mPreviewAvatar; -- cgit v1.3 From 8729f5d23a52263e55df5574c672c87d00b563bd Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Tue, 13 Oct 2015 16:40:39 -0700 Subject: Bandaid for SL-202 Skin weights with joint offsets. --- indra/llprimitive/lldaeloader.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 6ff9613c80..6db6bc4dc7 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1368,10 +1368,14 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i]; newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() ); model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse ); - } + } else { LL_WARNS()<<"Possibly misnamed/missing joint [" <mSkinInfo.mAlternateBindMatrix.push_back( emptyInverse ); } } -- cgit v1.3 From 58992e2cb4ae2787b85cff63c3ed680cd99fa8ce Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 16 Oct 2015 15:05:29 -0400 Subject: SL-234 WIP - Track which joints are part of base skeleton, remap non-base ones when not being rendered. --- indra/llappearance/llavatarappearance.cpp | 9 + indra/llcharacter/lljoint.cpp | 22 ++ indra/llcharacter/lljoint.h | 13 + indra/llprimitive/lldaeloader.cpp | 6 +- indra/llprimitive/llmodel.h | 4 +- indra/newview/app_settings/settings.xml | 11 + .../character/avatar_skeleton_tentacles.xml | 307 ++++++++++----------- indra/newview/lldrawpoolavatar.cpp | 201 ++++++++++++-- indra/newview/lldrawpoolavatar.h | 1 + 9 files changed, 401 insertions(+), 173 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index f2cd2768d8..a464ffcb43 100755 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -87,6 +87,7 @@ public: private: std::string mName; + std::string mSupport; BOOL mIsJoint; LLVector3 mPos; LLVector3 mRot; @@ -605,6 +606,7 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY], info->mRot.mV[VZ], LLQuaternion::XYZ)); joint->setScale(info->mScale); + joint->setSupport(info->mSupport); if (info->mIsJoint) { @@ -1564,6 +1566,13 @@ BOOL LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node) return FALSE; } + static LLStdStringHandle support_string = LLXmlTree::addAttributeString("support"); + if (!node->getFastAttributeString(support_string,mSupport)) + { + LL_WARNS() << "Bone without support" << LL_ENDL; + mSupport = "base"; + } + if (mIsJoint) { static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 8fa08a2a6c..2c6278fe45 100755 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -108,6 +108,7 @@ void LLJoint::init() mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f)); mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY; mUpdateXform = TRUE; + mSupport = SUPPORT_BASE; } LLJoint::LLJoint() : @@ -169,6 +170,27 @@ void LLJoint::setup(const std::string &name, LLJoint *parent) } } +//----------------------------------------------------------------------------- +// setSupport() +//----------------------------------------------------------------------------- +void LLJoint::setSupport(const std::string& support_name) +{ + if (support_name == "extended") + { + setSupport(SUPPORT_EXTENDED); + } + else if (support_name == "base") + { + setSupport(SUPPORT_BASE); + } + else + { + LL_WARNS() << "unknown support string " << support_name << LL_ENDL; + setSupport(SUPPORT_BASE); + } +} + + //----------------------------------------------------------------------------- // touch() // Sets all dirty flags for all children, recursively. diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index b3bf588d79..de61d56101 100755 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -91,9 +91,17 @@ public: POSITION_DIRTY = 0x1 << 2, ALL_DIRTY = 0x7 }; +public: + enum SupportCategory + { + SUPPORT_BASE, + SUPPORT_EXTENDED + }; protected: std::string mName; + SupportCategory mSupport; + // parent joint LLJoint *mParent; @@ -144,6 +152,11 @@ public: const std::string& getName() const { return mName; } void setName( const std::string &name ) { mName = name; } + // get/set support + SupportCategory getSupport() const { return mSupport; } + void setSupport( const SupportCategory& support) { mSupport = support; } + void setSupport( const std::string& support_string); + // getParent LLJoint *getParent() { return mParent; } diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 6ff9613c80..e7fbbba84e 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1257,7 +1257,8 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do name = mJointMap[name]; } model->mSkinInfo.mJointNames.push_back(name); - model->mSkinInfo.mJointMap[name] = j; + // BENTO this does not appear to be used anywhere. + // model->mSkinInfo.mJointMap[name] = j; } } else @@ -1275,7 +1276,8 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do name = mJointMap[name]; } model->mSkinInfo.mJointNames.push_back(name); - model->mSkinInfo.mJointMap[name] = j; + // BENTO not used? + // model->mSkinInfo.mJointMap[name] = j; } } } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index ae602c09df..56844ac16d 100755 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -46,7 +46,9 @@ public: std::vector mJointNames; std::vector mInvBindMatrix; std::vector mAlternateBindMatrix; - std::map mJointMap; + std::vector mJointRemap; + // BENTO not used? + //std::map mJointMap; LLMeshSkinInfo() { } LLMeshSkinInfo(LLSD& data); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 133e51b531..8bf91c0f1e 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3492,6 +3492,17 @@ Value 0 + IncludeEnhancedSkeleton + + Comment + Include extended skeleton joints when rendering skinned meshes. + Persist + 1 + Type + Boolean + Value + 1 + MinObjectsForUnlinkConfirm Comment diff --git a/indra/newview/character/avatar_skeleton_tentacles.xml b/indra/newview/character/avatar_skeleton_tentacles.xml index 9863a5cbfd..929feaf25c 100644 --- a/indra/newview/character/avatar_skeleton_tentacles.xml +++ b/indra/newview/character/avatar_skeleton_tentacles.xml @@ -1,64 +1,63 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + + + @@ -69,16 +68,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -89,16 +88,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -109,16 +108,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -129,16 +128,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -149,16 +148,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -169,16 +168,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -189,16 +188,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -209,16 +208,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -229,16 +228,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -251,27 +250,27 @@ - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index e8f53e0f3d..987a15c72d 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1549,6 +1549,156 @@ U32 LLDrawPoolAvatar::getMeshJointCount(const LLMeshSkinInfo *skin) return llmin((U32)getMaxJointCount(), (U32)skin->mJointNames.size()); } +bool getNameIndex(const std::string& name, std::vector& names, U32& result) +{ + std::vector::const_iterator find_it = + std::find(names.begin(), names.end(), name); + if (find_it != names.end()) + { + result = find_it - names.begin(); + return true; + } + else + { + return false; + } +} + +// Find a name table index that is also a valid joint on the +// avatar. Order of preference is: requested name, mPelvis, first +// valid match in names table. +U32 getValidJointIndex(const std::string& name, LLVOAvatar *avatar, std::vector& joint_names) +{ + U32 result; + if (avatar->getJoint(name) && getNameIndex(name,joint_names,result)) + { + return result; + } + if (getNameIndex("mPelvis",joint_names,result)) + { + return result; + } + for (U32 j=0; jgetJoint(joint_names[j])) + { + return j; + } + } + // BENTO how to handle? + LL_ERRS() << "no valid joints in joint_names" << LL_ENDL; + return 0; +} + +// Which joint will stand in for this joint? +U32 getProxyJointIndex(U32 joint_index, LLVOAvatar *avatar, std::vector& joint_names) +{ +#if 1 + bool include_enhanced = gSavedSettings.getBOOL("IncludeEnhancedSkeleton"); + U32 j_proxy = getValidJointIndex(joint_names[joint_index], avatar, joint_names); + LLJoint *joint = avatar->getJoint(joint_names[j_proxy]); + llassert(joint); + // BENTO - test of simple push-to-base-ancestor + // complexity reduction scheme. Find the first + // ancestor that's not flagged as extended, or the + // last ancestor that's rigged in this mesh, whichever + // comes first. + while (1) + { + if (include_enhanced || + joint->getSupport()==LLJoint::SUPPORT_BASE) + break; + LLJoint *parent = joint->getParent(); + if (!parent) + break; + if (!getNameIndex(parent->getName(), joint_names, j_proxy)) + { + break; + } + joint = parent; + } + return j_proxy; +#else + return 0; +#endif +} + +// static + +// Destructively remap the joints in skin info based on what joints +// are known in the avatar, and which are currently supported. This +// will also populate mJointRemap[] in the skin, which can be used to +// make the corresponding changes to the integer part of vertex +// weights. +// +// This will throw away joint info for any joints that are not known +// in the avatar, or not currently flagged to support based on the +// debug setting for IncludeEnhancedSkeleton. +void LLDrawPoolAvatar::remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin) +{ + // skip if already done. + if (!skin->mJointRemap.empty()) + { + return; + } + + // Compute the remap + std::vector j_proxy(skin->mJointNames.size()); + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + U32 j_rep = getProxyJointIndex(j, avatar, skin->mJointNames); + j_proxy[j] = j_rep; + } + S32 top = 0; + std::vector j_remap(skin->mJointNames.size()); + // Fill in j_remap for all joints that will make the cut. + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + if (j_proxy[j] == j) + { + // Joint will be included + j_remap[j] = top++; + } + } + // Then use j_proxy to fill in j_remap for the joints that will be discarded + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + if (j_proxy[j] != j) + { + j_remap[j] = j_remap[j_proxy[j]]; + } + } + + + // Apply the remap to mJointNames, mInvBindMatrix, and mAlternateBindMatrix + std::vector new_joint_names; + std::vector new_inv_bind_matrix; + std::vector new_alternate_bind_matrix; + + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + if (j_proxy[j] == j) + { + new_joint_names.push_back(skin->mJointNames[j]); + new_inv_bind_matrix.push_back(skin->mInvBindMatrix[j]); + if (!skin->mAlternateBindMatrix.empty()) + { + new_alternate_bind_matrix.push_back(skin->mAlternateBindMatrix[j]); + } + } + } + + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + LL_INFOS() << "Starting joint[" << j << "] = " << skin->mJointNames[j] << " j_remap " << j_remap[j] << " ==> " << new_joint_names[j_remap[j]] << LL_ENDL; + } + + //skin->mJointNames = new_joint_names; + //skin->mInvBindMatrix = new_inv_bind_matrix; + //skin->mAlternateBindMatrix = new_alternate_bind_matrix; + skin->mJointRemap = j_remap; +} + // static void LLDrawPoolAvatar::initSkinningMatrixPalette( LLMatrix4* mat, @@ -1556,38 +1706,57 @@ void LLDrawPoolAvatar::initSkinningMatrixPalette( const LLMeshSkinInfo* skin, LLVOAvatar *avatar) { + // BENTO ugly const cast + remapSkinInfoJoints(avatar, const_cast(skin)); + // BENTO - switching to use Matrix4a and SSE might speed this up. // Note that we are mostly passing Matrix4a's to this routine anyway, just dubiously casted. for (U32 j = 0; j < count; ++j) { LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); +#if 1 // Don't need this stuff if we've already remapped/cleaned up above if (!joint) { joint = avatar->getJoint("mPelvis"); } if (joint) { -#if 0 - // BENTO HACK - test of simple push-to-ancestor complexity reduction scheme. - const std::string& name = joint->getName(); - S32 digit = name.back()-'0'; - while (joint->getParent() && (digit<=9) && (digit>=5)) + if (!gSavedSettings.getBOOL("IncludeEnhancedSkeleton")) { - joint = joint->getParent(); - const std::string& name = joint->getName(); - digit = name.back()-'0'; + // BENTO - test of simple push-to-base-ancestor + // complexity reduction scheme. Find the first + // ancestor that's not flagged as extended, or the + // last ancestor that's rigged in this mesh, whichever + // comes first. + U32 j_remap = 0; + while (1) + { + if (joint->getSupport()==LLJoint::SUPPORT_BASE) + break; + LLJoint *parent = joint->getParent(); + if (!parent) + break; + std::vector::const_iterator find_it = + std::find(skin->mJointNames.begin(), skin->mJointNames.end(), parent->getName()); + if (find_it != skin->mJointNames.end()) + { + j_remap = find_it - skin->mJointNames.begin(); + } + else + { + break; + } + joint = parent; + } + mat[j] = skin->mInvBindMatrix[j_remap]; } - U32 j_remap = 0; - std::vector::const_iterator find_it = - std::find(skin->mJointNames.begin(), skin->mJointNames.end(), joint->getName()); - if (find_it != skin->mJointNames.end()) + else { - j_remap = find_it - skin->mJointNames.begin(); + mat[j] = skin->mInvBindMatrix[j]; } - // BENTO for hack, use invBindMatrix of up-casted joint - mat[j] = skin->mInvBindMatrix[j_remap]; -#endif +#else mat[j] = skin->mInvBindMatrix[j]; +#endif mat[j] *= joint->getWorldMatrix(); } } diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 79d16c26bc..27d4c949fd 100755 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -136,6 +136,7 @@ public: void getRiggedGeometry(LLFace* face, LLPointer& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face); static U32 getMaxJointCount(); static U32 getMeshJointCount(const LLMeshSkinInfo *skin); + static void remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin); static void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar); static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, -- cgit v1.3 From 97374a5362f097afd3027ea51757de2e36af4798 Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Tue, 27 Oct 2015 15:15:34 -0700 Subject: Fixes SL-202 joint offset and skin weight import. Race condition still exists. --- indra/llprimitive/lldaeloader.cpp | 12 ++----- indra/llprimitive/lldaeloader.h | 1 - indra/newview/llappviewer.cpp | 2 +- indra/newview/llfloatermodelpreview.cpp | 20 ++++------- indra/newview/llfloatermodelpreview.h | 2 -- indra/newview/llvoavatar.cpp | 63 +-------------------------------- indra/newview/llvoavatar.h | 5 +-- 7 files changed, 13 insertions(+), 92 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 6db6bc4dc7..b4c5c844ef 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1303,8 +1303,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do mat.mMatrix[i][j] = transform[k*16 + i + j*4]; } } - - model->mSkinInfo.mInvBindMatrix.push_back(mat); + model->mSkinInfo.mInvBindMatrix.push_back(mat); } } } @@ -1362,20 +1361,15 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do std::string lookingForJoint = (*jointIt).c_str(); //Look for the joint xform that we extracted from the skeleton, using the jointIt as the key //and store it in the alternate bind matrix - if ( mJointList.find( lookingForJoint ) != mJointList.end() ) + if ( mJointMap.find( lookingForJoint ) != mJointMap.end() ) { - LLMatrix4 jointTransform = mJointList[lookingForJoint]; LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i]; newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() ); model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse ); } else { - LL_WARNS()<<"Possibly misnamed/missing joint [" <mSkinInfo.mAlternateBindMatrix.push_back( emptyInverse ); + LL_WARNS()<<"Possibly misnamed/missing joint [" <getName()); } } + + std::stringstream cvstr; + for (S32 i = 0; i < av->mNumCollisionVolumes; i++) + { + legal_joint_names.push_back(av->mCollisionVolumes[i].getName()); + cvstr << legal_joint_names[i]; + } } void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable_slm) @@ -3351,19 +3358,6 @@ void LLModelPreview::update() } } -//----------------------------------------------------------------------------- -// getTranslationForJointOffset() -//----------------------------------------------------------------------------- -LLVector3 LLModelPreview::getTranslationForJointOffset( std::string joint ) -{ - LLMatrix4 jointTransform; - if ( mJointTransformMap.find( joint ) != mJointTransformMap.end() ) - { - jointTransform = mJointTransformMap[joint]; - return jointTransform.getTranslation(); - } - return LLVector3(0.0f,0.0f,0.0f); -} //----------------------------------------------------------------------------- // createPreviewAvatar //----------------------------------------------------------------------------- diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 25c650a725..d9351029ec 100755 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -300,8 +300,6 @@ public: void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; } const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; } - LLVector3 getTranslationForJointOffset( std::string joint ); - static bool sIgnoreLoadedCallback; protected: diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 68bb39eb98..3b482e1bc0 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -213,24 +213,6 @@ struct LLTextureMaskData ** **/ -//------------------------------------------------------------------------ -// LLVOAvatarBoneInfo -// Trans/Scale/Rot etc. info about each avatar bone. Used by LLVOAvatarSkeleton. -//------------------------------------------------------------------------ -struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block -{ - LLVOAvatarCollisionVolumeInfo() - : name("name"), - pos("pos"), - rot("rot"), - scale("scale") - {} - - Mandatory name; - Mandatory pos, - rot, - scale; -}; struct LLAppearanceMessageContents { @@ -252,49 +234,6 @@ struct LLAppearanceMessageContents bool mHoverOffsetWasSet; }; -struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock - { - Alternative > bone; - Alternative collision_volume; - - LLVOAvatarChildJoint() - : bone("bone"), - collision_volume("collision_volume") - {} -}; - - - -struct LLVOAvatarBoneInfo : public LLInitParam::Block -{ - LLVOAvatarBoneInfo() - : pivot("pivot") - {} - - Mandatory pivot; - Multiple children; -}; - -//------------------------------------------------------------------------ -// LLVOAvatarSkeletonInfo -// Overall avatar skeleton -//------------------------------------------------------------------------ -struct LLVOAvatarSkeletonInfo : public LLInitParam::Block -{ - LLVOAvatarSkeletonInfo() - : skeleton_root(""), - num_bones("num_bones"), - num_collision_volumes("num_collision_volumes"), - version("version") - {} - - Mandatory version; - Mandatory num_bones, - num_collision_volumes; - Mandatory skeleton_root; -}; - - //----------------------------------------------------------------------------- // class LLBodyNoiseMotion @@ -1527,7 +1466,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& for (S32 i = 0; i < mNumCollisionVolumes; ++i) { mCollisionVolumes[i].updateWorldMatrix(); - + glh::matrix4f mat((F32*) mCollisionVolumes[i].getXform()->getWorldMatrix().mMatrix); glh::matrix4f inverse = mat.inverse(); glh::matrix4f norm_mat = inverse.transpose(); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 5b4379165a..7a2355b447 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -68,11 +68,8 @@ class LLVoiceVisualizer; class LLHUDNameTag; class LLHUDEffectSpiral; class LLTexGlobalColor; -struct LLVOAvatarBoneInfo; -struct LLVOAvatarChildJoint; -//class LLViewerJoint; + struct LLAppearanceMessageContents; -struct LLVOAvatarSkeletonInfo; class LLViewerJointMesh; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.3 From ded9b10d5dd60cb85934d0ab029e8c5a297d4123 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 29 Oct 2015 16:09:22 -0400 Subject: SL-114 WIP - constrain uploaded meshes based on max joints per mesh. Set max joints per mesh to 110. Also fixed some uninitialized members of LLModelLoader. --- indra/llcharacter/lljoint.h | 2 +- indra/llprimitive/lldaeloader.cpp | 4 +++- indra/llprimitive/lldaeloader.h | 1 + indra/llprimitive/llmodelloader.cpp | 17 +++++++++++++++-- indra/llprimitive/llmodelloader.h | 4 +++- indra/newview/llfloatermodelpreview.cpp | 1 + 6 files changed, 24 insertions(+), 5 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 113742ad74..2a8ebed408 100755 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -42,7 +42,7 @@ const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15; // BENTO JOINT COUNT LIMIT const U32 LL_CHARACTER_MAX_JOINTS = 152; // must be divisible by 4! -const U32 LL_MAX_JOINTS_PER_MESH_OBJECT = 132; +const U32 LL_MAX_JOINTS_PER_MESH_OBJECT = 110; // FIXME BENTO - these should be higher than the joint_num of any // other joint, to avoid conflicts in updateMotionsByType() diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index c50db824af..c7eaba412d 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -811,6 +811,7 @@ LLDAELoader::LLDAELoader( JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, JointNameSet& legalJointNames, + U32 maxJointsPerMesh, U32 modelLimit) : LLModelLoader( filename, @@ -822,7 +823,8 @@ LLDAELoader::LLDAELoader( opaque_userdata, jointTransformMap, jointsFromNodes, - legalJointNames), + legalJointNames, + maxJointsPerMesh), mGeneratedModelLimit(modelLimit) { } diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 79856741db..ebc6acf18f 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -57,6 +57,7 @@ public: JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, JointNameSet& legalJointNames, + U32 maxJointsPerMesh, U32 modelLimit); virtual ~LLDAELoader() ; diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index 9cf0f10a7e..4acf695f22 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -111,12 +111,14 @@ LLModelLoader::LLModelLoader( void* opaque_userdata, JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, - JointNameSet& legalJointNames) + JointNameSet& legalJointNames, + U32 maxJointsPerMesh) : mJointList( jointTransformMap ) , mJointsFromNode( jointsFromNodes ) , LLThread("Model Loader") , mFilename(filename) , mLod(lod) +, mTrySLM(false) , mFirstTransform(TRUE) , mNumOfFetchingTextures(0) , mLoadCallback(load_cb) @@ -124,9 +126,13 @@ LLModelLoader::LLModelLoader( , mTextureLoadFunc(texture_load_func) , mStateCallback(state_cb) , mOpaqueData(opaque_userdata) +, mRigParityWithScene(false) +, mRigValidJointUpload(false) +, mLegacyRigValid(false) , mNoNormalize(false) , mNoOptimize(false) , mCacheOnlyHitIfRigged(false) +, mMaxJointsPerMesh(maxJointsPerMesh) { // Recognize all names we've been told are legal. for (JointNameSet::iterator joint_name_it = legalJointNames.begin(); @@ -456,7 +462,14 @@ void LLModelLoader::loadModelCallback() void LLModelLoader::critiqueRigForUploadApplicability( const std::vector &jointListFromAsset ) { critiqueJointToNodeMappingFromScene(); - + + if (jointListFromAsset.size()>mMaxJointsPerMesh) + { + LL_WARNS() << "Rigged to " << jointListFromAsset.size() << " joints, max is " << mMaxJointsPerMesh << LL_ENDL; + LL_WARNS() << "Skinning disabled" << LL_ENDL; + return; + } + //Determines the following use cases for a rig: //1. It is suitable for upload with skin weights & joint positions, or //2. It is suitable for upload as standard av with just skin weights diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index 894de2c76f..0b5d7168fa 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -117,6 +117,7 @@ public: JointMap mJointMap; JointTransformMap& mJointList; JointNameSet& mJointsFromNode; + U32 mMaxJointsPerMesh; LLModelLoader( std::string filename, @@ -128,7 +129,8 @@ public: void* opaque_userdata, JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, - JointNameSet& legalJointNames); + JointNameSet& legalJointNames, + U32 maxJointsPerMesh); virtual ~LLModelLoader() ; virtual void setNoNormalize() { mNoNormalize = true; } diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 9c72238d87..a8069dd569 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1786,6 +1786,7 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable mJointTransformMap, mJointsFromNode, legal_joint_names, + LLSkinningUtil::getMaxJointCount(), gSavedSettings.getU32("ImporterModelLimit")); if (force_disable_slm) -- cgit v1.3 From 3cf938bcec9a4925a4f7d8becb9b89ff559eb2e3 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 4 Nov 2015 16:41:37 -0500 Subject: SL-124 WIP - BENTO comments and related cleanup --- indra/llcharacter/llbvhloader.cpp | 3 +-- indra/llcharacter/lljoint.h | 2 +- indra/llprimitive/lldaeloader.cpp | 4 ---- indra/llprimitive/llmodel.h | 2 -- indra/newview/llskinningutil.cpp | 4 +--- 5 files changed, 3 insertions(+), 12 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 4dedeeab52..b4f0bb9e18 100755 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -903,8 +903,7 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & return E_ST_NO_CHANNELS; } - // FIXME BENTO do we want to open up motion of non-hip joints or - // not? Already effectively allowed via .anim upload. + // Animating position (via mNumChannels = 6) is only supported for mPelvis. int res = sscanf(line.c_str(), " CHANNELS %d", &joint->mNumChannels); if ( res != 1 ) { diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 2a8ebed408..8d380cdc82 100755 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -40,7 +40,7 @@ #include "xform.h" const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15; -// BENTO JOINT COUNT LIMIT +// BENTO JOINT COUNT LIMIT - need to set this to final skeleton size + 2 const U32 LL_CHARACTER_MAX_JOINTS = 152; // must be divisible by 4! const U32 LL_MAX_JOINTS_PER_MESH_OBJECT = 110; diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index c7eaba412d..ab38973dfe 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1259,8 +1259,6 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do name = mJointMap[name]; } model->mSkinInfo.mJointNames.push_back(name); - // BENTO this does not appear to be used anywhere. - // model->mSkinInfo.mJointMap[name] = j; } } else @@ -1278,8 +1276,6 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do name = mJointMap[name]; } model->mSkinInfo.mJointNames.push_back(name); - // BENTO not used? - // model->mSkinInfo.mJointMap[name] = j; } } } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 56844ac16d..5f98942340 100755 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -47,8 +47,6 @@ public: std::vector mInvBindMatrix; std::vector mAlternateBindMatrix; std::vector mJointRemap; - // BENTO not used? - //std::map mJointMap; LLMeshSkinInfo() { } LLMeshSkinInfo(LLSD& data); diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 4f974d5912..c32345cbe9 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -85,9 +85,7 @@ U32 get_proxy_joint_index(U32 joint_index, LLVOAvatar *avatar, std::vectorgetJoint(joint_names[j_proxy]); llassert(joint); - // BENTO - test of simple push-to-base-ancestor - // complexity reduction scheme. Find the first - // ancestor that's not flagged as extended, or the + // Find the first ancestor that's not flagged as extended, or the // last ancestor that's rigged in this mesh, whichever // comes first. while (1) -- cgit v1.3 From be11d020ca6b941ec86622718c9eeafd5fddb7b5 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 9 Nov 2015 14:57:00 -0500 Subject: SL-266 WIP - removed obsolete rigParityWithScene code, set legacy and joint offset upload based on AND-ing state of all meshes in file. --- indra/llprimitive/lldaeloader.cpp | 69 +++++++++++++----------- indra/llprimitive/llmodelloader.cpp | 96 ++++++++++++++------------------- indra/llprimitive/llmodelloader.h | 5 -- indra/newview/llfloatermodelpreview.cpp | 1 - indra/newview/llfloatermodelpreview.h | 3 -- 5 files changed, 77 insertions(+), 97 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index ab38973dfe..7e2cf67297 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1187,6 +1187,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do extractTranslation( pTranslateA, workingTransform ); } else + { if ( pTranslateB ) { extractTranslation( pTranslateB, workingTransform ); @@ -1211,9 +1212,10 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do } } + } - //Store the joint transform w/respect to it's name. - mJointList[(*jointIt).second.c_str()] = workingTransform; + //Store the joint transform w/respect to its name. + mJointList[(*jointIt).second.c_str()] = workingTransform; } } @@ -1319,35 +1321,40 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do if ( !missingSkeletonOrScene ) { - //Set the joint translations on the avatar - if it's a full mapping - //The joints are reset in the dtor - if ( getRigWithSceneParity() ) - { - JointMap :: const_iterator masterJointIt = mJointMap.begin(); - JointMap :: const_iterator masterJointItEnd = mJointMap.end(); - for (;masterJointIt!=masterJointItEnd;++masterJointIt ) - { - std::string lookingForJoint = (*masterJointIt).first.c_str(); - - if ( mJointList.find( lookingForJoint ) != mJointList.end() ) - { - //LL_INFOS()<<"joint "<addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, ""); - } - else - { - //Most likely an error in the asset. - LL_WARNS()<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << LL_ENDL; - } - } - } - } + //Set the joint translations on the avatar + JointMap :: const_iterator masterJointIt = mJointMap.begin(); + JointMap :: const_iterator masterJointItEnd = mJointMap.end(); + for (;masterJointIt!=masterJointItEnd;++masterJointIt ) + { + std::string lookingForJoint = (*masterJointIt).first.c_str(); + + if ( mJointList.find( lookingForJoint ) != mJointList.end() ) + { + //LL_INFOS()<<"joint "<addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, ""); + } + else + { + //Most likely an error in the asset. + LL_WARNS()<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << LL_ENDL; + } + } + } } //missingSkeletonOrScene //We need to construct the alternate bind matrix (which contains the new joint positions) diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index 4acf695f22..b12d1042da 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -126,9 +126,8 @@ LLModelLoader::LLModelLoader( , mTextureLoadFunc(texture_load_func) , mStateCallback(state_cb) , mOpaqueData(opaque_userdata) -, mRigParityWithScene(false) -, mRigValidJointUpload(false) -, mLegacyRigValid(false) +, mRigValidJointUpload(true) +, mLegacyRigValid(true) , mNoNormalize(false) , mNoOptimize(false) , mCacheOnlyHitIfRigged(false) @@ -461,15 +460,6 @@ void LLModelLoader::loadModelCallback() //----------------------------------------------------------------------------- void LLModelLoader::critiqueRigForUploadApplicability( const std::vector &jointListFromAsset ) { - critiqueJointToNodeMappingFromScene(); - - if (jointListFromAsset.size()>mMaxJointsPerMesh) - { - LL_WARNS() << "Rigged to " << jointListFromAsset.size() << " joints, max is " << mMaxJointsPerMesh << LL_ENDL; - LL_WARNS() << "Skinning disabled" << LL_ENDL; - return; - } - //Determines the following use cases for a rig: //1. It is suitable for upload with skin weights & joint positions, or //2. It is suitable for upload as standard av with just skin weights @@ -477,59 +467,27 @@ void LLModelLoader::critiqueRigForUploadApplicability( const std::vector &jointListFromAs return false; } + // Too many joints in asset + if (jointListFromAsset.size()>mMaxJointsPerMesh) + { + LL_WARNS() << "Rigged to " << jointListFromAsset.size() << " joints, max is " << mMaxJointsPerMesh << LL_ENDL; + LL_WARNS() << "Skinning disabled" << LL_ENDL; + return false; + } + + // Unknown joints in asset + S32 unknown_joint_count = 0; + for (std::vector::const_iterator it = jointListFromAsset.begin(); + it != jointListFromAsset.end(); ++it) + { + if (mJointMap.find(*it)==mJointMap.end()) + { + LL_WARNS() << "Rig to unrecognized name " << *it << ", isRigLegacy() will fail" << LL_ENDL; + unknown_joint_count++; + } + } + if (unknown_joint_count>0) + { + return false; + } + bool result = false; JointNameSet :: const_iterator masterJointIt = mMasterLegacyJointList.begin(); diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index 0b5d7168fa..ad8372f077 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -161,7 +161,6 @@ public: //Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps) void critiqueRigForUploadApplicability( const std::vector &jointListFromAsset ); - void critiqueJointToNodeMappingFromScene( void ); //Determines if a rig is a legacy from the joint list bool isRigLegacy( const std::vector &jointListFromAsset ); @@ -169,9 +168,6 @@ public: //Determines if a rig is suitable for upload bool isRigSuitableForJointPositionUpload( const std::vector &jointListFromAsset ); - void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; } - const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; } - const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; } void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; } @@ -194,7 +190,6 @@ protected: LLModelLoader::state_callback_t mStateCallback; void* mOpaqueData; - bool mRigParityWithScene; bool mRigValidJointUpload; bool mLegacyRigValid; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index dac49aa0b3..8c3c12291e 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1184,7 +1184,6 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) , mPhysicsSearchLOD( LLModel::LOD_PHYSICS ) , mResetJoints( false ) , mModelNoErrors( true ) -, mRigParityWithScene( false ) , mLastJointUpdate( false ) { mNeedsUpdate = TRUE; diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index d9351029ec..2a39f54e92 100755 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -297,8 +297,6 @@ public: void setLoadState( U32 state ) { mLoadState = state; } U32 getLoadState() { return mLoadState; } - void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; } - const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; } static bool sIgnoreLoadedCallback; @@ -346,7 +344,6 @@ private: bool mLoading; U32 mLoadState; bool mResetJoints; - bool mRigParityWithScene; bool mModelNoErrors; std::map mViewOption; -- cgit v1.3 From b72480ddb9b01202f1bbe4bfb84595549faeacf3 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 10 Nov 2015 15:52:41 -0500 Subject: SL-114 WIP - made mesh upload errors/warnings slightly more informative and less spammy. --- indra/llprimitive/lldaeloader.cpp | 4 +- indra/llprimitive/llmodelloader.cpp | 74 ++++++++++++++++--------------------- 2 files changed, 33 insertions(+), 45 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 7e2cf67297..f83f58faa6 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1376,7 +1376,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do } else { - LL_WARNS()<<"Possibly misnamed/missing joint [" <getAttribute("id") << "\"" << LL_ENDL; + LL_DEBUGS("Mesh")<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << LL_ENDL; return NULL; } diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index b12d1042da..bdecfe243b 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -475,14 +475,14 @@ void LLModelLoader::critiqueRigForUploadApplicability( const std::vector &jointListFromAs if (jointListFromAsset.size()>mMaxJointsPerMesh) { LL_WARNS() << "Rigged to " << jointListFromAsset.size() << " joints, max is " << mMaxJointsPerMesh << LL_ENDL; - LL_WARNS() << "Skinning disabled" << LL_ENDL; + LL_WARNS() << "Skinning disabled due to too many joints" << LL_ENDL; return false; } @@ -514,77 +514,65 @@ bool LLModelLoader::isRigLegacy( const std::vector &jointListFromAs { if (mJointMap.find(*it)==mJointMap.end()) { - LL_WARNS() << "Rig to unrecognized name " << *it << ", isRigLegacy() will fail" << LL_ENDL; + LL_WARNS() << "Rigged to unrecognized joint name " << *it << LL_ENDL; unknown_joint_count++; } } if (unknown_joint_count>0) { + LL_WARNS() << "Skinning disabled due to unknown joints" << LL_ENDL; return false; } - bool result = false; - + // Note that this is basically the same code as + // isRigSuitableForJointPositionUpload(), but the set of joints is + // different. JointNameSet :: const_iterator masterJointIt = mMasterLegacyJointList.begin(); JointNameSet :: const_iterator masterJointEndIt = mMasterLegacyJointList.end(); std::vector :: const_iterator modelJointIt = jointListFromAsset.begin(); std::vector :: const_iterator modelJointItEnd = jointListFromAsset.end(); - + + S32 missing_joint_count = 0; for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) { - result = false; - modelJointIt = jointListFromAsset.begin(); - - for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt ) - { - if ( *masterJointIt == *modelJointIt ) - { - result = true; - break; - } - } - if ( !result ) - { - LL_INFOS() <<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< LL_ENDL; - break; - } + if (std::find(modelJointIt,modelJointItEnd,*masterJointIt)==modelJointItEnd) + { + LL_INFOS() <<" Asset did not contain a joint required for skinned mesh upload: " << *masterJointIt<< LL_ENDL; + missing_joint_count++; + } } - return result; + if (missing_joint_count>0) + { + LL_WARNS() << "Skinning disabled due to missing joints" << LL_ENDL; + } + return missing_joint_count==0; } //----------------------------------------------------------------------------- // isRigSuitableForJointPositionUpload() //----------------------------------------------------------------------------- bool LLModelLoader::isRigSuitableForJointPositionUpload( const std::vector &jointListFromAsset ) { - bool result = false; - JointNameSet :: const_iterator masterJointIt = mMasterJointList.begin(); JointNameSet :: const_iterator masterJointEndIt = mMasterJointList.end(); std::vector :: const_iterator modelJointIt = jointListFromAsset.begin(); std::vector :: const_iterator modelJointItEnd = jointListFromAsset.end(); + S32 missing_joint_count = 0; for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) { - result = false; - modelJointIt = jointListFromAsset.begin(); - - for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt ) - { - if ( *masterJointIt == *modelJointIt ) - { - result = true; - break; - } - } - if ( !result ) - { - LL_INFOS() <<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< LL_ENDL; - break; - } + if (std::find(modelJointIt,modelJointItEnd,*masterJointIt)==modelJointItEnd) + { + LL_INFOS() <<" Asset did not contain a joint required for joint position upload: " << *masterJointIt<< LL_ENDL; + missing_joint_count++; + } } - return result; + if (missing_joint_count>0) + { + LL_WARNS() << "Joint upload disabled due to missing joints" << LL_ENDL; + } + return missing_joint_count==0; } -- cgit v1.3 From 146919fa764bed09bfa5e27bc30d02ce2afb6188 Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Wed, 11 Nov 2015 13:44:51 -0800 Subject: animations and meshes will recognize all joint names in joint_aliases.xml --- indra/llcharacter/llbvhloader.cpp | 589 ++++----------------------- indra/llcharacter/llbvhloader.h | 11 +- indra/llprimitive/lldaeloader.cpp | 4 +- indra/llprimitive/lldaeloader.h | 1 + indra/llprimitive/llmodelloader.cpp | 71 +--- indra/llprimitive/llmodelloader.h | 3 +- indra/newview/CMakeLists.txt | 2 +- indra/newview/app_settings/anim.ini | 87 ---- indra/newview/app_settings/joint_aliases.xml | 97 +++++ indra/newview/llfloaterbvhpreview.cpp | 18 +- indra/newview/llfloaterbvhpreview.h | 3 +- indra/newview/llfloatermodelpreview.cpp | 7 + indra/newview/llstartup.cpp | 2 +- indra/newview/llvoavatar.cpp | 23 ++ indra/newview/llvoavatar.h | 3 + 15 files changed, 257 insertions(+), 664 deletions(-) delete mode 100755 indra/newview/app_settings/anim.ini create mode 100755 indra/newview/app_settings/joint_aliases.xml (limited to 'indra/llprimitive') diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 4dedeeab52..cc2505a5ab 100755 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -37,6 +37,7 @@ #include "llquantize.h" #include "llstl.h" #include "llapr.h" +#include "llsdserialize.h" using namespace std; @@ -122,47 +123,21 @@ LLQuaternion::Order bvhStringToOrder( char *str ) // LLBVHLoader() //----------------------------------------------------------------------------- -/* - LLBVHLoader::LLBVHLoader(const char* buffer) +LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::deque& legal_joint_names) { reset(); + errorLine = 0; + + // Recognize all names we've been told are legal. + for (std::deque::iterator joint_name_it = legal_joint_names.begin(); + joint_name_it != legal_joint_names.end(); ++joint_name_it) + { + const std::string& name = *joint_name_it; - mStatus = loadTranslationTable("anim.ini"); - - if (mStatus == LLBVHLoader::ST_NO_XLT_FILE) - { - LL_WARNS() << "NOTE: No translation table found." << LL_ENDL; - return; - } - else - { - if (mStatus != LLBVHLoader::ST_OK) - { - LL_WARNS() << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; - return; - } - } - - char error_text[128]; // Flawfinder: ignore - S32 error_line; - mStatus = loadBVHFile(buffer, error_text, error_line); - if (mStatus != LLBVHLoader::ST_OK) - { - LL_WARNS() << "ERROR: [line: " << getLineNumber() << "] " << mStatus << LL_ENDL; - return; - } - - applyTranslations(); - optimize(); + makeTranslation(name, name); + } - mInitialized = TRUE; -} -*/ -LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine) -{ - reset(); - errorLine = 0; - mStatus = loadTranslationTable("anim.ini"); + mStatus = loadAliases("joint_aliases.xml"); //Load joint name aliases loadStatus = mStatus; LL_INFOS("BVH") << "Load Status 00 : " << loadStatus << LL_ENDL; if (mStatus == E_ST_NO_XLT_FILE) @@ -184,7 +159,7 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error char error_text[128]; /* Flawfinder: ignore */ S32 error_line; - mStatus = loadBVHFile(buffer, error_text, error_line); + mStatus = loadBVHFile(buffer, error_text, error_line); //Reads all joints in BVH file. LL_DEBUGS("BVH") << "============================================================" << LL_ENDL; LL_DEBUGS("BVH") << "Raw data from file" << LL_ENDL; @@ -198,7 +173,7 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error return; } - applyTranslations(); + applyTranslations(); //Maps between joints found in file and the aliased names. optimize(); LL_DEBUGS("BVH") << "============================================================" << LL_ENDL; @@ -215,464 +190,64 @@ LLBVHLoader::~LLBVHLoader() mJoints.clear(); } -//------------------------------------------------------------------------ -// LLBVHLoader::loadTranslationTable() -//------------------------------------------------------------------------ -ELoadStatus LLBVHLoader::loadTranslationTable(const char *fileName) +void LLBVHLoader::makeTranslation(std::string alias_name, std::string joint_name) { - mLineNumber = 0; - mTranslations.clear(); - mConstraints.clear(); - - //-------------------------------------------------------------------- - // open file - //-------------------------------------------------------------------- - std::string path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,fileName); - - LLAPRFile infile ; - infile.open(path, LL_APR_R); - apr_file_t *fp = infile.getFileHandle(); - if (!fp) - return E_ST_NO_XLT_FILE; - - LL_INFOS("BVH") << "NOTE: Loading translation table: " << fileName << LL_ENDL; - - //-------------------------------------------------------------------- - // register file to be closed on function exit - //-------------------------------------------------------------------- - - //-------------------------------------------------------------------- - // load header - //-------------------------------------------------------------------- - if ( ! getLine(fp) ) - return E_ST_EOF; - if ( strncmp(mLine, "Translations 1.0", 16) ) - return E_ST_NO_XLT_HEADER; - - //-------------------------------------------------------------------- - // load data one line at a time - //-------------------------------------------------------------------- - BOOL loadingGlobals = FALSE; - Translation *trans = NULL; - while ( getLine(fp) ) - { - //---------------------------------------------------------------- - // check the 1st token on the line to determine if it's empty or a comment - //---------------------------------------------------------------- - char token[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %127s", token) != 1 ) /* Flawfinder: ignore */ - continue; - - if (token[0] == '#') - continue; - - //---------------------------------------------------------------- - // check if a [jointName] or [GLOBALS] was specified. - //---------------------------------------------------------------- - if (token[0] == '[') - { - char name[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " [%127[^]]", name) != 1 ) - return E_ST_NO_XLT_NAME; - - if (strcmp(name, "GLOBALS")==0) - { - loadingGlobals = TRUE; - continue; - } - else - { - loadingGlobals = FALSE; - Translation &newTrans = mTranslations[ name ]; - trans = &newTrans; - continue; - } - } - - //---------------------------------------------------------------- - // check for optional emote - //---------------------------------------------------------------- - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "emote")==0) - { - char emote_str[1024]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %1023s", emote_str) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_EMOTE; - - mEmoteName.assign( emote_str ); -// LL_INFOS() << "NOTE: Emote: " << mEmoteName.c_str() << LL_ENDL; - continue; - } - - - //---------------------------------------------------------------- - // check for global priority setting - //---------------------------------------------------------------- - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "priority")==0) - { - S32 priority; - if ( sscanf(mLine, " %*s = %d", &priority) != 1 ) - return E_ST_NO_XLT_PRIORITY; - - mPriority = priority; -// LL_INFOS() << "NOTE: Priority: " << mPriority << LL_ENDL; - continue; - } - - //---------------------------------------------------------------- - // check for global loop setting - //---------------------------------------------------------------- - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "loop")==0) - { - char trueFalse[128]; /* Flawfinder: ignore */ - trueFalse[0] = '\0'; - - F32 loop_in = 0.f; - F32 loop_out = 1.f; - - if ( sscanf(mLine, " %*s = %f %f", &loop_in, &loop_out) == 2 ) - { - mLoop = TRUE; - } - else if ( sscanf(mLine, " %*s = %127s", trueFalse) == 1 ) /* Flawfinder: ignore */ - { - mLoop = (LLStringUtil::compareInsensitive(trueFalse, "true")==0); - } - else - { - return E_ST_NO_XLT_LOOP; - } - - mLoopInPoint = loop_in * mDuration; - mLoopOutPoint = loop_out * mDuration; - - continue; - } - - //---------------------------------------------------------------- - // check for global easeIn setting - //---------------------------------------------------------------- - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "easein")==0) - { - F32 duration; - char type[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %f %127s", &duration, type) != 2 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_EASEIN; - - mEaseIn = duration; - continue; - } - - //---------------------------------------------------------------- - // check for global easeOut setting - //---------------------------------------------------------------- - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "easeout")==0) - { - F32 duration; - char type[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %f %127s", &duration, type) != 2 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_EASEOUT; - - mEaseOut = duration; - continue; - } - - //---------------------------------------------------------------- - // check for global handMorph setting - //---------------------------------------------------------------- - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "hand")==0) - { - S32 handMorph; - if (sscanf(mLine, " %*s = %d", &handMorph) != 1) - return E_ST_NO_XLT_HAND; - - mHand = handMorph; - continue; - } - - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "constraint")==0) - { - Constraint constraint; - - // try reading optional target direction - if(sscanf( /* Flawfinder: ignore */ - mLine, - " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f %f %f %f", - &constraint.mChainLength, - &constraint.mEaseInStart, - &constraint.mEaseInStop, - &constraint.mEaseOutStart, - &constraint.mEaseOutStop, - constraint.mSourceJointName, - &constraint.mSourceOffset.mV[VX], - &constraint.mSourceOffset.mV[VY], - &constraint.mSourceOffset.mV[VZ], - constraint.mTargetJointName, - &constraint.mTargetOffset.mV[VX], - &constraint.mTargetOffset.mV[VY], - &constraint.mTargetOffset.mV[VZ], - &constraint.mTargetDir.mV[VX], - &constraint.mTargetDir.mV[VY], - &constraint.mTargetDir.mV[VZ]) != 16) - { - if(sscanf( /* Flawfinder: ignore */ - mLine, - " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f", - &constraint.mChainLength, - &constraint.mEaseInStart, - &constraint.mEaseInStop, - &constraint.mEaseOutStart, - &constraint.mEaseOutStop, - constraint.mSourceJointName, - &constraint.mSourceOffset.mV[VX], - &constraint.mSourceOffset.mV[VY], - &constraint.mSourceOffset.mV[VZ], - constraint.mTargetJointName, - &constraint.mTargetOffset.mV[VX], - &constraint.mTargetOffset.mV[VY], - &constraint.mTargetOffset.mV[VZ]) != 13) - { - return E_ST_NO_CONSTRAINT; - } - } - else - { - // normalize direction - if (!constraint.mTargetDir.isExactlyZero()) - { - constraint.mTargetDir.normVec(); - } - - } - - constraint.mConstraintType = CONSTRAINT_TYPE_POINT; - mConstraints.push_back(constraint); - continue; - } - - if (loadingGlobals && LLStringUtil::compareInsensitive(token, "planar_constraint")==0) - { - Constraint constraint; - - // try reading optional target direction - if(sscanf( /* Flawfinder: ignore */ - mLine, - " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f %f %f %f", - &constraint.mChainLength, - &constraint.mEaseInStart, - &constraint.mEaseInStop, - &constraint.mEaseOutStart, - &constraint.mEaseOutStop, - constraint.mSourceJointName, - &constraint.mSourceOffset.mV[VX], - &constraint.mSourceOffset.mV[VY], - &constraint.mSourceOffset.mV[VZ], - constraint.mTargetJointName, - &constraint.mTargetOffset.mV[VX], - &constraint.mTargetOffset.mV[VY], - &constraint.mTargetOffset.mV[VZ], - &constraint.mTargetDir.mV[VX], - &constraint.mTargetDir.mV[VY], - &constraint.mTargetDir.mV[VZ]) != 16) - { - if(sscanf( /* Flawfinder: ignore */ - mLine, - " %*s = %d %f %f %f %f %15s %f %f %f %15s %f %f %f", - &constraint.mChainLength, - &constraint.mEaseInStart, - &constraint.mEaseInStop, - &constraint.mEaseOutStart, - &constraint.mEaseOutStop, - constraint.mSourceJointName, - &constraint.mSourceOffset.mV[VX], - &constraint.mSourceOffset.mV[VY], - &constraint.mSourceOffset.mV[VZ], - constraint.mTargetJointName, - &constraint.mTargetOffset.mV[VX], - &constraint.mTargetOffset.mV[VY], - &constraint.mTargetOffset.mV[VZ]) != 13) - { - return E_ST_NO_CONSTRAINT; - } - } - else - { - // normalize direction - if (!constraint.mTargetDir.isExactlyZero()) - { - constraint.mTargetDir.normVec(); - } - - } - - constraint.mConstraintType = CONSTRAINT_TYPE_PLANE; - mConstraints.push_back(constraint); - continue; - } - - - //---------------------------------------------------------------- - // at this point there must be a valid trans pointer - //---------------------------------------------------------------- - if ( ! trans ) - return E_ST_NO_XLT_NAME; - - //---------------------------------------------------------------- - // check for ignore flag - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "ignore")==0 ) - { - char trueFalse[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", trueFalse) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_IGNORE; - - trans->mIgnore = (LLStringUtil::compareInsensitive(trueFalse, "true")==0); - continue; - } - - //---------------------------------------------------------------- - // check for relativepos flag - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "relativepos")==0 ) - { - F32 x, y, z; - char relpos[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %f %f %f", &x, &y, &z) == 3 ) - { - trans->mRelativePosition.setVec( x, y, z ); - } - else if ( sscanf(mLine, " %*s = %127s", relpos) == 1 ) /* Flawfinder: ignore */ - { - if ( LLStringUtil::compareInsensitive(relpos, "firstkey")==0 ) - { - trans->mRelativePositionKey = TRUE; - } - else - { - return E_ST_NO_XLT_RELATIVE; - } - } - else - { - return E_ST_NO_XLT_RELATIVE; - } - - continue; - } + //Translation &newTrans = (foomap.insert(value_type(alias_name, Translation()))).first(); + Translation &newTrans = mTranslations[ alias_name ]; //Uses []'s implicit call to ctor. + + newTrans.mOutName = joint_name; + LLMatrix3 fm; + LLVector3 vect1(0, 1, 0); + LLVector3 vect2(0, 0, 1); + LLVector3 vect3(1, 0, 0); + fm.setRows(vect1, vect2, vect3); + + newTrans.mFrameMatrix = fm; + + if (joint_name == "mPelvis") + { + newTrans.mRelativePositionKey = TRUE; + newTrans.mRelativeRotationKey = TRUE; + } - //---------------------------------------------------------------- - // check for relativerot flag - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "relativerot")==0 ) - { - //F32 x, y, z; - char relpos[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", relpos) == 1 ) /* Flawfinder: ignore */ - { - if ( LLStringUtil::compareInsensitive(relpos, "firstkey")==0 ) - { - trans->mRelativeRotationKey = TRUE; - } - else - { - return E_ST_NO_XLT_RELATIVE; - } - } - else - { - return E_ST_NO_XLT_RELATIVE; - } - - continue; - } - - //---------------------------------------------------------------- - // check for outname value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "outname")==0 ) - { - char outName[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", outName) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_OUTNAME; - - trans->mOutName = outName; - continue; - } - - //---------------------------------------------------------------- - // check for frame matrix value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "frame")==0 ) - { - LLMatrix3 fm; - if ( sscanf(mLine, " %*s = %f %f %f, %f %f %f, %f %f %f", - &fm.mMatrix[0][0], &fm.mMatrix[0][1], &fm.mMatrix[0][2], - &fm.mMatrix[1][0], &fm.mMatrix[1][1], &fm.mMatrix[1][2], - &fm.mMatrix[2][0], &fm.mMatrix[2][1], &fm.mMatrix[2][2] ) != 9 ) - return E_ST_NO_XLT_MATRIX; - - trans->mFrameMatrix = fm; - continue; - } - - //---------------------------------------------------------------- - // check for offset matrix value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "offset")==0 ) - { - LLMatrix3 om; - if ( sscanf(mLine, " %*s = %f %f %f, %f %f %f, %f %f %f", - &om.mMatrix[0][0], &om.mMatrix[0][1], &om.mMatrix[0][2], - &om.mMatrix[1][0], &om.mMatrix[1][1], &om.mMatrix[1][2], - &om.mMatrix[2][0], &om.mMatrix[2][1], &om.mMatrix[2][2] ) != 9 ) - return E_ST_NO_XLT_MATRIX; - - trans->mOffsetMatrix = om; - continue; - } - - //---------------------------------------------------------------- - // check for mergeparent value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "mergeparent")==0 ) - { - char mergeParentName[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", mergeParentName) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_MERGEPARENT; - - trans->mMergeParentName = mergeParentName; - continue; - } - - //---------------------------------------------------------------- - // check for mergechild value - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "mergechild")==0 ) - { - char mergeChildName[128]; /* Flawfinder: ignore */ - if ( sscanf(mLine, " %*s = %127s", mergeChildName) != 1 ) /* Flawfinder: ignore */ - return E_ST_NO_XLT_MERGECHILD; - - trans->mMergeChildName = mergeChildName; - continue; - } - - //---------------------------------------------------------------- - // check for per-joint priority - //---------------------------------------------------------------- - if ( LLStringUtil::compareInsensitive(token, "priority")==0 ) - { - S32 priority; - if ( sscanf(mLine, " %*s = %d", &priority) != 1 ) - return E_ST_NO_XLT_PRIORITY; - - trans->mPriorityModifier = priority; - continue; - } - - } +} - infile.close() ; - return E_ST_OK; +ELoadStatus LLBVHLoader::loadAliases(const char * filename) +{ + LLSD aliases_sd; + + std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,filename); + + llifstream input_stream; + input_stream.open(fullpath.c_str(), std::ios::in | std::ios::binary); + + if(input_stream.is_open()) + { + if ( LLSDSerialize::fromXML(aliases_sd, input_stream) ) + { + for(LLSD::map_iterator alias_iter = aliases_sd.beginMap(); + alias_iter != aliases_sd.endMap(); + ++alias_iter) + { + LLSD::String alias_name = alias_iter->first; + LLSD::String joint_name = alias_iter->second; + makeTranslation(alias_name, joint_name); + + } + } + else + { + return E_ST_NO_XLT_HEADER; + } + input_stream.close(); + } + else + { + LL_WARNS("BVH") << "Can't open joint alias file " << fullpath << LL_ENDL; + return E_ST_NO_XLT_FILE; + } + + return E_ST_OK; } void LLBVHLoader::dumpBVHInfo() @@ -1374,6 +949,7 @@ void LLBVHLoader::reset() mInitialized = FALSE; mEmoteName = ""; + mTranslations.clear(); } //------------------------------------------------------------------------ @@ -1603,28 +1179,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) } } - S32 num_constraints = (S32)mConstraints.size(); - dp.packS32(num_constraints, "num_constraints"); - - for (ConstraintVector::iterator constraint_it = mConstraints.begin(); - constraint_it != mConstraints.end(); - constraint_it++) - { - U8 byte = constraint_it->mChainLength; - dp.packU8(byte, "chain_length"); - - byte = constraint_it->mConstraintType; - dp.packU8(byte, "constraint_type"); - dp.packBinaryDataFixed((U8*)constraint_it->mSourceJointName, 16, "source_volume"); - dp.packVector3(constraint_it->mSourceOffset, "source_offset"); - dp.packBinaryDataFixed((U8*)constraint_it->mTargetJointName, 16, "target_volume"); - dp.packVector3(constraint_it->mTargetOffset, "target_offset"); - dp.packVector3(constraint_it->mTargetDir, "target_dir"); - dp.packF32(constraint_it->mEaseInStart, "ease_in_start"); - dp.packF32(constraint_it->mEaseInStop, "ease_in_stop"); - dp.packF32(constraint_it->mEaseOutStart, "ease_out_start"); - dp.packF32(constraint_it->mEaseOutStop, "ease_out_stop"); - } - + dp.packS32(0, "num_constraints"); + return TRUE; } diff --git a/indra/llcharacter/llbvhloader.h b/indra/llcharacter/llbvhloader.h index 033d8714a9..a0207750ed 100755 --- a/indra/llcharacter/llbvhloader.h +++ b/indra/llcharacter/llbvhloader.h @@ -32,6 +32,7 @@ #include "llmath.h" #include "llapr.h" #include "llbvhconsts.h" +#include const S32 BVH_PARSER_LINE_SIZE = 2048; class LLDataPacker; @@ -228,7 +229,8 @@ class LLBVHLoader public: // Constructor // LLBVHLoader(const char* buffer); - LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine); + LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine); + LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::deque& legal_joint_names); ~LLBVHLoader(); /* @@ -267,9 +269,16 @@ public: static const char *ST_NO_XLT_EMOTE; static const char *ST_BAD_ROOT; */ + // Loads the specified translation table. ELoadStatus loadTranslationTable(const char *fileName); + //Create a new joint alias + void makeTranslation(std::string key, std::string value); + + // Loads joint aliases from XML file. + ELoadStatus loadAliases(const char * filename); + // Load the specified BVH file. // Returns status code. ELoadStatus loadBVHFile(const char *buffer, char *error_text, S32 &error_line); diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index c50db824af..63457512ff 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -811,6 +811,7 @@ LLDAELoader::LLDAELoader( JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, JointNameSet& legalJointNames, + std::string jointAliasesFilename, U32 modelLimit) : LLModelLoader( filename, @@ -822,7 +823,8 @@ LLDAELoader::LLDAELoader( opaque_userdata, jointTransformMap, jointsFromNodes, - legalJointNames), + legalJointNames, + jointAliasesFilename), mGeneratedModelLimit(modelLimit) { } diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 79856741db..52ad9d4705 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -57,6 +57,7 @@ public: JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, JointNameSet& legalJointNames, + std::string jointAliasesFilename, U32 modelLimit); virtual ~LLDAELoader() ; diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index 9cf0f10a7e..b4bd467c64 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -111,7 +111,8 @@ LLModelLoader::LLModelLoader( void* opaque_userdata, JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, - JointNameSet& legalJointNames) + JointNameSet& legalJointNames, + std::string jointAliasFilename) : mJointList( jointTransformMap ) , mJointsFromNode( jointsFromNodes ) , LLThread("Model Loader") @@ -135,57 +136,27 @@ LLModelLoader::LLModelLoader( const std::string& name = *joint_name_it; mJointMap[name] = name; } + // Also support various legacy aliases for commonly used joints - mJointMap["avatar_mPelvis"] = "mPelvis"; - mJointMap["avatar_mTorso"] = "mTorso"; - mJointMap["avatar_mChest"] = "mChest"; - mJointMap["avatar_mNeck"] = "mNeck"; - mJointMap["avatar_mHead"] = "mHead"; - mJointMap["avatar_mSkull"] = "mSkull"; - mJointMap["avatar_mEyeRight"] = "mEyeRight"; - mJointMap["avatar_mEyeLeft"] = "mEyeLeft"; - mJointMap["avatar_mCollarLeft"] = "mCollarLeft"; - mJointMap["avatar_mShoulderLeft"] = "mShoulderLeft"; - mJointMap["avatar_mElbowLeft"] = "mElbowLeft"; - mJointMap["avatar_mWristLeft"] = "mWristLeft"; - mJointMap["avatar_mCollarRight"] = "mCollarRight"; - mJointMap["avatar_mShoulderRight"] = "mShoulderRight"; - mJointMap["avatar_mElbowRight"] = "mElbowRight"; - mJointMap["avatar_mWristRight"] = "mWristRight"; - mJointMap["avatar_mHipRight"] = "mHipRight"; - mJointMap["avatar_mKneeRight"] = "mKneeRight"; - mJointMap["avatar_mAnkleRight"] = "mAnkleRight"; - mJointMap["avatar_mFootRight"] = "mFootRight"; - mJointMap["avatar_mToeRight"] = "mToeRight"; - mJointMap["avatar_mHipLeft"] = "mHipLeft"; - mJointMap["avatar_mKneeLeft"] = "mKneeLeft"; - mJointMap["avatar_mAnkleLeft"] = "mAnkleLeft"; - mJointMap["avatar_mFootLeft"] = "mFootLeft"; - mJointMap["avatar_mToeLeft"] = "mToeLeft"; - - - mJointMap["hip"] = "mPelvis"; - mJointMap["abdomen"] = "mTorso"; - mJointMap["chest"] = "mChest"; - mJointMap["neck"] = "mNeck"; - mJointMap["head"] = "mHead"; - mJointMap["figureHair"] = "mSkull"; - mJointMap["lCollar"] = "mCollarLeft"; - mJointMap["lShldr"] = "mShoulderLeft"; - mJointMap["lForeArm"] = "mElbowLeft"; - mJointMap["lHand"] = "mWristLeft"; - mJointMap["rCollar"] = "mCollarRight"; - mJointMap["rShldr"] = "mShoulderRight"; - mJointMap["rForeArm"] = "mElbowRight"; - mJointMap["rHand"] = "mWristRight"; - mJointMap["rThigh"] = "mHipRight"; - mJointMap["rShin"] = "mKneeRight"; - mJointMap["rFoot"] = "mFootRight"; - mJointMap["lThigh"] = "mHipLeft"; - mJointMap["lShin"] = "mKneeLeft"; - mJointMap["lFoot"] = "mFootLeft"; - + LLSD aliases_sd; + llifstream input_stream; + input_stream.open(jointAliasFilename.c_str(), std::ios::in | std::ios::binary); + + if(input_stream.is_open()) + { + LLSDSerialize::fromXML(aliases_sd, input_stream); + for(LLSD::map_iterator alias_iter = aliases_sd.beginMap(); + alias_iter != aliases_sd.endMap(); + ++alias_iter) + { + LLSD::String alias_name = alias_iter->first; + LLSD::String joint_name = alias_iter->second; + mJointMap[ alias_name ] = joint_name; + } + input_stream.close(); + } + //move into joint mapper class //1. joints for joint offset verification mMasterJointList.push_front("mPelvis"); diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index 894de2c76f..20c3aee649 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -128,7 +128,8 @@ public: void* opaque_userdata, JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, - JointNameSet& legalJointNames); + JointNameSet& legalJointNames, + std::string jointAliasFilename); virtual ~LLModelLoader() ; virtual void setNoNormalize() { mNoNormalize = true; } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index a006611a45..b371939fb5 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1600,12 +1600,12 @@ set_source_files_properties(${viewer_XUI_FILES} list(APPEND viewer_SOURCE_FILES ${viewer_XUI_FILES}) set(viewer_APPSETTINGS_FILES - app_settings/anim.ini app_settings/cmd_line.xml app_settings/commands.xml app_settings/grass.xml app_settings/high_graphics.xml app_settings/ignorable_dialogs.xml + app_settings/joint_aliases.xml app_settings/keys.xml app_settings/keywords_lsl_default.xml app_settings/logcontrol.xml diff --git a/indra/newview/app_settings/anim.ini b/indra/newview/app_settings/anim.ini deleted file mode 100755 index 63c84e544d..0000000000 --- a/indra/newview/app_settings/anim.ini +++ /dev/null @@ -1,87 +0,0 @@ -Translations 1.0 - -[hip] - relativepos = firstkey - relativerot = firstkey - outname = mPelvis - frame = 0 1 0, 0 0 1, 1 0 0 - -[abdomen] - outname = mTorso - frame = 0 1 0, 0 0 1, 1 0 0 - -[chest] - outname = mChest - frame = 0 1 0, 0 0 1, 1 0 0 - -[neckDummy] - ignore = true - frame = 0 1 0, 0 0 1, 1 0 0 - -[neck] - outname = mNeck - frame = 0 1 0, 0 0 1, 1 0 0 - -[head] - outname = mHead - frame = 0 1 0, 0 0 1, 1 0 0 - -[figureHair] - ignore = true - frame = 0 1 0, 0 0 1, 1 0 0 - -[lCollar] - outname = mCollarLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lShldr] - outname = mShoulderLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lForeArm] - outname = mElbowLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lHand] - outname = mWristLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[rCollar] - outname = mCollarRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rShldr] - outname = mShoulderRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rForeArm] - outname = mElbowRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rHand] - outname = mWristRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[lThigh] - outname = mHipLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lShin] - outname = mKneeLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[lFoot] - outname = mAnkleLeft - frame = 0 1 0, 0 0 1, 1 0 0 - -[rThigh] - outname = mHipRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rShin] - outname = mKneeRight - frame = 0 1 0, 0 0 1, 1 0 0 - -[rFoot] - outname = mAnkleRight - frame = 0 1 0, 0 0 1, 1 0 0 \ No newline at end of file diff --git a/indra/newview/app_settings/joint_aliases.xml b/indra/newview/app_settings/joint_aliases.xml new file mode 100755 index 0000000000..1e4a233837 --- /dev/null +++ b/indra/newview/app_settings/joint_aliases.xml @@ -0,0 +1,97 @@ + + + + avatar_mPelvis + mPelvis + avatar_mTorso + mTorso + avatar_mChest + mChest + avatar_mNeck + mNeck + avatar_mHead + mHead + avatar_mSkull + mSkull + avatar_mEyeRight + mEyeRight + avatar_mEyeLeft + mEyeLeft + avatar_mCollarLeft + mCollarLeft + avatar_mShoulderLeft + mShoulderLeft + avatar_mElbowLeft + mElbowLeft + avatar_mWristLeft + mWristLeft + avatar_mCollarRight + mCollarRight + avatar_mShoulderRight + mShoulderRight + avatar_mElbowRight + mElbowRight + avatar_mWristRight + mWristRight + avatar_mHipRight + mHipRight + avatar_mKneeRight + mKneeRight + avatar_mAnkleRight + mAnkleRight + avatar_mFootRight + mFootRight + avatar_mToeRight + mToeRight + avatar_mHipLeft + mHipLeft + avatar_mKneeLeft + mKneeLeft + avatar_mAnkleLeft + mAnkleLeft + avatar_mFootLeft + mFootLeft + avatar_mToeLeft + mToeLeft + hip + mPelvis + abdomen + mTorso + chest + mChest + neck + mNeck + head + mHead + figureHair + mSkull + lCollar + mCollarLeft + lShldr + mShoulderLeft + lForeArm + mElbowLeft + lHand + mWristLeft + rCollar + mCollarRight + rShldr + mShoulderRight + rForeArm + mElbowRight + rHand + mWristRight + rThigh + mHipRight + rShin + mKneeRight + rFoot + mFootRight + lThigh + mHipLeft + lShin + mKneeLeft + lFoot + mFootLeft + + diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index a800a3ca14..97769838e8 100755 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -178,6 +178,14 @@ void LLFloaterBvhPreview::setAnimCallbacks() getChild("ease_out_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseOut, this, _1)); } +void LLFloaterBvhPreview::getLegalJointNames(std::deque& legal_joint_names) +{ + // Get all standard skeleton joints from the preview avatar. + LLPointer av = (LLVOAvatar*)mAnimPreview->getDummyAvatar(); + av->getLegalJointNames(legal_joint_names, false); +} + + //----------------------------------------------------------------------------- // postBuild() //----------------------------------------------------------------------------- @@ -215,6 +223,8 @@ BOOL LLFloaterBvhPreview::postBuild() getChildView("bad_animation_text")->setVisible(FALSE); + mAnimPreview = new LLPreviewAnimation(256, 256); + std::string exten = gDirUtilp->getExtension(mFilename); if (exten == "bvh") { @@ -241,8 +251,10 @@ BOOL LLFloaterBvhPreview::postBuild() file_buffer[file_size] = '\0'; LL_INFOS() << "Loading BVH file " << mFilename << LL_ENDL; ELoadStatus load_status = E_ST_OK; - S32 line_number = 0; - loaderp = new LLBVHLoader(file_buffer, load_status, line_number); + S32 line_number = 0; + std::deque legal_joint_names; + getLegalJointNames(legal_joint_names); + loaderp = new LLBVHLoader(file_buffer, load_status, line_number, legal_joint_names); std::string status = getString(STATUS[load_status]); if(load_status == E_ST_NO_XLT_FILE) @@ -266,8 +278,6 @@ BOOL LLFloaterBvhPreview::postBuild() mTransactionID.generate(); mMotionID = mTransactionID.makeAssetID(gAgent.getSecureSessionID()); - mAnimPreview = new LLPreviewAnimation(256, 256); - // motion will be returned, but it will be in a load-pending state, as this is a new motion // this motion will not request an asset transfer until next update, so we have a chance to // load the keyframe data locally diff --git a/indra/newview/llfloaterbvhpreview.h b/indra/newview/llfloaterbvhpreview.h index b81cc6e3a5..74d77d0004 100755 --- a/indra/newview/llfloaterbvhpreview.h +++ b/indra/newview/llfloaterbvhpreview.h @@ -109,7 +109,8 @@ public: S32 status, LLExtStat ext_status); private: void setAnimCallbacks() ; - + void getLegalJointNames(std::deque& legal_joint_names); + protected: void draw(); void resetMotion(); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 9c72238d87..30051a79f1 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1712,6 +1712,8 @@ void LLModelPreview::getLegalJointNames(JointNameSet& legal_joint_names) { // Get all standard skeleton joints from the preview avatar. LLVOAvatar *av = getPreviewAvatar(); + + av->getLegalJointNames(legal_joint_names, true); const LLVOAvatar::avatar_joint_list_t &skel = av->getSkeleton(); for (S32 i=0; igetExpandedFilename(LL_PATH_APP_SETTINGS,"joint_aliases.xml"); + + mModelLoader = new LLDAELoader( filename, lod, @@ -1786,6 +1792,7 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable mJointTransformMap, mJointsFromNode, legal_joint_names, + joint_aliases_filename, gSavedSettings.getU32("ImporterModelLimit")); if (force_disable_slm) diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 54ecc76867..6610330a56 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1258,7 +1258,7 @@ bool idle_startup() LLPostProcess::initClass(); display_startup(); - LLAvatarAppearance::initClass(gSavedSettings.getString("AvatarFileName"),gSavedSettings.getString("SkeletonFileName")); + LLAvatarAppearance::initClass(gSavedSettings.getString("AvatarFileName"),gSavedSettings.getString("SkeletonFileName")); display_startup(); LLViewerObject::initVOClasses(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 3b482e1bc0..d14ec7e55b 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -937,6 +937,29 @@ std::string LLVOAvatar::rezStatusToString(S32 rez_status) return "unknown"; } +void LLVOAvatar::getLegalJointNames(std::deque& legal_joint_names, + bool include_collision_volumes) +{ + // Get all standard skeleton joints from the preview avatar. + const LLVOAvatar::avatar_joint_list_t &skel = getSkeleton(); + for (S32 i=0; igetName()); + } + } + + if (include_collision_volumes) + { + for (S32 i = 0; i < mNumCollisionVolumes; i++) + { + legal_joint_names.push_back(mCollisionVolumes[i].getName()); + } + } +} + // static void LLVOAvatar::dumpBakedStatus() { diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 7a2355b447..29f70fca18 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -72,6 +72,7 @@ class LLTexGlobalColor; struct LLAppearanceMessageContents; class LLViewerJointMesh; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLVOAvatar // @@ -146,6 +147,8 @@ public: void collectBakedTextureUUIDs(std::set& ids) const; void collectTextureUUIDs(std::set& ids); void releaseOldTextures(); + void getLegalJointNames(std::deque& legal_joint_names, + bool include_collision_volumes); /*virtual*/ void updateTextures(); LLViewerFetchedTexture* getBakedTextureImage(const U8 te, const LLUUID& uuid); /*virtual*/ S32 setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim. -- cgit v1.3 From 7b410df303d37a800ddd0024932729a574a00860 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 25 Nov 2015 15:07:26 -0500 Subject: SL-124 WIP - cleanup of comments and test code before going to project viewer. --- indra/llcharacter/lljoint.h | 2 +- indra/llcharacter/llkeyframemotion.cpp | 4 ---- indra/llcharacter/llmotioncontroller.cpp | 18 ------------------ indra/llprimitive/llmodel.cpp | 2 +- indra/newview/app_settings/settings.xml | 11 ----------- indra/newview/lldrawpoolavatar.cpp | 2 +- indra/newview/llpreviewanim.cpp | 7 ------- indra/newview/llskinningutil.cpp | 15 ++++++++++----- indra/newview/llskinningutil.h | 1 - indra/newview/llstartup.cpp | 1 + indra/newview/llviewercontrol.cpp | 3 +-- indra/newview/llvovolume.cpp | 1 - 12 files changed, 15 insertions(+), 52 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index f11cbacaaa..3282e82cd6 100755 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -44,7 +44,7 @@ const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15; const U32 LL_CHARACTER_MAX_JOINTS = 152; // must be divisible by 4! const U32 LL_MAX_JOINTS_PER_MESH_OBJECT = 110; -// FIXME BENTO - these should be higher than the joint_num of any +// These should be higher than the joint_num of any // other joint, to avoid conflicts in updateMotionsByType() const U32 LL_HAND_JOINT_NUM = (LL_CHARACTER_MAX_JOINTS-1); const U32 LL_FACE_JOINT_NUM = (LL_CHARACTER_MAX_JOINTS-2); diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index c227c3f8e9..33d3a7146b 100755 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -2007,7 +2007,6 @@ U32 LLKeyframeMotion::getFileSize() } //----------------------------------------------------------------------------- -// FIXME BENTO TEMP // dumpToFile() //----------------------------------------------------------------------------- void LLKeyframeMotion::dumpToFile(const std::string& name) @@ -2252,9 +2251,6 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs, if (motionp->deserialize(dp)) { motionp->mAssetStatus = ASSET_LOADED; - // FIXME BENTO TEMP - //motionp->dumpToFile(""); - } else { diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index eabd7390b1..ea51dcc864 100755 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -377,14 +377,6 @@ LLMotion* LLMotionController::createMotion( const LLUUID &id ) case LLMotion::STATUS_SUCCESS: // add motion to our list mLoadedMotions.insert(motion); - // BENTO TEMP - { - LLKeyframeMotion *km = dynamic_cast(motion); - if (km) - { - //km->dumpToFile(""); - } - } break; default: LL_ERRS() << "Invalid initialization status" << LL_ENDL; @@ -584,8 +576,6 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty } else { - // NUM_JOINT_SIGNATURE_STRIDES should be multiple of 4 - // FIXME BENTO - think it's just the number of joints that needs to be a multiple of 4, not the number of strides. for (S32 i = 0; i < NUM_JOINT_SIGNATURE_STRIDES; i++) { U32 *current_signature = (U32*)&(mJointSignature[0][i * 4]); @@ -789,14 +779,6 @@ void LLMotionController::updateLoadingMotions() mLoadingMotions.erase(curiter); // add motion to our loaded motion list mLoadedMotions.insert(motionp); - // FIXME BENTO SO MUCH DUMP - { - LLKeyframeMotion *km = dynamic_cast(motionp); - if (km) - { - //km->dumpToFile(""); - } - } // this motion should be playing if (!motionp->isStopped()) { diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 72b5ca77dd..adf392fa21 100755 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -867,7 +867,7 @@ LLSD LLModel::writeModel( S32 count = 0; for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter) { - // BENTO JOINT COUNT LIMIT 255? + // Note joint index cannot exceed 255. if (iter->mJointIdx < 255 && iter->mJointIdx >= 0) { U8 idx = (U8) iter->mJointIdx; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 8bf91c0f1e..9a4def3be2 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6123,17 +6123,6 @@ Value 1.6 - MaxJointsPerMeshObject - - Comment - Maximum joints per rigged mesh object - Persist - 1 - Type - U32 - Value - 999 - MaxPersistentNotifications Comment diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 89233b8e32..33c6d0b00a 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1550,7 +1550,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( { return; } - // BENTO ugly const cast + // FIXME ugly const cast LLSkinningUtil::remapSkinInfoJoints(avatar, const_cast(skin)); LLPointer buffer = face->getVertexBuffer(); diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index f83532ea83..fb40af1302 100755 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -110,13 +110,6 @@ void LLPreviewAnim::play(const LLSD& param) } else { - // BENTO TEMP - LLKeyframeMotion *motionp = dynamic_cast(gAgentAvatarp->findMotion(itemID)); - if (motionp && motionp->isLoaded()) - { - //motionp->dumpToFile(item->getName()); - } - gAgentAvatarp->startMotion(item->getAssetUUID()); } diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 279035d769..202c932da5 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -33,7 +33,6 @@ #include "llmeshrepository.h" bool LLSkinningUtil::sIncludeEnhancedSkeleton = true; -U32 LLSkinningUtil::sMaxJointsPerMeshObject = LL_MAX_JOINTS_PER_MESH_OBJECT; namespace { @@ -111,17 +110,19 @@ U32 get_proxy_joint_index(U32 joint_index, LLVOAvatar *avatar, std::vectorgetSignal()->connect(boost::bind(&handleSpellCheckChanged)); gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged)); - // BENTO - remove MaxJointsPerMeshObject before release - gSavedSettings.getControl("MaxJointsPerMeshObject")->getCommitSignal()->connect(boost::bind(&handleDeferredDebugSettingChanged, _2)); + // BENTO - need UI. gSavedSettings.getControl("IncludeEnhancedSkeleton")->getCommitSignal()->connect(boost::bind(&handleDeferredDebugSettingChanged, _2)); } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 9b2e9db59a..af87bb904d 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4176,7 +4176,6 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } //build matrix palette - // BENTO JOINT COUNT LIMIT static const size_t kMaxJoints = LL_MAX_JOINTS_PER_MESH_OBJECT; LLMatrix4a mat[kMaxJoints]; -- cgit v1.3 From a6c8de97bbb2609d24e212672b192650aed91e1e Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 15 Jan 2016 11:29:34 -0500 Subject: SL-302 WIP - handle the case that node name is NULL --- indra/llprimitive/llmodelloader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index 568b3ead4e..9a042a4e30 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -179,7 +179,7 @@ public: //----------------------------------------------------------------------------- bool isNodeAJoint(const char* name) { - return mJointMap.find(name) != mJointMap.end(); + return name != NULL && mJointMap.find(name) != mJointMap.end(); } protected: -- cgit v1.3 From 299c04fa42d04f3ecf717a63d326d99efbe77c88 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 20 Jan 2016 10:52:37 -0500 Subject: SL-319 - removed specific joint requirements for skinned mesh and joint offset uploads. --- indra/llprimitive/llmodelloader.cpp | 80 +------------------------------------ indra/llprimitive/llmodelloader.h | 2 - 2 files changed, 2 insertions(+), 80 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index 9bfd6dc3e6..816ebc558a 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -134,41 +134,6 @@ LLModelLoader::LLModelLoader( , mMaxJointsPerMesh(maxJointsPerMesh) , mJointMap(legalJointNamesMap) { - //move into joint mapper class - //1. joints for joint offset verification - mMasterJointList.push_front("mPelvis"); - mMasterJointList.push_front("mTorso"); - mMasterJointList.push_front("mChest"); - mMasterJointList.push_front("mNeck"); - mMasterJointList.push_front("mHead"); - mMasterJointList.push_front("mCollarLeft"); - mMasterJointList.push_front("mShoulderLeft"); - mMasterJointList.push_front("mElbowLeft"); - mMasterJointList.push_front("mWristLeft"); - mMasterJointList.push_front("mCollarRight"); - mMasterJointList.push_front("mShoulderRight"); - mMasterJointList.push_front("mElbowRight"); - mMasterJointList.push_front("mWristRight"); - mMasterJointList.push_front("mHipRight"); - mMasterJointList.push_front("mKneeRight"); - mMasterJointList.push_front("mFootRight"); - mMasterJointList.push_front("mHipLeft"); - mMasterJointList.push_front("mKneeLeft"); - mMasterJointList.push_front("mFootLeft"); - - //2. legacy joint list - used to verify rigs that will not be using joint offsets - mMasterLegacyJointList.push_front("mPelvis"); - mMasterLegacyJointList.push_front("mTorso"); - mMasterLegacyJointList.push_front("mChest"); - mMasterLegacyJointList.push_front("mNeck"); - mMasterLegacyJointList.push_front("mHead"); - mMasterLegacyJointList.push_front("mHipRight"); - mMasterLegacyJointList.push_front("mKneeRight"); - mMasterLegacyJointList.push_front("mFootRight"); - mMasterLegacyJointList.push_front("mHipLeft"); - mMasterLegacyJointList.push_front("mKneeLeft"); - mMasterLegacyJointList.push_front("mFootLeft"); - assert_main_thread(); sActiveLoaderList.push_back(this) ; } @@ -467,55 +432,14 @@ bool LLModelLoader::isRigLegacy( const std::vector &jointListFromAs return false; } - // Note that this is basically the same code as - // isRigSuitableForJointPositionUpload(), but the set of joints is - // different. - JointNameSet :: const_iterator masterJointIt = mMasterLegacyJointList.begin(); - JointNameSet :: const_iterator masterJointEndIt = mMasterLegacyJointList.end(); - - std::vector :: const_iterator modelJointIt = jointListFromAsset.begin(); - std::vector :: const_iterator modelJointItEnd = jointListFromAsset.end(); - - S32 missing_joint_count = 0; - for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) - { - if (std::find(modelJointIt,modelJointItEnd,*masterJointIt)==modelJointItEnd) - { - LL_INFOS() <<" Asset did not contain a joint required for skinned mesh upload: " << *masterJointIt<< LL_ENDL; - missing_joint_count++; - } - } - if (missing_joint_count>0) - { - LL_WARNS() << "Skinning disabled due to missing joints" << LL_ENDL; - } - return missing_joint_count==0; + return true; } //----------------------------------------------------------------------------- // isRigSuitableForJointPositionUpload() //----------------------------------------------------------------------------- bool LLModelLoader::isRigSuitableForJointPositionUpload( const std::vector &jointListFromAsset ) { - JointNameSet :: const_iterator masterJointIt = mMasterJointList.begin(); - JointNameSet :: const_iterator masterJointEndIt = mMasterJointList.end(); - - std::vector :: const_iterator modelJointIt = jointListFromAsset.begin(); - std::vector :: const_iterator modelJointItEnd = jointListFromAsset.end(); - - S32 missing_joint_count = 0; - for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) - { - if (std::find(modelJointIt,modelJointItEnd,*masterJointIt)==modelJointItEnd) - { - LL_INFOS() <<" Asset did not contain a joint required for joint position upload: " << *masterJointIt<< LL_ENDL; - missing_joint_count++; - } - } - if (missing_joint_count>0) - { - LL_WARNS() << "Joint upload disabled due to missing joints" << LL_ENDL; - } - return missing_joint_count==0; + return true; } diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index 9a042a4e30..a902ca3404 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -196,8 +196,6 @@ protected: bool mNoNormalize; bool mNoOptimize; - JointNameSet mMasterJointList; - JointNameSet mMasterLegacyJointList; JointTransformMap mJointTransformMap; static std::list sActiveLoaderList; -- cgit v1.3 From b138ca8aeec421f6e5b1412e7c7fbcefd87570d0 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 6 Apr 2016 16:12:39 -0400 Subject: SL-366 - more cases where skinned weights can go awry, and a bunch more asserts to verify. --- indra/llmath/llvolume.cpp | 10 ++++++---- indra/llprimitive/llmodel.cpp | 3 +-- indra/newview/llfloatermodelpreview.cpp | 5 ++++- indra/newview/llskinningutil.cpp | 9 ++++++++- 4 files changed, 19 insertions(+), 8 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 725e50ee2b..e5b1cf536d 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2544,7 +2544,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) U16 influence = weights[idx++]; influence |= ((U16) weights[idx++] << 8); - F32 w = llclamp((F32) influence / 65535.f, 0.f, 0.99999f); + F32 w = llclamp((F32) influence / 65535.f, 0.001f, 0.999f); wght.mV[cur_influence] = w; joints[cur_influence] = joint; cur_influence++; @@ -2561,11 +2561,13 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) F32 wsum = wght.mV[VX] + wght.mV[VY] + wght.mV[VZ] + wght.mV[VW]; if (wsum <= 0.f) { - wght = LLVector4(0.99999f,0.f,0.f,0.f); + wght = LLVector4(0.999f,0.f,0.f,0.f); } - for (U32 k=0; k<4; k++) + for (U32 k=0; k0); // If this fails, we have a floating point precision error. + joints_with_weights[k] = f_combined; } face.mWeights[cur_vertex].loadua(joints_with_weights.mV); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index adf392fa21..398f0997f3 100755 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1001,7 +1001,7 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) { - //1. If a vertex has been weighted then we'll find it via pos and return it's weight list + //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(); @@ -1224,7 +1224,6 @@ bool LLModel::loadModel(std::istream& is) } return false; - } bool LLModel::isMaterialListSubset( LLModel* ref ) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index ceb3566d95..cda704f47b 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -3317,14 +3317,17 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) LLVector3 pos(vf.mPositions[i].getF32ptr()); const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos); + llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this LLVector4 w(0,0,0,0); for (U32 i = 0; i < weight_list.size(); ++i) { - F32 wght = llmin(weight_list[i].mWeight, 0.999999f); + F32 wght = llclamp(weight_list[i].mWeight, 0.001f, 0.999f); F32 joint = (F32) weight_list[i].mJointIdx; w.mV[i] = joint + wght; + llassert(w.mV[i]-(S32)w.mV[i]>0.0f); // because weights are non-zero, and range of wt values + //should not cause floating point precision issues. } *(weights_strider++) = w; diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index fbe45c8ea6..732afdfa9a 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -291,12 +291,15 @@ void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, con { F32 *w = weights[j].getF32ptr(); + F32 wsum = 0.0; for (U32 k=0; k<4; ++k) { S32 i = llfloor(w[k]); llassert(i>=0); llassert(i 0.0f); } } #endif @@ -310,7 +313,7 @@ void LLSkinningUtil::getPerVertexSkinMatrix( LLMatrix4a& final_mat, U32 max_joints) { - + bool valid_weights = true; final_mat.clear(); S32 idx[4]; @@ -336,6 +339,7 @@ void LLSkinningUtil::getPerVertexSkinMatrix( if (handle_bad_scale && scale <= 0.f) { wght = LLVector4(1.0f, 0.0f, 0.0f, 0.0f); + valid_weights = false; } else { @@ -353,5 +357,8 @@ void LLSkinningUtil::getPerVertexSkinMatrix( final_mat.add(src); } + // SL-366 - with weight validation/cleanup code, it should no longer be + // possible to hit the bad scale case. + llassert(valid_weights); } -- cgit v1.3 From b092147a0be579e102c9210c6c99110862e9ad02 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 19 Apr 2016 11:48:06 -0400 Subject: SL-372 - handle dae models with multiple skeleton roots --- indra/llprimitive/lldaeloader.cpp | 186 +++++++++++++++++++------------------- 1 file changed, 95 insertions(+), 91 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 50875669fa..df69607404 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1152,28 +1152,29 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do //Some collada setup for accessing the skeleton - daeElement* pElement = 0; - dae->getDatabase()->getElement( &pElement, 0, 0, "skeleton" ); + U32 skeleton_count = dae->getDatabase()->getElementCount( NULL, "skeleton" ); + std::vector skeletons; + for (S32 i=0; igetDatabase()->getElement( &pElement, i, 0, "skeleton" ); - //Try to get at the skeletal instance controller - domInstance_controller::domSkeleton* pSkeleton = daeSafeCast( pElement ); + //Try to get at the skeletal instance controller + domInstance_controller::domSkeleton* pSkeleton = daeSafeCast( pElement ); + daeElement* pSkeletonRootNode = NULL; + if (pSkeleton) + { + pSkeletonRootNode = pSkeleton->getValue().getElement(); + } + if (pSkeleton && pSkeletonRootNode) + { + skeletons.push_back(pSkeleton); + } + } bool missingSkeletonOrScene = false; //If no skeleton, do a breadth-first search to get at specific joints - bool rootNode = false; - - //Need to test for a skeleton that does not have a root node - //This occurs when your instance controller does not have an associated scene - if ( pSkeleton ) - { - daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); - if ( pSkeletonRootNode ) - { - rootNode = true; - } - - } - if ( !pSkeleton || !rootNode ) + if ( skeletons.size() == 0 ) { daeElement* pScene = root->getDescendant("visual_scene"); if ( !pScene ) @@ -1200,85 +1201,88 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do } } else - //Has Skeleton - { - //Get the root node of the skeleton - daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); - if ( pSkeletonRootNode ) - { - //Once we have the root node - start acccessing it's joint components - const int jointCnt = mJointMap.size(); - JointMap :: const_iterator jointIt = mJointMap.begin(); - - //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor. - for ( int i=0; i::iterator skel_it = skeletons.begin(); + skel_it != skeletons.end(); ++skel_it) + { + domInstance_controller::domSkeleton* pSkeleton = *skel_it; + //Get the root node of the skeleton + daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); + if ( pSkeletonRootNode ) + { + //Once we have the root node - start acccessing it's joint components + const int jointCnt = mJointMap.size(); + JointMap :: const_iterator jointIt = mJointMap.begin(); - //Look for the joint - domNode* pJoint = daeSafeCast( resolver.getElement() ); - if ( pJoint ) - { - //Pull out the translate id and store it in the jointTranslations map - daeSIDResolver jointResolverA( pJoint, "./translate" ); - domTranslate* pTranslateA = daeSafeCast( jointResolverA.getElement() ); - daeSIDResolver jointResolverB( pJoint, "./location" ); - domTranslate* pTranslateB = daeSafeCast( jointResolverB.getElement() ); + //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor. + for ( int i=0; i( resolver.getElement() ); + if ( pJoint ) { - if ( pTranslateB ) - { - extractTranslation( pTranslateB, workingTransform ); - } - else - { - //Translation via child from element - daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" ); - if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() ) - { - LL_WARNS()<< "The found element is not a translate node" <( jointResolverA.getElement() ); + daeSIDResolver jointResolverB( pJoint, "./location" ); + domTranslate* pTranslateB = daeSafeCast( jointResolverB.getElement() ); + + LLMatrix4 workingTransform; + + //Translation via SID + if ( pTranslateA ) + { + extractTranslation( pTranslateA, workingTransform ); + } + else + { + if ( pTranslateB ) + { + extractTranslation( pTranslateB, workingTransform ); + } + else + { + //Translation via child from element + daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" ); + if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() ) + { + LL_WARNS()<< "The found element is not a translate node" <getJoints(); -- cgit v1.3 From 0447fe5a57c2b3e0406fd28b665ea9f47d689b2f Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 20 Apr 2016 13:18:56 -0400 Subject: SL-371 - increased the limit for StackWalker strings, avoid crashing if mesh has wrong number of mAlternateBindMatrix matrices --- indra/llcommon/StackWalker.h | 2 +- indra/llprimitive/lldaeloader.cpp | 4 +++- indra/newview/llvoavatar.cpp | 8 ++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llcommon/StackWalker.h b/indra/llcommon/StackWalker.h index 5a5ed96e6f..834f89c471 100644 --- a/indra/llcommon/StackWalker.h +++ b/indra/llcommon/StackWalker.h @@ -127,7 +127,7 @@ public: // in older compilers in order to use it... starting with VC7 we can declare it as "protected" protected: #endif - enum { STACKWALK_MAX_NAMELEN = 2048 }; // max name length for found symbols + enum { STACKWALK_MAX_NAMELEN = 4096 }; // max name length for found symbols protected: // Entry for each Callstack-Entry diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index df69607404..38b061dd79 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1189,7 +1189,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do S32 childCount = children.getCount(); //Process any children that are joints - //Not all children are joints, some code be ambient lights, cameras, geometry etc.. + //Not all children are joints, some could be ambient lights, cameras, geometry etc.. for (S32 i = 0; i < childCount; ++i) { domNode* pNode = daeSafeCast(children[i]); @@ -1229,6 +1229,8 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do domNode* pJoint = daeSafeCast( resolver.getElement() ); if ( pJoint ) { + // FIXME this has a lot of overlap with processJointNode(), would be nice to refactor. + //Pull out the translate id and store it in the jointTranslations map daeSIDResolver jointResolverA( pJoint, "./translate" ); domTranslate* pTranslateA = daeSafeCast( jointResolverA.getElement() ); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index a82f92b01a..af10af98f2 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5299,9 +5299,13 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData ) { const int bindCnt = pSkinData->mAlternateBindMatrix.size(); - if ( bindCnt > 0 ) + const int jointCnt = pSkinData->mJointNames.size(); + if ((bindCnt > 0) && (bindCnt != jointCnt)) + { + LL_WARNS_ONCE() << "invalid mesh, bindCnt " << bindCnt << "!= jointCnt " << jointCnt << ", joint overrides will be ignored." << LL_ENDL; + } + if ((bindCnt > 0) && (bindCnt == jointCnt)) { - const int jointCnt = pSkinData->mJointNames.size(); const F32 pelvisZOffset = pSkinData->mPelvisOffset; const LLUUID& mesh_id = pSkinData->mMeshID; bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false; -- cgit v1.3 From d2302886bc132f5afe96612c8f13702775f0a303 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 15 Jun 2016 15:24:54 -0400 Subject: MAINT-6380, SL-399 - vertical flicker related to joint offsets for mPelvis. Having a joint offset for mPelvis is still a bad idea, but it won't cause as much flickering now. --- indra/llcharacter/lljoint.cpp | 58 ++++++++++++++++++++++++++++----------- indra/llcharacter/lljoint.h | 4 +-- indra/llprimitive/lldaeloader.cpp | 3 +- indra/newview/llvoavatar.cpp | 15 ++++------ 4 files changed, 51 insertions(+), 29 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index c4eda0b432..6e6208a617 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -361,8 +361,11 @@ void LLJoint::setPosition( const LLVector3& requested_pos, bool apply_attachment LL_DEBUGS("Avatar") << "CONTEXT:\n" << "====================\n" << con_status << "====================" << LL_ENDL; LL_DEBUGS("Avatar") << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; } - mXform.setPosition(pos); - touch(MATRIX_DIRTY | POSITION_DIRTY); + if (pos != getPosition()) + { + mXform.setPosition(pos); + touch(MATRIX_DIRTY | POSITION_DIRTY); + } } void LLJoint::setDefaultPosition( const LLVector3& pos ) @@ -392,8 +395,9 @@ bool above_joint_pos_threshold(const LLVector3& diff) //-------------------------------------------------------------------- // addAttachmentPosOverride() //-------------------------------------------------------------------- -void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info ) +void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ) { + active_override_changed = false; if (mesh_id.isNull()) { return; @@ -407,6 +411,10 @@ void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh } return; } + + LLVector3 before_pos; + LLUUID before_mesh_id; + bool has_active_override_before = hasAttachmentPosOverride( before_pos, before_mesh_id ); if (!m_attachmentOverrides.count()) { if (do_debug_joint(getName())) @@ -416,31 +424,49 @@ void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh m_posBeforeOverrides = getPosition(); } m_attachmentOverrides.add(mesh_id,pos); - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL; - } - updatePos(av_info); + LLVector3 after_pos; + LLUUID after_mesh_id; + hasAttachmentPosOverride(after_pos, after_mesh_id); + if (!has_active_override_before || (after_pos != before_pos)) + { + active_override_changed = true; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL; + } + updatePos(av_info); + } } //-------------------------------------------------------------------- // removeAttachmentPosOverride() //-------------------------------------------------------------------- -void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info ) +void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ) { + active_override_changed = false; if (mesh_id.isNull()) { return; } + LLVector3 before_pos; + LLUUID before_mesh_id; + hasAttachmentPosOverride( before_pos, before_mesh_id ); if (m_attachmentOverrides.remove(mesh_id)) { - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() - << " removeAttachmentPosOverride for " << mesh_id << LL_ENDL; - showJointPosOverrides(*this, "remove", av_info); - } - updatePos(av_info); + LLVector3 after_pos; + LLUUID after_mesh_id; + bool has_active_override_after = hasAttachmentPosOverride(after_pos, after_mesh_id); + if (!has_active_override_after || (after_pos != before_pos)) + { + active_override_changed = true; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " removeAttachmentPosOverride for " << mesh_id << LL_ENDL; + showJointPosOverrides(*this, "remove", av_info); + } + updatePos(av_info); + } } } diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index d2c573864b..40e0a2749b 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -254,8 +254,8 @@ public: virtual BOOL isAnimatable() const { return TRUE; } - void addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info ); - void removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info ); + void addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ); + void removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ); bool hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const; void clearAttachmentPosOverrides(); void showAttachmentPosOverrides(const std::string& av_info) const; diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 38b061dd79..2642dea6d8 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1404,7 +1404,8 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do // incorrect. LLUUID fake_mesh_id; fake_mesh_id.generate(); - pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, ""); + bool dummy; // not used + pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, "", dummy); } else { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 7a3a72d789..0448fc6138 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5451,17 +5451,11 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) { pJoint->setId( currentId ); const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation(); - //Set the joint position - LLUUID curr_mesh_id; - LLVector3 joint_pos_before; - bool has_pos_before = pJoint->hasAttachmentPosOverride( joint_pos_before, curr_mesh_id ); - pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString() ); + bool override_changed; + pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString(), override_changed ); - LLVector3 joint_pos_after; - pJoint->hasAttachmentPosOverride( joint_pos_after, curr_mesh_id ); - - if (!has_pos_before || joint_pos_before != joint_pos_after) + if (override_changed) { //If joint is a pelvis then handle old/new pelvis to foot values if ( lookingForJoint == "mPelvis" ) @@ -5633,8 +5627,9 @@ void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id) //Reset joints except for pelvis if ( pJoint ) { + bool dummy; // unused pJoint->setId( LLUUID::null ); - pJoint->removeAttachmentPosOverride(mesh_id, avString()); + pJoint->removeAttachmentPosOverride(mesh_id, avString(), dummy); } if ( pJoint && pJoint == pJointPelvis) { -- cgit v1.3 From 72d5ff36f56c4afee85f5863f64f237980341014 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 17 Aug 2016 16:31:28 -0400 Subject: MAINT-6647 - ignore previously created slm files on model upload. SL-442 - change coloring for show bones, to highlight joint positions and rigging --- indra/llprimitive/llmodelloader.cpp | 30 ++++++++++++++++++++++-------- indra/llprimitive/llmodelloader.h | 4 +++- indra/newview/llface.cpp | 1 + indra/newview/llfloatermodelpreview.cpp | 17 +++++++++++------ indra/newview/llfloatermodelpreview.h | 4 ++-- indra/newview/llvoavatar.cpp | 31 ++++++++++++++++++------------- 6 files changed, 57 insertions(+), 30 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index 816ebc558a..4e468ff45f 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -150,6 +150,23 @@ void LLModelLoader::run() doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this)); } +// static +bool LLModelLoader::getSLMFilename(const std::string& model_filename, std::string& slm_filename) +{ + slm_filename = model_filename; + + std::string::size_type i = model_filename.rfind("."); + if (i != std::string::npos) + { + slm_filename.replace(i, model_filename.size()-1, ".slm"); + return true; + } + else + { + return false; + } +} + bool LLModelLoader::doLoadModel() { //first, look for a .slm file of the same name that was modified later @@ -157,20 +174,17 @@ bool LLModelLoader::doLoadModel() if (mTrySLM) { - std::string filename = mFilename; - - std::string::size_type i = filename.rfind("."); - if (i != std::string::npos) - { - filename.replace(i, filename.size()-1, ".slm"); + std::string slm_filename; + if (getSLMFilename(mFilename, slm_filename)) + { llstat slm_status; - if (LLFile::stat(filename, &slm_status) == 0) + if (LLFile::stat(slm_filename, &slm_status) == 0) { //slm file exists llstat dae_status; if (LLFile::stat(mFilename, &dae_status) != 0 || dae_status.st_mtime < slm_status.st_mtime) { - if (loadFromSLM(filename)) + if (loadFromSLM(slm_filename)) { //slm successfully loaded, if this fails, fall through and //try loading from dae diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index a902ca3404..d64e0a0773 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -137,7 +137,9 @@ public: virtual void setNoOptimize() { mNoOptimize = true; } virtual void run(); - + + static bool getSLMFilename(const std::string& model_filename, std::string& slm_filename); + // Will try SLM or derived class OpenFile as appropriate // virtual bool doLoadModel(); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index de349a03d4..424bc0228c 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -573,6 +573,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) LLRiggedVolume* rigged = volume->getRiggedVolume(); if (rigged) { + // BENTO - called when selecting a face during edit of a mesh object LLGLEnable offset(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.f, -1.f); gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 0f0fafcce6..1fd2d429a7 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1656,12 +1656,11 @@ void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_posit if (!mLODFile[LLModel::LOD_HIGH].empty()) { std::string filename = mLODFile[LLModel::LOD_HIGH]; - - std::string::size_type i = filename.rfind("."); - if (i != std::string::npos) - { - filename.replace(i, filename.size()-1, ".slm"); - saveUploadData(filename, save_skinweights, save_joint_positions); + std::string slm_filename; + + if (LLModelLoader::getSLMFilename(filename, slm_filename)) + { + saveUploadData(slm_filename, save_skinweights, save_joint_positions); } } } @@ -1818,6 +1817,12 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable } else { + // For MAINT-6647, we have set force_disable_slm to true, + // which means this code path will never be taken. Trying to + // re-use SLM files has never worked properly; in particular, + // it tends to force the UI into strange checkbox options + // which cannot be altered. + //only try to load from slm if viewer is configured to do so and this is the //initial model load (not an LoD or physics shape) mModelLoader->mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mUploadData.empty(); diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 217ac35888..c4e42c76bd 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -106,7 +106,7 @@ public: void refresh(); void loadModel(S32 lod); - void loadModel(S32 lod, const std::string& file_name, bool force_disable_slm = false); + void loadModel(S32 lod, const std::string& file_name, bool force_disable_slm = true); void onViewOptionChecked(LLUICtrl* ctrl); bool isViewOptionChecked(const LLSD& userdata); @@ -261,7 +261,7 @@ public: void setPreviewLOD(S32 lod); void clearModel(S32 lod); void getJointAliases(JointMap& joint_map); - void loadModel(std::string filename, S32 lod, bool force_disable_slm = false); + void loadModel(std::string filename, S32 lod, bool force_disable_slm = true); void loadModelCallback(S32 lod); bool lodsReady() { return !mGenLOD && mLodsQuery.empty(); } void queryLODs() { mGenLOD = true; }; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index db0316ebcd..946db6713e 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1428,12 +1428,15 @@ void LLVOAvatar::renderBones() avatar_joint_list_t::iterator iter = mSkeleton.begin(); avatar_joint_list_t::iterator end = mSkeleton.end(); - static LLVector3 BASE_COLOR_OCCLUDED(1.0f, 0.0f, 0.0f); - static LLVector3 BASE_COLOR_VISIBLE(0.5f, 0.5f, 0.5f); - static LLVector3 EXTENDED_COLOR_OCCLUDED(0.0f, 1.0f, 0.0f); - static LLVector3 EXTENDED_COLOR_VISIBLE(0.5f, 0.5f, 0.5f); + // For bones with position overrides defined + static LLVector3 OVERRIDE_COLOR_OCCLUDED(1.0f, 0.0f, 0.0f); + static LLVector3 OVERRIDE_COLOR_VISIBLE(0.5f, 0.5f, 0.5f); + // For bones which are rigged to by at least one attachment static LLVector3 RIGGED_COLOR_OCCLUDED(0.0f, 1.0f, 1.0f); static LLVector3 RIGGED_COLOR_VISIBLE(0.5f, 0.5f, 0.5f); + // For bones not otherwise colored + static LLVector3 OTHER_COLOR_OCCLUDED(0.0f, 1.0f, 0.0f); + static LLVector3 OTHER_COLOR_VISIBLE(0.5f, 0.5f, 0.5f); static F32 SPHERE_SCALEF = 0.001f; @@ -1446,25 +1449,27 @@ void LLVOAvatar::renderBones() } jointp->updateWorldMatrix(); - LLJoint::SupportCategory sc = jointp->getSupport(); + LLVector3 occ_color, visible_color; - if (jointIsRiggedTo(jointp->getName())) + LLVector3 pos; + LLUUID mesh_id; + if (jointp->hasAttachmentPosOverride(pos,mesh_id)) { - occ_color = RIGGED_COLOR_OCCLUDED; - visible_color = RIGGED_COLOR_VISIBLE; + occ_color = OVERRIDE_COLOR_OCCLUDED; + visible_color = OVERRIDE_COLOR_VISIBLE; } else { - if (sc == LLJoint::SUPPORT_BASE) + if (jointIsRiggedTo(jointp->getName())) { - occ_color = BASE_COLOR_OCCLUDED; - visible_color = BASE_COLOR_VISIBLE; + occ_color = RIGGED_COLOR_OCCLUDED; + visible_color = RIGGED_COLOR_VISIBLE; } else { - occ_color = EXTENDED_COLOR_OCCLUDED; - visible_color = EXTENDED_COLOR_VISIBLE; + occ_color = OTHER_COLOR_OCCLUDED; + visible_color = OTHER_COLOR_VISIBLE; } } LLVector3 begin_pos(0,0,0); -- cgit v1.3 From 34ced1aa2cc286db26e2866cfc7a53ef72d828a4 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 2 Sep 2016 16:44:57 -0400 Subject: SL-395 - partial support for joint scale locking via flag in skin info --- indra/llcharacter/lljoint.cpp | 26 +++-------------- indra/llcharacter/lljoint.h | 4 +++ indra/llprimitive/lldaeloader.cpp | 33 ++++++++++++--------- indra/llprimitive/llmodel.cpp | 11 +++++-- indra/llprimitive/llmodel.h | 1 + indra/newview/llvoavatar.cpp | 60 +++++++++++++++++++++------------------ 6 files changed, 70 insertions(+), 65 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index d2a5c59023..8d101ff1fc 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -404,16 +404,16 @@ void showJointScaleOverrides( const LLJoint& joint, const std::string& note, con LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL; } -bool above_joint_pos_threshold(const LLVector3& diff) +bool LLJoint::aboveJointPosThreshold(const LLVector3& pos) const { - //return !diff.isNull(); + LLVector3 diff = pos - getDefaultPosition(); const F32 max_joint_pos_offset = 0.0001f; // 0.1 mm return diff.lengthSquared() > max_joint_pos_offset * max_joint_pos_offset; } -bool above_joint_scale_threshold(const LLVector3& diff) +bool LLJoint::aboveJointScaleThreshold(const LLVector3& scale) const { - //return !diff.isNull(); + LLVector3 diff = scale - getDefaultScale(); const F32 max_joint_scale_offset = 0.0001f; // 0.1 mm return diff.lengthSquared() > max_joint_scale_offset * max_joint_scale_offset; } @@ -434,15 +434,6 @@ void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh //{ // return; //} - if (!above_joint_pos_threshold(pos-getDefaultPosition())) - { - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "Attachment pos override ignored for " << getName() - << ", pos " << pos << " is same as default pos" << LL_ENDL; - } - return; - } LLVector3 before_pos; LLUUID before_mesh_id; @@ -627,15 +618,6 @@ void LLJoint::addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& { return; } - if (!above_joint_scale_threshold(scale-getDefaultScale())) - { - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "Attachment scale override ignored for " << getName() - << ", scale " << scale << " is same as default scale" << LL_ENDL; - } - return; - } if (!m_attachmentScaleOverrides.count()) { if (do_debug_joint(getName())) diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 509523ae4b..42c2c6f1ad 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -278,6 +278,10 @@ public: void clearAttachmentScaleOverrides(); void showAttachmentScaleOverrides(const std::string& av_info) const; + // These are used in checks of whether a pos/scale override is considered significant. + bool aboveJointPosThreshold(const LLVector3& pos) const; + bool aboveJointScaleThreshold(const LLVector3& scale) const; + //Accessor for the joint id LLUUID getId( void ) { return mId; } //Setter for the joints id diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 37ebdf2cec..c194d677c8 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1379,6 +1379,16 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do if ( !missingSkeletonOrScene ) { + // FIXME: mesh_id is used to determine which mesh gets to + // set the joint offset, in the event of a conflict. Since + // we don't know the mesh id yet, we can't guarantee that + // joint offsets will be applied with the same priority as + // in the uploaded model. If the file contains multiple + // meshes with conflicting joint offsets, preview may be + // incorrect. + LLUUID fake_mesh_id; + fake_mesh_id.generate(); + //Set the joint translations on the avatar JointMap :: const_iterator masterJointIt = mJointMap.begin(); JointMap :: const_iterator masterJointItEnd = mJointMap.end(); @@ -1393,19 +1403,16 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do LLJoint* pJoint = mJointLookupFunc(lookingForJoint,mOpaqueData); if ( pJoint ) { - // FIXME: mesh_id is used to determine which - // mesh gets to set the joint offset, in the - // event of a conflict. Since we don't know - // the mesh id yet, we can't guarantee that - // joint offsets will be applied with the same - // priority as in the uploaded model. If the - // file contains multiple meshes with - // conflicting joint offsets, preview may be - // incorrect. - LLUUID fake_mesh_id; - fake_mesh_id.generate(); - bool dummy; // not used - pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, "", dummy); + const LLVector3& joint_pos = jointTransform.getTranslation(); + if (pJoint->aboveJointPosThreshold(joint_pos)) + { + bool override_changed; // not used + pJoint->addAttachmentPosOverride(joint_pos, fake_mesh_id, "", override_changed); + if (model->mSkinInfo.mLockScaleIfJointPosition) + { + pJoint->addAttachmentScaleOverride(pJoint->getDefaultScale(), fake_mesh_id, ""); + } + } } else { diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 398f0997f3..cd9e5cfa54 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -50,8 +50,12 @@ std::string model_names[] = const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string); LLModel::LLModel(LLVolumeParams& params, F32 detail) - : LLVolume(params, detail), mNormalizedScale(1,1,1), mNormalizedTranslation(0,0,0) - , mPelvisOffset( 0.0f ), mStatus(NO_ERRORS), mSubmodelID(0) + : LLVolume(params, detail), + mNormalizedScale(1,1,1), + mNormalizedTranslation(0,0,0), + mPelvisOffset( 0.0f ), + mStatus(NO_ERRORS), + mSubmodelID(0) { mDecompID = -1; mLocalID = -1; @@ -1446,6 +1450,9 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) { mPelvisOffset = skin["pelvis_offset"].asReal(); } + + // FIXME BENTO check contents of asset. + mLockScaleIfJointPosition = true; } LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 5f98942340..fe6ce148c4 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -54,6 +54,7 @@ public: LLSD asLLSD(bool include_joints) const; LLMatrix4 mBindShapeMatrix; float mPelvisOffset; + bool mLockScaleIfJointPosition; }; class LLModel : public LLVolume diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 3354678af9..7af15fb351 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5539,16 +5539,25 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo) { pJoint->setId( currentId ); const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation(); - bool override_changed; - pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString(), override_changed ); - - if (override_changed) + if (pJoint->aboveJointPosThreshold(jointPos)) { - //If joint is a pelvis then handle old/new pelvis to foot values - if ( lookingForJoint == "mPelvis" ) - { - pelvisGotSet = true; - } + bool override_changed; + pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString(), override_changed ); + + if (override_changed) + { + //If joint is a pelvis then handle old/new pelvis to foot values + if ( lookingForJoint == "mPelvis" ) + { + pelvisGotSet = true; + } + } + if (pSkinData->mLockScaleIfJointPosition) + { + // Note that unlike positions, there's no threshold check here, + // just a lock at the default value. + pJoint->addAttachmentScaleOverride(pJoint->getDefaultScale(), mesh_id, avString()); + } } } } @@ -5567,25 +5576,6 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo) } } } - // Set the joint scales - // FIXME replace with real logic for finding scale, probably inside the bindcnt loop above - const LLUUID& mesh_id = pSkinData->mMeshID; - for (int i = 0; i < jointCnt; ++i) - { - std::string lookingForJoint = pSkinData->mJointNames[i].c_str(); - LLJoint* pJoint = getJoint(lookingForJoint); - if (pJoint) - { - if (pJoint->getName() == "mCollarRight" || - pJoint->getName() == "mShoulderRight" || - pJoint->getName() == "mElbowRight" || - pJoint->getName() == "mHandRight") - { - LLVector3 jointScale(2.0f, 2.0f, 2.0f); - pJoint->addAttachmentScaleOverride(jointScale, mesh_id, avString()); - } - } - } } //Rebuild body data if we altered joints/pelvis @@ -8491,6 +8481,20 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str()); } } + // Joint scale overrides + for (iter = mSkeleton.begin(); iter != end; ++iter) + { + LLJoint* pJoint = (*iter); + + LLVector3 scale; + LLUUID mesh_id; + + if (pJoint->hasAttachmentScaleOverride(scale,mesh_id)) + { + apr_file_printf( file, "\t\t\n", + pJoint->getName().c_str(), scale[0], scale[1], scale[2], mesh_id.asString().c_str()); + } + } F32 pelvis_fixup; LLUUID mesh_id; if (hasPelvisFixup(pelvis_fixup, mesh_id)) -- cgit v1.3 From 6c46b3caf20af1a2987c0ca4ed0bf8e6ebe80fb4 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 6 Sep 2016 16:32:41 -0400 Subject: SL-395 - can enable/disable scale lock in mesh upload UI. Feature works. --- indra/llprimitive/llmodel.cpp | 20 ++++++-- indra/llprimitive/llmodel.h | 10 ++-- indra/newview/llfloatermodelpreview.cpp | 55 +++++++++++++++++----- indra/newview/llfloatermodelpreview.h | 4 +- indra/newview/llmeshrepository.cpp | 14 ++++-- indra/newview/llmeshrepository.h | 10 ++-- .../skins/default/xui/en/floater_model_preview.xml | 7 +++ 7 files changed, 92 insertions(+), 28 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index cd9e5cfa54..6637f41966 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -671,6 +671,7 @@ LLSD LLModel::writeModel( const LLModel::Decomposition& decomp, BOOL upload_skin, BOOL upload_joints, + BOOL lock_scale_if_joint_position, BOOL nowrite, BOOL as_slm, int submodel_id) @@ -690,7 +691,7 @@ LLSD LLModel::writeModel( if (skinning) { //write skinning block - mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints); + mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints, lock_scale_if_joint_position); } if (!decomp.mBaseHull.empty() || @@ -1451,11 +1452,17 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) mPelvisOffset = skin["pelvis_offset"].asReal(); } - // FIXME BENTO check contents of asset. - mLockScaleIfJointPosition = true; + if (skin.has("lock_scale_if_joint_position")) + { + mLockScaleIfJointPosition = skin["lock_scale_if_joint_position"].asBoolean(); + } + else + { + mLockScaleIfJointPosition = false; + } } -LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const +LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_position) const { LLSD ret; @@ -1493,6 +1500,11 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const } } + if (lock_scale_if_joint_position) + { + ret["lock_scale_if_joint_position"] = mLockScaleIfJointPosition; + } + ret["pelvis_offset"] = mPelvisOffset; } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index fe6ce148c4..c23d65bc8f 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -42,16 +42,17 @@ class domMesh; class LLMeshSkinInfo { public: + LLMeshSkinInfo() { } + LLMeshSkinInfo(LLSD& data); + void fromLLSD(LLSD& data); + LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; + LLUUID mMeshID; std::vector mJointNames; std::vector mInvBindMatrix; std::vector mAlternateBindMatrix; std::vector mJointRemap; - LLMeshSkinInfo() { } - LLMeshSkinInfo(LLSD& data); - void fromLLSD(LLSD& data); - LLSD asLLSD(bool include_joints) const; LLMatrix4 mBindShapeMatrix; float mPelvisOffset; bool mLockScaleIfJointPosition; @@ -139,6 +140,7 @@ public: const LLModel::Decomposition& decomp, BOOL upload_skin, BOOL upload_joints, + BOOL lock_scale_if_joint_position, BOOL nowrite = FALSE, BOOL as_slm = FALSE, int submodel_id = 0); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index c1ec86b110..7aae48cf5d 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -298,6 +298,7 @@ BOOL LLFloaterModelPreview::postBuild() childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); + childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); childSetTextArg("status", "[STATUS]", getString("status_idle")); @@ -311,6 +312,7 @@ BOOL LLFloaterModelPreview::postBuild() childSetCommitCallback("upload_skin", onUploadSkinCommit, this); childSetCommitCallback("upload_joints", onUploadJointsCommit, this); + childSetCommitCallback("lock_scale_if_joint_position", onUploadJointsCommit, this); childSetCommitCallback("import_scale", onImportScaleCommit, this); childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this); @@ -323,6 +325,7 @@ BOOL LLFloaterModelPreview::postBuild() childDisable("upload_skin"); childDisable("upload_joints"); + childDisable("lock_scale_if_joint_position"); initDecompControls(); @@ -488,6 +491,7 @@ void LLFloaterModelPreview::onClickCalculateBtn() bool upload_skinweights = childGetValue("upload_skin").asBoolean(); bool upload_joint_positions = childGetValue("upload_joints").asBoolean(); + bool lock_scale_if_joint_position = childGetValue("lock_scale_if_joint_position").asBoolean(); if (upload_joint_positions) { @@ -499,7 +503,8 @@ void LLFloaterModelPreview::onClickCalculateBtn() mUploadModelUrl.clear(); gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, - childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, + childGetValue("upload_textures").asBoolean(), + upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, mUploadModelUrl, false, getWholeModelFeeObserverHandle()); @@ -1324,9 +1329,10 @@ U32 LLModelPreview::calcResourceCost() decomp, mFMP->childGetValue("upload_skin").asBoolean(), mFMP->childGetValue("upload_joints").asBoolean(), + mFMP->childGetValue("lock_scale_if_joint_position").asBoolean(), TRUE, - FALSE, - instance.mModel->mSubmodelID); + FALSE, + instance.mModel->mSubmodelID); num_hulls += decomp.mHull.size(); for (U32 i = 0; i < decomp.mHull.size(); ++i) @@ -1651,7 +1657,7 @@ void LLModelPreview::rebuildUploadData() } -void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_positions) +void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position) { if (!mLODFile[LLModel::LOD_HIGH].empty()) { @@ -1660,12 +1666,13 @@ void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_posit if (LLModelLoader::getSLMFilename(filename, slm_filename)) { - saveUploadData(slm_filename, save_skinweights, save_joint_positions); + saveUploadData(slm_filename, save_skinweights, save_joint_positions, lock_scale_if_joint_position); } } } -void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_positions) +void LLModelPreview::saveUploadData(const std::string& filename, + bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position) { std::set > meshes; @@ -1706,7 +1713,9 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw instance.mLOD[LLModel::LOD_LOW], instance.mLOD[LLModel::LOD_IMPOSTOR], decomp, - save_skinweights, save_joint_positions, + save_skinweights, + save_joint_positions, + lock_scale_if_joint_position, FALSE, TRUE, instance.mModel->mSubmodelID); data["mesh"][instance.mModel->mLocalID] = str.str(); @@ -1946,6 +1955,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) bool skin_weights = false; bool joint_positions = false; + bool lock_scale_if_joint_position = false; for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) { //for each LoD @@ -1993,6 +2003,10 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) { joint_positions = true; } + if (list_iter->mModel->mSkinInfo.mLockScaleIfJointPosition) + { + lock_scale_if_joint_position = true; + } } } } @@ -2016,6 +2030,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) mViewOption["show_joint_positions"] = true; fmp->childSetValue("upload_joints", true); } + + if (lock_scale_if_joint_position) + { + fmp->enableViewOption("lock_scale_if_joint_position"); + mViewOption["lock_scale_if_joint_position"] = true; + fmp->childSetValue("lock_scale_if_joint_position", true); + } } //copy high lod to base scene for LoD generation @@ -3645,7 +3666,17 @@ BOOL LLModelPreview::render() mFMP->childSetValue("upload_joints", false); upload_joints = false; } - + + if (upload_skin && upload_joints) + { + mFMP->childEnable("lock_scale_if_joint_position"); + } + else + { + mFMP->childDisable("lock_scale_if_joint_position"); + mFMP->childSetValue("lock_scale_if_joint_position", false); + } + //Only enable joint offsets if it passed the earlier critiquing if ( isRigValidForJointPositionUpload() ) { @@ -4239,15 +4270,17 @@ void LLFloaterModelPreview::onUpload(void* user_data) bool upload_skinweights = mp->childGetValue("upload_skin").asBoolean(); bool upload_joint_positions = mp->childGetValue("upload_joints").asBoolean(); - + bool lock_scale_if_joint_position = mp->childGetValue("lock_scale_if_joint_position").asBoolean(); if (gSavedSettings.getBOOL("MeshImportUseSLM")) { - mp->mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions); + mp->mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions, lock_scale_if_joint_position); } gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale, - mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mp->mUploadModelUrl, + mp->childGetValue("upload_textures").asBoolean(), + upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, + mp->mUploadModelUrl, true, LLHandle(), mp->getWholeModelUploadObserverHandle()); } diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 217ac35888..a7a5c1b33a 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -270,8 +270,8 @@ public: void restoreNormals(); U32 calcResourceCost(); void rebuildUploadData(); - void saveUploadData(bool save_skinweights, bool save_joint_poisitions); - void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions); + void saveUploadData(bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position); + void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position); void clearIncompatible(S32 lod); void updateStatusMessages(); void updateLodControls(S32 lod); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 54f8fb93d0..5f8f42a1d6 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1896,7 +1896,8 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 } LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, const std::string & upload_url, bool do_upload, + bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, + const std::string & upload_url, bool do_upload, LLHandle fee_observer, LLHandle upload_observer) : LLThread("mesh upload"), @@ -1911,6 +1912,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, mUploadTextures = upload_textures; mUploadSkin = upload_skin; mUploadJoints = upload_joints; + mLockScaleIfJointPosition = lock_scale_if_joint_position; mMutex = new LLMutex(NULL); mPendingUploads = 0; mFinished = false; @@ -2097,6 +2099,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) decomp, mUploadSkin, mUploadJoints, + mLockScaleIfJointPosition, FALSE, FALSE, data.mBaseModel->mSubmodelID); @@ -2255,6 +2258,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) decomp, mUploadSkin, mUploadJoints, + mLockScaleIfJointPosition, FALSE, FALSE, data.mBaseModel->mSubmodelID); @@ -3946,11 +3950,13 @@ LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id) void LLMeshRepository::uploadModel(std::vector& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload, + bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, + std::string upload_url, bool do_upload, LLHandle fee_observer, LLHandle upload_observer) { - LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, upload_skin, upload_joints, upload_url, - do_upload, fee_observer, upload_observer); + LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, + upload_skin, upload_joints, lock_scale_if_joint_position, + upload_url, do_upload, fee_observer, upload_observer); mUploadWaitList.push_back(thread); } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index a762042597..30f042845a 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -400,6 +400,7 @@ public: bool mUploadTextures; bool mUploadSkin; bool mUploadJoints; + bool mLockScaleIfJointPosition; volatile bool mDiscarded; LLHost mHost; @@ -407,7 +408,8 @@ public: std::string mWholeModelUploadURL; LLMeshUploadThread(instance_list& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, const std::string & upload_url, bool do_upload = true, + bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, + const std::string & upload_url, bool do_upload = true, LLHandle fee_observer = (LLHandle()), LLHandle upload_observer = (LLHandle())); ~LLMeshUploadThread(); @@ -510,8 +512,10 @@ public: LLSD& getMeshHeader(const LLUUID& mesh_id); void uploadModel(std::vector& data, LLVector3& scale, bool upload_textures, - bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true, - LLHandle fee_observer= (LLHandle()), LLHandle upload_observer = (LLHandle())); + bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, + std::string upload_url, bool do_upload = true, + LLHandle fee_observer= (LLHandle()), + LLHandle upload_observer = (LLHandle())); S32 getMeshSize(const LLUUID& mesh_id, S32 lod); diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index d2c8dddfe1..2750316f2e 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1217,6 +1217,13 @@ label_text.text_color="White" name="upload_joints" top_pad="15"/> + Date: Tue, 27 Sep 2016 17:29:22 -0400 Subject: SL-451 - support for getJoint() by number, use in initSkinningMatrixPalette() --- indra/llappearance/llavatarappearance.cpp | 16 ++++++------ indra/llappearance/llavatarappearance.h | 1 + indra/llprimitive/llmodel.cpp | 1 + indra/llprimitive/llmodel.h | 1 + indra/newview/llskinningutil.cpp | 16 +++++++++++- indra/newview/llvoavatar.cpp | 42 ++++++++++++++++++++++++++++--- indra/newview/llvoavatar.h | 1 + indra/newview/llvoavatarself.cpp | 18 ++++++++++--- indra/newview/llvovolume.cpp | 2 ++ 9 files changed, 82 insertions(+), 16 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index af14e3418b..ebeab22dcc 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -187,7 +187,11 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) : mHeadOffset(), mRoot(NULL), mWearableData(wearable_data), - mNextJointNum(0) + mNextJointNum(0), + mNumBones(0), + mNumCollisionVolumes(0), + mCollisionVolumes(NULL), + mIsBuilt(FALSE) { llassert_always(mWearableData); mBakedTextureDatas.resize(LLAvatarAppearanceDefines::BAKED_NUM_INDICES); @@ -200,11 +204,6 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) : mBakedTextureDatas[i].mMaskTexName = 0; mBakedTextureDatas[i].mTextureIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i); } - - mIsBuilt = FALSE; - - mNumCollisionVolumes = 0; - mCollisionVolumes = NULL; } // virtual @@ -667,14 +666,16 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent if (info->mIsJoint) { joint->setSkinOffset( info->mPivot ); + joint->setJointNum(joint_num); joint_num++; } else // collision volume { + joint->setJointNum(mNumBones+volume_num); volume_num++; } + mNextJointNum++; - joint->setJointNum(mNextJointNum++); // setup children LLAvatarBoneInfo::child_list_t::const_iterator iter; @@ -699,6 +700,7 @@ BOOL LLAvatarAppearance::allocateCharacterJoints( U32 num ) { clearSkeleton(); mSkeleton = avatar_joint_list_t(num,NULL); + mNumBones = num; } return TRUE; diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 6938ca2dea..77795f3bf6 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -352,6 +352,7 @@ protected: // Collision volumes //-------------------------------------------------------------------- public: + S32 mNumBones; S32 mNumCollisionVolumes; LLAvatarJointCollisionVolume* mCollisionVolumes; protected: diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 6637f41966..7677dc9e27 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1399,6 +1399,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) for (U32 i = 0; i < skin["joint_names"].size(); ++i) { mJointNames.push_back(skin["joint_names"][i]); + mJointNums.push_back(-1); } } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index c23d65bc8f..2034686529 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -49,6 +49,7 @@ public: LLUUID mMeshID; std::vector mJointNames; + mutable std::vector mJointNums; std::vector mInvBindMatrix; std::vector mAlternateBindMatrix; std::vector mJointRemap; diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index d69432ad21..e1333b8352 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -203,6 +203,7 @@ void LLSkinningUtil::remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* ski // Apply the remap to mJointNames, mInvBindMatrix, and mAlternateBindMatrix std::vector new_joint_names; + std::vector new_joint_nums; std::vector new_inv_bind_matrix; std::vector new_alternate_bind_matrix; @@ -211,6 +212,7 @@ void LLSkinningUtil::remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* ski if (j_proxy[j] == j && new_joint_names.size() < max_joints) { new_joint_names.push_back(skin->mJointNames[j]); + new_joint_nums.push_back(-1); new_inv_bind_matrix.push_back(skin->mInvBindMatrix[j]); if (!skin->mAlternateBindMatrix.empty()) { @@ -245,7 +247,19 @@ void LLSkinningUtil::initSkinningMatrixPalette( // Note that we are mostly passing Matrix4a's to this routine anyway, just dubiously casted. for (U32 j = 0; j < count; ++j) { - LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); + LLJoint *joint = NULL; + if (skin->mJointNums[j] == -1) + { + joint = avatar->getJoint(skin->mJointNames[j]); + if (joint) + { + skin->mJointNums[j] = joint->getJointNum(); + } + } + else + { + joint = avatar->getJoint(skin->mJointNums[j]); + } mat[j] = skin->mInvBindMatrix[j]; if (joint) { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 7af15fb351..1ff4c1f681 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5324,18 +5324,52 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) LLJoint* jointp = NULL; if (iter == mJointMap.end() || iter->second == NULL) - { //search for joint and cache found joint in lookup table + { //search for joint and cache found joint in lookup table jointp = mRoot->findJoint(name); mJointMap[name] = jointp; } else - { //return cached pointer + { //return cached pointer jointp = iter->second; } +#ifndef LL_RELEASE_FOR_DOWNLOAD + if (jointp && jointp->getName()!="mScreen" && jointp->getName()!="mRoot") + { + llassert(getJoint(jointp->getJointNum())==jointp); + } +#endif return jointp; } +LLJoint *LLVOAvatar::getJoint( S32 joint_num ) +{ + LLJoint *pJoint = NULL; + S32 collision_start = mNumBones; + S32 attachment_start = mNumBones + mNumCollisionVolumes; + if (joint_num>=attachment_start) + { + // Attachment IDs start at 1 + S32 attachment_id = joint_num - attachment_start + 1; + attachment_map_t::iterator iter = mAttachmentPoints.find(attachment_id); + if (iter != mAttachmentPoints.end()) + { + pJoint = iter->second; + } + } + else if (joint_num>=collision_start) + { + S32 collision_id = joint_num-collision_start; + pJoint = &mCollisionVolumes[collision_id]; + } + else if (joint_num>=0) + { + pJoint = mSkeleton[joint_num]; + } + llassert(!pJoint || pJoint->getJointNum() == joint_num); + return pJoint; +} + //----------------------------------------------------------------------------- // getRiggedMeshID // @@ -5966,7 +6000,8 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints) attachment->setVisibleInFirstPerson(info->mVisibleFirstPerson); attachment->setIsHUDAttachment(info->mIsHUDAttachment); // attachment can potentially be animated, needs a number. - attachment->setJointNum(mNextJointNum++); + attachment->setJointNum(mNumBones + mNumCollisionVolumes + attachmentID - 1); + LL_WARNS() << "Initialized attachment" << attachment->getName() << " joint_num " << attachment->getJointNum() << LL_ENDL; if (newly_created) { @@ -6647,7 +6682,6 @@ LLVOAvatar* LLVOAvatar::findAvatarFromAttachment( LLViewerObject* obj ) return NULL; } -// warning: order(N) not order(1) S32 LLVOAvatar::getAttachmentCount() { S32 count = mAttachmentPoints.size(); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 64171e7243..fe76f9852f 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -199,6 +199,7 @@ public: void dumpAnimationState(); virtual LLJoint* getJoint(const std::string &name); + LLJoint* getJoint(S32 num); void addAttachmentOverridesForObject(LLViewerObject *vo); void resetJointsOnDetach(const LLUUID& mesh_id); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index b6655dd078..aa5d82a096 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -700,13 +700,23 @@ void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time) // virtual LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) { - if (mScreenp) + LLJoint *jointp = NULL; + jointp = LLVOAvatar::getJoint(name); + if (!jointp && mScreenp) { - LLJoint* jointp = mScreenp->findJoint(name); - if (jointp) return jointp; + jointp = mScreenp->findJoint(name); + if (jointp) + { + mJointMap[name] = jointp; + } } - return LLVOAvatar::getJoint(name); + if (jointp && jointp != mScreenp && jointp != mRoot) + { + llassert(LLVOAvatar::getJoint((S32)jointp->getJointNum())==jointp); + } + return jointp; } + // virtual BOOL LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight) { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6d3e2e4a39..fd77bc2985 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4779,11 +4779,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (rigged && pAvatarVO) { pAvatarVO->addAttachmentOverridesForObject(vobj); +#if 0 if (pAvatarVO->isSelf()) { bool verbose = true; pAvatarVO->showAttachmentOverrides(verbose); } +#endif } //for each face -- cgit v1.3 From 8230a9937f3bded847dae6c33e01b44158a7f8ee Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 18 Oct 2016 16:05:35 -0400 Subject: MAINT-6841 - removed the joint remapping code, since it was designed to support a feature we no longer have. This also incidentally fixes any bugs caused by the joint remapping code. --- indra/llmath/llvolume.cpp | 3 - indra/llmath/llvolume.h | 4 - indra/llprimitive/llmodel.h | 1 - indra/newview/lldrawpoolavatar.cpp | 8 +- indra/newview/llskinningutil.cpp | 224 ++----------------------------------- indra/newview/llskinningutil.h | 6 +- indra/newview/llvoavatar.cpp | 1 - 7 files changed, 13 insertions(+), 234 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index ac6f77b5ab..d57fe81de4 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4572,7 +4572,6 @@ LLVolumeFace::LLVolumeFace() : mTexCoords(NULL), mIndices(NULL), mWeights(NULL), - mWeightsRemapped(FALSE), mOctree(NULL), mOptimized(FALSE) { @@ -4598,7 +4597,6 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mTexCoords(NULL), mIndices(NULL), mWeights(NULL), - mWeightsRemapped(FALSE), mOctree(NULL) { mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); @@ -4670,7 +4668,6 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) ll_aligned_free_16(mWeights); mWeights = NULL; } - mWeightsRemapped = src.mWeightsRemapped; } if (mNumIndices) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 33e1403a14..1da2d0c6b1 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -953,10 +953,6 @@ public: // mWeights.size() should be empty or match mVertices.size() LLVector4a* mWeights; - // Whether or not the weights have been cleaned up and remapped - // based on currently supported joints. - mutable BOOL mWeightsRemapped; - LLOctreeNode* mOctree; //whether or not face has been cache optimized diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 2034686529..365ba8a51c 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -52,7 +52,6 @@ public: mutable std::vector mJointNums; std::vector mInvBindMatrix; std::vector mAlternateBindMatrix; - std::vector mJointRemap; LLMatrix4 mBindShapeMatrix; float mPelvisOffset; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index e9524189ed..517c69305a 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1550,19 +1550,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer( return; } // FIXME ugly const cast - LLSkinningUtil::remapSkinInfoJoints(avatar, const_cast(skin)); + LLSkinningUtil::scrubInvalidJoints(avatar, const_cast(skin)); LLPointer buffer = face->getVertexBuffer(); LLDrawable* drawable = face->getDrawable(); U32 data_mask = face->getRiggedVertexBufferDataMask(); - if (!vol_face.mWeightsRemapped) - { - LLSkinningUtil::remapSkinWeights(weight, vol_face.mNumVertices, skin); - vol_face.mWeightsRemapped = TRUE; - } - if (buffer.isNull() || buffer->getTypeMask() != data_mask || buffer->getNumVerts() != vol_face.mNumVertices || diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 3ad30dac69..c0589e33bb 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -32,97 +32,15 @@ #include "llviewercontrol.h" #include "llmeshrepository.h" -bool LLSkinningUtil::sIncludeEnhancedSkeleton = true; - -namespace { - -bool get_name_index(const std::string& name, std::vector& names, U32& result) -{ - std::vector::const_iterator find_it = - std::find(names.begin(), names.end(), name); - if (find_it != names.end()) - { - result = find_it - names.begin(); - return true; - } - else - { - return false; - } -} - -// Find a name table index that is also a valid joint on the -// avatar. Order of preference is: requested name, mPelvis, first -// valid match in names table. -U32 get_valid_joint_index(const std::string& name, LLVOAvatar *avatar, std::vector& joint_names) -{ - U32 result; - if (avatar->getJoint(name) && get_name_index(name,joint_names,result)) - { - return result; - } - if (get_name_index("mPelvis",joint_names,result)) - { - return result; - } - for (U32 j=0; jgetJoint(joint_names[j])) - { - return j; - } - } - // Shouldn't ever get here, because of the name cleanup pass in remapSkinInfoJoints() - LL_ERRS() << "no valid joints in joint_names" << LL_ENDL; - return 0; -} - -// Which joint will stand in for this joint? -U32 get_proxy_joint_index(U32 joint_index, LLVOAvatar *avatar, std::vector& joint_names) -{ - bool include_enhanced = LLSkinningUtil::sIncludeEnhancedSkeleton; - U32 j_proxy = get_valid_joint_index(joint_names[joint_index], avatar, joint_names); - LLJoint *joint = avatar->getJoint(joint_names[j_proxy]); - llassert(joint); - // Find the first ancestor that's not flagged as extended, or the - // last ancestor that's rigged in this mesh, whichever - // comes first. - while (1) - { - if (include_enhanced || - joint->getSupport()==LLJoint::SUPPORT_BASE) - break; - LLJoint *parent = joint->getParent(); - if (!parent) - break; - if (!get_name_index(parent->getName(), joint_names, j_proxy)) - { - break; - } - joint = parent; - } - return j_proxy; -} - -} - // static void LLSkinningUtil::initClass() { - sIncludeEnhancedSkeleton = gSavedSettings.getBOOL("IncludeEnhancedSkeleton"); } // static U32 LLSkinningUtil::getMaxJointCount() { U32 result = LL_MAX_JOINTS_PER_MESH_OBJECT; - if (!sIncludeEnhancedSkeleton) - { - // Currently the remap logic does not guarantee joint count <= 52; - // if one of the base ancestors is not rigged in a given mesh, an extended - // joint can still be included. - result = llmin(result,(U32)52); - } return result; } @@ -133,33 +51,8 @@ U32 LLSkinningUtil::getMeshJointCount(const LLMeshSkinInfo *skin) } // static - -// Destructively remap the joints in skin info based on what joints -// are known in the avatar, and which are currently supported. This -// will also populate mJointRemap[] in the skin, which can be used to -// make the corresponding changes to the integer part of vertex -// weights. -// -// This will throw away joint info for any joints that are not known -// in the avatar, or not currently flagged to support based on the -// debug setting for IncludeEnhancedSkeleton. -// - -// BENTO maybe this really only makes sense for new leaf joints? New spine -// joints may need different logic. - -// static -void LLSkinningUtil::remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin) +void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin) { - // skip if already done. - if (!skin->mJointRemap.empty()) - { - return; - } - - U32 max_joints = getMeshJointCount(skin); - - // Compute the remap for (U32 j = 0; j < skin->mJointNames.size(); ++j) { // Fix invalid names to "mPelvis". Currently meshes with @@ -170,70 +63,6 @@ void LLSkinningUtil::remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* ski skin->mJointNames[j] = "mPelvis"; } } - std::vector j_proxy(skin->mJointNames.size()); - for (U32 j = 0; j < skin->mJointNames.size(); ++j) - { - U32 j_rep = get_proxy_joint_index(j, avatar, skin->mJointNames); - j_proxy[j] = j_rep; - } - S32 top = 0; - std::vector j_remap(skin->mJointNames.size()); - // Fill in j_remap for all joints that will be kept. - for (U32 j = 0; j < skin->mJointNames.size(); ++j) - { - if (j_proxy[j] == j) - { - // Joint will be included - j_remap[j] = top; - if (top < max_joints-1) - { - top++; - } - } - } - // Then use j_proxy to fill in j_remap for the joints that will be discarded - for (U32 j = 0; j < skin->mJointNames.size(); ++j) - { - if (j_proxy[j] != j) - { - j_remap[j] = j_remap[j_proxy[j]]; - } - } - - - // Apply the remap to mJointNames, mInvBindMatrix, and mAlternateBindMatrix - std::vector new_joint_names; - std::vector new_joint_nums; - std::vector new_inv_bind_matrix; - std::vector new_alternate_bind_matrix; - - for (U32 j = 0; j < skin->mJointNames.size(); ++j) - { - if (j_proxy[j] == j && new_joint_names.size() < max_joints) - { - new_joint_names.push_back(skin->mJointNames[j]); - new_joint_nums.push_back(-1); - new_inv_bind_matrix.push_back(skin->mInvBindMatrix[j]); - if (!skin->mAlternateBindMatrix.empty()) - { - new_alternate_bind_matrix.push_back(skin->mAlternateBindMatrix[j]); - } - } - } - llassert(new_joint_names.size() <= max_joints); - - for (U32 j = 0; j < skin->mJointNames.size(); ++j) - { - if (skin->mJointNames[j] != new_joint_names[j_remap[j]]) - { - LL_DEBUGS("Avatar") << "Starting joint[" << j << "] = " << skin->mJointNames[j] << " j_remap " << j_remap[j] << " ==> " << new_joint_names[j_remap[j]] << LL_ENDL; - } - } - - skin->mJointNames = new_joint_names; - skin->mInvBindMatrix = new_inv_bind_matrix; - skin->mAlternateBindMatrix = new_alternate_bind_matrix; - skin->mJointRemap = j_remap; } // static @@ -278,61 +107,30 @@ void LLSkinningUtil::initSkinningMatrixPalette( // This shouldn't happen - in mesh upload, skinned // rendering should be disabled unless all joints are // valid. In other cases of skinned rendering, invalid - // joints should already have been removed during remap. + // joints should already have been removed during scrubInvalidJoints(). LL_WARNS_ONCE("Avatar") << "Rigged to invalid joint name " << skin->mJointNames[j] << LL_ENDL; } } } -// Transform the weights based on the remap info stored in skin. Note -// that this is destructive and non-idempotent, so we need to keep -// track of whether we've done it already. If the desired remapping -// changes, the viewer must be restarted. -// // static -void LLSkinningUtil::remapSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) +void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) { - checkSkinWeights(weights, num_vertices, skin); - llassert(skin->mJointRemap.size()>0); // Must call remapSkinInfoJoints() first, which this checks for. - const U32* remap = &skin->mJointRemap[0]; - const S32 max_joints = skin->mJointRemap.size(); +#ifndef LL_RELEASE_FOR_DOWNLOAD + const S32 max_joints = skin->mJointNames.size(); for (U32 j=0; jmJointRemap.size(); - if (skin->mJointRemap.size()>0) - { - // Check the weights are consistent with the current remap. - for (U32 j=0; j=0); - llassert(i 0.0f); + llassert(i>=0); + llassert(i 0.0f); } #endif } diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index 9a28100dc3..6a6091114c 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -37,14 +37,10 @@ public: static void initClass(); static U32 getMaxJointCount(); static U32 getMeshJointCount(const LLMeshSkinInfo *skin); - static void remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin); + static void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin); static void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar); static void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); - static void remapSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); - - // This is initialized from gSavedSettings at startup and then left alone. - static bool sIncludeEnhancedSkeleton; }; #endif diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 1ff4c1f681..46c367b4e6 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -6001,7 +6001,6 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints) attachment->setIsHUDAttachment(info->mIsHUDAttachment); // attachment can potentially be animated, needs a number. attachment->setJointNum(mNumBones + mNumCollisionVolumes + attachmentID - 1); - LL_WARNS() << "Initialized attachment" << attachment->getName() << " joint_num " << attachment->getJointNum() << LL_ENDL; if (newly_created) { -- cgit v1.3 From 45ab1429b2e6feae6ac8cd5ee59feacccd86f7b7 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 19 Oct 2016 11:05:02 -0400 Subject: SL-395 - believed fix for intermittent problem uploading meshes with scale locks --- indra/llprimitive/llmodel.cpp | 12 +++++++++--- indra/llprimitive/llmodel.h | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 7677dc9e27..c98cee218c 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1343,7 +1343,6 @@ bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCn return true; } - bool LLModel::loadSkinInfo(LLSD& header, std::istream &is) { S32 offset = header["skin"]["offset"].asInteger(); @@ -1386,8 +1385,15 @@ bool LLModel::loadDecomposition(LLSD& header, std::istream& is) return true; } +LLMeshSkinInfo::LLMeshSkinInfo(): + mPelvisOffset(0.0), + mLockScaleIfJointPosition(false) +{ +} -LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin) +LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin): + mPelvisOffset(0.0), + mLockScaleIfJointPosition(false) { fromLLSD(skin); } @@ -1503,7 +1509,7 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_positi if (lock_scale_if_joint_position) { - ret["lock_scale_if_joint_position"] = mLockScaleIfJointPosition; + ret["lock_scale_if_joint_position"] = lock_scale_if_joint_position; } ret["pelvis_offset"] = mPelvisOffset; diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 365ba8a51c..40c3916168 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -42,7 +42,7 @@ class domMesh; class LLMeshSkinInfo { public: - LLMeshSkinInfo() { } + LLMeshSkinInfo(); LLMeshSkinInfo(LLSD& data); void fromLLSD(LLSD& data); LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; -- cgit v1.3 From a2fd408c9bc8c7030910e8a2da8c39b596ae6b09 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 21 Oct 2016 09:50:13 -0400 Subject: MAINT-6853 - fix for viewer crash when checking preview skin weights --- indra/llprimitive/lldaeloader.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index c194d677c8..3e279924a8 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1319,6 +1319,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do name = mJointMap[name]; } model->mSkinInfo.mJointNames.push_back(name); + model->mSkinInfo.mJointNums.push_back(-1); } } else @@ -1336,6 +1337,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do name = mJointMap[name]; } model->mSkinInfo.mJointNames.push_back(name); + model->mSkinInfo.mJointNums.push_back(-1); } } } -- cgit v1.3 From 5dcd81c15507ad8f487e5727bc7a94de82f6fb45 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 28 Oct 2016 09:33:57 -0400 Subject: SL-451 - avoid more high-cost string operations in a per-frame function --- indra/llprimitive/llmodel.cpp | 6 ++++-- indra/llprimitive/llmodel.h | 1 + indra/newview/llskinningutil.cpp | 5 +++++ 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index c98cee218c..db6d00bc2c 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1387,13 +1387,15 @@ bool LLModel::loadDecomposition(LLSD& header, std::istream& is) LLMeshSkinInfo::LLMeshSkinInfo(): mPelvisOffset(0.0), - mLockScaleIfJointPosition(false) + mLockScaleIfJointPosition(false), + mInvalidJointsScrubbed(false) { } LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin): mPelvisOffset(0.0), - mLockScaleIfJointPosition(false) + mLockScaleIfJointPosition(false), + mInvalidJointsScrubbed(false) { fromLLSD(skin); } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 40c3916168..097558ef67 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -56,6 +56,7 @@ public: LLMatrix4 mBindShapeMatrix; float mPelvisOffset; bool mLockScaleIfJointPosition; + bool mInvalidJointsScrubbed; }; class LLModel : public LLVolume diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index c0589e33bb..b2fd1744bc 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -53,6 +53,10 @@ U32 LLSkinningUtil::getMeshJointCount(const LLMeshSkinInfo *skin) // static void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin) { + if (skin->mInvalidJointsScrubbed) + { + return; + } for (U32 j = 0; j < skin->mJointNames.size(); ++j) { // Fix invalid names to "mPelvis". Currently meshes with @@ -63,6 +67,7 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin skin->mJointNames[j] = "mPelvis"; } } + skin->mInvalidJointsScrubbed = true; } // static -- cgit v1.3