From 1da60c1d92e7af7d9f3de141574179717cf1e9cd Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 17 Apr 2015 13:37:46 -0400 Subject: reorganize visual muting, impostors, and complexity criteria [does not render correctly yet] --- indra/newview/llavatarrenderinfoaccountant.cpp | 4 +- indra/newview/llviewermenu.cpp | 1 - indra/newview/llviewertexturelist.cpp | 2 +- indra/newview/llviewerwindow.cpp | 2 +- indra/newview/llvoavatar.cpp | 202 +++++++++++++------------ indra/newview/llvoavatar.h | 20 ++- indra/newview/llvoavatarself.cpp | 8 +- indra/newview/pipeline.cpp | 40 +++-- 8 files changed, 150 insertions(+), 129 deletions(-) diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index 44e19b1449..5746a43306 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -51,7 +51,7 @@ static const std::string KEY_AGENTS = "agents"; // map static const std::string KEY_WEIGHT = "weight"; // integer -static const std::string KEY_MUTED = "muted"; // bool +static const std::string KEY_TOO_COMPLEX = "tooComplex"; // bool static const std::string KEY_IDENTIFIER = "identifier"; static const std::string KEY_MESSAGE = "message"; @@ -255,7 +255,7 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio if (avatar->getVisualComplexity() > 0) { info[KEY_WEIGHT] = avatar->getVisualComplexity(); - info[KEY_MUTED] = avatar->isVisuallyMuted(); + info[KEY_TOO_COMPLEX] = avatar->isTooComplex(); agents[avatar->getID().asString()] = info; LL_DEBUGS("AvatarRenderInfo") << "Sending avatar render info for " << avatar->getID() diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 213dee9328..793697b3df 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3020,7 +3020,6 @@ class LLAvatarSetImpostorMode : public view_listener_t return false; } - avatar->forceUpdateVisualMuteSettings(); LLVOAvatar::cullAvatarsByPixelArea(); return true; } // handleEvent() diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 8c27ddc63c..33bf4f823e 100755 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -447,7 +447,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, // If the image is not found, creates new image and // enqueues a request for transmission - if ((&image_id == NULL) || image_id.isNull()) + if (image_id.isNull()) { return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI)); } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 57c1643b8d..09173f0742 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -680,7 +680,7 @@ public: avatar->calculateUpdateRenderComplexity(); // Make sure the numbers are up-to-date trunc_name = utf8str_truncate(avatar->getFullname(), 16); - addText(xpos, ypos, llformat("%s : rez %d, weight %d, bytes %d area %.2f", + addText(xpos, ypos, llformat("%s : rez %d, complexity %d, bytes %d area %.2f", trunc_name.c_str(), avatar->getRezzedStatus(), avatar->getVisualComplexity(), diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 7bd4ab4bb4..b3129a85cd 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -114,8 +114,6 @@ extern U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG; const F32 MAX_HOVER_Z = 2.0; const F32 MIN_HOVER_Z = -2.0; -// #define OUTPUT_BREAST_DATA - using namespace LLAvatarAppearanceDefines; //----------------------------------------------------------------------------- @@ -182,6 +180,8 @@ const F32 NAMETAG_UPDATE_THRESHOLD = 0.3f; const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f; const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f; +const S32 LLVOAvatar::VISUAL_COMPLEXITY_UNKNOWN = 0; + enum ERenderName { RENDER_NAME_NEVER, @@ -645,7 +645,7 @@ BOOL LLVOAvatar::sShowFootPlane = FALSE; BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE; F32 LLVOAvatar::sLODFactor = 1.f; F32 LLVOAvatar::sPhysicsLODFactor = 1.f; -bool LLVOAvatar::sUseImpostors = false; +bool LLVOAvatar::sUseImpostors = false; // overwridden by RenderAvatarMaxNonImpostors BOOL LLVOAvatar::sJointDebug = FALSE; F32 LLVOAvatar::sUnbakedTime = 0.f; F32 LLVOAvatar::sUnbakedUpdateTime = 0.f; @@ -668,7 +668,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mSpecialRenderMode(0), mAttachmentGeometryBytes(-1), mAttachmentSurfaceArea(-1.f), - mReportedVisualComplexity(-1), + mReportedVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN), mTurning(FALSE), mLastSkeletonSerialNum( 0 ), mIsSitting(FALSE), @@ -698,12 +698,14 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mNeedsSkin(FALSE), mLastSkinTime(0.f), mUpdatePeriod(1), + mVisualComplexityStale(true), + mVisuallyMuteSetting(VISUAL_MUTE_NOT_SET), + mMutedAVColor(calcMutedAVColor(getID())), mFirstFullyVisible(TRUE), mFullyLoaded(FALSE), mPreviousFullyLoaded(FALSE), mFullyLoadedInitialized(FALSE), - mVisualComplexity(0), - mVisualComplexityStale(TRUE), + mVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN), mLoadedCallbacksPaused(FALSE), mRenderUnloadedAvatar(LLCachedControl(gSavedSettings, "RenderUnloadedAvatar", false)), mLastRezzedStatus(-1), @@ -712,6 +714,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mLastUpdateRequestCOFVersion(-1), mLastUpdateReceivedCOFVersion(-1) { + LL_DEBUGS("AvatarRender") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL; + //VTResume(); // VTune setHoverOffset(LLVector3(0.0, 0.0, 0.0)); @@ -719,8 +723,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, const BOOL needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim ); - LL_DEBUGS("Avatar") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL; - mPelvisp = NULL; mDirtyMesh = 2; // Dirty geometry, need to regenerate. @@ -771,14 +773,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, if(LLSceneMonitor::getInstance()->isEnabled()) { - LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this); + LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this); } - - mCachedVisualMute = !isSelf(); // default to muting everyone else? hmmm.... - mCachedVisualMuteUpdateTime = LLFrameTimer::getTotalSeconds() + 5.0; - mVisuallyMuteSetting = VISUAL_MUTE_NOT_SET; - - mMutedAVColor = calcMutedAVColor(getID()); } std::string LLVOAvatar::avString() const @@ -2535,7 +2531,10 @@ void LLVOAvatar::idleUpdateLoadingEffect() LLPartData::LL_PART_EMISSIVE_MASK | // LLPartData::LL_PART_FOLLOW_SRC_MASK | LLPartData::LL_PART_TARGET_POS_MASK ); - setParticleSource(particle_parameters, getID()); + if (!isTooComplex()) // do not generate particles for overly-complex avatars + { + setParticleSource(particle_parameters, getID()); + } } } } @@ -3080,62 +3079,9 @@ void LLVOAvatar::slamPosition() bool LLVOAvatar::isVisuallyMuted() const { - bool muted = false; - - // Priority order (highest priority first) - // * own avatar is never visually muted - // * if on the "always draw normally" list, draw them normally - // * if on the "always visually mute" list, mute them - // * check against the render cost and attachment limits - if (!isSelf()) - { - static LLCachedControl max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit", 0); - static LLCachedControl max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 0.0); - static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); - - if (mVisuallyMuteSetting == ALWAYS_VISUAL_MUTE) - { // Always want to see this AV as an impostor - muted = true; - } - else if (mVisuallyMuteSetting == NEVER_VISUAL_MUTE) - { // Never show as impostor - muted = false; - } - else - { - F64 now = LLFrameTimer::getTotalSeconds(); - - if (now < mCachedVisualMuteUpdateTime) - { // Use cached mute value - muted = mCachedVisualMute; - } - else - { // Determine if visually muted or not - - muted = ( (max_render_cost > 0 && mVisualComplexity > max_render_cost) - || (max_attachment_bytes > 0 && mAttachmentGeometryBytes > max_attachment_bytes) - || (max_attachment_area > 0.f && mAttachmentSurfaceArea > max_attachment_area) - || LLMuteList::getInstance()->isMuted(getID()) - ); - - // Save visual mute state and set interval for updating - const F64 SECONDS_BETWEEN_RENDER_AUTO_MUTE_UPDATES = 1.5; - mCachedVisualMuteUpdateTime = now + SECONDS_BETWEEN_RENDER_AUTO_MUTE_UPDATES; - mCachedVisualMute = muted; - } - } - } - - return muted; + return ( mVisuallyMuteSetting == ALWAYS_VISUAL_MUTE ); } -void LLVOAvatar::forceUpdateVisualMuteSettings() -{ - // Set the cache time so it's updated ASAP - mCachedVisualMuteUpdateTime = LLFrameTimer::getTotalSeconds() - 1.0; -} - - void LLVOAvatar::updateDebugText() { // clear debug text @@ -3279,18 +3225,18 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) { // visually muted avatars update at 16 hz mUpdatePeriod = 16; } - else if ( mVisibilityRank <= LLVOAvatar::sMaxNonImpostors + else if ( ! isImpostor() || mDrawable->mDistanceWRTCamera < 1.f + mag) { // first 25% of max visible avatars are not impostored // also, don't impostor avatars whose bounding box may be penetrating the // impostor camera near clip plane mUpdatePeriod = 1; } - else if (mVisibilityRank > LLVOAvatar::sMaxNonImpostors * 4) + else if ( isImpostor(4) ) { //background avatars are REALLY slow updating impostors mUpdatePeriod = 16; } - else if (mVisibilityRank > LLVOAvatar::sMaxNonImpostors * 3) + else if ( isImpostor(3) ) { //back 25% of max visible avatars are slow updating impostors mUpdatePeriod = 8; } @@ -3874,6 +3820,10 @@ void LLVOAvatar::updateVisibility() } } + if ( visible != mVisible ) + { + LL_DEBUGS("AvatarRender") << "visible was " << mVisible << " now " << visible << LL_ENDL; + } mVisible = visible; } @@ -4146,8 +4096,8 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) } // Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair) // TODO: 1.25 will be able to switch this logic back to calling isTextureVisible(); - if ( ( getImage(TEX_HAIR_BAKED, 0) && - getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE ) || LLDrawPoolAlpha::sShowDebugAlpha) + if ( (getImage(TEX_HAIR_BAKED, 0) && getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE) + || LLDrawPoolAlpha::sShowDebugAlpha) { LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); if (hair_mesh) @@ -5765,7 +5715,7 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o return 0; } - mVisualComplexityStale = TRUE; + updateVisualComplexity(); if (viewer_object->isSelected()) { @@ -5914,7 +5864,7 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) if (attachment->isObjectAttached(viewer_object)) { - mVisualComplexityStale = TRUE; + updateVisualComplexity(); cleanupAttachedMesh( viewer_object ); attachment->removeObject(viewer_object); @@ -6460,6 +6410,32 @@ BOOL LLVOAvatar::isFullyLoaded() const return (mRenderUnloadedAvatar || mFullyLoaded); } +bool LLVOAvatar::isTooComplex() const +{ + static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); + static LLCachedControl max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit", 0); + static LLCachedControl max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit", 0.0); + bool too_complex; + + if (isSelf()) + { + too_complex = false; + } + else + { + too_complex = ( (max_render_cost > 0 && mVisualComplexity > max_render_cost) + || (max_attachment_bytes > 0 && mAttachmentGeometryBytes > max_attachment_bytes) + || (max_attachment_area > 0.f && mAttachmentSurfaceArea > max_attachment_area) + ); + } + + return too_complex; +} + +bool LLVOAvatar::isImpostor(const U32 rank_factor) const +{ + return (!isSelf() && sMaxNonImpostors != 0 && mVisibilityRank > (sMaxNonImpostors * rank_factor)); +} //----------------------------------------------------------------------------- // findMotion() @@ -8064,20 +8040,29 @@ void LLVOAvatar::updateImpostors() iter != LLCharacter::sInstances.end(); ++iter) { LLVOAvatar* avatar = (LLVOAvatar*) *iter; - if (!avatar->isDead() && avatar->needsImpostorUpdate() && avatar->isVisible() && avatar->isImpostor()) + + if (!avatar->isDead() && avatar->isVisible() + && ( (avatar->isImpostor() && avatar->needsImpostorUpdate()) + || avatar->isTooComplex() + )) { gPipeline.generateImpostor(avatar); } + else + { + LL_DEBUGS_ONCE("AvatarRender") << "Avatar " << avatar->getID() + << (avatar->isDead() ? " _is_ " : " is not ") << "dead" + << (avatar->needsImpostorUpdate() ? " needs " : " _does_not_need_ ") << "impostor update" + << (avatar->isVisible() ? " is " : " _is_not_ ") << "visible" + << (avatar->isImpostor() ? " is " : " is not ") << "impostor" + << (avatar->isTooComplex() ? " is " : " is not ") << "too complex" + << LL_ENDL; + } } LLCharacter::sAllowInstancesChange = TRUE ; } -BOOL LLVOAvatar::isImpostor() -{ - return sUseImpostors && (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE; -} - BOOL LLVOAvatar::needsImpostorUpdate() const { @@ -8138,16 +8123,21 @@ void LLVOAvatar::updateImpostorRendering(U32 newMaxNonImpostorsValue) } // the sUseImpostors flag depends on whether or not sMaxNonImpostors is set to the no-limit value (0) sUseImpostors = (0 != sMaxNonImpostors); - - LL_DEBUGS("AvatarRender") - << "was " << (oldflg ? "use" : "don't use" ) << " impostors (max " << oldmax << "); " - << "now " << (sUseImpostors ? "use" : "don't use" ) << " impostors (max " << sMaxNonImpostors << "); " - << LL_ENDL; + if ( oldflg != sUseImpostors ) + { + LL_DEBUGS("AvatarRender") + << "was " << (oldflg ? "use" : "don't use" ) << " impostors (max " << oldmax << "); " + << "now " << (sUseImpostors ? "use" : "don't use" ) << " impostors (max " << sMaxNonImpostors << "); " + << LL_ENDL; + } } void LLVOAvatar::idleUpdateRenderComplexity() { + // Render Complexity + calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO)) { std::string info_line; @@ -8168,12 +8158,9 @@ void LLVOAvatar::idleUpdateRenderComplexity() /* * NOTE: the logic for whether or not each of the values below - * controls muting MUST match that in the isVisuallyMuted method. + * controls muting MUST match that in the isVisuallyMuted and isTooComplex methods. */ - // Render Complexity - calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed - static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); info_line = llformat("%d Complexity", mVisualComplexity); @@ -8195,7 +8182,7 @@ 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((sMaxNonImpostors > 0 && mVisibilityRank > sMaxNonImpostors) ? LLColor4::grey : LLColor4::white); + info_color.set(isImpostor() ? LLColor4::grey : LLColor4::white); info_style = LLFontGL::NORMAL; mText->addLine(info_line, info_color, info_style); @@ -8242,6 +8229,13 @@ void LLVOAvatar::idleUpdateRenderComplexity() } +void LLVOAvatar::updateVisualComplexity() +{ + LL_DEBUGS("AvatarRender") << "avatar " << this->getID() << " appearance changed" << LL_ENDL; + // Set the cache time to in the past so it's updated ASAP + mVisualComplexityStale = true; +} + // Calculations for mVisualComplexity value void LLVOAvatar::calculateUpdateRenderComplexity() { @@ -8252,8 +8246,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() if (mVisualComplexityStale) { - mVisualComplexityStale = FALSE; - U32 cost = 0; + U32 cost = VISUAL_COMPLEXITY_UNKNOWN; LLVOVolume::texture_cost_t textures; for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) @@ -8357,7 +8350,21 @@ void LLVOAvatar::calculateUpdateRenderComplexity() } } + if ( cost != mVisualComplexity ) + { + LL_DEBUGS("AvatarRender") << "Avatar "<< getID() + << " complexity updated was " << mVisualComplexity << " now " << cost + << " reported " << mReportedVisualComplexity + << LL_ENDL; + } + { + LL_DEBUGS("AvatarRender") << "Avatar "<< getID() + << " complexity updated no change " << mVisualComplexity + << " reported " << mReportedVisualComplexity + << LL_ENDL; + } mVisualComplexity = cost; + mVisualComplexityStale = false; } } @@ -8383,10 +8390,7 @@ LLColor4 LLVOAvatar::calcMutedAVColor(const LLUUID av_id) new_color.normalize(); new_color *= 0.5f; // Tone it down - LL_DEBUGS("AvatarRender") << "avatar "<< av_id << " color " << std::setprecision(3) << color_value << " returning color " << new_color - << " using indexes " << spectrum_index_1 << ", " << spectrum_index_2 - << " and fractBetween " << fractBetween - << LL_ENDL; + LL_DEBUGS("AvatarRender") << "avatar "<< av_id << " muted color " << std::setprecision(3) << new_color << LL_ENDL; return new_color; } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index aa1dc43a11..48f7ea92e1 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -253,7 +253,8 @@ public: void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font); void idleUpdateRenderComplexity(); void calculateUpdateRenderComplexity(); - void updateVisualComplexity() { mVisualComplexityStale = TRUE; } + static const S32 VISUAL_COMPLEXITY_UNKNOWN; + void updateVisualComplexity(); S32 getVisualComplexity() { return mVisualComplexity; }; // Numbers calculated here by rendering AV S32 getAttachmentGeometryBytes() { return mAttachmentGeometryBytes; }; // number of bytes in attached geometry @@ -303,6 +304,8 @@ public: //-------------------------------------------------------------------- public: BOOL isFullyLoaded() const; + bool isTooComplex() const; + bool isImpostor(const U32 rank_factor = 1) const; bool visualParamWeightsAreDefault(); virtual bool getIsCloud() const; BOOL isFullyTextured() const; @@ -335,8 +338,6 @@ private: BOOL mPreviousFullyLoaded; BOOL mFullyLoadedInitialized; S32 mFullyLoadedFrameCounter; - S32 mVisualComplexity; - BOOL mVisualComplexityStale; LLColor4 mMutedAVColor; LLFrameTimer mFullyLoadedTimer; LLFrameTimer mRuthTimer; @@ -384,7 +385,6 @@ public: public: U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0); bool isVisuallyMuted() const; - void setCachedVisualMute(bool muted) { mCachedVisualMute = muted; }; void forceUpdateVisualMuteSettings(); enum VisualMuteSettings @@ -409,8 +409,6 @@ public: S32 mAttachmentGeometryBytes; //number of bytes in attached geometry F32 mAttachmentSurfaceArea; //estimated surface area of attachments - S32 mReportedVisualComplexity; // Numbers as reported by the SL server - private: bool shouldAlphaMask(); @@ -420,9 +418,11 @@ private: S32 mUpdatePeriod; S32 mNumInitFaces; //number of faces generated when creating the avatar drawable, does not inculde splitted faces due to long vertex buffer. - // the isVisuallyMuted method uses these mutable values to avoid recalculating too frequently - mutable bool mCachedVisualMute; // cached return value for isVisuallyMuted() - mutable F64 mCachedVisualMuteUpdateTime; // Time to update mCachedVisualMute + // the isTooComplex method uses these mutable values to avoid recalculating too frequently + mutable S32 mVisualComplexity; + mutable bool mVisualComplexityStale; + S32 mReportedVisualComplexity; // from other viewers through the simulator + VisualMuteSettings mVisuallyMuteSetting; // Always or never visually mute this AV @@ -464,7 +464,6 @@ private: // Impostors //-------------------------------------------------------------------- public: - BOOL isImpostor(); BOOL needsImpostorUpdate() const; const LLVector3& getImpostorOffset() const; const LLVector2& getImpostorDim() const; @@ -699,7 +698,6 @@ private: public: BOOL isVisible() const; void setVisibilityRank(U32 rank); - U32 getVisibilityRank() const { return mVisibilityRank; } // unused static S32 sNumVisibleAvatars; // Number of instances of this class /** Appearance ** ** diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index d0bdd5bc03..32ccc75d39 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -434,7 +434,7 @@ BOOL LLVOAvatarSelf::buildMenus() ++iter) { LLViewerJointAttachment* attachment = iter->second; - if (attachment->getGroup() == i) + if (attachment && attachment->getGroup() == i) { LLMenuItemCallGL::Params item_params; @@ -473,7 +473,7 @@ BOOL LLVOAvatarSelf::buildMenus() ++iter) { LLViewerJointAttachment* attachment = iter->second; - if (attachment->getGroup() == i) + if (attachment && attachment->getGroup() == i) { LLMenuItemCallGL::Params item_params; std::string sub_piemenu_name = attachment->getName(); @@ -506,7 +506,7 @@ BOOL LLVOAvatarSelf::buildMenus() ++iter) { LLViewerJointAttachment* attachment = iter->second; - if (attachment->getGroup() == 8) + if (attachment && attachment->getGroup() == 8) { LLMenuItemCallGL::Params item_params; std::string sub_piemenu_name = attachment->getName(); @@ -608,7 +608,7 @@ BOOL LLVOAvatarSelf::buildMenus() ++iter) { LLViewerJointAttachment* attachment = iter->second; - if(attachment->getGroup() == group) + if(attachment && attachment->getGroup() == group) { // use multimap to provide a partial order off of the pie slice key S32 pie_index = attachment->getPieSlice(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 6002b5a4eb..0536a2bbcf 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -11294,6 +11294,17 @@ static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_RESIZE("Impostor Resize"); void LLPipeline::generateImpostor(LLVOAvatar* avatar) { + LL_WARNS("AvatarRenderPipeline"); + if (avatar) + { + LL_CONT << "Avatar " << avatar->getID() << " is " << (avatar->mDrawable?"":"not ") << "drawable"; + } + else + { + LL_CONT << " is null"; + } + LL_CONT << LL_ENDL; + LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); @@ -11310,10 +11321,17 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) assertInitialized(); bool visually_muted = avatar->isVisuallyMuted(); + LL_DEBUGS("AvatarRenderPipeline") << "Avatar " << avatar->getID() + << " is " << ( visually_muted ? "" : "not ") << "visually muted" + << LL_ENDL; + bool too_complex = avatar->isTooComplex(); + LL_DEBUGS("AvatarRenderPipeline") << "Avatar " << avatar->getID() + << " is " << ( too_complex ? "" : "not ") << "too complex" + << LL_ENDL; pushRenderTypeMask(); - if (visually_muted) + if (visually_muted || too_complex) { andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); } @@ -11358,7 +11376,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) { LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_MARK_VISIBLE); markVisible(avatar->mDrawable, *viewer_camera); - LLVOAvatar::sUseImpostors = false; // @TODO why? + LLVOAvatar::sUseImpostors = false; // @TODO ??? LLVOAvatar::attachment_map_t::iterator iter; for (iter = avatar->mAttachmentPoints.begin(); @@ -11471,7 +11489,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha; - if (visually_muted) + if (visually_muted || too_complex) { //disable alpha masking for muted avatars (get whole skin silhouette) LLDrawPoolAvatar::sMinimumAlpha = 0.f; } @@ -11533,7 +11551,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLGLDisable blend(GL_BLEND); - if (visually_muted) + if (too_complex) { gGL.setColorMask(true, true); } @@ -11562,14 +11580,16 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) } - if (LLMuteList::getInstance()->isMuted(avatar->getID())) - { //grey muted avatar - gGL.diffuseColor4ub(64,64,64,255); - } - else + if (avatar->isTooComplex()) { // Visually muted avatar + LL_DEBUGS("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " set jellybaby" << LL_ENDL; gGL.diffuseColor4fv( avatar->getMutedAVColor().mV ); } + else + { //grey muted avatar + LL_DEBUGS("AvatarRenderPipeline") << "Avatar " << avatar->getID() << " set grey" << LL_ENDL; + gGL.diffuseColor4ub(64,64,64,255); + } { gGL.begin(LLRender::QUADS); @@ -11595,7 +11615,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) avatar->setImpostorDim(tdim); - LLVOAvatar::sUseImpostors = true; // @TODO why? + LLVOAvatar::sUseImpostors = true; // @TODO ??? sUseOcclusion = occlusion; sReflectionRender = FALSE; sImpostorRender = FALSE; -- cgit v1.2.3