diff options
| -rw-r--r-- | indra/llappearance/llavatarappearancedefines.cpp | 1 | ||||
| -rw-r--r-- | indra/llappearance/llavatarappearancedefines.h | 1 | ||||
| -rw-r--r-- | indra/newview/VIEWER_VERSION.txt | 2 | ||||
| -rw-r--r-- | indra/newview/llcontrolavatar.cpp | 77 | ||||
| -rw-r--r-- | indra/newview/llcontrolavatar.h | 7 | ||||
| -rw-r--r-- | indra/newview/lldrawable.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolavatar.cpp | 27 | ||||
| -rw-r--r-- | indra/newview/llfloaterpreference.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llviewermenu.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llviewerpartsource.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 917 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.h | 64 | ||||
| -rw-r--r-- | indra/newview/llvoavatarself.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llvoavatarself.h | 2 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 9 | ||||
| -rw-r--r-- | scripts/content_tools/arche_tool.py | 21 | 
16 files changed, 828 insertions, 314 deletions
| diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp index 9398ce3822..2bcfd06c40 100644 --- a/indra/llappearance/llavatarappearancedefines.cpp +++ b/indra/llappearance/llavatarappearancedefines.cpp @@ -30,7 +30,6 @@  const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 1024;  const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 1024; -const S32 LLAvatarAppearanceDefines::IMPOSTOR_PERIOD = 2;  using namespace LLAvatarAppearanceDefines; diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h index 8968187531..49dfbebeea 100644 --- a/indra/llappearance/llavatarappearancedefines.h +++ b/indra/llappearance/llavatarappearancedefines.h @@ -39,7 +39,6 @@ namespace LLAvatarAppearanceDefines  extern const S32 SCRATCH_TEX_WIDTH;  extern const S32 SCRATCH_TEX_HEIGHT; -extern const S32 IMPOSTOR_PERIOD;  static const U32 AVATAR_HOVER = 11001; diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 0438a6cd91..df41a3918c 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.4.13 +6.4.14 diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 5a6b66df52..fab249f988 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -78,6 +78,24 @@ void LLControlAvatar::initInstance()      mInitFlags |= 1<<4;  } +const LLVOAvatar *LLControlAvatar::getAttachedAvatar() const +{ +	if (mRootVolp && mRootVolp->isAttachment()) +	{ +		return mRootVolp->getAvatarAncestor(); +	} +	return NULL; +} + +LLVOAvatar *LLControlAvatar::getAttachedAvatar() +{ +	if (mRootVolp && mRootVolp->isAttachment()) +	{ +		return mRootVolp->getAvatarAncestor(); +	} +	return NULL; +} +  void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_scale_fixup) const  { @@ -165,7 +183,7 @@ void LLControlAvatar::matchVolumeTransform()          if (mRootVolp->isAttachment())          { -            LLVOAvatar *attached_av = mRootVolp->getAvatarAncestor(); +            LLVOAvatar *attached_av = getAttachedAvatar();              if (attached_av)              {                  LLViewerJointAttachment *attach = attached_av->getTargetAttachmentPoint(mRootVolp); @@ -360,7 +378,34 @@ void LLControlAvatar::idleUpdate(LLAgent &agent, const F64 &time)      }  } -BOOL LLControlAvatar::updateCharacter(LLAgent &agent) +bool LLControlAvatar::computeNeedsUpdate() +{ +	computeUpdatePeriod(); + +	// Animesh attachments are a special case. Should have the same update cadence as their attached parent avatar. +	LLVOAvatar *attached_av = getAttachedAvatar(); +	if (attached_av) +	{ +		// Have to run computeNeedsUpdate() for attached av in +		// case it hasn't run updateCharacter() already this +		// frame.  Note this means that the attached av will +		// run computeNeedsUpdate() multiple times per frame +		// if it has animesh attachments. Results will be +		// consistent except for the corner case of exceeding +		// MAX_IMPOSTOR_INTERVAL in one call but not another, +		// which should be rare. +		attached_av->computeNeedsUpdate(); +		mNeedsImpostorUpdate = attached_av->mNeedsImpostorUpdate; +		if (mNeedsImpostorUpdate) +		{ +			mLastImpostorUpdateReason = 12; +		} +		return mNeedsImpostorUpdate; +	} +	return LLVOAvatar::computeNeedsUpdate(); +} + +bool LLControlAvatar::updateCharacter(LLAgent &agent)  {      return LLVOAvatar::updateCharacter(agent);  } @@ -634,29 +679,23 @@ std::string LLControlAvatar::getFullname() const  // virtual  bool LLControlAvatar::shouldRenderRigged() const  { -    if (mRootVolp && mRootVolp->isAttachment()) -    { -        LLVOAvatar *attached_av = mRootVolp->getAvatarAncestor(); -        if (attached_av) -        { -            return attached_av->shouldRenderRigged(); -        } -    } +	const LLVOAvatar *attached_av = getAttachedAvatar(); +	if (attached_av) +	{ +		return attached_av->shouldRenderRigged(); +	}      return true;  }  // virtual  BOOL LLControlAvatar::isImpostor()  { -    if (mRootVolp && mRootVolp->isAttachment()) -    { -		// Attached animated objects should match state of their attached av. -        LLVOAvatar *attached_av = mRootVolp->getAvatarAncestor(); -		if (attached_av) -		{ -			return attached_av->isImpostor(); -		} -    } +	// Attached animated objects should match state of their attached av. +	LLVOAvatar *attached_av = getAttachedAvatar(); +	if (attached_av) +	{ +		return attached_av->isImpostor(); +	}  	return LLVOAvatar::isImpostor();  } diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h index 288d07cd48..8e87299f3e 100644 --- a/indra/newview/llcontrolavatar.h +++ b/indra/newview/llcontrolavatar.h @@ -40,6 +40,10 @@ public:  	virtual void 			initInstance(); // Called after construction to initialize the class.  	virtual	~LLControlAvatar(); +	// If this is an attachment, return the avatar it is attached to. Otherwise NULL. +	virtual const LLVOAvatar *getAttachedAvatar() const; +	virtual LLVOAvatar *getAttachedAvatar(); +	      void getNewConstraintFixups(LLVector3& new_pos_constraint, F32& new_scale_constraint) const;      void matchVolumeTransform();      void updateVolumeGeom(); @@ -53,7 +57,8 @@ public:      void markForDeath();      virtual void idleUpdate(LLAgent &agent, const F64 &time); -	virtual BOOL updateCharacter(LLAgent &agent); +	virtual bool computeNeedsUpdate(); +	virtual bool updateCharacter(LLAgent &agent);      void getAnimatedVolumes(std::vector<LLVOVolume*>& volumes);      void updateAnimations();   diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 2219f20272..5034bd1c5e 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -1485,7 +1485,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*  				LLVOAvatar* avatarp = (LLVOAvatar*) objparent;  				if (avatarp->isVisible())  				{ -					impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor(); +					impostor = objparent->isAvatar() && !LLPipeline::sImpostorRender && ((LLVOAvatar*) objparent)->isImpostor();  					loaded   = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isFullyLoaded();  				}  				else @@ -1569,7 +1569,8 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)  	if (mDrawable->getVObj())  	{ -		if (mDrawable->getVObj()->isAttachment()) +		// Don't update if we are part of impostor, unles it's an impostor pass +		if (!LLPipeline::sImpostorRender && mDrawable->getVObj()->isAttachment())  		{  			LLDrawable* parent = mDrawable->getParent();  			if (parent && parent->getVObj()) diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 87772d9eb6..687b13d2c8 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -572,12 +572,12 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)  	{  		return;  	} - -	BOOL impostor = avatarp->isImpostor(); -	if (impostor  -		&& LLVOAvatar::AV_DO_NOT_RENDER != avatarp->getVisualMuteSettings() -		&& LLVOAvatar::AV_ALWAYS_RENDER != avatarp->getVisualMuteSettings()) +	LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance(); +	BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor(); +	if (oa == LLVOAvatar::AOA_INVISIBLE || +		(impostor && oa == LLVOAvatar::AOA_JELLYDOLL))  	{ +		// No shadows for jellydolled or invisible avs.  		return;  	} @@ -1464,7 +1464,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		return;  	} -	LLVOAvatar *avatarp; +	LLVOAvatar *avatarp = NULL;  	if (single_avatar)  	{ @@ -1510,11 +1510,12 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		return;  	} -	BOOL impostor = avatarp->isImpostor() && !single_avatar; +	BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor() && !single_avatar;  	if (( avatarp->isInMuteList()   		  || impostor  -		  || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()) ) && pass != 0) +		  || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()) ) && pass != 0) +//		  || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()) ) && pass != 0)  	{ //don't draw anything but the impostor for impostored avatars  		return;  	} @@ -1524,6 +1525,13 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		return;  	} +	LLVOAvatar *attached_av = avatarp->getAttachedAvatar(); +	if (attached_av && LLVOAvatar::AOA_NORMAL != attached_av->getOverallAppearance()) +	{ +		// Animesh attachment of a jellydolled or invisible parent - don't show +		return; +	} +  	if (pass == 0)  	{  		if (!LLPipeline::sReflectionRender) @@ -1531,7 +1539,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  			LLVOAvatar::sNumVisibleAvatars++;  		} -		if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate())) +//		if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate())) +		if (impostor || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()))  		{  			if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete())   			{ diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index c17e1d38f8..6bf2136f60 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1355,7 +1355,7 @@ void LLAvatarComplexityControls::setIndirectMaxNonImpostors()  {  	U32 max_non_impostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors");  	// for this one, we just need to make zero, which means off, the max value of the slider -	U32 indirect_max_non_impostors = (0 == max_non_impostors) ? LLVOAvatar::IMPOSTORS_OFF : max_non_impostors; +	U32 indirect_max_non_impostors = (0 == max_non_impostors) ? LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER : max_non_impostors;  	gSavedSettings.setU32("IndirectMaxNonImpostors", indirect_max_non_impostors);  } @@ -1778,7 +1778,7 @@ void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()  	LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors",true);  	U32 value = ctrl->getValue().asInteger(); -	if (0 == value || LLVOAvatar::IMPOSTORS_OFF <= value) +	if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value)  	{  		value=0;  	} diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c385e90d81..eef48ad083 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3184,6 +3184,7 @@ class LLObjectMute : public view_listener_t  		if (avatar)  		{  			avatar->mNeedsImpostorUpdate = TRUE; +			avatar->mLastImpostorUpdateReason = 9;  			id = avatar->getID(); diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index 998ae52fe0..f042040e98 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -136,7 +136,7 @@ void LLViewerPartSourceScript::update(const F32 dt)  	{  		mOwnerAvatarp = find_avatar(mOwnerUUID);  	} -	if (mOwnerAvatarp.notNull() && LLVOAvatar::AV_DO_NOT_RENDER == mOwnerAvatarp->getVisualMuteSettings()) +	if (mOwnerAvatarp.notNull() && LLVOAvatar::AOA_NORMAL != mOwnerAvatarp->getOverallAppearance())  	{  		return;  	} diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index b205823820..f69b9b3861 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -207,6 +207,8 @@ enum ERenderName  	RENDER_NAME_FADE  }; +#define JELLYDOLLS_SHOULD_IMPOSTOR +  //-----------------------------------------------------------------------------  // Callback data  //----------------------------------------------------------------------------- @@ -574,7 +576,8 @@ private:  // Static Data  //-----------------------------------------------------------------------------  S32 LLVOAvatar::sFreezeCounter = 0; -U32 LLVOAvatar::sMaxNonImpostors = 12; // overridden based on graphics setting +U32 LLVOAvatar::sMaxNonImpostors = 12; // Set from RenderAvatarMaxNonImpostors +bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonImpostors is 0 (unlimited)  F32 LLVOAvatar::sRenderDistance = 256.f;  S32	LLVOAvatar::sNumVisibleAvatars = 0;  S32	LLVOAvatar::sNumLODChangesThisFrame = 0; @@ -601,7 +604,6 @@ BOOL LLVOAvatar::sShowFootPlane = FALSE;  BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE;  F32 LLVOAvatar::sLODFactor = 1.f;  F32 LLVOAvatar::sPhysicsLODFactor = 1.f; -bool LLVOAvatar::sUseImpostors = false; // overwridden by RenderAvatarMaxNonImpostors  BOOL LLVOAvatar::sJointDebug = FALSE;  F32 LLVOAvatar::sUnbakedTime = 0.f;  F32 LLVOAvatar::sUnbakedUpdateTime = 0.f; @@ -634,6 +636,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mMeshValid(FALSE),  	mVisible(FALSE),  	mLastImpostorUpdateFrameTime(0.f), +	mLastImpostorUpdateReason(0),  	mWindFreq(0.f),  	mRipplePhase( 0.f ),  	mBelowWater(FALSE), @@ -656,6 +659,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mNeedsSkin(FALSE),  	mLastSkinTime(0.f),  	mUpdatePeriod(1), +	mOverallAppearance(AOA_INVISIBLE),  	mVisualComplexityStale(true),  	mVisuallyMuteSetting(AV_RENDER_NORMALLY),  	mMutedAVColor(LLColor4::white /* used for "uninitialize" */), @@ -700,6 +704,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	setAnimationData("Speed", &mSpeed);  	mNeedsImpostorUpdate = TRUE; +	mLastImpostorUpdateReason = 0;  	mNeedsAnimUpdate = TRUE;  	mNeedsExtentUpdate = true; @@ -755,8 +760,8 @@ std::string LLVOAvatar::avString() const      }      else      { -	std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); -	return " Avatar '" + getFullname() + "' " + viz_string + " "; +		std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); +		return " Avatar '" + getFullname() + "' " + viz_string + " ";      }  } @@ -1075,6 +1080,7 @@ void LLVOAvatar::resetImpostors()  		LLVOAvatar* avatar = (LLVOAvatar*) *iter;  		avatar->mImpostor.release();  		avatar->mNeedsImpostorUpdate = TRUE; +		avatar->mLastImpostorUpdateReason = 1;  	}  } @@ -1319,72 +1325,84 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)      LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE);      S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); +    if (getOverallAppearance() != AOA_NORMAL) +    { +        if (isControlAvatar()) +        { +            // Animated objects don't show system avatar but do need to include rigged meshes in their bounding box. +            box_detail = 3; +        } +        else +        { +            // Jellydolled avatars ignore attachments, etc, use only system avatar. +            box_detail = 1; +        } +    }      // FIXME the update_min_max function used below assumes there is a      // known starting point, but in general there isn't. Ideally the      // box update logic should be modified to handle the no-point-yet      // case. For most models, starting with the pelvis is safe though.      LLVector3 zero_pos; -	LLVector4a pos; +    LLVector4a pos;      if (dist_vec(zero_pos, mPelvisp->getWorldPosition())<0.001)      {          // Don't use pelvis until av initialized -	pos.load3(getRenderPosition().mV); +        pos.load3(getRenderPosition().mV);      }      else      {          pos.load3(mPelvisp->getWorldPosition().mV);      } -	newMin = pos; -	newMax = pos; +    newMin = pos; +    newMax = pos; -	//stretch bounding box by joint positions. Doing this for -	//control avs, where the polymeshes aren't maintained or -	//displayed, can give inaccurate boxes due to joints stuck at (0,0,0). -    if ((box_detail>=1) && !isControlAvatar()) +    if (box_detail>=1 && !isControlAvatar())      { -	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); -		} -	} - +        //stretch bounding box by joint positions. Doing this for +        //control avs, where the polymeshes aren't maintained or +        //displayed, can give inaccurate boxes due to joints stuck at (0,0,0). +        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); +            } +        }      } -	// Pad bounding box for starting joint, plus polymesh if -	// applicable. Subsequent calcs should be accurate enough to not -	// need padding. -	LLVector4a padding(0.25); -	newMin.sub(padding); -	newMax.add(padding); +    // Pad bounding box for starting joint, plus polymesh if +    // applicable. Subsequent calcs should be accurate enough to not +    // need padding. +    LLVector4a padding(0.25); +    newMin.sub(padding); +    newMax.add(padding); -	//stretch bounding box by static attachments +    //stretch bounding box by static attachments      if (box_detail >= 2)      {          float max_attachment_span = get_default_max_prim_scale() * 5.0f; -	 -	for (attachment_map_t::iterator iter = mAttachmentPoints.begin();  -		 iter != mAttachmentPoints.end(); -		 ++iter) -	{ -		LLViewerJointAttachment* attachment = iter->second; +     +        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) -			{ +            if (attachment->getValid()) +            { +                for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +                     attachment_iter != attachment->mAttachedObjects.end(); +                     ++attachment_iter) +                {                      // Don't we need to look at children of attached_object as well? -                const LLViewerObject* attached_object = attachment_iter->get(); -				if (attached_object && !attached_object->isHUDAttachment()) -				{ +                    const LLViewerObject* attached_object = attachment_iter->get(); +                    if (attached_object && !attached_object->isHUDAttachment()) +                    {                          const LLVOVolume *vol = dynamic_cast<const LLVOVolume*>(attached_object);                          if (vol && vol->isAnimatedObject())                          { @@ -1406,39 +1424,39 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)                          {                              continue;                          } -					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]); -							} -						} -					} -				} -			} -		} -	} +                        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      if (box_detail>=3)      { -		updateRiggingInfo(); +        updateRiggingInfo();          for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++)          {              LLJoint *joint = getJoint(joint_num); @@ -2024,6 +2042,38 @@ void LLVOAvatar::resetVisualParams()  	}  } +void LLVOAvatar::applyDefaultParams() +{ +	// These are params from avs with newly created copies of shape, +	// skin, hair, eyes, plus gender set as noted. Run arche_tool.py +	// to get params from some other xml appearance dump. +	std::map<S32, U8> male_params = { +		{1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,255}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127} +	}; +	std::map<S32, U8> female_params = { +		{1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,0}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127} +	}; +	std::map<S32, U8> *params = NULL; +	if (getSex() == SEX_MALE) +		params = &male_params; +	else +		params = &female_params; +			 +	for( auto it = params->begin(); it != params->end(); ++it) +	{ +		LLVisualParam* param = getVisualParam(it->first); +		if( !param ) +		{ +			// invalid id +			break; +		} + +		U8 value = it->second; +		F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight()); +		param->setWeight(newWeight); +	} +} +  //-----------------------------------------------------------------------------  // resetSkeleton()  //----------------------------------------------------------------------------- @@ -2086,15 +2136,30 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)      }      // Reset tweakable params to preserved state -    if (mLastProcessedAppearance) -    { -    bool slam_params = true; -    applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params); -    } +	if (getOverallAppearance() == AOA_NORMAL) +	{ +		if (mLastProcessedAppearance) +		{ +			bool slam_params = true; +			applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params); +		} +	} +	else +	{ +		// Stripped down approximation of +		// applyParsedAppearanceMessage, but with alternative default +		// (jellydoll) params +		setCompositeUpdatesEnabled( FALSE ); +		gPipeline.markGLRebuild(this); +		applyDefaultParams(); +		setCompositeUpdatesEnabled( TRUE ); +		updateMeshTextures(); +		updateMeshVisibility(); +	}      updateVisualParams();      // Restore attachment pos overrides -    updateAttachmentOverrides(); +	updateAttachmentOverrides();      // Animations      if (reset_animations) @@ -2729,7 +2794,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)  	BOOL visible = isVisible() || mNeedsAnimUpdate;  	// update attachments positions -	if (detailed_update || !sUseImpostors) +	if (detailed_update)  	{  		LL_RECORD_BLOCK_TIME(FTM_ATTACHMENT_UPDATE);  		for (attachment_map_t::iterator iter = mAttachmentPoints.begin();  @@ -2789,6 +2854,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)  			if (angle_diff > F_PI/512.f*distance*mUpdatePeriod)  			{  				mNeedsImpostorUpdate = TRUE; +				mLastImpostorUpdateReason = 2;  			}  		} @@ -2800,6 +2866,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)  			if (dist_diff/mImpostorDistance > 0.1f)  			{  				mNeedsImpostorUpdate = TRUE; +				mLastImpostorUpdateReason = 3;  			}  			else  			{ @@ -2812,6 +2879,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)  				if (diff.getLength3().getF32() > 0.05f)  				{  					mNeedsImpostorUpdate = TRUE; +					mLastImpostorUpdateReason = 4;  				}  				else  				{ @@ -2819,6 +2887,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)  					if (diff.getLength3().getF32() > 0.05f)  					{  						mNeedsImpostorUpdate = TRUE; +						mLastImpostorUpdateReason = 5;  					}  				}  			} @@ -2827,13 +2896,13 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)      if (mDrawable.notNull())      { -	mDrawable->movePartition(); +		mDrawable->movePartition(); -	//force a move if sitting on an active object -	if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) -	{ -		gPipeline.markMoved(mDrawable, TRUE); -	} +		//force a move if sitting on an active object +		if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) +		{ +			gPipeline.markMoved(mDrawable, TRUE); +		}      }  } @@ -3562,14 +3631,19 @@ bool LLVOAvatar::isVisuallyMuted()  			muted = false;  		}  		else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER) -		{	// Always want to see this AV as an impostor +		{ +#ifdef JELLYDOLLS_SHOULD_IMPOSTOR  			muted = true; +			// Always want to see this AV as an impostor +#else +			muted = false; +#endif  		}          else if (isInMuteList())          {              muted = true;          } -		else +		else   		{  			muted = isTooComplex();  		} @@ -3578,7 +3652,7 @@ bool LLVOAvatar::isVisuallyMuted()  	return muted;  } -bool LLVOAvatar::isInMuteList() +bool LLVOAvatar::isInMuteList() const  {  	bool muted = false;  	F64 now = LLFrameTimer::getTotalSeconds(); @@ -3640,9 +3714,14 @@ void LLVOAvatar::updateAppearanceMessageDebugText()  		if (hover_offset[2] != 0.0)  		{  			debug_line += llformat(" hov_z: %.3f", hover_offset[2]); -        debug_line += llformat(" %s", (isSitting() ? "S" : "T")); +			debug_line += llformat(" %s", (isSitting() ? "S" : "T"));  			debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-"));  		} +		if (mInAir) +		{ +			debug_line += " A"; +			 +		}          LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition();  		LLVector3 normal; @@ -3655,9 +3734,38 @@ void LLVOAvatar::updateAppearanceMessageDebugText()          LLVector3 pelvis_pos = mPelvisp->getPosition();          debug_line += llformat(" rp %.3f pp %.3f", root_pos[2], pelvis_pos[2]); -    S32 is_visible = (S32) isVisible(); -    S32 is_m_visible = (S32) mVisible; -    debug_line += llformat(" v %d/%d", is_visible, is_m_visible); +		const LLVector3& scale = getScale(); +		debug_line += llformat(" scale-z %.3f", scale[2]); +		S32 is_visible = (S32) isVisible(); +		S32 is_m_visible = (S32) mVisible; +		debug_line += llformat(" v %d/%d", is_visible, is_m_visible); + +		AvatarOverallAppearance aoa = getOverallAppearance(); +		if (aoa == AOA_NORMAL) +		{ +			debug_line += " N"; +		} +		else if (aoa == AOA_JELLYDOLL) +		{ +			debug_line += " J"; +		} +		else +		{ +			debug_line += " I"; +		} + +		if (mMeshValid) +		{ +			debug_line += "m"; +		} +		else +		{ +			debug_line += "-"; +		} +		if (isImpostor()) +		{ +			debug_line += " Imp" + llformat("%d[%d]:%.1f", mUpdatePeriod, mLastImpostorUpdateReason, ((F32)(gFrameTimeSeconds-mLastImpostorUpdateFrameTime))); +		}  		addDebugText(debug_line);  } @@ -3699,13 +3807,13 @@ LLViewerInventoryItem* recursiveGetObjectInventoryItem(LLViewerObject *vobj, LLU  void LLVOAvatar::updateAnimationDebugText()  { -		for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); -			 iter != mMotionController.getActiveMotions().end(); ++iter) +	for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); +		 iter != mMotionController.getActiveMotions().end(); ++iter) +	{ +		LLMotion* motionp = *iter; +		if (motionp->getMinPixelArea() < getPixelArea())  		{ -			LLMotion* motionp = *iter; -			if (motionp->getMinPixelArea() < getPixelArea()) -			{ -				std::string output; +			std::string output;              std::string motion_name = motionp->getName();              if (motion_name.empty())              { @@ -3722,73 +3830,74 @@ void LLVOAvatar::updateAnimationDebugText()                  }              }              if (motion_name.empty()) +			{ +				std::string name; +				if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf())  				{ -					std::string name; -					if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf()) +					name = motionp->getID().asString(); +					LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin(); +					for (; anim_it != mAnimationSources.end(); ++anim_it)  					{ -						name = motionp->getID().asString(); -						LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin(); -						for (; anim_it != mAnimationSources.end(); ++anim_it) +						if (anim_it->second == motionp->getID())  						{ -							if (anim_it->second == motionp->getID()) +							LLViewerObject* object = gObjectList.findObject(anim_it->first); +							if (!object) +							{ +								break; +							} +							if (object->isAvatar()) +							{ +								if (mMotionController.mIsSelf) +								{ +									// Searching inventory by asset id is really long +									// so just mark as inventory +									// Also item is likely to be named by LLPreviewAnim +									name += "(inventory)"; +								} +							} +							else  							{ -								LLViewerObject* object = gObjectList.findObject(anim_it->first); -								if (!object) +								LLViewerInventoryItem* item = NULL; +								if (!object->isInventoryDirty())  								{ -									break; +									item = object->getInventoryItemByAsset(motionp->getID());  								} -								if (object->isAvatar()) +								if (item)  								{ -									if (mMotionController.mIsSelf) -									{ -										// Searching inventory by asset id is really long -										// so just mark as inventory -										// Also item is likely to be named by LLPreviewAnim -										name += "(inventory)"; -									} +									name = item->getName(); +								} +								else if (object->isAttachment()) +								{ +									name += "(att:" + getAttachmentItemName() + ")";  								}  								else  								{ -									LLViewerInventoryItem* item = NULL; -									if (!object->isInventoryDirty()) -									{ -										item = object->getInventoryItemByAsset(motionp->getID()); -									} -									if (item) -									{ -										name = item->getName(); -									} -									else if (object->isAttachment()) -									{ -										name += "(" + getAttachmentItemName() + ")"; -									} -									else -									{ -										// in-world object, name or content unknown -										name += "(in-world)"; -									} +									// in-world object, name or content unknown +									name += "(in-world)";  								} -								break;  							} +							break;  						}  					} -					else -					{ -						name = LLUUID::null.asString(); -					} -					output = llformat("%s - %d", -							  name.c_str(), -							  (U32)motionp->getPriority());  				}  				else  				{ -					output = llformat("%s - %d", -                                  motion_name.c_str(), -							  (U32)motionp->getPriority()); +					name = LLUUID::null.asString();  				} -				addDebugText(output); +				motion_name = name; +			} +			std::string motion_tag = ""; +			if (mPlayingAnimations.find(motionp->getID()) != mPlayingAnimations.end()) +			{ +				motion_tag = "*";  			} +			output = llformat("%s%s - %d", +							  motion_name.c_str(), +							  motion_tag.c_str(), +							  (U32)motionp->getPriority()); +			addDebugText(output);  		} +	}  }  void LLVOAvatar::updateDebugText() @@ -3917,7 +4026,14 @@ void LLVOAvatar::updateFootstepSounds()  // computeUpdatePeriod()  // Factored out from updateCharacter()  // Set new value for mUpdatePeriod based on distance and various other factors. -//------------------------------------------------------------------------ +// +// Note 10-2020: it turns out that none of these update period +// calculations have been having any effect, because +// mNeedsImpostorUpdate was not being set in updateCharacter(). So +// it's really open to question whether we want to enable time based updates, and if +// so, at what rate. Leaving the rates as given would lead to +// drastically more frequent impostor updates than we've been doing all these years. +// ------------------------------------------------------------------------  void LLVOAvatar::computeUpdatePeriod()  {  	bool visually_muted = isVisuallyMuted(); @@ -3925,7 +4041,7 @@ void LLVOAvatar::computeUpdatePeriod()          && isVisible()           && (!isSelf() || visually_muted)          && !isUIAvatar() -        && sUseImpostors +        && (sLimitNonImpostors || visually_muted)          && !mNeedsAnimUpdate           && !sFreezeCounter)  	{ @@ -3933,11 +4049,14 @@ void LLVOAvatar::computeUpdatePeriod()  		LLVector4a size;  		size.setSub(ext[1],ext[0]);  		F32 mag = size.getLength3().getF32()*0.5f; + +		const S32 UPDATE_RATE_SLOW = 64; +		const S32 UPDATE_RATE_MED = 48; +		const S32 UPDATE_RATE_FAST = 32; -		F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f);  		if (visually_muted) -		{ // visually muted avatars update at 16 hz -			mUpdatePeriod = 16; +		{   // visually muted avatars update at lowest rate +			mUpdatePeriod = UPDATE_RATE_SLOW;  		}  		else if (! shouldImpostor()  				 || mDrawable->mDistanceWRTCamera < 1.f + mag) @@ -3946,34 +4065,29 @@ void LLVOAvatar::computeUpdatePeriod()  			// impostor camera near clip plane  			mUpdatePeriod = 1;  		} -		else if ( shouldImpostor(4) ) +		else if ( shouldImpostor(4.0) )  		{ //background avatars are REALLY slow updating impostors -			mUpdatePeriod = 16; +			mUpdatePeriod = UPDATE_RATE_SLOW;  		}  		else if (mLastRezzedStatus <= 0)  		{  			// Don't update cloud avatars too often -			mUpdatePeriod = 8; +			mUpdatePeriod = UPDATE_RATE_SLOW;  		} -		else if ( shouldImpostor(3) ) +		else if ( shouldImpostor(3.0) )  		{ //back 25% of max visible avatars are slow updating impostors -			mUpdatePeriod = 8; -		} -		else if (mImpostorPixelArea <= impostor_area) -		{  // stuff in between gets an update period based on pixel area -			mUpdatePeriod = llclamp((S32) sqrtf(impostor_area*4.f/mImpostorPixelArea), 2, 8); +			mUpdatePeriod = UPDATE_RATE_MED;  		} -		else +		else   		{  			//nearby avatars, update the impostors more frequently. -			mUpdatePeriod = 4; +			mUpdatePeriod = UPDATE_RATE_FAST;  		}  	}  	else  	{  		mUpdatePeriod = 1;  	} -  }  //------------------------------------------------------------------------ @@ -4244,7 +4358,33 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w  		if (!isSitting() && !was_sit_ground_constrained)  		{  			root_pos += LLVector3d(getHoverOffset()); -		} +			if (getOverallAppearance() == AOA_JELLYDOLL) +			{ +				F32 offz = -0.5 * (getScale()[VZ] - mBodySize.mV[VZ]); +				root_pos[2] += offz; +				// if (!isSelf() && !isControlAvatar()) +				// { +				// 	LL_DEBUGS("Avatar") << "av " << getFullname()  +				// 						<< " frame " << LLFrameTimer::getFrameCount() +				// 						<< " root adjust offz " << offz +				// 						<< " scalez " << getScale()[VZ] +				// 						<< " bsz " << mBodySize.mV[VZ] +				// 						<< LL_ENDL; +				// } +			} +		} +		// if (!isSelf() && !isControlAvatar()) +		// { +		// 	LL_DEBUGS("Avatar") << "av " << getFullname() << " aoa " << (S32) getOverallAppearance() +		// 						<< " frame " << LLFrameTimer::getFrameCount() +		// 						<< " scalez " << getScale()[VZ] +		// 						<< " bsz " << mBodySize.mV[VZ] +		// 						<< " root pos " << root_pos[2] +		// 						<< " curr rootz " << mRoot->getPosition()[2]  +		// 						<< " pp-z " << mPelvisp->getPosition()[2] +		// 						<< " renderpos " << getRenderPosition() +		// 						<< LL_ENDL; +		// }          LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this);          if (cav) @@ -4255,6 +4395,14 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w          else          {              LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos); +			// if (!isSelf() && !isControlAvatar()) +			// { +			// 	LL_DEBUGS("Avatar") << "av " << getFullname()  +			// 						<< " frame " << LLFrameTimer::getFrameCount() +			// 						<< " newPosition " << newPosition +			// 						<< " renderpos " << getRenderPosition() +			// 						<< LL_ENDL; +			// }              if (newPosition != mRoot->getXform()->getWorldPosition())              {		                  mRoot->touch(); @@ -4285,6 +4433,37 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w  }  //------------------------------------------------------------------------ +// LLVOAvatar::computeNeedsUpdate() +//  +// Most of the logic here is to figure out when to periodically update impostors. +// Non-impostors have mUpdatePeriod == 1 and will need update every frame. +//------------------------------------------------------------------------ +bool LLVOAvatar::computeNeedsUpdate() +{ +	const F32 MAX_IMPOSTOR_INTERVAL = 4.0f; +	computeUpdatePeriod(); + +	bool needs_update_by_frame_count = ((LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0); + +    bool needs_update_by_max_time = ((gFrameTimeSeconds-mLastImpostorUpdateFrameTime)> MAX_IMPOSTOR_INTERVAL); +	bool needs_update = needs_update_by_frame_count || needs_update_by_max_time; + +	if (needs_update && !isSelf()) +	{ +		if (needs_update_by_max_time) +		{ +			mNeedsImpostorUpdate = TRUE; +			mLastImpostorUpdateReason = 11; +		} +		else +		{ +			//mNeedsImpostorUpdate = TRUE; +			//mLastImpostorUpdateReason = 10; +		} +	} +	return needs_update; +} +  // updateCharacter()  //  // This is called for all avatars, so there are 4 possible situations: @@ -4307,7 +4486,7 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w  // simulator.  //  //------------------------------------------------------------------------ -BOOL LLVOAvatar::updateCharacter(LLAgent &agent) +bool LLVOAvatar::updateCharacter(LLAgent &agent)  {	  	updateDebugText(); @@ -4319,6 +4498,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  	BOOL visible = isVisible();      bool is_control_avatar = isControlAvatar(); // capture state to simplify tracing  	bool is_attachment = false; +  	if (is_control_avatar)  	{          LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this); @@ -4338,11 +4518,11 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  	//--------------------------------------------------------------------  	// The rest should only be done occasionally for far away avatars. -    // Set mUpdatePeriod and visible based on distance and other criteria. +    // Set mUpdatePeriod and visible based on distance and other criteria, +	// and flag for impostor update if needed.  	//-------------------------------------------------------------------- -    computeUpdatePeriod(); -    bool needs_update = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0; - +	bool needs_update = computeNeedsUpdate(); +	  	//--------------------------------------------------------------------  	// Early out if does not need update and not self  	// don't early out for your own avatar, as we rely on your animations playing reliably @@ -4356,6 +4536,12 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  	}  	//-------------------------------------------------------------------- +	// Handle transitions between regular rendering, jellydoll, or invisible. +	// Can trigger skeleton reset or animation changes +	//-------------------------------------------------------------------- +	updateOverallAppearance(); +	 +	//--------------------------------------------------------------------  	// change animation time quanta based on avatar render load  	//--------------------------------------------------------------------      // SL-763 the time step quantization does not currently work. @@ -4438,8 +4624,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)      if (visible)      { -	// System avatar mesh vertices need to be reskinned. -	mNeedsSkin = TRUE; +		// System avatar mesh vertices need to be reskinned. +		mNeedsSkin = TRUE;      }  	return visible; @@ -4885,7 +5071,8 @@ U32 LLVOAvatar::renderSkinned()  			}  			if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)  			{ -				if (isTextureVisible(TEX_HEAD_BAKED) || isUIAvatar()) +	 +				if (isTextureVisible(TEX_HEAD_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())  				{  					LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);  					if (head_mesh) @@ -4895,7 +5082,7 @@ U32 LLVOAvatar::renderSkinned()  					first_pass = FALSE;  				}  			} -			if (isTextureVisible(TEX_UPPER_BAKED) || isUIAvatar()) +			if (isTextureVisible(TEX_UPPER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())  			{  				LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);  				if (upper_mesh) @@ -4905,7 +5092,7 @@ U32 LLVOAvatar::renderSkinned()  				first_pass = FALSE;  			} -			if (isTextureVisible(TEX_LOWER_BAKED) || isUIAvatar()) +			if (isTextureVisible(TEX_LOWER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())  			{  				LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);  				if (lower_mesh) @@ -4962,7 +5149,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)  			}  			first_pass = FALSE;  		} -		if (isTextureVisible(TEX_HAIR_BAKED)) +		if (isTextureVisible(TEX_HAIR_BAKED) && (getOverallAppearance() != AOA_JELLYDOLL))  		{  			LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);  			if (hair_mesh) @@ -5010,7 +5197,7 @@ U32 LLVOAvatar::renderRigid()  		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);  	} -	if (isTextureVisible(TEX_EYES_BAKED)  || isUIAvatar()) +	if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())  	{  		LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT);  		LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT); @@ -5639,8 +5826,8 @@ void LLVOAvatar::processAnimationStateChanges()  		stopMotion(ANIM_AGENT_TARGET);          if (mEnableDefaultMotions)          { -		startMotion(ANIM_AGENT_BODY_NOISE); -	} +			startMotion(ANIM_AGENT_BODY_NOISE); +		}  	}  	// clear all current animations @@ -5660,23 +5847,32 @@ void LLVOAvatar::processAnimationStateChanges()  		++anim_it;  	} +	// if jellydolled, shelve all playing animations +	if (getOverallAppearance() != AOA_NORMAL) +	{ +		mPlayingAnimations.clear(); +	} +	  	// start up all new anims -	for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();) +	if (getOverallAppearance() == AOA_NORMAL)  	{ -		AnimIterator found_anim = mPlayingAnimations.find(anim_it->first); - -		// signaled but not playing, or different sequence id, start motion -		if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second) +		for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();)  		{ -			if (processSingleAnimationStateChange(anim_it->first, TRUE)) +			AnimIterator found_anim = mPlayingAnimations.find(anim_it->first); + +			// signaled but not playing, or different sequence id, start motion +			if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second)  			{ -				mPlayingAnimations[anim_it->first] = anim_it->second; -				++anim_it; -				continue; +				if (processSingleAnimationStateChange(anim_it->first, TRUE)) +				{ +					mPlayingAnimations[anim_it->first] = anim_it->second; +					++anim_it; +					continue; +				}  			} -		} -		++anim_it; +			++anim_it; +		}  	}  	// clear source information for animations which have been stopped @@ -6239,6 +6435,11 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL  	}      LLScopedContextString str("addAttachmentOverridesForObject " + getFullname()); + +	if (getOverallAppearance() != AOA_NORMAL) +	{ +		return; +	}      LL_DEBUGS("AnimatedObjects") << "adding" << LL_ENDL;      dumpStack("AnimatedObjectsStack"); @@ -7658,9 +7859,15 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color)  }  // virtual +// Do rigged mesh attachments display with this av?  bool LLVOAvatar::shouldRenderRigged() const  { -    return true; +	if (getOverallAppearance() == AOA_NORMAL) +	{ +		return true; +	} +	// TBD - render for AOA_JELLYDOLL? +	return false;  }  // FIXME: We have an mVisible member, set in updateVisibility(), but this @@ -7941,12 +8148,14 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)  	}  	// did our loading state "change" from last call? -	// runway - why are we updating every 30 calls even if nothing has changed? +	// FIXME runway - why are we updating every 30 calls even if nothing has changed? +	// This causes updateLOD() to run every 30 frames, among other things.  	const S32 UPDATE_RATE = 30;  	BOOL changed =  		((mFullyLoaded != mPreviousFullyLoaded) ||         // if the value is different from the previous call  		 (!mFullyLoadedInitialized) ||                     // if we've never been called before  		 (mFullyLoadedFrameCounter % UPDATE_RATE == 0));   // every now and then issue a change +	BOOL fully_loaded_changed = (mFullyLoaded != mPreviousFullyLoaded);  	mPreviousFullyLoaded = mFullyLoaded;  	mFullyLoadedInitialized = TRUE; @@ -7957,7 +8166,13 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)          // to know about outfit switching          LLAvatarRenderNotifier::getInstance()->updateNotificationState();      } -	 + +	if (fully_loaded_changed && !isSelf() && mFullyLoaded && isImpostor()) +	{ +		// Fix for jellydoll initially invisible +		mNeedsImpostorUpdate = TRUE; +		mLastImpostorUpdateReason = 6; +	}	  	return changed;  } @@ -8029,47 +8244,25 @@ void LLVOAvatar::updateMeshVisibility()  	bool bake_flag[BAKED_NUM_INDICES];  	memset(bake_flag, 0, BAKED_NUM_INDICES*sizeof(bool)); -	for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); -		iter != mAttachmentPoints.end(); -		++iter) +	if (getOverallAppearance() == AOA_NORMAL)  	{ -		LLViewerJointAttachment* attachment = iter->second; -		if (attachment) +		for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); +			 iter != mAttachmentPoints.end(); +			 ++iter)  		{ -			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); -				attachment_iter != attachment->mAttachedObjects.end(); -				++attachment_iter) +			LLViewerJointAttachment* attachment = iter->second; +			if (attachment)  			{ -				LLViewerObject *objectp = attachment_iter->get(); -				if (objectp) -				{ -					for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++) -					{ -						LLTextureEntry* tex_entry = objectp->getTE(face_index); -						bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); -						bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); -						bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); -						bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); -						bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); -						bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); -						bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM); -						bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG); -						bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1); -						bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2); -						bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); -					} -				} - -				LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); -				for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); -					iter1 != child_list.end(); ++iter1) +				for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +					 attachment_iter != attachment->mAttachedObjects.end(); +					 ++attachment_iter)  				{ -					LLViewerObject* objectchild = *iter1; -					if (objectchild) +					LLViewerObject *objectp = attachment_iter->get(); +					if (objectp)  					{ -						for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++) +						for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++)  						{ -							LLTextureEntry* tex_entry = objectchild->getTE(face_index); +							LLTextureEntry* tex_entry = objectp->getTE(face_index);  							bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD);  							bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES);  							bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); @@ -8083,6 +8276,31 @@ void LLVOAvatar::updateMeshVisibility()  							bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3);  						}  					} + +					LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); +					for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); +						 iter1 != child_list.end(); ++iter1) +					{ +						LLViewerObject* objectchild = *iter1; +						if (objectchild) +						{ +							for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++) +							{ +								LLTextureEntry* tex_entry = objectchild->getTE(face_index); +								bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); +								bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); +								bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); +								bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); +								bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); +								bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); +								bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM); +								bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG); +								bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1); +								bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2); +								bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); +							} +						} +					}  				}  			}  		} @@ -9013,7 +9231,11 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )      mLastProcessedAppearance = contents;      bool slam_params = false; -    applyParsedAppearanceMessage(*contents, slam_params); +	applyParsedAppearanceMessage(*contents, slam_params); +	if (getOverallAppearance() != AOA_NORMAL) +	{ +		resetSkeleton(false); +	}  }  void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params) @@ -9906,7 +10128,7 @@ BOOL LLVOAvatar::updateLOD()          return FALSE;      } -	if (isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry()) +	if (!LLPipeline::sImpostorRender && isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry())  	{  		return TRUE;  	} @@ -10097,10 +10319,10 @@ void LLVOAvatar::updateImpostors()  		iter != instances_copy.end(); ++iter)  	{  		LLVOAvatar* avatar = (LLVOAvatar*) *iter; -		if (!avatar->isDead() && avatar->isVisible() -			&& ( -                (avatar->isImpostor() || LLVOAvatar::AV_DO_NOT_RENDER == avatar->getVisualMuteSettings()) && avatar->needsImpostorUpdate()) -            ) +		if (!avatar->isDead() +			&& avatar->isVisible() +			&& avatar->isImpostor() +			&& avatar->needsImpostorUpdate())  		{              avatar->calcMutedAVColor();  			gPipeline.generateImpostor(avatar); @@ -10113,12 +10335,20 @@ void LLVOAvatar::updateImpostors()  // virtual  BOOL LLVOAvatar::isImpostor()  { -	return sUseImpostors && (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE; +	return isVisuallyMuted() || (sLimitNonImpostors && (mUpdatePeriod > 1));  } -BOOL LLVOAvatar::shouldImpostor(const U32 rank_factor) const +BOOL LLVOAvatar::shouldImpostor(const F32 rank_factor)  { -	return (!isSelf() && sUseImpostors && mVisibilityRank > (sMaxNonImpostors * rank_factor)); +	if (isSelf()) +	{ +		return false; +	} +	if (isVisuallyMuted()) +	{ +		return true; +	} +	return sLimitNonImpostors && (mVisibilityRank > sMaxNonImpostors * rank_factor);  }  BOOL LLVOAvatar::needsImpostorUpdate() const @@ -10161,16 +10391,16 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d  }  // static -const U32 LLVOAvatar::IMPOSTORS_OFF = 66; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors +const U32 LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER = 66; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors  										   * slider in panel_preferences_graphics1.xml */  // static  void LLVOAvatar::updateImpostorRendering(U32 newMaxNonImpostorsValue)  {  	U32  oldmax = sMaxNonImpostors; -	bool oldflg = sUseImpostors; +	bool oldflg = sLimitNonImpostors; -	if (IMPOSTORS_OFF <= newMaxNonImpostorsValue) +	if (NON_IMPOSTORS_MAX_SLIDER <= newMaxNonImpostorsValue)  	{  		sMaxNonImpostors = 0;  	} @@ -10178,13 +10408,13 @@ void LLVOAvatar::updateImpostorRendering(U32 newMaxNonImpostorsValue)  	{  		sMaxNonImpostors = newMaxNonImpostorsValue;  	} -	// the sUseImpostors flag depends on whether or not sMaxNonImpostors is set to the no-limit value (0) -	sUseImpostors = (0 != sMaxNonImpostors); -    if ( oldflg != sUseImpostors ) +	// the sLimitNonImpostors flag depends on whether or not sMaxNonImpostors is set to the no-limit value (0) +	sLimitNonImpostors = (0 != sMaxNonImpostors); +    if ( oldflg != sLimitNonImpostors )      {          LL_DEBUGS("AvatarRender")              << "was " << (oldflg ? "use" : "don't use" ) << " impostors (max " << oldmax << "); " -            << "now " << (sUseImpostors ? "use" : "don't use" ) << " impostors (max " << sMaxNonImpostors << "); " +            << "now " << (sLimitNonImpostors ? "use" : "don't use" ) << " impostors (max " << sMaxNonImpostors << "); "              << LL_ENDL;      }  } @@ -10569,10 +10799,178 @@ void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set)  {      mVisuallyMuteSetting = set;      mNeedsImpostorUpdate = TRUE; +	mLastImpostorUpdateReason = 7;      LLRenderMuteList::getInstance()->saveVisualMuteSetting(getID(), S32(set));  } + +void LLVOAvatar::setOverallAppearanceNormal() +{ +	if (isControlAvatar()) +		return; + +    LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition(); +	resetSkeleton(false); +    getJoint("mPelvis")->setPosition(pelvis_pos); + +	for (auto it = mJellyAnims.begin(); it !=  mJellyAnims.end(); ++it) +	{ +		bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end()); +		LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL; +		if (!is_playing) +		{ +			// Anim was not requested for this av by sim, but may be playing locally +			stopMotion(*it); +		} +	} +	mJellyAnims.clear(); + +	processAnimationStateChanges(); +} + +void LLVOAvatar::setOverallAppearanceJellyDoll() +{ +	if (isControlAvatar()) +		return; + +	// stop current animations +	{ +		for ( LLVOAvatar::AnimIterator anim_it= mPlayingAnimations.begin(); +			  anim_it != mPlayingAnimations.end(); +			  ++anim_it) +		{ +			{ +				stopMotion(anim_it->first, TRUE); +			} +		} +	} +	processAnimationStateChanges(); + +	// Start any needed anims for jellydoll +	updateOverallAppearanceAnimations(); +	 +    LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition(); +	resetSkeleton(false); +    getJoint("mPelvis")->setPosition(pelvis_pos); + +} + +void LLVOAvatar::setOverallAppearanceInvisible() +{ +} + +void LLVOAvatar::updateOverallAppearance() +{ +	AvatarOverallAppearance new_overall = getOverallAppearance(); +	if (new_overall != mOverallAppearance) +	{ +		switch (new_overall) +		{ +			case AOA_NORMAL: +				setOverallAppearanceNormal(); +				break; +			case AOA_JELLYDOLL: +				setOverallAppearanceJellyDoll(); +				break; +			case AOA_INVISIBLE: +				setOverallAppearanceInvisible(); +				break; +		} +		mOverallAppearance = new_overall; +		if (!isSelf()) +		{ +			mNeedsImpostorUpdate = TRUE; +			mLastImpostorUpdateReason = 8; +		} +		updateMeshVisibility(); +	} + +	// This needs to be done even if overall appearance has not +	// changed, since sit/stand status can be different. +	updateOverallAppearanceAnimations(); +} + +void LLVOAvatar::updateOverallAppearanceAnimations() +{ +	if (isControlAvatar()) +		return; + +	if (getOverallAppearance() == AOA_JELLYDOLL) +	{ +		LLUUID motion_id; +		if (isSitting() && getParent()) // sitting on object +		{ +			motion_id = ANIM_AGENT_SIT_FEMALE;  +		} +		else if (isSitting()) // sitting on ground +		{ +			motion_id = ANIM_AGENT_SIT_GROUND_CONSTRAINED; +		} +		else // standing +		{ +			motion_id = ANIM_AGENT_STAND; +		} +		if (mJellyAnims.find(motion_id) == mJellyAnims.end()) +		{ +			for (auto it = mJellyAnims.begin(); it !=  mJellyAnims.end(); ++it) +			{ +				bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end()); +				LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL; +				if (!is_playing) +				{ +					// Anim was not requested for this av by sim, but may be playing locally +					stopMotion(*it, TRUE); +				} +			} +			mJellyAnims.clear(); + +			startMotion(motion_id); +			mJellyAnims.insert(motion_id); + +			processAnimationStateChanges(); +		} +	} +} + +// Based on isVisuallyMuted(), but has 3 possible results. +LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const +{ +	AvatarOverallAppearance result = AOA_NORMAL; + +	// Priority order (highest priority first) +	// * own avatar is always drawn normally +	// * if on the "always draw normally" list, draw them normally +	// * if on the "always visually mute" list, show as jellydoll +	// * if explicitly muted (blocked), show as invisible +	// * check against the render cost and attachment limits - if too complex, show as jellydoll +	if (isSelf()) +	{ +		result = AOA_NORMAL; +	} +	else // !isSelf() +	{ +		if (isInMuteList()) +		{ +			result = AOA_INVISIBLE; +		} +		else if (mVisuallyMuteSetting == AV_ALWAYS_RENDER) +		{ +			result = AOA_NORMAL; +		} +		else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER) +		{	// Always want to see this AV as an impostor +			result = AOA_JELLYDOLL; +		} +		else if (isTooComplex()) +		{ +			result = AOA_JELLYDOLL; +		} +	} + +	return result; +} +  void LLVOAvatar::calcMutedAVColor()  {      LLColor4 new_color(mMutedAVColor); @@ -10582,8 +10980,8 @@ void LLVOAvatar::calcMutedAVColor()      if (getVisualMuteSettings() == AV_DO_NOT_RENDER)      {          // explicitly not-rendered avatars are light grey -        new_color = LLColor4::grey3; -        change_msg = " not rendered: color is grey3"; +        new_color = LLColor4::grey4; +        change_msg = " not rendered: color is grey4";      }      else if (LLMuteList::getInstance()->isMuted(av_id)) // the user blocked them      { @@ -10596,26 +10994,31 @@ void LLVOAvatar::calcMutedAVColor()          new_color = LLColor4::white;          change_msg = " simple imposter ";      } +#ifdef COLORIZE_JELLYDOLLS      else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 ) -    { +	{          // select a color based on the first byte of the agents uuid so any muted agent is always the same color          F32 color_value = (F32) (av_id.mData[0]); -        F32 spectrum = (color_value / 256.0);		// spectrum is between 0 and 1.f +        F32 spectrum = (color_value / 256.0);          // spectrum is between 0 and 1.f -        // Array of colors.  These are arranged so only one RGB color changes between each step,  +        // Array of colors.  These are arranged so only one RGB color changes between each step,          // and it loops back to red so there is an even distribution.  It is not a heat map -        const S32 NUM_SPECTRUM_COLORS = 7;               +        const S32 NUM_SPECTRUM_COLORS = 7;          static LLColor4 * spectrum_color[NUM_SPECTRUM_COLORS] = { &LLColor4::red, &LLColor4::magenta, &LLColor4::blue, &LLColor4::cyan, &LLColor4::green, &LLColor4::yellow, &LLColor4::red }; -  -        spectrum = spectrum * (NUM_SPECTRUM_COLORS - 1);		// Scale to range of number of colors -        S32 spectrum_index_1  = floor(spectrum);				// Desired color will be after this index -        S32 spectrum_index_2  = spectrum_index_1 + 1;			//    and before this index (inclusive) + +        spectrum = spectrum * (NUM_SPECTRUM_COLORS - 1);               // Scale to range of number of colors +        S32 spectrum_index_1  = floor(spectrum);                               // Desired color will be after this index +        S32 spectrum_index_2  = spectrum_index_1 + 1;                  //    and before this index (inclusive)          F32 fractBetween = spectrum - (F32)(spectrum_index_1);  // distance between the two indexes (0-1) -  -        new_color = lerp(*spectrum_color[spectrum_index_1], *spectrum_color[spectrum_index_2], fractBetween); -        new_color.normalize(); -        new_color *= 0.28f;		// Tone it down +        new_color = lerp(*spectrum_color[spectrum_index_1], *spectrum_color[spectrum_index_2], fractBetween); +		new_color.normalize(); +        new_color *= 0.28f;            // Tone it down +	} +#endif +    else +    { +		new_color = LLColor4::grey4;          change_msg = " over limit color ";      } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 79f31ba5b5..74ef589ca4 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -91,6 +91,7 @@ class LLVOAvatar :  public:  	friend class LLVOAvatarSelf; +	friend class LLAvatarCheckImpostorMode;  /********************************************************************************   **                                                                            ** @@ -131,6 +132,7 @@ protected:  public:  	/*virtual*/ void			updateGL();  	/*virtual*/ LLVOAvatar*		asAvatar(); +  	virtual U32    	 	 	processUpdateMessage(LLMessageSystem *mesgsys,  													 void **user_data,  													 U32 block_num, @@ -252,6 +254,11 @@ public:  	virtual bool 	isControlAvatar() const { return mIsControlAvatar; } // True if this avatar is a control av (no associated user)  	virtual bool 	isUIAvatar() const { return mIsUIAvatar; } // True if this avatar is a supplemental av used in some UI views (no associated user) +	// If this is an attachment, return the avatar it is attached to. Otherwise NULL. +	virtual const LLVOAvatar *getAttachedAvatar() const { return NULL; } +	virtual LLVOAvatar *getAttachedAvatar() { return NULL; } + +  private: //aligned members  	LL_ALIGN_16(LLVector4a	mImpostorExtents[2]); @@ -262,7 +269,8 @@ public:      void			updateAppearanceMessageDebugText();  	void 			updateAnimationDebugText();  	virtual void	updateDebugText(); -	virtual BOOL 	updateCharacter(LLAgent &agent); +	virtual bool 	computeNeedsUpdate(); +	virtual bool 	updateCharacter(LLAgent &agent);      void			updateFootstepSounds();      void			computeUpdatePeriod();      void			updateOrientation(LLAgent &agent, F32 speed, F32 delta_time); @@ -314,12 +322,12 @@ public:  public:  	static S32		sRenderName;  	static BOOL		sRenderGroupTitles; -	static const U32 IMPOSTORS_OFF; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors -									 * slider in panel_preferences_graphics1.xml */ -	static U32		sMaxNonImpostors; //(affected by control "RenderAvatarMaxNonImpostors") -	static F32		sRenderDistance; //distance at which avatars will render. +	static const U32 NON_IMPOSTORS_MAX_SLIDER; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors +												* slider in panel_preferences_graphics1.xml */ +	static U32		sMaxNonImpostors; // affected by control "RenderAvatarMaxNonImpostors" +	static bool		sLimitNonImpostors; // use impostors for far away avatars +	static F32		sRenderDistance; // distance at which avatars will render.  	static BOOL		sShowAnimationDebug; // show animation debug info -	static bool		sUseImpostors; //use impostors for far away avatars  	static BOOL		sShowFootPlane;	// show foot collision plane reported by server  	static BOOL		sShowCollisionVolumes;	// show skeletal collision volumes  	static BOOL		sVisibleInFirstPerson; @@ -407,6 +415,7 @@ public:      void                initAttachmentPoints(bool ignore_hud_joints = false);  	/*virtual*/ void	buildCharacter();      void                resetVisualParams(); +	void				applyDefaultParams();      void				resetSkeleton(bool reset_animations);  	LLVector3			mCurRootToHeadOffset; @@ -427,9 +436,12 @@ public:  public:  	U32 		renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0);  	bool		isVisuallyMuted(); -	bool 		isInMuteList(); +	bool 		isInMuteList() const;  	void		forceUpdateVisualMuteSettings(); +	// Visual Mute Setting is an input. Does not necessarily determine +	// what the avatar looks like, because it interacts with other +	// settings like muting, complexity threshold. Should be private or protected.  	enum VisualMuteSettings  	{  		AV_RENDER_NORMALLY = 0, @@ -437,8 +449,36 @@ public:  		AV_ALWAYS_RENDER   = 2  	};  	void		setVisualMuteSettings(VisualMuteSettings set); + +protected: +	// If you think you need to access this outside LLVOAvatar, you probably want getOverallAppearance()  	VisualMuteSettings  getVisualMuteSettings()						{ return mVisuallyMuteSetting;	}; +public: + +	// Overall Appearance is an output. Depending on whether the +	// avatar is blocked/muted, whether it exceeds the complexity +	// threshold, etc, avatar will want to be displayed in one of +	// these ways. Rendering code that wants to know how to display an +	// avatar should be looking at this value, NOT the visual mute +	// settings +	enum AvatarOverallAppearance +	{ +		AOA_NORMAL, +		AOA_JELLYDOLL, +		AOA_INVISIBLE +	}; + +	AvatarOverallAppearance getOverallAppearance() const; +	void setOverallAppearanceNormal(); +	void setOverallAppearanceJellyDoll(); +	void setOverallAppearanceInvisible(); +		 +	void updateOverallAppearance(); +	void updateOverallAppearanceAnimations(); + +	std::set<LLUUID> mJellyAnims; +  	U32 		renderRigid();  	U32 		renderSkinned();  	F32			getLastSkinTime() { return mLastSkinTime; } @@ -451,7 +491,8 @@ public:  	static void	restoreGL();  	S32			mSpecialRenderMode; // special lighting -  private: +private: +	AvatarOverallAppearance mOverallAppearance;  	F32			mAttachmentSurfaceArea; //estimated surface area of attachments      U32			mAttachmentVisibleTriangleCount;      F32			mAttachmentEstTriangleCount; @@ -468,8 +509,8 @@ public:  	mutable bool mVisualComplexityStale;  	U32          mReportedVisualComplexity; // from other viewers through the simulator -	bool		mCachedInMuteList; -	F64			mCachedMuteListUpdateTime; +	mutable bool		mCachedInMuteList; +	mutable F64			mCachedMuteListUpdateTime;  	VisualMuteSettings		mVisuallyMuteSetting;			// Always or never visually mute this AV @@ -520,7 +561,7 @@ private:  	//--------------------------------------------------------------------  public:  	virtual BOOL isImpostor(); -	BOOL 		shouldImpostor(const U32 rank_factor = 1) const; +	BOOL 		shouldImpostor(const F32 rank_factor = 1.0);  	BOOL 	    needsImpostorUpdate() const;  	const LLVector3& getImpostorOffset() const;  	const LLVector2& getImpostorDim() const; @@ -531,6 +572,7 @@ public:  	static void updateImpostors();  	LLRenderTarget mImpostor;  	BOOL		mNeedsImpostorUpdate; +	S32			mLastImpostorUpdateReason;  	F32SecondsImplicit mLastImpostorUpdateFrameTime;      const LLVector3*  getLastAnimExtents() const { return mLastAnimExtents; }  	void		setNeedsExtentUpdate(bool val) { mNeedsExtentUpdate = val; } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 58109b838e..458d8ced65 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -668,7 +668,7 @@ LLVOAvatarSelf::~LLVOAvatarSelf()   *********************************************************************************/  // virtual -BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent) +bool LLVOAvatarSelf::updateCharacter(LLAgent &agent)  {  	// update screen joint size  	if (mScreenp) diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index b0fdae9bf0..279dbd61a6 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -116,7 +116,7 @@ public:  	// Updates  	//--------------------------------------------------------------------  public: -	/*virtual*/ BOOL 	updateCharacter(LLAgent &agent); +	/*virtual*/ bool 	updateCharacter(LLAgent &agent);  	/*virtual*/ void 	idleUpdateTractorBeam();  	bool				checkStuckAppearance(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 15738c618c..7ba7e545f4 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3083,9 +3083,10 @@ 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()  -							|| (LLVOAvatar::AV_DO_NOT_RENDER == av->getVisualMuteSettings() && !av->needsImpostorUpdate()) )) +						if (av && +							((!sImpostorRender && av->isImpostor()) //ignore impostor flag during impostor pass +							 || av->isInMuteList()  +							 || (LLVOAvatar::AOA_JELLYDOLL == av->getOverallAppearance() && !av->needsImpostorUpdate()) ))  						{  							return;  						} @@ -10953,7 +10954,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	{  		LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_MARK_VISIBLE);  		markVisible(avatar->mDrawable, *viewer_camera); -		LLVOAvatar::sUseImpostors = false; // @TODO ???  		LLVOAvatar::attachment_map_t::iterator iter;  		for (iter = avatar->mAttachmentPoints.begin(); @@ -11193,7 +11193,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	avatar->setImpostorDim(tdim); -	LLVOAvatar::sUseImpostors = (0 != LLVOAvatar::sMaxNonImpostors);  	sUseOcclusion = occlusion;  	sReflectionRender = false;  	sImpostorRender = false; diff --git a/scripts/content_tools/arche_tool.py b/scripts/content_tools/arche_tool.py index 23c96fc64e..f99d7be39a 100644 --- a/scripts/content_tools/arche_tool.py +++ b/scripts/content_tools/arche_tool.py @@ -79,15 +79,32 @@ def compare_trees(file_trees):      print "Summary:"      print summary - +def dump_appearance_params(tree): +    vals = [] +    for e in tree.getroot().iter(): +        if e.tag == "param": +            g = int(e.get("group")) +            if g in [0,3]: +                vals.append("{" + e.get("id") + "," +e.get("u8") + "}") +                #print e.get("id"), e.get("name"), e.get("group"), e.get("u8") +    if len(vals)==253: +        print ", ".join(vals) +         +      if __name__ == "__main__":      parser = argparse.ArgumentParser(description="compare avatar XML archetype files")      parser.add_argument("--verbose", help="verbose flag", action="store_true") +    parser.add_argument("--compare", help="compare flag", action="store_true") +    parser.add_argument("--appearance_params", help="compare flag", action="store_true")      parser.add_argument("files", nargs="+", help="name of one or more archtype files")      args = parser.parse_args()      print "files",args.files      file_trees = [etree.parse(filename) for filename in args.files] -    compare_trees(file_trees) +    print args +    if args.compare: +        compare_trees(file_trees) +    if args.appearance_params: +        dump_appearance_params(file_trees[0]) | 
