From fbb160b061b5f77705e0a5b4861a3631e3364f04 Mon Sep 17 00:00:00 2001 From: Nicky Date: Fri, 16 Sep 2016 21:43:06 +0200 Subject: [PATCH 1/2] Cache results from FT_Get_Kerning for pairs of glyph < 256 to avoid costly FT_Get_Kerning calls. --- indra/llrender/llfontfreetype.cpp | 56 +++++++++++++++++++++++++++++++ indra/llrender/llfontfreetype.h | 6 ++++ 2 files changed, 62 insertions(+) diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index f7cb87ffd2..7e3a7073e5 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -114,6 +114,12 @@ LLFontFreetype::LLFontFreetype() mStyle(0), mPointSize(0) { + // Set up kerning cache, size is 256x256, the initial cache lines are all null + mKerningCache = new F32*[ 256 ]; + + for( int i = 0; i < 256; ++i ) + mKerningCache[i] = NULL; + // } @@ -130,6 +136,13 @@ LLFontFreetype::~LLFontFreetype() delete mFontBitmapCachep; // mFallbackFonts cleaned up by LLPointer destructor + + // Delete the kerning cache + for( int i = 0; i < 256; ++i ) + delete[] mKerningCache[i]; + + delete[] mKerningCache; + // } BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) @@ -307,10 +320,32 @@ F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const LLFontGlyphInfo* right_glyph_info = getGlyphInfo(char_right); U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0; + // Use cached kerning if possible, only do so for glyphs < 256 for now + if( right_glyph < 256 && left_glyph < 256 ) + { + if( mKerningCache[ left_glyph ] && mKerningCache[ left_glyph ][ right_glyph ] < FLT_MAX ) + return mKerningCache[ left_glyph ][ right_glyph ]; + } + // + FT_Vector delta; llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta)); + // Cache kerning if possible, only do so for glyphs < 256 for now + if( right_glyph < 256 && left_glyph < 256 ) + { + if( !mKerningCache[ left_glyph ] ) + { + mKerningCache[ left_glyph ] = new F32[ 256 ]; + for( int i = 0; i < 256; ++i ) + mKerningCache[ left_glyph ][ i ] = FLT_MAX; + } + + mKerningCache[ left_glyph ][ right_glyph ] = delta.x*(1.f / 64.f); + } + // + return delta.x*(1.f/64.f); } @@ -322,10 +357,31 @@ F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LL U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0; U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0; + // Use cached kerning if possible, only do so for glyphs < 256 for now + if( right_glyph < 256 && left_glyph < 256 ) + { + if( mKerningCache[ left_glyph ] && mKerningCache[ left_glyph ][ right_glyph ] < FLT_MAX ) + return mKerningCache[ left_glyph ][ right_glyph ]; + } + // + FT_Vector delta; llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta)); + // Cache kerning if possible, only do so for glyphs < 256 for now + if( right_glyph < 256 && left_glyph < 256 ) + { + if( !mKerningCache[ left_glyph ] ) + { + mKerningCache[ left_glyph ] = new F32[ 256 ]; + for( int i = 0; i < 256; ++i ) + mKerningCache[ left_glyph ][ i ] = FLT_MAX; + } + + mKerningCache[ left_glyph ][ right_glyph ] = delta.x*(1.f / 64.f); + } + // return delta.x*(1.f/64.f); } diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index 5820b55da9..12bcebf5e2 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -189,6 +189,12 @@ private: mutable S32 mRenderGlyphCount; mutable S32 mAddGlyphCount; + + // Save X-kerning data, so far only for all glyphs with index small than 256 (to not waste too much memory) + // right now it is 256 slots with 256 glyphs each, maybe consider splitting it into smaller slices to use less memory if we + // we want to cache 0xFFFF glyphs + F32 **mKerningCache; + // Date: Fri, 16 Sep 2016 21:46:39 +0200 Subject: [PATCH 2/2] The sheer amount of calls into LLVOAvatar::getJoint get very costly in complex scenes. This is due to a string being used as index. Change the index to U32 for faster access. --- indra/llappearance/llavatarappearance.h | 2 +- indra/llcharacter/llcharacter.cpp | 8 ++++ indra/llcharacter/llcharacter.h | 8 +++- indra/llcharacter/lljoint.cpp | 22 ++++++++++ indra/llcharacter/lljoint.h | 10 +++++ indra/llprimitive/lldaeloader.cpp | 26 +++++++++--- indra/llprimitive/llmodel.cpp | 10 ++++- indra/llprimitive/llmodel.h | 8 +++- indra/llprimitive/llmodelloader.cpp | 5 ++- indra/llprimitive/llmodelloader.h | 11 +++++ indra/newview/lldrawpoolavatar.cpp | 17 ++++++-- indra/newview/llfloatermodelpreview.cpp | 5 ++- indra/newview/llmeshrepository.cpp | 1 + indra/newview/llmorphview.cpp | 7 +++- indra/newview/llpaneleditwearable.cpp | 18 +++++--- indra/newview/llvoavatar.cpp | 56 ++++++++++++++++++++----- indra/newview/llvoavatar.h | 8 +++- indra/newview/llvoavatarself.cpp | 10 ++++- indra/newview/llvoavatarself.h | 8 +++- indra/newview/llvoicevivox.cpp | 2 +- indra/newview/llvovolume.cpp | 7 +++- 21 files changed, 206 insertions(+), 43 deletions(-) diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 1cb23cb8e6..0ced39d338 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -137,7 +137,7 @@ public: // This map gets queried a huge amount of time. // typedef std::map joint_map_t; - typedef boost::unordered_map joint_map_t; + typedef boost::unordered_map< U32, LLJoint*> joint_map_t; // joint_map_t mJointMap; diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 1b14337d46..de700a6e83 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -111,6 +111,14 @@ LLJoint *LLCharacter::getJoint( const std::string &name ) return joint; } +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// Default fallback is string. +LLJoint *LLCharacter::getJoint( const JointKey &name ) +{ + return getJoint( name.mName ); +} +// + //----------------------------------------------------------------------------- // registerMotion() //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 74c0373852..25c224f5ee 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -76,7 +76,13 @@ public: // get the specified joint // default implementation does recursive search, // subclasses may optimize/cache results. - virtual LLJoint *getJoint( const std::string &name ); + // virtual LLJoint *getJoint( const std::string &name ); + + // Query by JointKey rather than just a string, the key can be a U32 index for faster lookup + virtual LLJoint *getJoint( const JointKey &name ); + // + + LLJoint *getJoint( const std::string &name ); // get the position of the character virtual LLVector3 getCharacterPosition() = 0; diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 8fa08a2a6c..9be1ab685f 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -33,6 +33,28 @@ #include "llmath.h" +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +#include + +boost::unordered_map< std::string, U32 > mpStringToKeys; + +JointKey JointKey::construct( std::string aName ) +{ + boost::unordered_map< std::string, U32 >::iterator itr = mpStringToKeys.find( aName ); + + if( mpStringToKeys.end() == itr ) + { + U32 size = mpStringToKeys.size() + 1; + JointKey key{ aName, size }; + mpStringToKeys[ aName ] = size; + return key; + } + + return JointKey{ aName, itr->second }; + +} +// + S32 LLJoint::sNumUpdates = 0; S32 LLJoint::sNumTouches = 0; diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 2abe1d6db1..5e7d75501b 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -39,6 +39,16 @@ #include "llquaternion.h" #include "xform.h" +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +struct JointKey +{ + std::string mName; + U32 mKey; + + static JointKey construct( std::string aName ); +}; +// + const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15; const U32 LL_CHARACTER_MAX_JOINTS = 32; // must be divisible by 4! const U32 LL_HAND_JOINT_NUM = 31; diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 647e2a9cce..fd407767f2 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1358,8 +1358,11 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do { name = mJointMap[name]; } - model->mSkinInfo.mJointNames.push_back(name); - model->mSkinInfo.mJointMap[name] = j; +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// model->mSkinInfo.mJointNames.push_back( name ); + model->mSkinInfo.mJointNames.push_back( JointKey::construct( name ) ); + model->mSkinInfo.mJointMap[ name ] = j; +// } } else @@ -1376,7 +1379,10 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do { name = mJointMap[name]; } - model->mSkinInfo.mJointNames.push_back(name); +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// model->mSkinInfo.mJointNames.push_back( name ); + model->mSkinInfo.mJointNames.push_back( JointKey::construct( name ) ); +// model->mSkinInfo.mJointMap[name] = j; } } @@ -1418,7 +1424,11 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do //a skinned asset attached to a node in a file that contains an entire skeleton, //but does not use the skeleton). buildJointToNodeMappingFromScene( root ); - critiqueRigForUploadApplicability( model->mSkinInfo.mJointNames ); + +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// critiqueRigForUploadApplicability( model->mSkinInfo.mJointNames ); + critiqueRigForUploadApplicability( toStringVector( model->mSkinInfo.mJointNames ) ); +// if ( !missingSkeletonOrScene ) { @@ -1457,7 +1467,13 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do //in the same order as they were stored in the joint buffer. The joints associated //with the skeleton are not stored in the same order as they are in the exported joint buffer. //This remaps the skeletal joints to be in the same order as the joints stored in the model. - std::vector :: const_iterator jointIt = model->mSkinInfo.mJointNames.begin(); + +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup + // std::vector ::const_iterator jointIt = model->mSkinInfo.mJointNames.begin(); + std::vector< std::string > jointNames = toStringVector( model->mSkinInfo.mJointNames ); + std::vector ::const_iterator jointIt = jointNames.begin(); +// + const int jointCnt = model->mSkinInfo.mJointNames.size(); for ( int i=0; i Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// mJointNames.push_back( skin[ "joint_names" ][ i ] ); + mJointNames.push_back( JointKey::construct( skin[ "joint_names" ][ i ] ) ); +// ND> } } @@ -1467,7 +1470,10 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const for (U32 i = 0; i < mJointNames.size(); ++i) { - ret["joint_names"][i] = mJointNames[i]; +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// ret[ "joint_names" ][ i ] = mJointNames[ i ]; + ret[ "joint_names" ][ i ] = mJointNames[ i ].mName; +// for (U32 j = 0; j < 4; j++) { diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index ae602c09df..7059defdd5 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -33,6 +33,8 @@ #include "m4math.h" #include +#include "lljoint.h" + class daeElement; class domMesh; @@ -43,7 +45,11 @@ class LLMeshSkinInfo { public: LLUUID mMeshID; - std::vector mJointNames; +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// std::vector mJointNames; + std::vector< JointKey > mJointNames; +// + std::vector mInvBindMatrix; std::vector mAlternateBindMatrix; std::map mJointMap; diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index 996f115314..6a2d0788cc 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -376,7 +376,10 @@ bool LLModelLoader::loadFromSLM(const std::string& filename) if (!loaded_model->mSkinInfo.mJointNames.empty()) { //check to see if rig is valid - critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames ); +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames ); + critiqueRigForUploadApplicability( toStringVector( loaded_model->mSkinInfo.mJointNames ) ); +// } else if (mCacheOnlyHitIfRigged) { diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index bb4d06dca3..ea1459323a 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -184,6 +184,17 @@ public: } protected: +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup + std::vector< std::string > toStringVector( std::vector< JointKey > const &aIn ) const + { + std::vector< std::string > out; + + for( std::vector< JointKey >::const_iterator itr = aIn.begin(); itr != aIn.end(); ++itr ) + out.push_back( itr->mName ); + + return out; + } +// LLModelLoader::load_callback_t mLoadCallback; LLModelLoader::joint_lookup_func_t mJointLookupFunc; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 854018623a..2de041629f 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1747,11 +1747,17 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); if (!joint) { - joint = avatar->getJoint("mPelvis"); +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// joint = avatar->getJoint( "mPelvis" ); + joint = avatar->getJoint( JointKey::construct( "mPelvis" ) ); +// } if (!joint) { - LL_DEBUGS("Avatar") << "Failed to find " << skin->mJointNames[j] << LL_ENDL; +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// LL_DEBUGS( "Avatar" ) << "Failed to find " << skin->mJointNames[ j ] << LL_ENDL; + LL_DEBUGS( "Avatar" ) << "Failed to find " << skin->mJointNames[ j ].mName << LL_ENDL; +// } if (joint) { @@ -1906,8 +1912,11 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) LLJoint* joint = avatar->getJoint(skin->mJointNames[i]); if (!joint) { - joint = avatar->getJoint("mPelvis"); - } +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// joint = avatar->getJoint( "mPelvis" ); + joint = avatar->getJoint( JointKey::construct( "mPelvis" ) ); +// ND> + } if (joint) { mat[i] = skin->mInvBindMatrix[i]; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index cb8fd2a224..967bd3ba6e 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -3535,7 +3535,10 @@ LLJoint* LLModelPreview::lookupJointByName(const std::string& str, void* opaque) LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque); if (pPreview) { - return pPreview->getPreviewAvatar()->getJoint(str); +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// return pPreview->getPreviewAvatar()->getJoint( str ); + return pPreview->getPreviewAvatar()->getJoint( JointKey::construct( str ) ); +// } return NULL; } diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 2af4020fad..78a6107d07 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1612,6 +1612,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) if (header_size > 0) { + x S32 version = mMeshHeader[mesh_id]["version"].asInteger(); S32 offset = header_size + mMeshHeader[mesh_id][header_lod[lod]]["offset"].asInteger(); S32 size = mMeshHeader[mesh_id][header_lod[lod]]["size"].asInteger(); diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp index 461d301df8..98117b0f04 100644 --- a/indra/newview/llmorphview.cpp +++ b/indra/newview/llmorphview.cpp @@ -146,8 +146,11 @@ void LLMorphView::updateCamera() { if (!mCameraTargetJoint) { - setCameraTargetJoint(gAgentAvatarp->getJoint("mHead")); - } +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// setCameraTargetJoint( gAgentAvatarp->getJoint( "mHead" ) ); + setCameraTargetJoint( gAgentAvatarp->getJoint( JointKey::construct( "mHead" ) ) ); +// + } if (!isAgentAvatarValid()) return; LLJoint* root_joint = gAgentAvatarp->getRootJoint(); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 041acea8ea..dd2749e1e4 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -1262,11 +1262,15 @@ void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BO value_map_t sorted_params; getSortedParams(sorted_params, edit_group); - LLJoint* jointp = gAgentAvatarp->getJoint( subpart_entry->mTargetJoint ); - if (!jointp) +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// LLJoint* jointp = gAgentAvatarp->getJoint( subpart_entry->mTargetJoint ); + LLJoint* jointp = gAgentAvatarp->getJoint( JointKey::construct( subpart_entry->mTargetJoint ) ); + if( !jointp ) { - jointp = gAgentAvatarp->getJoint("mHead"); - } +// jointp = gAgentAvatarp->getJoint( "mHead" ); + jointp = gAgentAvatarp->getJoint( JointKey::construct( "mHead" ) ); + } +// buildParamList(panel_list, sorted_params, tab, jointp); @@ -1334,7 +1338,11 @@ void LLPanelEditWearable::changeCamera(U8 subpart) } // Update the camera - gMorphView->setCameraTargetJoint( gAgentAvatarp->getJoint( subpart_entry->mTargetJoint ) ); +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup + //gMorphView->setCameraTargetJoint( gAgentAvatarp->getJoint( subpart_entry->mTargetJoint ) ); + gMorphView->setCameraTargetJoint( gAgentAvatarp->getJoint( JointKey::construct( subpart_entry->mTargetJoint ) ) ); +// ND> + gMorphView->setCameraTargetOffset( subpart_entry->mTargetOffset ); gMorphView->setCameraOffset( subpart_entry->mCameraOffset ); if (gSavedSettings.getBOOL("AppearanceCameraMovement")) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 82fe2e6e70..167c9c6625 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5688,21 +5688,40 @@ const LLUUID& LLVOAvatar::getID() const // getJoint() //----------------------------------------------------------------------------- // RN: avatar joints are multi-rooted to include screen-based attachments -LLJoint *LLVOAvatar::getJoint( const std::string &name ) +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +//LLJoint *LLVOAvatar::getJoint( const std::string &name ) +LLJoint *LLVOAvatar::getJoint( const JointKey &name ) +// { - joint_map_t::iterator iter = mJointMap.find(name); +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup + //joint_map_t::iterator iter = mJointMap.find( name ); + + //LLJoint* jointp = NULL; + + //if( iter == mJointMap.end() || iter->second == NULL ) + //{ //search for joint and cache found joint in lookup table + // jointp = mRoot->findJoint( name ); + // mJointMap[ name ] = jointp; + //} + //else + //{ //return cached pointer + // jointp = iter->second; + //} + + joint_map_t::iterator iter = mJointMap.find( name.mKey ); LLJoint* jointp = NULL; - if (iter == mJointMap.end() || iter->second == NULL) + if( iter == mJointMap.end() || iter->second == NULL ) { //search for joint and cache found joint in lookup table - jointp = mRoot->findJoint(name); - mJointMap[name] = jointp; + jointp = mRoot->findJoint( name.mName ); + mJointMap[ name.mKey ] = jointp; } else { //return cached pointer jointp = iter->second; } +// return jointp; } @@ -5798,7 +5817,11 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) { for ( int i=0; imJointNames[i].c_str(); +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// std::string lookingForJoint = pSkinData->mJointNames[ i ].c_str(); + JointKey lookingForJoint = pSkinData->mJointNames[ i ]; +// + LLJoint* pJoint = getJoint( lookingForJoint ); if ( pJoint && pJoint->getId() != currentId ) { @@ -5808,7 +5831,10 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString() ); //If joint is a pelvis then handle old/new pelvis to foot values - if ( lookingForJoint == "mPelvis" ) +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// if( lookingForJoint == "mPelvis" ) + if( lookingForJoint.mName == "mPelvis" ) +// { pelvisGotSet = true; } @@ -5867,8 +5893,11 @@ void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id) avatar_joint_list_t::iterator iter = mSkeleton.begin(); avatar_joint_list_t::iterator end = mSkeleton.end(); - LLJoint* pJointPelvis = getJoint("mPelvis"); - +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// LLJoint* pJointPelvis = getJoint( "mPelvis" ); + LLJoint* pJointPelvis = getJoint( JointKey::construct( "mPelvis" ) ); +// + for (; iter != end; ++iter) { LLJoint* pJoint = (*iter); @@ -6028,8 +6057,13 @@ BOOL LLVOAvatar::loadSkeletonNode () LLViewerJointAttachment* attachment = new LLViewerJointAttachment(); attachment->setName(info->mName); - LLJoint *parentJoint = getJoint(info->mJointName); - if (!parentJoint) + +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// LLJoint *parentJoint = getJoint( info->mJointName ); + LLJoint *parentJoint = getJoint( JointKey::construct( info->mJointName ) ); +// + + if( !parentJoint ) { LL_WARNS() << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << LL_ENDL; delete attachment; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 247b0d8ba6..08a5cc643e 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -201,8 +201,12 @@ public: void startDefaultMotions(); void dumpAnimationState(); - virtual LLJoint* getJoint(const std::string &name); - +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup + //virtual LLJoint* getJoint( const std::string &name ); + virtual LLJoint* getJoint( const JointKey &name ); + LLJoint* getJoint( const std::string &name ) { return getJoint( JointKey::construct( name ) ); } +// + void addAttachmentPosOverridesForObject(LLViewerObject *vo); void resetJointPositionsOnDetach(const LLUUID& mesh_id); void resetJointPositionsOnDetach(LLViewerObject *vo); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index a688646ab2..104f51d8bd 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -891,11 +891,17 @@ void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time) } // virtual -LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +//LLJoint *LLVOAvatarSelf::getJoint( const std::string &name ) +LLJoint *LLVOAvatarSelf::getJoint( const JointKey &name ) +// { if (mScreenp) { - LLJoint* jointp = mScreenp->findJoint(name); +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// LLJoint* jointp = mScreenp->findJoint( name ); + LLJoint* jointp = mScreenp->findJoint( name.mName ); +// if (jointp) return jointp; } return LLVOAvatar::getJoint(name); diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index f1af6cb271..fc69125879 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -90,8 +90,12 @@ public: /*virtual*/ bool hasMotionFromSource(const LLUUID& source_id); /*virtual*/ void stopMotionFromSource(const LLUUID& source_id); /*virtual*/ void requestStopMotion(LLMotion* motion); - /*virtual*/ LLJoint* getJoint(const std::string &name); - + +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// /*virtual*/ LLJoint* getJoint( const std::string &name ); + /*virtual*/ LLJoint* getJoint( const JointKey &name ); +// + // [Legacy Bake] ///*virtual*/ BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight); ///*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight); diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 18771adfc8..be7192b196 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -969,7 +969,7 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait) else { // If we are not doing a corowait then we must sleep until the connector has responded // otherwise we may very well close the socket too early. -#if LL_WINDOWS +#if LL_WINDOWSx int count = 0; while (!mShutdownComplete && 10 > count++) { // Rider: This comes out to a max wait time of 10 seconds. diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 177f8a4f64..4b1afb26b8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4270,8 +4270,11 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons { // Fall back to a point inside the avatar if mesh is // rigged to an unknown joint. - joint = avatar->getJoint("mPelvis"); - } +// Query by JointKey rather than just a string, the key can be a U32 index for faster lookup +// joint = avatar->getJoint( "mPelvis" ); + joint = avatar->getJoint( JointKey::construct( "mPelvis" ) ); +// + } if (joint) { mat[j] = skin->mInvBindMatrix[j];