diff options
-rw-r--r-- | indra/llmath/llrigginginfo.cpp | 5 | ||||
-rw-r--r-- | indra/llmath/llvolume.cpp | 5 | ||||
-rw-r--r-- | indra/llmath/llvolume.h | 5 | ||||
-rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
-rw-r--r-- | indra/newview/llskinningutil.cpp | 58 | ||||
-rw-r--r-- | indra/newview/llskinningutil.h | 2 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 218 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 29 | ||||
-rw-r--r-- | indra/newview/llvovolume.h | 1 |
9 files changed, 232 insertions, 102 deletions
diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp index 925179c2ba..18fea2088c 100644 --- a/indra/llmath/llrigginginfo.cpp +++ b/indra/llmath/llrigginginfo.cpp @@ -27,6 +27,11 @@ #include "llmath.h" #include "llrigginginfo.h" +#ifndef LL_RELEASE_FOR_DOWNLOAD +// AXON to remove +#pragma optimize("", off) +#endif + //----------------------------------------------------------------------------- // LLJointRiggingInfo //----------------------------------------------------------------------------- diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 4613e17605..5aa1f6b44b 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4643,6 +4643,7 @@ LLVolumeFace::LLVolumeFace() : mNumVertices(0), mNumAllocatedVertices(0), mNumIndices(0), + mJointRiggingInfoTabPtr(NULL), mPositions(NULL), mNormals(NULL), mTangents(NULL), @@ -4674,6 +4675,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mTangents(NULL), mTexCoords(NULL), mIndices(NULL), + mJointRiggingInfoTabPtr(NULL), mWeights(NULL), mWeightsScrubbed(FALSE), mOctree(NULL) @@ -4788,6 +4790,9 @@ void LLVolumeFace::freeData() ll_aligned_free_16(mWeights); mWeights = NULL; + free(mJointRiggingInfoTabPtr); + mJointRiggingInfoTabPtr = NULL; + delete mOctree; mOctree = NULL; } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 4357b69b90..e92cf0b21f 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -57,6 +57,7 @@ class LLVolumeTriangle; #include "llpointer.h" #include "llfile.h" #include "llalignedarray.h" +#include "llrigginginfo.h" //============================================================================ @@ -958,6 +959,10 @@ public: LLVector4a* mWeights; mutable BOOL mWeightsScrubbed; + + // Which joints are rigged to, and the bounding box of any rigged + // vertices per joint. + joint_rig_info_tab *mJointRiggingInfoTabPtr; LLOctreeNode<LLVolumeTriangle>* mOctree; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index cfdf5e546b..ac46106721 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2215,6 +2215,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>AvatarBoundingBoxComplexity</key> + <map> + <key>Comment</key> + <string>How many aspects to consider for avatar bounding box</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>3</integer> + </map> <key>DebugAvatarAppearanceMessage</key> <map> <key>Comment</key> diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 7adb2fa8d2..f446c57897 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -31,6 +31,12 @@ #include "llvoavatar.h" #include "llviewercontrol.h" #include "llmeshrepository.h" +#include "llvolume.h" + +#ifndef LL_RELEASE_FOR_DOWNLOAD +// AXON to remove +#pragma optimize("", off) +#endif // static void LLSkinningUtil::initClass() @@ -219,25 +225,47 @@ void LLSkinningUtil::getPerVertexSkinMatrix( //static void LLSkinningUtil::initIsRiggedTo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, joint_rig_info_tab& rig_info_tab) { - S32 rigged_count = 0; - rig_info_tab.resize(LL_CHARACTER_MAX_ANIMATED_JOINTS); - for (U32 j = 0; j < skin->mJointNames.size(); ++j) + // AXON REMOVE +} + +//static +void LLSkinningUtil::updateRiggedExtents(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face) +{ + S32 num_verts = vol_face.mNumVertices; + if (num_verts>0 && vol_face.mWeights && (skin->mJointNames.size()>0)) { - LLJoint *joint = NULL; - if (skin->mJointNums[j] == -1) + if (!vol_face.mJointRiggingInfoTabPtr) { - joint = avatar->getJoint(skin->mJointNames[j]); - if (joint) + vol_face.mJointRiggingInfoTabPtr = new joint_rig_info_tab(LL_CHARACTER_MAX_ANIMATED_JOINTS); + joint_rig_info_tab& rig_info_tab = *vol_face.mJointRiggingInfoTabPtr; + for (S32 i=0; i<vol_face.mNumVertices; i++) { - skin->mJointNums[j] = joint->getJointNum(); + LLVector4a& pos = vol_face.mPositions[i]; + F32 *w = vol_face.mWeights[i].getF32ptr(); + for (U32 k=0; k<4; ++k) + { + S32 joint_index = llfloor(w[k]); + S32 joint_num = skin->mJointNums[joint_index]; + if (joint_num != -1) + { + rig_info_tab[joint_num].setIsRiggedTo(true); + + // AXON can precompute that matMuls. + LLMatrix4a bind_shape; + bind_shape.loadu(skin->mBindShapeMatrix); + LLMatrix4a inv_bind; + inv_bind.loadu(skin->mInvBindMatrix[joint_index]); + LLMatrix4a mat; + matMul(bind_shape, inv_bind, mat); + LLVector4a pos_joint_space; + mat.affineTransform(pos, pos_joint_space); + LLVector4a *extents = rig_info_tab[joint_num].getRiggedExtents(); + update_min_max(extents[0], extents[1], pos_joint_space); + } + } } - } - S32 joint_num = skin->mJointNums[j]; - if (joint_num != -1) - { - rig_info_tab[joint_num].setIsRiggedTo(true); - rigged_count++; + LL_DEBUGS("RigSpammish") << "updated rigging info for vf " << &vol_face + << " num_verts " << vol_face.mNumVertices << LL_ENDL; } } - //LL_INFOS() << "rigged_count " << rigged_count << LL_ENDL; } diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index 3eba3dc93a..5fd8a08d7a 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -30,6 +30,7 @@ class LLVOAvatar; class LLMeshSkinInfo; class LLMatrix4a; +class LLVolumeFace; #include "llrigginginfo.h" @@ -46,6 +47,7 @@ public: static void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); static void initIsRiggedTo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, joint_rig_info_tab& rig_info_tab); + static void updateRiggedExtents(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face); }; #endif diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 50a012ad82..bbb0f732a1 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -112,6 +112,11 @@ #include <boost/lexical_cast.hpp> +#ifndef LL_RELEASE_FOR_DOWNLOAD +// AXON to remove +#pragma optimize("", off) +#endif + extern F32 SPEED_ADJUST_MAX; extern F32 SPEED_ADJUST_MAX_SEC; extern F32 ANIM_SPEED_MAX; @@ -1281,6 +1286,7 @@ void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { + S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); LLVector4a buffer(0.0); LLVector4a pos; pos.load3(getRenderPosition().mV); @@ -1290,106 +1296,115 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) float max_attachment_span = get_default_max_prim_scale() * 5.0f; //stretch bounding box by joint positions - for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i) - { - LLPolyMesh* mesh = i->second; - for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.size(); joint_num++) - { - LLVector4a trans; - trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV); - update_min_max(newMin, newMax, trans); - } - } + if (box_detail>=1) + { + for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i) + { + LLPolyMesh* mesh = i->second; + for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.size(); joint_num++) + { + LLVector4a trans; + trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV); + update_min_max(newMin, newMax, trans); + } + } - LLVector4a center, size; - center.setAdd(newMin, newMax); - center.mul(0.5f); + LLVector4a center, size; + center.setAdd(newMin, newMax); + center.mul(0.5f); - size.setSub(newMax,newMin); - size.mul(0.5f); + size.setSub(newMax,newMin); + size.mul(0.5f); - mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); + mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); + } //stretch bounding box by static attachments - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; + if (box_detail >= 2) + { + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; - if (attachment->getValid()) - { - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - const LLViewerObject* attached_object = (*attachment_iter); - if (attached_object && !attached_object->isHUDAttachment()) - { - LLDrawable* drawable = attached_object->mDrawable; - if (drawable && !drawable->isState(LLDrawable::RIGGED)) - { - LLSpatialBridge* bridge = drawable->getSpatialBridge(); - if (bridge) - { - const LLVector4a* ext = bridge->getSpatialExtents(); - LLVector4a distance; - distance.setSub(ext[1], ext[0]); - LLVector4a max_span(max_attachment_span); + if (attachment->getValid()) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && !attached_object->isHUDAttachment()) + { + LLDrawable* drawable = attached_object->mDrawable; + if (drawable && !drawable->isState(LLDrawable::RIGGED)) + { + LLSpatialBridge* bridge = drawable->getSpatialBridge(); + if (bridge) + { + const LLVector4a* ext = bridge->getSpatialExtents(); + LLVector4a distance; + distance.setSub(ext[1], ext[0]); + LLVector4a max_span(max_attachment_span); - S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7; + S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7; - // Only add the prim to spatial extents calculations if it isn't a megaprim. - // max_attachment_span calculated at the start of the function - // (currently 5 times our max prim size) - if (lt == 0x7) - { - update_min_max(newMin,newMax,ext[0]); - update_min_max(newMin,newMax,ext[1]); - } - } - } - } - } - } - } + // Only add the prim to spatial extents calculations if it isn't a megaprim. + // max_attachment_span calculated at the start of the function + // (currently 5 times our max prim size) + if (lt == 0x7) + { + update_min_max(newMin,newMax,ext[0]); + update_min_max(newMin,newMax,ext[1]); + } + } + } + } + } + } + } + } // Stretch bounding box by rigged mesh joint boxes - updateRiggingInfo(); - for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) + if (box_detail>=3) { - LLJoint *joint = getJoint(joint_num); - LLJointRiggingInfo *rig_info = NULL; - if (joint_num < mJointRiggingInfoTab.size()) - { - rig_info = &mJointRiggingInfoTab[joint_num]; - } - - // FIXME TEMP HACK FOR TESTING - //if (joint) - //{ - // rig_info.setIsRiggedTo(true); - //} - - if (joint && rig_info && rig_info->isRiggedTo()) + updateRiggingInfo(); + for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) { - LLViewerJointAttachment *as_joint_attach = dynamic_cast<LLViewerJointAttachment*>(joint); - if (as_joint_attach && as_joint_attach->getIsHUDAttachment()) + LLJoint *joint = getJoint(joint_num); + LLJointRiggingInfo *rig_info = NULL; + if (joint_num < mJointRiggingInfoTab.size()) { - // Ignore bounding box of HUD joints - continue; + rig_info = &mJointRiggingInfoTab[joint_num]; } - LLMatrix4a mat; - LLVector4a new_extents[2]; - mat.loadu(joint->getWorldMatrix()); - matMulBoundBox(mat, rig_info->getRiggedExtents(), new_extents); - update_min_max(newMin, newMax, new_extents[0]); - update_min_max(newMin, newMax, new_extents[1]); - //if (isSelf()) + + // FIXME TEMP HACK FOR TESTING + //if (joint) //{ - // LL_INFOS() << joint->getName() << " extents " << new_extents[0] << "," << new_extents[1] << LL_ENDL; - // LL_INFOS() << joint->getName() << " av box is " << newMin << "," << newMax << LL_ENDL; + // rig_info.setIsRiggedTo(true); //} + + if (joint && rig_info && rig_info->isRiggedTo()) + { + LLViewerJointAttachment *as_joint_attach = dynamic_cast<LLViewerJointAttachment*>(joint); + if (as_joint_attach && as_joint_attach->getIsHUDAttachment()) + { + // Ignore bounding box of HUD joints + continue; + } + LLMatrix4a mat; + LLVector4a new_extents[2]; + mat.loadu(joint->getWorldMatrix()); + matMulBoundBox(mat, rig_info->getRiggedExtents(), new_extents); + update_min_max(newMin, newMax, new_extents[0]); + update_min_max(newMin, newMax, new_extents[1]); + //if (isSelf()) + //{ + // LL_INFOS() << joint->getName() << " extents " << new_extents[0] << "," << new_extents[1] << LL_ENDL; + // LL_INFOS() << joint->getName() << " av box is " << newMin << "," << newMax << LL_ENDL; + //} + } } } @@ -9447,6 +9462,28 @@ S32 countRigInfoTab(joint_rig_info_tab& tab) return count; } +void showRigInfoTabExtents(LLVOAvatar *avatar, joint_rig_info_tab& tab, S32& count_rigged, S32& count_box) +{ + count_rigged = count_box = 0; + LLVector4a zero_vec; + zero_vec.clear(); + for (S32 i=0; i<tab.size(); i++) + { + if (tab[i].isRiggedTo()) + { + count_rigged++; + LLJoint *joint = avatar->getJoint(i); + LL_DEBUGS("RigSpam") << "joint " << i << " name " << joint->getName() << " box " + << tab[i].getRiggedExtents()[0] << ", " << tab[i].getRiggedExtents()[1] << LL_ENDL; + if ((!tab[i].getRiggedExtents()[0].equals3(zero_vec)) || + (!tab[i].getRiggedExtents()[1].equals3(zero_vec))) + { + count_box++; + } + } + } +} + // virtual void LLVOAvatar::updateRiggingInfo() { @@ -9485,6 +9522,10 @@ void LLVOAvatar::updateRiggingInfo() { volp->updateRiggingInfo(); mergeRigInfoTab(mJointRiggingInfoTab, volp->mJointRiggingInfoTab); + LL_DEBUGS("RigSpammish") << getFullname() << " after cav update rig tab:" << LL_ENDL; + S32 joint_count, box_count; + showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count); + LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; //LL_INFOS() << "cav after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; LLViewerObject::const_child_list_t& children = volp->getChildren(); @@ -9494,12 +9535,21 @@ void LLVOAvatar::updateRiggingInfo() LLViewerObject *childp = *it; childp->updateRiggingInfo(); mergeRigInfoTab(mJointRiggingInfoTab, childp->mJointRiggingInfoTab); + + LL_DEBUGS("RigSpammish") << getFullname() << " after cav child update rig tab:" << LL_ENDL; + S32 joint_count, box_count; + showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count); + LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; //LL_INFOS() << "cav after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; } } } //LL_INFOS() << "done update rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; + LL_DEBUGS("RigSpammish") << getFullname() << " after update rig tab:" << LL_ENDL; + S32 joint_count, box_count; + showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count); + LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; } U32 LLVOAvatar::getPartitionType() const diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 321ea22ff9..81852cd878 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -85,6 +85,11 @@ #include "llviewerinventory.h" #include "llcallstack.h" +#ifndef LL_RELEASE_FOR_DOWNLOAD +// AXON to remove +#pragma optimize("", off) +#endif + const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1; @@ -230,6 +235,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mLastFetchedMediaVersion = -1; memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS); mMDCImplCount = 0; + mLastRiggingInfoLOD = -1; } LLVOVolume::~LLVOVolume() @@ -3571,11 +3577,28 @@ void LLVOVolume::updateRiggingInfo() { const LLMeshSkinInfo* skin = getSkinInfo(); LLVOAvatar *avatar = getAvatar(); - if (skin && avatar) + if (skin && avatar && getLOD()>mLastRiggingInfoLOD) { - LLSkinningUtil::initIsRiggedTo(skin, avatar, mJointRiggingInfoTab); + LLVolume *volume = getVolume(); + if (volume) + { + mJointRiggingInfoTab.clear(); + for (S32 f = 0; f < volume->getNumVolumeFaces(); ++f) + { + LLVolumeFace& vol_face = volume->getVolumeFace(f); + LLSkinningUtil::updateRiggedExtents(skin, avatar, vol_face); + if (vol_face.mJointRiggingInfoTabPtr) + { + mergeRigInfoTab(mJointRiggingInfoTab, *vol_face.mJointRiggingInfoTabPtr); + } + } + // Keep the highest LOD info available. + // AXON would this ever need to be forced to refresh? Set to -1 if so. + mLastRiggingInfoLOD = getLOD(); + LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume " + << this << " lod " << mLastRiggingInfoLOD << LL_ENDL; + } } - // AXON add bbox processing from volume faces. } } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index d77c2f231b..2ba73b9d86 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -284,6 +284,7 @@ public: //virtual void updateRiggingInfo(); + S32 mLastRiggingInfoLOD; // Functions that deal with media, or media navigation |