SL-808 - updated ARC display to largely work with animated objects. Gives some triangle information that we may or may not ultimately keep. Surface area calcs still not working

meow-7.2.2
Brad Payne (Vir Linden) 2017-10-02 21:52:24 +01:00
parent 853924c7ef
commit 217df36656
7 changed files with 227 additions and 147 deletions

View File

@ -330,11 +330,7 @@ void LLFace::dirtyTexture()
{
vobj->mLODChanged = TRUE;
LLVOAvatar* avatar = vobj->getAvatar();
if (avatar)
{ //avatar render cost may have changed
avatar->updateVisualComplexity();
}
vobj->updateVisualComplexity();
}
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
}

View File

@ -3627,6 +3627,22 @@ U32 LLViewerObject::getHighLODTriangleCount()
return 0;
}
U32 LLViewerObject::recursiveGetTriangleCount(S32* vcount) const
{
S32 total_tris = getTriangleCount(vcount);
LLViewerObject::const_child_list_t& child_list = getChildren();
for (LLViewerObject::const_child_list_t::const_iterator iter = child_list.begin();
iter != child_list.end(); ++iter)
{
LLViewerObject* childp = *iter;
if (childp)
{
total_tris += childp->getTriangleCount(vcount);
}
}
return total_tris;
}
void LLViewerObject::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
{
LLVector4a center;

View File

@ -364,6 +364,8 @@ public:
virtual U32 getTriangleCount(S32* vcount = NULL) const;
virtual U32 getHighLODTriangleCount();
U32 recursiveGetTriangleCount(S32* vcount = NULL) const;
void setObjectCost(F32 cost);
F32 getObjectCost();

View File

@ -620,6 +620,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
LLViewerObject(id, pcode, regionp),
mSpecialRenderMode(0),
mAttachmentSurfaceArea(0.f),
mAttachmentVisibleTriangleCount(0),
mAttachmentEstTriangleCount(0.f),
mReportedVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN),
mTurning(FALSE),
mLastSkeletonSerialNum( 0 ),
@ -9167,8 +9169,13 @@ void LLVOAvatar::idleUpdateRenderComplexity()
{
if (isControlAvatar())
{
// ARC for animated object attachments is accounted with the avatar they're attached to.
return;
LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this);
bool is_attachment = cav && cav->mRootVolp && cav->mRootVolp->isAttachment(); // For attached animated objects
if (is_attachment)
{
// ARC for animated object attachments is accounted with the avatar they're attached to.
return;
}
}
// Render Complexity
@ -9218,10 +9225,14 @@ void LLVOAvatar::idleUpdateRenderComplexity()
// Visual rank
info_line = llformat("%d rank", mVisibilityRank);
// Use grey for imposters, white for normal rendering or no impostors
info_color.set(isImpostor() ? LLColor4::grey : LLColor4::white);
info_color.set(isImpostor() ? LLColor4::grey : (isControlAvatar() ? LLColor4::yellow : LLColor4::white));
info_style = LLFontGL::NORMAL;
mText->addLine(info_line, info_color, info_style);
// Triangle count
mText->addLine(llformat("Tris %u",mAttachmentVisibleTriangleCount), info_color, info_style);
mText->addLine(llformat("Est Tris %f",mAttachmentEstTriangleCount), info_color, info_style);
// Attachment Surface Area
static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 1000.0f);
info_line = llformat("%.0f m^2", mAttachmentSurfaceArea);
@ -9263,6 +9274,133 @@ void LLVOAvatar::updateVisualComplexity()
mVisualComplexityStale = true;
}
// Account for the complexity of a single top-level object associated
// with an avatar. This will be either an attached object or an animated
// object.
void LLVOAvatar::accountRenderComplexityForObject(
const LLViewerObject *attached_object,
const F32 max_attachment_complexity,
LLVOVolume::texture_cost_t& textures,
U32& cost,
hud_complexity_list_t& hud_complexity_list)
{
if (attached_object && !attached_object->isHUDAttachment())
{
mAttachmentVisibleTriangleCount += attached_object->recursiveGetTriangleCount();
mAttachmentEstTriangleCount += attached_object->recursiveGetEstTrianglesMax();
textures.clear();
const LLDrawable* drawable = attached_object->mDrawable;
if (drawable)
{
const LLVOVolume* volume = drawable->getVOVolume();
if (volume)
{
F32 attachment_total_cost = 0;
F32 attachment_volume_cost = 0;
F32 attachment_texture_cost = 0;
F32 attachment_children_cost = 0;
// AXON placeholder value, will revisit in testing.
const F32 animated_object_attachment_surcharge = 20000;
if (attached_object->isAnimatedObject())
{
attachment_volume_cost += animated_object_attachment_surcharge;
}
attachment_volume_cost += volume->getRenderCost(textures);
const_child_list_t children = volume->getChildren();
for (const_child_list_t::const_iterator child_iter = children.begin();
child_iter != children.end();
++child_iter)
{
LLViewerObject* child_obj = *child_iter;
LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
if (child)
{
attachment_children_cost += child->getRenderCost(textures);
}
}
for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
volume_texture != textures.end();
++volume_texture)
{
// add the cost of each individual texture in the linkset
attachment_texture_cost += volume_texture->second;
}
attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost;
LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID()
<< " total: " << attachment_total_cost
<< ", volume: " << attachment_volume_cost
<< ", textures: " << attachment_texture_cost
<< ", " << volume->numChildren()
<< " children: " << attachment_children_cost
<< LL_ENDL;
// Limit attachment complexity to avoid signed integer flipping of the wearer's ACI
cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity);
}
}
}
if (isSelf()
&& attached_object
&& attached_object->isHUDAttachment()
&& !attached_object->isTempAttachment()
&& attached_object->mDrawable)
{
textures.clear();
const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
if (volume)
{
LLHUDComplexity hud_object_complexity;
hud_object_complexity.objectName = attached_object->getAttachmentItemName();
hud_object_complexity.objectId = attached_object->getAttachmentItemID();
std::string joint_name;
gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name);
hud_object_complexity.jointName = joint_name;
// get cost and individual textures
hud_object_complexity.objectsCost += volume->getRenderCost(textures);
hud_object_complexity.objectsCount++;
LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
iter != child_list.end(); ++iter)
{
LLViewerObject* childp = *iter;
const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp);
if (chld_volume)
{
// get cost and individual textures
hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures);
hud_object_complexity.objectsCount++;
}
}
hud_object_complexity.texturesCount += textures.size();
for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
volume_texture != textures.end();
++volume_texture)
{
// add the cost of each individual texture (ignores duplicates)
hud_object_complexity.texturesCost += volume_texture->second;
LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first);
if (tex)
{
// Note: Texture memory might be incorect since texture might be still loading.
hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory();
if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE)
{
hud_object_complexity.largeTexturesCount++;
}
}
}
hud_complexity_list.push_back(hud_object_complexity);
}
}
}
// Calculations for mVisualComplexity value
void LLVOAvatar::calculateUpdateRenderComplexity()
{
@ -9301,7 +9439,24 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
}
LL_DEBUGS("ARCdetail") << "Avatar body parts complexity: " << cost << LL_ENDL;
mAttachmentVisibleTriangleCount = 0;
mAttachmentEstTriangleCount = 0.f;
// A standalone animated object needs to be accounted for
// using its associated volume. Attached animated objects
// will be covered by the subsequent loop over attachments.
LLControlAvatar *control_av = dynamic_cast<LLControlAvatar*>(this);
if (control_av)
{
LLVOVolume *volp = control_av->mRootVolp;
if (volp && !volp->isAttachment())
{
accountRenderComplexityForObject(volp, max_attachment_complexity,
textures, cost, hud_complexity_list);
}
}
// Account for complexity of all attachments.
for (attachment_map_t::const_iterator attachment_point = mAttachmentPoints.begin();
attachment_point != mAttachmentPoints.end();
++attachment_point)
@ -9312,118 +9467,8 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
++attachment_iter)
{
const LLViewerObject* attached_object = (*attachment_iter);
if (attached_object && !attached_object->isHUDAttachment())
{
textures.clear();
const LLDrawable* drawable = attached_object->mDrawable;
if (drawable)
{
const LLVOVolume* volume = drawable->getVOVolume();
if (volume)
{
F32 attachment_total_cost = 0;
F32 attachment_volume_cost = 0;
F32 attachment_texture_cost = 0;
F32 attachment_children_cost = 0;
// AXON placeholder value, will revisit in testing.
const F32 animated_object_attachment_surcharge = 20000;
if (attached_object->isAnimatedObject())
{
attachment_volume_cost += animated_object_attachment_surcharge;
}
attachment_volume_cost += volume->getRenderCost(textures);
const_child_list_t children = volume->getChildren();
for (const_child_list_t::const_iterator child_iter = children.begin();
child_iter != children.end();
++child_iter)
{
LLViewerObject* child_obj = *child_iter;
LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
if (child)
{
attachment_children_cost += child->getRenderCost(textures);
}
}
for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
volume_texture != textures.end();
++volume_texture)
{
// add the cost of each individual texture in the linkset
attachment_texture_cost += volume_texture->second;
}
attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost;
LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID()
<< " total: " << attachment_total_cost
<< ", volume: " << attachment_volume_cost
<< ", textures: " << attachment_texture_cost
<< ", " << volume->numChildren()
<< " children: " << attachment_children_cost
<< LL_ENDL;
// Limit attachment complexity to avoid signed integer flipping of the wearer's ACI
cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity);
}
}
}
if (isSelf()
&& attached_object
&& attached_object->isHUDAttachment()
&& !attached_object->isTempAttachment()
&& attached_object->mDrawable)
{
textures.clear();
const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
if (volume)
{
LLHUDComplexity hud_object_complexity;
hud_object_complexity.objectName = attached_object->getAttachmentItemName();
hud_object_complexity.objectId = attached_object->getAttachmentItemID();
std::string joint_name;
gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name);
hud_object_complexity.jointName = joint_name;
// get cost and individual textures
hud_object_complexity.objectsCost += volume->getRenderCost(textures);
hud_object_complexity.objectsCount++;
LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
iter != child_list.end(); ++iter)
{
LLViewerObject* childp = *iter;
const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp);
if (chld_volume)
{
// get cost and individual textures
hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures);
hud_object_complexity.objectsCount++;
}
}
hud_object_complexity.texturesCount += textures.size();
for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
volume_texture != textures.end();
++volume_texture)
{
// add the cost of each individual texture (ignores duplicates)
hud_object_complexity.texturesCost += volume_texture->second;
LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first);
if (tex)
{
// Note: Texture memory might be incorect since texture might be still loading.
hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory();
if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE)
{
hud_object_complexity.largeTexturesCount++;
}
}
}
hud_complexity_list.push_back(hud_object_complexity);
}
}
accountRenderComplexityForObject(attached_object, max_attachment_complexity,
textures, cost, hud_complexity_list);
}
}

View File

@ -50,6 +50,8 @@
#include "llviewertexlayer.h"
#include "material_codes.h" // LL_MCODE_END
#include "llviewerstats.h"
#include "llvovolume.h"
#include "llavatarrendernotifier.h"
extern const LLUUID ANIM_AGENT_BODY_NOISE;
extern const LLUUID ANIM_AGENT_BREATHE_ROT;
@ -268,6 +270,11 @@ public:
static void invalidateNameTags();
void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font);
void idleUpdateRenderComplexity();
void accountRenderComplexityForObject(const LLViewerObject *attached_object,
const F32 max_attachment_complexity,
LLVOVolume::texture_cost_t& textures,
U32& cost,
hud_complexity_list_t& hud_complexity_list);
void calculateUpdateRenderComplexity();
static const U32 VISUAL_COMPLEXITY_UNKNOWN;
void updateVisualComplexity();
@ -431,6 +438,8 @@ public:
private:
F32 mAttachmentSurfaceArea; //estimated surface area of attachments
U32 mAttachmentVisibleTriangleCount;
F32 mAttachmentEstTriangleCount;
bool shouldAlphaMask();
BOOL mNeedsSkin; // avatar has been animated and verts have not been updated

View File

@ -1103,16 +1103,26 @@ void LLVOVolume::updateSculptTexture()
}
void LLVOVolume::updateVisualComplexity()
{
LLVOAvatar* avatar = getAvatarAncestor();
if (avatar)
{
avatar->updateVisualComplexity();
}
LLVOAvatar* rigged_avatar = getAvatar();
if(rigged_avatar && (rigged_avatar != avatar))
{
rigged_avatar->updateVisualComplexity();
}
}
void LLVOVolume::notifyMeshLoaded()
{
mSculptChanged = TRUE;
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
LLVOAvatar* avatar = getAvatar();
if (avatar)
{
avatar->updateVisualComplexity();
}
updateVisualComplexity();
}
// sculpt replaces generate() for sculpted surfaces
@ -1302,18 +1312,7 @@ BOOL LLVOVolume::calcLOD()
{
if (isRootEdit() && getChildren().size()>0)
{
S32 total_tris = getTriangleCount();
LLViewerObject::const_child_list_t& child_list = getChildren();
for (LLViewerObject::const_child_list_t::const_iterator iter = child_list.begin();
iter != child_list.end(); ++iter)
{
LLViewerObject* childp = *iter;
LLVOVolume *child_volp = dynamic_cast<LLVOVolume*>(childp);
if (child_volp)
{
total_tris += child_volp->getTriangleCount();
}
}
S32 total_tris = recursiveGetTriangleCount();
setDebugText(llformat("TRIS %d TOTAL %d", getTriangleCount(), total_tris));
}
else
@ -1333,7 +1332,8 @@ BOOL LLVOVolume::calcLOD()
{
mAppAngle = ll_round((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
mLOD = cur_detail;
return TRUE;
return TRUE;
}
return FALSE;
@ -1691,6 +1691,11 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled)
if ((new_lod != old_lod) || mSculptChanged)
{
if (mDrawable->isState(LLDrawable::RIGGED))
{
updateVisualComplexity();
}
compiled = TRUE;
sNumLODChanges += new_num_faces;
@ -3342,7 +3347,7 @@ void LLVOVolume::setExtendedMeshFlags(U32 flags)
parameterChanged(LLNetworkData::PARAMS_EXTENDED_MESH, true);
if (isAttachment() && getAvatarAncestor())
{
getAvatarAncestor()->updateVisualComplexity();
updateVisualComplexity();
if (flags & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG)
{
// Making a rigged mesh into an animated object
@ -3392,7 +3397,7 @@ bool LLVOVolume::isAnimatedObject() const
if (root_is_animated_flag)
{
bool root_can_be_animated = root_vol->canBeAnimatedObject();
bool this_can_be_animated = ((root_vol == this) && root_can_be_animated) || canBeAnimatedObject();
bool this_can_be_animated = (root_vol == this) ? root_can_be_animated : canBeAnimatedObject();
if (this_can_be_animated && root_can_be_animated)
{
return true;
@ -4923,25 +4928,29 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
group->mBuilt = 1.f;
LLVOAvatar* pAvatarVO = NULL;
LLVOAvatar *attached_av = NULL;
LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
if (bridge)
{
LLViewerObject* vobj = bridge->mDrawable->getVObj();
if (bridge->mAvatar.isNull())
{
LLViewerObject* vobj = bridge->mDrawable->getVObj();
if (vobj)
{
bridge->mAvatar = vobj->getAvatar();
}
}
if (vobj)
{
attached_av = vobj->getAvatarAncestor();
}
pAvatarVO = bridge->mAvatar;
}
if (pAvatarVO)
if (attached_av)
{
pAvatarVO->subtractAttachmentArea( group->mSurfaceArea );
attached_av->subtractAttachmentArea( group->mSurfaceArea );
}
group->mGeometryBytes = 0;
@ -5518,9 +5527,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
mFaceList.clear();
if (pAvatarVO)
if (attached_av)
{
pAvatarVO->addAttachmentArea( group->mSurfaceArea );
attached_av->addAttachmentArea( group->mSurfaceArea );
}
}

View File

@ -315,7 +315,10 @@ public:
bool hasMedia() const;
LLVector3 getApproximateFaceNormal(U8 face_id);
// Flag any corresponding avatars as needing update.
void updateVisualComplexity();
void notifyMeshLoaded();
// Returns 'true' iff the media data for this object is in flight