summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llmath/llrigginginfo.cpp5
-rw-r--r--indra/llmath/llvolume.cpp5
-rw-r--r--indra/llmath/llvolume.h5
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/llskinningutil.cpp58
-rw-r--r--indra/newview/llskinningutil.h2
-rw-r--r--indra/newview/llvoavatar.cpp218
-rw-r--r--indra/newview/llvovolume.cpp29
-rw-r--r--indra/newview/llvovolume.h1
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