SL-915 - incremental updates to dynamic bounding box, setting to control detail.

master
Brad Payne (Vir Linden) 2018-06-05 15:35:21 +01:00
parent 228525aa27
commit 3fcf7a32ee
9 changed files with 238 additions and 108 deletions

View File

@ -27,6 +27,11 @@
#include "llmath.h"
#include "llrigginginfo.h"
#ifndef LL_RELEASE_FOR_DOWNLOAD
// AXON to remove
#pragma optimize("", off)
#endif
//-----------------------------------------------------------------------------
// LLJointRiggingInfo
//-----------------------------------------------------------------------------

View File

@ -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;
}

View File

@ -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;

View File

@ -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>

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
}
LLVector4a center, size;
center.setAdd(newMin, newMax);
center.mul(0.5f);
size.setSub(newMax,newMin);
size.mul(0.5f);
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 (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;
// 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>=1)
{
LLJoint *joint = getJoint(joint_num);
LLJointRiggingInfo *rig_info = NULL;
if (joint_num < mJointRiggingInfoTab.size())
for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i)
{
rig_info = &mJointRiggingInfoTab[joint_num];
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);
}
}
// FIXME TEMP HACK FOR TESTING
//if (joint)
//{
// rig_info.setIsRiggedTo(true);
//}
LLVector4a center, size;
center.setAdd(newMin, newMax);
center.mul(0.5f);
if (joint && rig_info && rig_info->isRiggedTo())
size.setSub(newMax,newMin);
size.mul(0.5f);
mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
}
//stretch bounding box by static attachments
if (box_detail >= 2)
{
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
{
LLViewerJointAttachment *as_joint_attach = dynamic_cast<LLViewerJointAttachment*>(joint);
if (as_joint_attach && as_joint_attach->getIsHUDAttachment())
LLViewerJointAttachment* attachment = iter->second;
if (attachment->getValid())
{
// Ignore bounding box of HUD joints
continue;
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;
// 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]);
}
}
}
}
}
}
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())
}
}
// Stretch bounding box by rigged mesh joint boxes
if (box_detail>=3)
{
updateRiggingInfo();
for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++)
{
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)
//{
// 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

View File

@ -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.
}
}

View File

@ -284,6 +284,7 @@ public:
//virtual
void updateRiggingInfo();
S32 mLastRiggingInfoLOD;
// Functions that deal with media, or media navigation