summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcharacter/llcharacter.cpp21
-rw-r--r--indra/llcharacter/llcharacter.h20
-rw-r--r--indra/llcharacter/llvisualparam.cpp2
-rw-r--r--indra/newview/app_settings/settings.xml13
-rw-r--r--indra/newview/character/avatar_lad.xml2
-rw-r--r--indra/newview/lltexlayer.cpp20
-rw-r--r--indra/newview/lltexlayer.h2
-rw-r--r--indra/newview/llvoavatar.cpp86
-rw-r--r--indra/newview/llvoavatar.h1
9 files changed, 115 insertions, 52 deletions
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index 40a9752268..27c0c0b640 100644
--- a/indra/llcharacter/llcharacter.cpp
+++ b/indra/llcharacter/llcharacter.cpp
@@ -389,27 +389,6 @@ void LLCharacter::clearVisualParamWeights()
}
//-----------------------------------------------------------------------------
-// BOOL visualParamWeightsAreDefault()
-//-----------------------------------------------------------------------------
-BOOL LLCharacter::visualParamWeightsAreDefault()
-{
- for (LLVisualParam *param = getFirstVisualParam();
- param;
- param = getNextVisualParam())
- {
- if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
- {
- if (param->getWeight() != param->getDefaultWeight())
- return false;
- }
- }
-
- return true;
-}
-
-
-
-//-----------------------------------------------------------------------------
// getVisualParam()
//-----------------------------------------------------------------------------
LLVisualParam* LLCharacter::getVisualParam(const char *param_name)
diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h
index 27e2a51c62..cac73c01b9 100644
--- a/indra/llcharacter/llcharacter.h
+++ b/indra/llcharacter/llcharacter.h
@@ -212,12 +212,9 @@ public:
F32 getVisualParamWeight(const char* param_name);
F32 getVisualParamWeight(S32 index);
- // set all morph weights to 0
+ // set all morph weights to defaults
void clearVisualParamWeights();
- // see if all the weights are default
- BOOL visualParamWeightsAreDefault();
-
// visual parameter accessors
LLVisualParam* getFirstVisualParam()
{
@@ -231,6 +228,21 @@ public:
return (mCurIterator++)->second;
}
+ S32 getVisualParamCountInGroup(const EVisualParamGroup group) const
+ {
+ S32 rtn = 0;
+ for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
+ iter != mVisualParamIndexMap.end();
+ /**/ )
+ {
+ if ((iter++)->second->getGroup() == group)
+ {
+ ++rtn;
+ }
+ }
+ return rtn;
+ }
+
LLVisualParam* getVisualParam(S32 id) const
{
visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(id);
diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp
index 297322fe58..703fe2f9cc 100644
--- a/indra/llcharacter/llvisualparam.cpp
+++ b/indra/llcharacter/llvisualparam.cpp
@@ -284,7 +284,7 @@ void LLVisualParam::setAnimationTarget(F32 target_value, BOOL upload_bake)
void LLVisualParam::setNextParam( LLVisualParam *next )
{
llassert(!mNext);
-
+ llassert(getWeight() == getDefaultWeight()); // need to establish mNext before we start changing values on this, else initial value won't get mirrored (we can fix that, but better to forbid this pattern)
mNext = next;
}
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index c2f110e8fc..a2fae41918 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -632,7 +632,18 @@
<key>BlockAvatarAppearanceMessages</key>
<map>
<key>Comment</key>
- <string>Ignore's appearance messages (for simulating Ruth)</string>
+ <string>Ignores appearance messages (for simulating Ruth)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>BlockSomeAvatarAppearanceVisualParams</key>
+ <map>
+ <key>Comment</key>
+ <string>Drop around 50% of VisualParam occurances in appearance messages (for simulating Ruth)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml
index 5efd997ab7..9564236ad2 100644
--- a/indra/newview/character/avatar_lad.xml
+++ b/indra/newview/character/avatar_lad.xml
@@ -4782,7 +4782,7 @@
group="1"
name="Saddlebags"
wearable="shape"
- edit_grouo="driven"
+ edit_group="driven"
value_min="-.5"
value_max="3">
<param_morph>
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 7290849fca..b13f9e3898 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -87,7 +87,7 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner,
mNeedsUpdate(TRUE),
mNeedsUpload(FALSE),
mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates
- mNeedsLowResUpload(TRUE),
+ mDebugNumLowresUploads(0),
mTexLayerSet(owner)
{
LLTexLayerSetBuffer::sGLByteCount += getSize();
@@ -141,12 +141,12 @@ void LLTexLayerSetBuffer::requestUpload()
// If we requested a new upload but haven't even uploaded
// a low res version of our last upload request, then
// keep the timer ticking instead of resetting it.
- if (mNeedsUpload && mNeedsLowResUpload)
+ if (mNeedsUpload && (mDebugNumLowresUploads == 0))
{
mNeedsUploadTimer.reset();
}
mNeedsUpload = TRUE;
- mNeedsLowResUpload = TRUE;
+ mDebugNumLowresUploads = 0;
mUploadPending = TRUE;
mNeedsUploadTimer.unpause();
}
@@ -292,7 +292,7 @@ BOOL LLTexLayerSetBuffer::isReadyToUpload() const
// If we hit our timeout and have textures available at even lower resolution, then upload.
const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout;
const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
- if (has_lower_lod && is_upload_textures_timeout && mNeedsLowResUpload) return TRUE;
+ if (has_lower_lod && is_upload_textures_timeout) return TRUE;
}
return FALSE;
}
@@ -434,12 +434,18 @@ void LLTexLayerSetBuffer::readBackAndUpload()
if (highest_lod)
{
+ // Got the final LOD for the baked texture.
+ // All done, pause the upload timer so we know how long it took.
mNeedsUpload = FALSE;
mNeedsUploadTimer.pause();
}
else
{
- mNeedsLowResUpload = FALSE;
+ // Got a lower level LOD for the baked texture.
+ // Restart the upload timer.
+ mDebugNumLowresUploads++;
+ mNeedsUploadTimer.unpause();
+ mNeedsUploadTimer.reset();
}
}
else
@@ -2235,11 +2241,11 @@ const std::string LLTexLayerSetBuffer::dumpTextureInfo() const
if (!isAgentAvatarValid()) return "";
const BOOL is_high_res = !mNeedsUpload;
- const BOOL is_low_res = !mNeedsLowResUpload;
+ const U32 num_low_res = mDebugNumLowresUploads;
const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32();
const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(mTexLayerSet);
std::string text = llformat("[ HiRes:%d LoRes:%d Timer:%d ] %s",
- is_high_res, is_low_res, upload_time,
+ is_high_res, num_low_res, upload_time,
local_texture_info.c_str());
return text;
}
diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h
index 8f386b5a19..313c5f24e1 100644
--- a/indra/newview/lltexlayer.h
+++ b/indra/newview/lltexlayer.h
@@ -360,7 +360,7 @@ private:
BOOL mNeedsUpdate; // Whether we need to update our baked textures
BOOL mNeedsUpload; // Whether we need to send our baked textures to the server
- BOOL mNeedsLowResUpload; // Whether we have sent a lowres version of our baked textures to the server
+ U32 mDebugNumLowresUploads; // Number of times we've sent a lowres version of our baked textures to the server
BOOL mUploadPending; // Whether we have received back the new baked textures
LLUUID mUploadID; // Identifies the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit)
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 14267d10ff..4217590ef5 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -6529,6 +6529,42 @@ void LLVOAvatar::onFirstTEMessageReceived()
}
//-----------------------------------------------------------------------------
+// bool visualParamWeightsAreDefault()
+//-----------------------------------------------------------------------------
+bool LLVOAvatar::visualParamWeightsAreDefault()
+{
+ bool rtn = true;
+
+ bool is_wearing_skirt = isWearingWearableType(LLWearableType::WT_SKIRT);
+ for (LLVisualParam *param = getFirstVisualParam();
+ param;
+ param = getNextVisualParam())
+ {
+ if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
+ {
+ if (param->getWeight() != param->getDefaultWeight() &&
+ // we have to not care whether skirt weights are default, if we're not actually wearing a skirt
+ (is_wearing_skirt ||
+ (param->getName() != "skirt length" &&
+ param->getName() != "slit front" &&
+ param->getName() != "slit back" &&
+ param->getName() != "slit left" &&
+ param->getName() != "slit right")))
+ {
+ //llinfos << "param '" << param->getName() << "'=" << param->getWeight() << " which differs from default=" << param->getDefaultWeight() << llendl;
+ rtn = false;
+ break;
+ }
+ }
+ }
+
+ //llinfos << "params are default ? " << int(rtn) << llendl;
+
+ return rtn;
+}
+
+
+//-----------------------------------------------------------------------------
// processAvatarAppearance()
//-----------------------------------------------------------------------------
void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
@@ -6596,16 +6632,17 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
{
releaseComponentTextures();
}
-
-
+
// parse visual params
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
- if( num_blocks > 1 )
+ bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (random()%2)!=0; // pretend that ~50% of AvatarAppearance messages arrived without a VisualParam block, for testing
+ if( num_blocks > 1 && !drop_visual_params_debug)
{
BOOL params_changed = FALSE;
BOOL interp_params = FALSE;
- LLVisualParam* param = getFirstVisualParam();
+ LLVisualParam* param = getFirstVisualParam(); // why do we peel away and ignore the first VisualParam?
+ llassert(param); // if this ever fires, we should do the same as when num_blocks<=1
if (!param)
{
llwarns << "No visual params!" << llendl;
@@ -6621,8 +6658,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
if( !param )
{
- llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl;
- return;
+ // more visual params supplied than expected - just process what we know about
+ break;
}
U8 value;
@@ -6647,14 +6684,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
}
}
- while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) )
+ const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE);
+ if (num_blocks != expected_tweakable_count)
{
- param = getNextVisualParam();
- }
- if( param )
- {
- llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl;
- return;
+ llwarns << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << "). Processing what we can. object: " << getID() << llendl;
}
if (params_changed)
@@ -6671,16 +6704,37 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
updateSexDependentLayerSets( FALSE );
}
}
+
+ llassert( getSex() == ((getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE) );
}
else
{
- llwarns << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl;
+ // AvatarAppearance message arrived without visual params
+ if (drop_visual_params_debug)
+ {
+ llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << llendl;
+ }
+ else
+ {
+ llinfos << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl;
+ }
+
+ // this isn't really a problem if we already have a non-default shape
+ if (visualParamWeightsAreDefault())
+ {
+ // re-request appearance, hoping that it comes back with a shape next time
+ llinfos << "Re-requesting AvatarAppearance for object: " << getID() << llendl;
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID());
+ }
+ else
+ {
+ llinfos << "That's okay, we already have a non-default shape for object: " << getID() << llendl;
+ // we don't really care.
+ }
}
setCompositeUpdatesEnabled( TRUE );
- llassert( getSex() == ((getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE) );
-
// If all of the avatars are completely baked, release the global image caches to conserve memory.
LLVOAvatar::cullAvatarsByPixelArea();
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index fdda3bdd37..27b3ffca39 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -249,6 +249,7 @@ public:
//--------------------------------------------------------------------
public:
BOOL isFullyLoaded() const;
+ bool visualParamWeightsAreDefault();
protected:
virtual BOOL getIsCloud();
BOOL updateIsFullyLoaded();