diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index b35828f795..3ac6dd7fd9 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -187,7 +187,10 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) : mHeadOffset(), mRoot(NULL), mWearableData(wearable_data), - mNextJointNum(0) + mNumBones(0), + mNumCollisionVolumes(0), + mCollisionVolumes(NULL), + mIsBuilt(FALSE) { llassert_always(mWearableData); mBakedTextureDatas.resize(LLAvatarAppearanceDefines::BAKED_NUM_INDICES); @@ -200,11 +203,6 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) : mBakedTextureDatas[i].mMaskTexName = 0; mBakedTextureDatas[i].mTextureIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i); } - - mIsBuilt = FALSE; - - mNumCollisionVolumes = 0; - mCollisionVolumes = NULL; } // virtual @@ -688,14 +686,15 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent if (info->mIsJoint) { joint->setSkinOffset( info->mPivot ); + joint->setJointNum(joint_num); joint_num++; } else // collision volume { + joint->setJointNum(mNumBones+volume_num); volume_num++; } - joint->setJointNum(mNextJointNum++); // setup children LLAvatarBoneInfo::child_list_t::const_iterator iter; @@ -720,6 +719,7 @@ BOOL LLAvatarAppearance::allocateCharacterJoints( S32 num ) { clearSkeleton(); mSkeleton = avatar_joint_list_t(num,NULL); + mNumBones = num; } return TRUE; @@ -732,7 +732,6 @@ BOOL LLAvatarAppearance::allocateCharacterJoints( S32 num ) BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info) { LL_DEBUGS("BVH") << "numBones " << info->mNumBones << " numCollisionVolumes " << info->mNumCollisionVolumes << LL_ENDL; - mNextJointNum = 0; // allocate joints if (!allocateCharacterJoints(info->mNumBones)) diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 16dbf26727..754f5b02f1 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -146,8 +146,6 @@ public: joint_map_t mJointMap; - S32 mNextJointNum; - typedef std::map joint_state_map_t; joint_state_map_t mLastBodySizeState; joint_state_map_t mCurrBodySizeState; @@ -371,6 +369,7 @@ protected: // Collision volumes //-------------------------------------------------------------------- public: + S32 mNumBones; S32 mNumCollisionVolumes; LLAvatarJointCollisionVolume* mCollisionVolumes; protected: diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 7acbdd0c08..cfdc2922bb 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1547,3 +1547,20 @@ namespace LLError } } +bool debugLoggingEnabled(const std::string& tag) +{ + const char* tags[] = {tag.c_str()}; + ::size_t tag_count = 1; + LLError::CallSite _site(LLError::LEVEL_DEBUG, __FILE__, __LINE__, + typeid(_LL_CLASS_TO_LOG), __FUNCTION__, false, tags, tag_count); + if (LL_UNLIKELY(_site.shouldLog())) + { + return true; + } + else + { + return false; + } +} + + diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index b8aaf4b9f4..4f5809708d 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -376,4 +376,7 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; #define LL_INFOS_ONCE(...) lllog(LLError::LEVEL_INFO, true, ##__VA_ARGS__) #define LL_WARNS_ONCE(...) lllog(LLError::LEVEL_WARN, true, ##__VA_ARGS__) +// Check at run-time whether logging is enabled, without generating output +bool debugLoggingEnabled(const std::string& tag); + #endif // LL_LLERROR_H diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index e11fa1bf72..216334752a 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -153,4 +153,27 @@ public: } }; +inline LLVector4a rowMul(const LLVector4a &row, const LLMatrix4a &mat) +{ + LLVector4a result; + result = _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(0, 0, 0, 0)), mat.mMatrix[0]); + result = _mm_add_ps(result, _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(1, 1, 1, 1)), mat.mMatrix[1])); + result = _mm_add_ps(result, _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(2, 2, 2, 2)), mat.mMatrix[2])); + result = _mm_add_ps(result, _mm_mul_ps(_mm_shuffle_ps(row, row, _MM_SHUFFLE(3, 3, 3, 3)), mat.mMatrix[3])); + return result; +} + +inline void matMul(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res) +{ + LLVector4a row0 = rowMul(a.mMatrix[0], b); + LLVector4a row1 = rowMul(a.mMatrix[1], b); + LLVector4a row2 = rowMul(a.mMatrix[2], b); + LLVector4a row3 = rowMul(a.mMatrix[3], b); + + res.mMatrix[0] = row0; + res.mMatrix[1] = row1; + res.mMatrix[2] = row2; + res.mMatrix[3] = row3; +} + #endif diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index d5ed49f372..c59e61abc5 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1415,6 +1415,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) // mJointNames.push_back( skin[ "joint_names" ][ i ] ); mJointNames.push_back( JointKey::construct( skin[ "joint_names" ][ i ] ) ); // ND> + mJointNums.push_back(-1); } } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 1ba1a618b8..65e0873eec 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -54,6 +54,7 @@ public: // std::vector mJointNames; std::vector< JointKey > mJointNames; // + mutable std::vector mJointNums; std::vector mInvBindMatrix; std::vector mAlternateBindMatrix; diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index f1e3284f0c..05be70289f 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -223,11 +223,12 @@ void LLSkinningUtil::remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* ski // Apply the remap to mJointNames, mInvBindMatrix, and mAlternateBindMatrix - // Query by JointKey rather than just a string, the key can be a U32 index for faster lookup - // std::vector new_joint_names; - std::vector< JointKey > new_joint_names; - // - std::vector new_inv_bind_matrix; + // Query by JointKey rather than just a string, the key can be a U32 index for faster lookup + // std::vector new_joint_names; + std::vector< JointKey > new_joint_names; + // + std::vector new_joint_nums; + std::vector new_inv_bind_matrix; std::vector new_alternate_bind_matrix; for (U32 j = 0; j < skin->mJointNames.size(); ++j) @@ -235,6 +236,7 @@ void LLSkinningUtil::remapSkinInfoJoints(LLVOAvatar *avatar, LLMeshSkinInfo* ski if (j_proxy[j] == j && new_joint_names.size() < max_joints) { new_joint_names.push_back(skin->mJointNames[j]); + new_joint_nums.push_back(-1); new_inv_bind_matrix.push_back(skin->mInvBindMatrix[j]); if (!skin->mAlternateBindMatrix.empty()) { @@ -265,18 +267,38 @@ void LLSkinningUtil::initSkinningMatrixPalette( const LLMeshSkinInfo* skin, LLVOAvatar *avatar) { - // 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]); - mat[j] = skin->mInvBindMatrix[j]; + LLJoint *joint = NULL; + if (skin->mJointNums[j] == -1) + { + joint = avatar->getJoint(skin->mJointNames[j]); + if (joint) + { + skin->mJointNums[j] = joint->getJointNum(); + } + } + else + { + joint = avatar->getJoint(skin->mJointNums[j]); + } if (joint) { +#define MAT_USE_SSE +#ifdef MAT_USE_SSE + LLMatrix4a bind, world, res; + bind.loadu(skin->mInvBindMatrix[j]); + world.loadu(joint->getWorldMatrix()); + matMul(bind,world,res); + memcpy(mat[j].mMatrix,res.mMatrix,16*sizeof(float)); +#else + mat[j] = skin->mInvBindMatrix[j]; mat[j] *= joint->getWorldMatrix(); +#endif } else { + mat[j] = skin->mInvBindMatrix[j]; // This shouldn't happen - in mesh upload, skinned // rendering should be disabled unless all joints are // valid. In other cases of skinned rendering, invalid diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 14b32950df..be6bc6abc4 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5982,19 +5982,53 @@ LLJoint *LLVOAvatar::getJoint( const JointKey &name ) LLJoint* jointp = NULL; if( iter == mJointMap.end() || iter->second == NULL ) - { //search for joint and cache found joint in lookup table + { //search for joint and cache found joint in lookup table jointp = mRoot->findJoint( name.mName ); mJointMap[ name.mKey ] = jointp; } else - { //return cached pointer + { //return cached pointer jointp = iter->second; } // +#ifndef LL_RELEASE_FOR_DOWNLOAD + if (jointp && jointp->getName()!="mScreen" && jointp->getName()!="mRoot") + { + llassert(getJoint(jointp->getJointNum())==jointp); + } +#endif return jointp; } +LLJoint *LLVOAvatar::getJoint( S32 joint_num ) +{ + LLJoint *pJoint = NULL; + S32 collision_start = mNumBones; + S32 attachment_start = mNumBones + mNumCollisionVolumes; + if (joint_num>=attachment_start) + { + // Attachment IDs start at 1 + S32 attachment_id = joint_num - attachment_start + 1; + attachment_map_t::iterator iter = mAttachmentPoints.find(attachment_id); + if (iter != mAttachmentPoints.end()) + { + pJoint = iter->second; + } + } + else if (joint_num>=collision_start) + { + S32 collision_id = joint_num-collision_start; + pJoint = &mCollisionVolumes[collision_id]; + } + else if (joint_num>=0) + { + pJoint = mSkeleton[joint_num]; + } + llassert(!pJoint || pJoint->getJointNum() == joint_num); + return pJoint; +} + //----------------------------------------------------------------------------- // getRiggedMeshID // @@ -6643,7 +6677,8 @@ void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints) attachment->setVisibleInFirstPerson(info->mVisibleFirstPerson); attachment->setIsHUDAttachment(info->mIsHUDAttachment); // attachment can potentially be animated, needs a number. - attachment->setJointNum(mNextJointNum++); + attachment->setJointNum(mNumBones + mNumCollisionVolumes + attachmentID - 1); + LL_WARNS() << "Initialized attachment" << attachment->getName() << " joint_num " << attachment->getJointNum() << LL_ENDL; if (newly_created) { @@ -7393,7 +7428,6 @@ LLVOAvatar* LLVOAvatar::findAvatarFromAttachment( LLViewerObject* obj ) return NULL; } -// warning: order(N) not order(1) S32 LLVOAvatar::getAttachmentCount() { S32 count = mAttachmentPoints.size(); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index af23ebf41c..0e1e815fc4 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -204,6 +204,7 @@ public: virtual LLJoint* getJoint( const JointKey &name ); LLJoint* getJoint( const std::string &name ) { return getJoint( JointKey::construct( name ) ); } // + LLJoint* getJoint(S32 num); void addAttachmentOverridesForObject(LLViewerObject *vo); void resetJointsOnDetach(const LLUUID& mesh_id); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 2aa2ba0b36..4b0e96fa44 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -931,16 +931,29 @@ void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time) LLJoint *LLVOAvatarSelf::getJoint( const JointKey &name ) // { - if (mScreenp) + LLJoint *jointp = NULL; + jointp = LLVOAvatar::getJoint(name); + if (!jointp && mScreenp) { -// 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; + // 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); + // + if (jointp) + { + // Query by JointKey rather than just a string, the key can be a U32 index for faster lookup + //mJointMap[name] = jointp; + mJointMap[name.mKey] = jointp; + // + } } - return LLVOAvatar::getJoint(name); + if (jointp && jointp != mScreenp && jointp != mRoot) + { + llassert(LLVOAvatar::getJoint((S32)jointp->getJointNum())==jointp); + } + return jointp; } + // virtual // [Legacy Bake] //BOOL LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f936a4af3c..c6f4710ae3 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4923,8 +4923,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (rigged && pAvatarVO) { pAvatarVO->addAttachmentOverridesForObject(vobj); - if (pAvatarVO->isSelf()) - { + if (debugLoggingEnabled("Avatar") && pAvatarVO->isSelf()) + { bool verbose = true; pAvatarVO->showAttachmentOverrides(verbose); }