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