Fix LL impostor hacking:

* Don't render shadows for impostors
* Show muted avatars as impostors (fix if RenderAvatarMaxNonImpostors = 0 = no limit)
* No detailed attachment updates for muted avatars if using no impostors
* Properly calculate update interval for muted avatars if using no impostors

Changed LLVOAvatar::isImpostor() so it also returns if an avatar is an impostor
in case RenderAvatarMaxNonImpostors = 0 = LLVOAvatar::sUseImpostors = FALSE is set,
so we can get rid of some

"isImpostor() || ((LLVOAvatar::AV_DO_NOT_RENDER == getVisualMuteSettings() || isInMuteList()) && !needsImpostorUpdate())"

and replace it with

"isImpostor() && !needsImpostorUpdate()"

This additional check would be necessary to render an avatar as impostor in case
it should never be rendered or it is muted, but LLVOAvatar::sUseImpostors is FALSE.
The check for !needsImpostorUpdate() is still needed to fail the condition in case
an impostor needs an update. For impostor updates, LLPipeline::generateImpostor()
will temporarily set LLVOAvatar::sUseImpostors = FALSE, so the rendering pipeline
doesn't skip parts needed to create a silhouette of the avatar. In that case,
needsImpostorUpdate() will return TRUE.
meow-7.2.2
Ansariel 2016-11-08 16:49:05 +01:00
parent b054bd2c99
commit c2b428e334
4 changed files with 63 additions and 16 deletions

View File

@ -1393,7 +1393,10 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
LLVOAvatar* avatarp = (LLVOAvatar*) objparent;
if (avatarp->isVisible())
{
impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor();
// <FS:Ansariel> Fix LL impostor hacking
//impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor();
impostor = objparent->isAvatar() && avatarp->isImpostor() && !avatarp->needsImpostorUpdate();
// </FS:Ansariel>
loaded = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isFullyLoaded();
}
else
@ -1483,7 +1486,10 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)
if (parent && parent->getVObj())
{
LLVOAvatar* av = parent->getVObj()->asAvatar();
if (av && av->isImpostor())
// <FS:Ansariel> Fix LL impostor hacking
//if (av && av->isImpostor())
if (av && av->isImpostor() && !av->needsImpostorUpdate())
// </FS:Ansariel>
{
return;
}

View File

@ -490,8 +490,11 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
BOOL impostor = avatarp->isImpostor();
if (impostor
&& LLVOAvatar::AV_DO_NOT_RENDER != avatarp->getVisualMuteSettings()
&& LLVOAvatar::AV_ALWAYS_RENDER != avatarp->getVisualMuteSettings())
// <FS:Ansariel> Fix LL impostor hacking; No shadow for impostors
//&& LLVOAvatar::AV_DO_NOT_RENDER != avatarp->getVisualMuteSettings()
//&& LLVOAvatar::AV_ALWAYS_RENDER != avatarp->getVisualMuteSettings())
)
// </FS:Ansariel>
{
return;
}
@ -1371,9 +1374,12 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
BOOL impostor = avatarp->isImpostor() && !single_avatar;
if (( /*avatarp->isInMuteList() // <FS:Ansariel> Partially undo MAINT-5700: Draw imposter for muted avatars
||*/ impostor
|| (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()) ) && pass != 0)
// <FS:Ansariel> Fix LL impostor hacking; Don't render impostored avatars unless it needs an update
//if (( avatarp->isInMuteList()
// || impostor
// || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()) ) && pass != 0)
if (impostor && !avatarp->needsImpostorUpdate() && pass != 0)
// </FS:Ansariel>
{ //don't draw anything but the impostor for impostored avatars
return;
}
@ -1390,7 +1396,10 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
LLVOAvatar::sNumVisibleAvatars++;
}
if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()))
// <FS:Ansariel> Fix LL impostor hacking
//if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()))
if (impostor && !avatarp->needsImpostorUpdate())
// </FS:Ansariel>
{
if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete())
{

View File

@ -2416,7 +2416,10 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
BOOL visible = isVisible() || mNeedsAnimUpdate;
// update attachments positions
if (detailed_update || !sUseImpostors)
// <FS:Ansariel> Fix LL impostor hacking; No detailed updates if muted when using no impostors
//if (detailed_update || !sUseImpostors)
if (detailed_update || (!sUseImpostors && !isInMuteList()))
// </FS:Ansariel>
{
LL_RECORD_BLOCK_TIME(FTM_ATTACHMENT_UPDATE);
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
@ -3809,7 +3812,10 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
//--------------------------------------------------------------------
bool visually_muted = isVisuallyMuted();
if (visible && (!isSelf() || visually_muted) && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter)
// <FS:Ansariel> Fix LL impostor hacking; Adjust update period for muted avatars if using no impostors
//if (visible && (!isSelf() || visually_muted) && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter)
if (visible && (!isSelf() || visually_muted) && !mIsDummy && (sUseImpostors || isInMuteList()) && !mNeedsAnimUpdate && !sFreezeCounter)
// </FS:Ansariel>
{
const LLVector4a* ext = mDrawable->getSpatialExtents();
LLVector4a size;
@ -8988,7 +8994,10 @@ void LLVOAvatar::updateFreezeCounter(S32 counter)
BOOL LLVOAvatar::updateLOD()
{
if (isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry())
// <FS:Ansariel> Fix LL impostor hacking
//if (isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry())
if (isImpostor() && !needsImpostorUpdate() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry())
// </FS:Ansariel>
{
return TRUE;
}
@ -9036,7 +9045,10 @@ void LLVOAvatar::updateImpostors()
LLVOAvatar* avatar = (LLVOAvatar*) *iter;
if (!avatar->isDead() && avatar->isVisible()
&& (
(avatar->isImpostor() || LLVOAvatar::AV_DO_NOT_RENDER == avatar->getVisualMuteSettings()) && avatar->needsImpostorUpdate())
// <FS:Ansariel> Fix LL impostor hacking; Generate new impostor if update is needed
//(avatar->isImpostor() || LLVOAvatar::AV_DO_NOT_RENDER == avatar->getVisualMuteSettings()) && avatar->needsImpostorUpdate())
avatar->isImpostor() && avatar->needsImpostorUpdate())
// </FS:Ansariel>
)
{
avatar->calcMutedAVColor();
@ -9049,7 +9061,24 @@ void LLVOAvatar::updateImpostors()
BOOL LLVOAvatar::isImpostor()
{
return sUseImpostors && (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE;
// <FS:Ansariel> Fix LL impostor hacking
// IMPORTANT: LLPipeline::generateImpostor() will set sUseImporstors = FALSE when generating
// an impostor. If checking for isImpostor() somewhere else to skip parts in the
// rendering process, an additional check for needsImpostorUpdate() needs to be
// done to determine if the particular part can really be skipped
// (mNeedsImpostorUpdate = FALSE) or is currently needed to generate the
// impostor (mNeedsImpostorUpdate = TRUE).
//return sUseImpostors && (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE;
if (sUseImpostors)
{
return (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD));
}
else
{
return (LLVOAvatar::AV_DO_NOT_RENDER == getVisualMuteSettings() || isInMuteList());
}
// </FS:Ansariel>
}
BOOL LLVOAvatar::shouldImpostor(const U32 rank_factor) const

View File

@ -3194,9 +3194,12 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
if (vobj) // this test may not be needed, see above
{
LLVOAvatar* av = vobj->asAvatar();
if (av && (av->isImpostor()
//|| av->isInMuteList() // <FS:Ansariel> Partially undo MAINT-5700: Draw imposter for muted avatars
|| (LLVOAvatar::AV_DO_NOT_RENDER == av->getVisualMuteSettings() && !av->needsImpostorUpdate()) ))
// <FS:Ansariel> Fix LL impostor hacking; Don't render impostored avatars unless it needs an update
//if (av && (av->isImpostor()
// || av->isInMuteList()
// || (LLVOAvatar::AV_DO_NOT_RENDER == av->getVisualMuteSettings() && !av->needsImpostorUpdate()) ))
if (av && av->isImpostor() && !av->needsImpostorUpdate())
// </FS:Ansariel>
{
return;
}