Replace JointKey construct with more upstream-based approach, optimized by using std::string_view and heterogeneous map lookups

master
Ansariel 2025-04-24 19:26:55 +02:00
parent e377fe66c8
commit 8ba07f3165
21 changed files with 82 additions and 264 deletions

View File

@ -140,10 +140,9 @@ public:
LLVector3 mHeadOffset{}; // current head position
LLAvatarJoint* mRoot{ nullptr };
// <FS:ND> This map gets queried a huge amount of time.
//<FS:Ansariel> Joint-lookup improvements
// typedef std::map<std::string, LLJoint*> joint_map_t;
typedef std::unordered_map<U32, LLJoint*> joint_map_t;
// </FS:ND>
typedef std::map<std::string, LLJoint*, std::less<>> joint_map_t;
joint_map_t mJointMap;

View File

@ -77,7 +77,9 @@ LLCharacter::~LLCharacter()
//-----------------------------------------------------------------------------
// getJoint()
//-----------------------------------------------------------------------------
LLJoint *LLCharacter::getJoint( const std::string &name )
//<FS:Ansariel> Joint-lookup improvements
//LLJoint *LLCharacter::getJoint( const std::string &name )
LLJoint* LLCharacter::getJoint(std::string_view name)
{
LLJoint* joint = NULL;
@ -94,14 +96,6 @@ LLJoint *LLCharacter::getJoint( const std::string &name )
return joint;
}
//<FS:ND> 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 );
}
// </FS:ND>
//-----------------------------------------------------------------------------
// registerMotion()
//-----------------------------------------------------------------------------

View File

@ -76,13 +76,9 @@ public:
// get the specified joint
// default implementation does recursive search,
// subclasses may optimize/cache results.
//<FS:Ansariel> Joint-lookup improvements
// virtual LLJoint *getJoint( const std::string &name );
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
virtual LLJoint *getJoint( const JointKey &name );
// </FS:ND>
LLJoint *getJoint( const std::string &name );
virtual LLJoint* getJoint(std::string_view name);
// get the position of the character
virtual LLVector3 getCharacterPosition() = 0;

View File

@ -34,32 +34,6 @@
#include "llmath.h"
#include <boost/algorithm/string.hpp>
#include "llmutex.h" // <FS:minerjr> [FIRE-35382] Add share_mutex to fix JointKey::construct lockup
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
#include <unordered_map>
std::unordered_map<std::string, U32> mpStringToKeys;
std::shared_mutex mpStringToKeysMutex; // <FS:minerjr> [FIRE-35382] Add share_mutex to fix JointKey::construct lockup
JointKey JointKey::construct(const std::string& aName)
{
{// <FS:minerjr> [FIRE-35382] Add share_mutex to fix JointKey::construct lockup
std::shared_lock lock(mpStringToKeysMutex); // </FS:minerjr> [FIRE-35382] Added a shared lock for reading the mpStringToKeys unordered_map.
if (const auto itr = mpStringToKeys.find(aName); itr != mpStringToKeys.end())
{
return { aName, itr->second };
}
}// <FS:minerjr> [FIRE-35382] Add share_mutex to fix JointKey::construct lockup
{ // Add a unique lock for writing to the mpStringToKeys unordered_map.
std::unique_lock lock(mpStringToKeysMutex);// </FS:minerjr> [FIRE-35382]
U32 size = static_cast<U32>(mpStringToKeys.size()) + 1;
mpStringToKeys.try_emplace(aName, size);
return { aName, size };
} // <FS:minerjr> [FIRE-35382] Add share_mutex to fix JointKey::construct lockup
}
// </FS:ND>
S32 LLJoint::sNumUpdates = 0;
S32 LLJoint::sNumTouches = 0;
@ -268,7 +242,9 @@ LLJoint *LLJoint::getRoot()
//-----------------------------------------------------------------------------
// findJoint()
//-----------------------------------------------------------------------------
LLJoint *LLJoint::findJoint( const std::string &name )
//<FS:Ansariel> Joint-lookup improvements
//LLJoint *LLJoint::findJoint( const std::string &name )
LLJoint *LLJoint::findJoint(std::string_view name)
{
if (name == getName())
return this;

View File

@ -40,31 +40,6 @@
#include "xform.h"
#include "llmatrix4a.h"
//<FS:ND> 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(const std::string& aName);
};
inline bool operator==(JointKey const &aLHS, JointKey const &aRHS)
{
return aLHS.mName == aRHS.mName;
}
inline bool operator!=(JointKey const &aLHS, JointKey const &aRHS)
{
return ! (aLHS == aRHS);
}
inline std::ostream& operator<<(std::ostream &aLHS, JointKey const &aRHS)
{
return aLHS << aRHS.mName << " (" << aRHS.mKey << ")";
}
// </FS:ND>
constexpr S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15;
// Need to set this to count of animate-able joints,
// currently = #bones + #collision_volumes + #attachments + 2,
@ -247,7 +222,9 @@ public:
LLJoint *getRoot();
// search for child joints by name
LLJoint *findJoint( const std::string &name );
//<FS:Ansariel> Joint-lookup improvements
//LLJoint *findJoint( const std::string &name );
LLJoint* findJoint(std::string_view name);
// add/remove children
void addChild( LLJoint *joint );

View File

@ -1467,10 +1467,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
{
name = mJointMap[name];
}
//<FS:ND> 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 ) );
// </FS:ND>
model->mSkinInfo.mJointNames.push_back(name);
model->mSkinInfo.mJointNums.push_back(-1);
}
}
@ -1488,10 +1485,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
{
name = mJointMap[name];
}
//<FS:ND> 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 ) );
// </FS:ND>
model->mSkinInfo.mJointNames.push_back(name);
model->mSkinInfo.mJointNums.push_back(-1);
}
}
@ -1533,10 +1527,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
//but does not use the skeleton).
buildJointToNodeMappingFromScene( root );
//<FS:ND> 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 ) );
// </FS:ND>
critiqueRigForUploadApplicability( model->mSkinInfo.mJointNames );
if ( !missingSkeletonOrScene )
{
@ -1589,11 +1580,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
//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.
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
// std::vector<std::string> ::const_iterator jointIt = model->mSkinInfo.mJointNames.begin();
std::vector< std::string > jointNames = toStringVector( model->mSkinInfo.mJointNames );
std::vector<std::string> ::const_iterator jointIt = jointNames.begin();
// </FS:ND>
std::vector<std::string> ::const_iterator jointIt = model->mSkinInfo.mJointNames.begin();
const int jointCnt = static_cast<int>(model->mSkinInfo.mJointNames.size());
for ( int i=0; i<jointCnt; ++i, ++jointIt )

View File

@ -1496,10 +1496,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
{
for (U32 i = 0; i < skin["joint_names"].size(); ++i)
{
//<FS:ND> 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 ] ) );
// </FS>ND>
mJointNames.push_back( skin[ "joint_names" ][ i ] );
mJointNums.push_back(-1);
}
}
@ -1589,10 +1586,7 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_positi
for (U32 i = 0; i < mJointNames.size(); ++i)
{
//<FS:ND> 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;
// </FS:ND>
ret[ "joint_names" ][ i ] = mJointNames[ i ];
for (U32 j = 0; j < 4; j++)
{
@ -1643,9 +1637,7 @@ void LLMeshSkinInfo::updateHash()
//mJointNames
for (auto& name : mJointNames)
{
// <FS:Ansariel> Joint lookup speedup
//hash.update(name);
hash.update(name.mName);
hash.update(name);
}
//mJointNums
@ -1671,10 +1663,7 @@ U32 LLMeshSkinInfo::sizeBytes() const
res += sizeof(std::vector<std::string>) + sizeof(std::string) * static_cast<U32>(mJointNames.size());
for (U32 i = 0; i < mJointNames.size(); ++i)
{
// <FS> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//res += static_cast<U32>(mJointNames[i].size()); // actual size, not capacity
res += static_cast<U32>(mJointNames[i].mName.size()); // actual size, not capacity
// </FS>
res += static_cast<U32>(mJointNames[i].size()); // actual size, not capacity
}
res += sizeof(std::vector<S32>) + sizeof(S32) * static_cast<U32>(mJointNums.size());

View File

@ -56,10 +56,7 @@ public:
U32 sizeBytes() const;
LLUUID mMeshID;
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
// std::vector<std::string> mJointNames;
std::vector< JointKey > mJointNames;
// </FS:ND>
std::vector<std::string> mJointNames;
mutable std::vector<S32> mJointNums;
typedef std::vector<LLMatrix4a> matrix_list_t;
matrix_list_t mInvBindMatrix;

View File

@ -257,10 +257,7 @@ bool LLModelLoader::loadFromSLM(const std::string& filename)
if (!loaded_model->mSkinInfo.mJointNames.empty())
{
//check to see if rig is valid
//<FS:ND> 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 ) );
// </FS:ND>
critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames );
}
else if (mCacheOnlyHitIfRigged)
{

View File

@ -196,18 +196,6 @@ public:
void clearLog() { mWarningsArray.clear(); }
protected:
//<FS:ND> 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;
}
// </FS:ND>
LLModelLoader::load_callback_t mLoadCallback;
LLModelLoader::joint_lookup_func_t mJointLookupFunc;
LLModelLoader::texture_load_func_t mTextureLoadFunc;

View File

@ -1652,7 +1652,7 @@ void FSFloaterPoser::updateManipWithFirstSelectedJoint(std::vector<FSPoserAnimat
return;
if (joints.size() >= 1)
FSToolCompPose::getInstance()->setJoint(avatarp->getJoint(JointKey::construct(joints[0]->jointName())));
FSToolCompPose::getInstance()->setJoint(avatarp->getJoint(joints[0]->jointName()));
else
FSToolCompPose::getInstance()->setJoint(nullptr);
}

View File

@ -1625,14 +1625,9 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
for (U32 j = 0; j < joint_count; ++j)
{
const LLVector3& joint_pos = LLVector3(skin->mAlternateBindMatrix[j].getTranslation());
// <FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
//LLJoint* pJoint = LLModelPreview::lookupJointByName(skin->mJointNames[j], mModelPreview);
LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j].mName];
LLJoint* pJoint = LLModelPreview::lookupJointByName(skin->mJointNames[j].mName, mModelPreview);
// <FS:ND>
LLJoint* pJoint = LLModelPreview::lookupJointByName(skin->mJointNames[j], mModelPreview);
if (pJoint)
{
// see how voavatar uses aboveJointPosThreshold
@ -1661,9 +1656,7 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
{
for (U32 j = 0; j < joint_count; ++j)
{
// <FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j].mName];
LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
data.mModelsNoOverrides.insert(model->getName());
}
}

View File

@ -4185,10 +4185,7 @@ LLJoint* LLModelPreview::lookupJointByName(const std::string& str, void* opaque)
LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
if (pPreview)
{
//<FS:ND> 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 ) );
// <FS:ND>
return pPreview->getPreviewAvatar()->getJoint(str);
}
return NULL;
}

View File

@ -131,10 +131,7 @@ void LLMorphView::updateCamera()
{
if (!mCameraTargetJoint)
{
//<FS:ND> 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" ) ) );
// </FS:ND>
setCameraTargetJoint( gAgentAvatarp->getJoint( "mHead" ) );
}
if (!isAgentAvatarValid()) return;

View File

@ -1316,15 +1316,11 @@ void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, bool show, bo
value_map_t sorted_params;
getSortedParams(sorted_params, edit_group);
//<FS:ND> 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 ) );
LLJoint* jointp = gAgentAvatarp->getJoint( subpart_entry->mTargetJoint );
if (!jointp)
{
//jointp = gAgentAvatarp->getJoint( "mHead" );
jointp = gAgentAvatarp->getJoint( JointKey::construct( "mHead" ) );
jointp = gAgentAvatarp->getJoint( "mHead" );
}
// </FS:ND>
buildParamList(panel_list, sorted_params, tab, jointp);
@ -1440,11 +1436,7 @@ void LLPanelEditWearable::changeCamera(U8 subpart)
}
// Update the camera
//<FS:ND> 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 ) ) );
// </FS>ND>
gMorphView->setCameraTargetJoint( gAgentAvatarp->getJoint( subpart_entry->mTargetJoint ) );
gMorphView->setCameraTargetOffset( subpart_entry->mTargetOffset );
gMorphView->setCameraOffset( subpart_entry->mCameraOffset );
if (gSavedSettings.getBOOL("AppearanceCameraMovement"))

View File

@ -54,10 +54,7 @@ void dump_avatar_and_skin_state(const std::string& reason, LLVOAvatar *avatar, c
{
LL_WARNS("Avatar") << "skin joint idx " << j << " name [" << skin->mJointNames[j]
<< "] num " << skin->mJointNums[j] << LL_ENDL;
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//const std::string& name = skin->mJointNames[j];
const std::string& name = skin->mJointNames[j].mName;
// </FS:ND>
const std::string& name = skin->mJointNames[j];
S32 joint_num = skin->mJointNums[j];
LLJoint *name_joint = avatar->getJoint(name);
@ -119,14 +116,9 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin
// needed for handling of any legacy bad data.
if (!avatar->getJoint(skin->mJointNames[j]))
{
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//LL_DEBUGS("Avatar") << avatar->getFullname() << " mesh rigged to invalid joint " << skin->mJointNames[j] << LL_ENDL;
//LL_WARNS_ONCE("Avatar") << avatar->getFullname() << " mesh rigged to invalid joint" << skin->mJointNames[j] << LL_ENDL;
//skin->mJointNames[j] = "mPelvis";
LL_DEBUGS("Avatar") << avatar->getFullname() << " mesh rigged to invalid joint " << skin->mJointNames[j].mName << LL_ENDL;
LL_WARNS_ONCE("Avatar") << avatar->getFullname() << " mesh rigged to invalid joint" << skin->mJointNames[j].mName << LL_ENDL;
skin->mJointNames[j] = JointKey::construct("mPelvis");
//</FS:ND>
LL_DEBUGS("Avatar") << avatar->getFullname() << " mesh rigged to invalid joint " << skin->mJointNames[j] << LL_ENDL;
LL_WARNS_ONCE("Avatar") << avatar->getFullname() << " mesh rigged to invalid joint" << skin->mJointNames[j] << LL_ENDL;
skin->mJointNames[j] = "mPelvis";
skin->mJointNumsInitialized = false; // force update after names change.
}
}

View File

@ -7267,69 +7267,44 @@ const LLUUID& LLVOAvatar::getID() const
// getJoint()
//-----------------------------------------------------------------------------
// RN: avatar joints are multi-rooted to include screen-based attachments
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//<FS:Ansariel> Joint-lookup improvements
//LLJoint *LLVOAvatar::getJoint(const std::string &name)
LLJoint *LLVOAvatar::getJoint(const JointKey &name)
// </FS:ND>
LLJoint *LLVOAvatar::getJoint(std::string_view name)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//<FS:Ansariel> Joint-lookup improvements
//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
// if (mJointAliasMap.empty())
// {
// getJointAliases();
// }
// joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name);
// std::string canonical_name;
// if (alias_iter != mJointAliasMap.end())
// {
// canonical_name = alias_iter->second;
// }
// else
// {
// canonical_name = name;
// }
// jointp = mRoot->findJoint(canonical_name);
// mJointMap[name] = jointp;
//}
//else
//{ //return cached pointer
// jointp = iter->second;
//}
joint_map_t::iterator iter = mJointMap.find( name.mKey );
joint_map_t::iterator iter = mJointMap.find(name.data());
LLJoint* jointp = NULL;
if (iter == mJointMap.end() || iter->second == NULL)
{ //search for joint and cache found joint in lookup table
if (mJointAliasMap.empty())
{
getJointAliases();
}
joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name.mName);
std::string canonical_name;
if (alias_iter != mJointAliasMap.end())
{
canonical_name = alias_iter->second;
}
else
{
canonical_name = name.mName;
}
jointp = mRoot->findJoint(canonical_name);
mJointMap[name.mKey] = jointp;
if( iter == mJointMap.end() || iter->second == NULL )
{ //search for joint and cache found joint in lookup table
if (mJointAliasMap.empty())
{
getJointAliases();
}
//<FS:Ansariel> Joint-lookup improvements
//joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name);
joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(std::string(name));
std::string canonical_name;
if (alias_iter != mJointAliasMap.end())
{
canonical_name = alias_iter->second;
}
else
{
canonical_name = name;
}
jointp = mRoot->findJoint(canonical_name);
//<FS:Ansariel> Joint-lookup improvements
//mJointMap[name] = jointp;
mJointMap[std::string(name)] = jointp;
}
else
{ //return cached pointer
jointp = iter->second;
{ //return cached pointer
jointp = iter->second;
}
// </FS:ND>
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (jointp && jointp->getName()!="mScreen" && jointp->getName()!="mRoot")
@ -7373,17 +7348,10 @@ LLJoint *LLVOAvatar::getJoint( S32 joint_num )
void LLVOAvatar::initAllJoints()
{
getJointAliases();
// <FS:Ansariel> Lookup performance changes
//for (auto& alias : mJointAliasMap)
//{
// mJointMap[alias.first] = mRoot->findJoint(alias.second);
// mJointMap[JointKey::construct(alias.first).mKey] = mRoot->findJoint(alias.second);
//}
for (const auto& alias : mJointAliasMap)
for (auto& alias : mJointAliasMap)
{
mJointMap[JointKey::construct(alias.first).mKey] = mRoot->findJoint(alias.second);
mJointMap[alias.first] = mRoot->findJoint(alias.second);
}
// </FS:Ansariel>
// ignore mScreen and mRoot
}
@ -7712,11 +7680,7 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL
{
for (unsigned int i = 0; i < jointCnt; ++i)
{
//<FS:ND> 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 ];
// </FS:ND>
std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
LLJoint* pJoint = getJoint( lookingForJoint );
if (pJoint)
{
@ -7729,10 +7693,7 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL
if (override_changed)
{
//If joint is a pelvis then handle old/new pelvis to foot values
//<FS:ND> 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" )
// </FS:ND>
if( lookingForJoint == "mPelvis" )
{
pelvisGotSet = true;
}
@ -7923,10 +7884,7 @@ void LLVOAvatar::removeAttachmentOverridesForObject(LLViewerObject *vo)
//-----------------------------------------------------------------------------
void LLVOAvatar::removeAttachmentOverridesForObject(const LLUUID& mesh_id)
{
//<FS:ND> 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" ) );
// </FS:ND>
LLJoint* pJointPelvis = getJoint( "mPelvis" );
const std::string av_string = avString();
for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++)
@ -8114,10 +8072,7 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints)
attachment->setName(info->mName);
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
// LLJoint *parent_joint = getJoint(info->mJointName);
LLJoint *parent_joint = getJoint( JointKey::construct( info->mJointName ) );
// </FS:ND>
LLJoint *parent_joint = getJoint(info->mJointName);
if (!parent_joint)
{

View File

@ -204,11 +204,9 @@ public:
void startDefaultMotions();
void dumpAnimationState();
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//<FS:Ansariel> Joint-lookup improvements
//virtual LLJoint* getJoint(const std::string &name);
virtual LLJoint* getJoint(const JointKey& name);
LLJoint* getJoint(const std::string& name) { return getJoint(JointKey::construct(name)); }
// </FS:ND>
virtual LLJoint* getJoint(std::string_view name);
LLJoint* getJoint(S32 num);
void initAllJoints();

View File

@ -1029,27 +1029,22 @@ void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time)
}
// virtual
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//<FS:Ansariel> Joint-lookup improvements
//LLJoint *LLVOAvatarSelf::getJoint(const std::string &name)
LLJoint *LLVOAvatarSelf::getJoint(const JointKey& name)
// </FS:ND>
LLJoint* LLVOAvatarSelf::getJoint(std::string_view name)
{
std::lock_guard lock(mJointMapMutex);
LLJoint *jointp = NULL;
jointp = LLVOAvatar::getJoint(name);
if (!jointp && mScreenp)
{
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//jointp = mScreenp->findJoint(name);
jointp = mScreenp->findJoint(name.mName);
// </FS:ND>
jointp = mScreenp->findJoint(name);
if (jointp)
{
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//<FS:Ansariel> Joint-lookup improvements
//mJointMap[name] = jointp;
mJointMap[name.mKey] = jointp;
// </FS:ND>
}
mJointMap[std::string(name)] = jointp;
}
}
if (jointp && jointp != mScreenp && jointp != mRoot)
{

View File

@ -91,10 +91,9 @@ public:
/*virtual*/ void stopMotionFromSource(const LLUUID& source_id);
/*virtual*/ void requestStopMotion(LLMotion* motion);
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
//<FS:Ansariel> Joint-lookup improvements
// /*virtual*/ LLJoint* getJoint(const std::string &name);
/*virtual*/ LLJoint* getJoint(const JointKey& name);
// </FS:ND>
/*virtual*/ LLJoint* getJoint(std::string_view name);
/*virtual*/ void renderJoints();

View File

@ -673,7 +673,7 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
{
LL_DEBUGS("LocalMesh") << "Found internal joint name: " << joint_name << LL_ENDL;
joint_name = joint_map[joint_name];
skininfo.mJointNames.push_back(JointKey::construct(joint_name));
skininfo.mJointNames.push_back(joint_name);
skininfo.mJointNums.push_back(-1);
}
};
@ -761,7 +761,7 @@ bool LLLocalMeshImportDAE::processSkin(daeDatabase* collada_db, daeElement* coll
jointname_iterator != skininfop->mJointNames.end();
++jointname_iterator, ++jointname_idx)
{
std::string name_lookup = jointname_iterator->mName;
const std::string& name_lookup = *jointname_iterator;
if (joint_map.find(name_lookup) == joint_map.end())
{
pushLog("DAE Importer", "WARNING: Unknown joint named " + name_lookup + " found, skipping over it.");