diff options
Diffstat (limited to 'indra')
50 files changed, 1577 insertions, 676 deletions
| diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 2d6d2a10d2..f0df3e1474 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -927,6 +927,9 @@ BOOL LLAvatarAppearance::loadAvatar()  		return FALSE;  	} +	// initialize mJointAliasMap +	getJointAliases(); +  	// avatar_lad.xml : <skeleton>  	if( !loadSkeletonNode() )  	{ @@ -1047,7 +1050,6 @@ BOOL LLAvatarAppearance::loadAvatar()  			return FALSE;  		}  	} -  	return TRUE;  } diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index a25ff16786..ebf7454a61 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1222,8 +1222,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8  //-----------------------------------------------------------------------------  // deserialize() +// +// allow_invalid_joints should be true when handling existing content, to avoid breakage. +// During upload, we should be more restrictive and reject such animations.  //----------------------------------------------------------------------------- -BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) +BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints)  {  	BOOL old_version = FALSE;  	mJointMotionList = new LLKeyframeMotion::JointMotionList; @@ -1344,6 +1347,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)  		return FALSE;  	} +	//SL-17206 hack to alter Female_land loop setting, while current behavior won't be changed serverside +	LLUUID const female_land_anim("ca1baf4d-0a18-5a1f-0330-e4bd1e71f09e"); +	LLUUID const formal_female_land_anim("6a9a173b-61fa-3ad5-01fa-a851cfc5f66a"); +	if (female_land_anim == asset_id || formal_female_land_anim == asset_id) +	{ +		LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL; +		mJointMotionList->mLoop = FALSE; +	} +  	//-------------------------------------------------------------------------  	// get easeIn and easeOut  	//------------------------------------------------------------------------- @@ -1443,6 +1455,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)  		if (joint)  		{              S32 joint_num = joint->getJointNum(); +			joint_name = joint->getName(); // canonical name in case this is an alias.  //			LL_INFOS() << "  joint: " << joint_name << LL_ENDL;              if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0))              { @@ -1457,7 +1470,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)  		{  			LL_WARNS() << "invalid joint name: " << joint_name                         << " for animation " << asset_id << LL_ENDL; -			//return FALSE; +			if (!allow_invalid_joints) +			{ +				return FALSE; +			}  		}  		joint_motion->mJointName = joint_name; @@ -2096,8 +2112,9 @@ U32	LLKeyframeMotion::getFileSize()  //-----------------------------------------------------------------------------  // dumpToFile()  //----------------------------------------------------------------------------- -void LLKeyframeMotion::dumpToFile(const std::string& name) +bool LLKeyframeMotion::dumpToFile(const std::string& name)  { +	bool succ = false;      if (isLoaded())      {          std::string outfile_base; @@ -2114,10 +2131,24 @@ void LLKeyframeMotion::dumpToFile(const std::string& name)              const LLUUID& id = getID();              outfile_base = id.asString();          } -        std::string outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base + ".anim"); + +		if (gDirUtilp->getExtension(outfile_base).empty()) +		{ +			outfile_base += ".anim"; +		} +		std::string outfilename; +		if (gDirUtilp->getDirName(outfile_base).empty()) +		{ +			outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base); +		} +		else +		{ +			outfilename = outfile_base; +		}          if (LLFile::isfile(outfilename))          { -            return; +			LL_WARNS() << outfilename << " already exists, write failed" << LL_ENDL; +            return false;          }          S32 file_size = getFileSize(); @@ -2131,11 +2162,13 @@ void LLKeyframeMotion::dumpToFile(const std::string& name)              outfile.open(outfilename, LL_APR_WPB);              if (outfile.getFileHandle())              { -                outfile.write(buffer, file_size); +                S32 wrote_bytes = outfile.write(buffer, file_size); +				succ = (wrote_bytes == file_size);              }          }          delete [] buffer;      } +	return succ;  }  //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index 9a927ede9a..96746f57c9 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -156,9 +156,9 @@ public:  public:  	U32		getFileSize();  	BOOL	serialize(LLDataPacker& dp) const; -	BOOL	deserialize(LLDataPacker& dp, const LLUUID& asset_id); +	BOOL	deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints = true);  	BOOL	isLoaded() { return mJointMotionList != NULL; } -    void	dumpToFile(const std::string& name); +    bool	dumpToFile(const std::string& name);  	// setters for modifying a keyframe animation @@ -432,6 +432,9 @@ protected:  	F32								mLastUpdateTime;  	F32								mLastLoopedTime;  	AssetStatus						mAssetStatus; + +public: +	void setCharacter(LLCharacter* character) { mCharacter = character; }  };  class LLKeyframeDataCache diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp index 53aa35c0f9..6664eb02dc 100644 --- a/indra/llmessage/llpartdata.cpp +++ b/indra/llmessage/llpartdata.cpp @@ -311,8 +311,9 @@ BOOL LLPartSysData::unpack(LLDataPacker &dp)  std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)  {  	s << "Flags: " << std::hex << data.mFlags; -	s << " Pattern: " << std::hex << (U32) data.mPattern << "\n"; -	s << "Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n"; +	s << "Pattern: " << std::hex << (U32) data.mPattern << "\n"; +	s << "Source Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n"; +    s << "Particle Age: " << data.mPartData.mMaxAge << "\n";  	s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n";  	s << "Burst Rate: " << data.mBurstRate << "\n";  	s << "Burst Radius: " << data.mBurstRadius << "\n"; diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml index 55babc88bc..8d5349550f 100644 --- a/indra/newview/app_settings/key_bindings.xml +++ b/indra/newview/app_settings/key_bindings.xml @@ -85,7 +85,6 @@      <binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>      <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/> -    <binding key="" mask="NONE" mouse="LMB" command="walk_to"/>      <binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>    </third_person> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 0000ae18bd..bc0d5c27d2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6808,6 +6808,9 @@        <key>Type</key>        <string>Boolean</string>        <key>Value</key> +      <!-- *HACK: On first run, set this to 0 for new users, +           otherwise the default is 1 to maintain consistent experience +           for existing users. Hardcoded in llnetmap.cpp -->        <integer>1</integer>      </map>      <key>MiniMapScale</key> @@ -6821,6 +6824,17 @@        <key>Value</key>        <real>128.0</real>      </map> +    <key>MiniMapShowPropertyLines</key> +    <map> +      <key>Comment</key> +      <string>Whether or not to show parcel borders on the MiniMap.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <real>1</real> +    </map>      <key>MouseSensitivity</key>      <map>        <key>Comment</key> diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml index 2241a12545..6cfc0b0be2 100644 --- a/indra/newview/character/avatar_skeleton.xml +++ b/indra/newview/character/avatar_skeleton.xml @@ -2,15 +2,15 @@     <bone aliases="hip avatar_mPelvis" connected="false" end="0.000 0.000 0.084" group="Torso" name="mPelvis" pivot="0.000000 0.000000 1.067015" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">        <collision_volume end="0.030 0.000 0.095" group="Collision" name="PELVIS" pos="-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17" support="base"/>        <collision_volume end="-0.100 0.000 0.000" group="Collision" name="BUTT" pos="-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1" support="base"/> -      <bone connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> -         <bone connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> +      <bone aliases="avatar_mSpine1" connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> +         <bone aliases="avatar_mSpine2" connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">              <bone aliases="abdomen avatar_mTorso" connected="true" end="-0.015 0.000 0.205" group="Torso" name="mTorso" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">                 <collision_volume end="0.028 0.000 0.094" group="Collision" name="BELLY" pos="0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15" support="base"/>                 <collision_volume end="0.000 0.100 0.000" group="Collision" name="LEFT_HANDLE" pos="0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/>                 <collision_volume end="0.000 -0.100 0.000" group="Collision" name="RIGHT_HANDLE" pos="0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/>                 <collision_volume end="-0.100 0.000 0.000" group="Collision" name="LOWER_BACK" pos="0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15" support="base"/> -               <bone connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> -                  <bone connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> +               <bone aliases="avatar_mSpine3" connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> +                  <bone aliases="avatar_mSpine4" connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">                       <bone aliases="chest avatar_mChest" connected="true" end="-0.010 0.000 0.250" group="Torso" name="mChest" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">                          <collision_volume end="-0.096 0.000 0.152" group="Collision" name="CHEST" pos="0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2" support="base"/>                          <collision_volume end="0.080 0.000 -0.006" group="Collision" name="LEFT_PEC" pos="0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05" support="base"/> @@ -23,58 +23,58 @@                                <bone aliases="figureHair avatar_mSkull" connected="false" end="0.000 0.000 0.033" group="Extra" name="mSkull" pivot="0.000000 0.000000 0.079000" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/>                                <bone aliases="avatar_mEyeRight" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeRight" pivot="0.098466 -0.036000 0.079000" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" support="base"/>                                <bone aliases="avatar_mEyeLeft" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeLeft" pivot="0.098461 0.036000 0.079000" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/> -                              <bone connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> -                                 <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                    <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                              <bone aliases="avatar_mFaceRoot" connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"> +                                 <bone aliases="avatar_mFaceEyeAltRight" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyeAltLeft" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceForeheadLeft" connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceForeheadRight" connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyebrowOuterLeft" connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyebrowCenterLeft" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyebrowInnerLeft" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyebrowOuterRight" connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyebrowCenterRight" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyebrowInnerRight" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyeLidUpperLeft" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyeLidLowerLeft" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyeLidUpperRight" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyeLidLowerRight" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEar1Left" connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                    <bone aliases="avatar_mFaceEar2Left" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                   </bone> -                                 <bone connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                    <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEar1Right" connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                    <bone aliases="avatar_mFaceEar2Right" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                   </bone> -                                 <bone connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                    <bone connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                    <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                       <bone connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                       <bone connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                       <bone connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                       <bone connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                          <bone connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceNoseLeft" connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceNoseCenter" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceNoseRight" connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceCheekLowerLeft" connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceCheekUpperLeft" connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceCheekLowerRight" connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceCheekUpperRight" connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceJaw" connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                    <bone aliases="avatar_mFaceChin" connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mFaceTeethLower" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                       <bone aliases="avatar_mFaceLipLowerLeft" connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                       <bone aliases="avatar_mFaceLipLowerRight" connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                       <bone aliases="avatar_mFaceLipLowerCenter" connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                       <bone aliases="avatar_mFaceTongueBase" connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                          <bone aliases="avatar_mFaceTongueTip" connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                         </bone>                                      </bone>                                   </bone> -                                 <bone connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                    <bone connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                    <bone connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                    <bone connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                    <bone connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                    <bone connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceJawShaper" connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceForeheadCenter" connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceNoseBase" connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceTeethUpper" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                    <bone aliases="avatar_mFaceLipUpperLeft" connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mFaceLipUpperRight" connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mFaceLipCornerLeft" connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mFaceLipCornerRight" connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mFaceLipUpperCenter" connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                   </bone> -                                 <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                 <bone connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyecornerInnerLeft" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceEyecornerInnerRight" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                 <bone aliases="avatar_mFaceNoseBridge" connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                </bone>                             </bone>                          </bone> @@ -86,29 +86,29 @@                                   <collision_volume end="0.000 0.100 -0.001" group="Collision" name="L_LOWER_ARM" pos="0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/>                                   <bone aliases="lHand avatar_mWristLeft" connected="true" end="0.000 0.060 0.000" group="Arms" name="mWristLeft" pivot="-0.000000 0.204846 0.000000" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">                                      <collision_volume end="0.005 0.049 -0.001" group="Collision" name="L_HAND" pos="0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03" support="base"/> -                                    <bone connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                       <bone connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                          <bone connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mHandMiddle1Left" connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                       <bone aliases="avatar_mHandMiddle2Left" connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                          <bone aliases="avatar_mHandMiddle3Left" connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                         </bone>                                      </bone> -                                    <bone connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                       <bone connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                          <bone connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mHandIndex1Left" connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                       <bone aliases="avatar_mHandIndex2Left" connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                          <bone aliases="avatar_mHandIndex3Left" connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                         </bone>                                      </bone> -                                    <bone connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                       <bone connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                          <bone connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mHandRing1Left" connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                       <bone aliases="avatar_mHandRing2Left" connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                          <bone aliases="avatar_mHandRing3Left" connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                         </bone>                                      </bone> -                                    <bone connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                       <bone connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                          <bone connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mHandPinky1Left" connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                       <bone aliases="avatar_mHandPinky2Left" connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                          <bone aliases="avatar_mHandPinky3Left" connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                         </bone>                                      </bone> -                                    <bone connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                       <bone connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                          <bone connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mHandThumb1Left" connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                       <bone aliases="avatar_mHandThumb2Left" connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                          <bone aliases="avatar_mHandThumb3Left" connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                         </bone>                                      </bone>                                   </bone> @@ -123,49 +123,49 @@                                   <collision_volume end="0.000 -0.100 -0.001" group="Collision" name="R_LOWER_ARM" pos="0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/>                                   <bone aliases="rHand avatar_mWristRight" connected="true" end="0.000 -0.060 0.000" group="Arms" name="mWristRight" pivot="-0.000000 -0.205000 -0.000000" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">                                      <collision_volume end="0.005 -0.049 -0.001" group="Collision" name="R_HAND" pos="0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03" support="base"/> -                                    <bone connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                       <bone connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                          <bone connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mHandMiddle1Right" connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                       <bone aliases="avatar_mHandMiddle2Right" connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                          <bone aliases="avatar_mHandMiddle3Right" connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                         </bone>                                      </bone> -                                    <bone connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                       <bone connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                          <bone connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mHandIndex1Right" connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                       <bone aliases="avatar_mHandIndex2Right" connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                          <bone aliases="avatar_mHandIndex3Right" connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                         </bone>                                      </bone> -                                    <bone connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                       <bone connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                          <bone connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mHandRing1Right" connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                       <bone aliases="avatar_mHandRing2Right" connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                          <bone aliases="avatar_mHandRing3Right" connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                         </bone>                                      </bone> -                                    <bone connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                       <bone connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                          <bone connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mHandPinky1Right" connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                       <bone aliases="avatar_mHandPinky2Right" connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                          <bone aliases="avatar_mHandPinky3Right" connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                         </bone>                                      </bone> -                                    <bone connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                       <bone connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                          <bone connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mHandThumb1Right" connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                       <bone aliases="avatar_mHandThumb2Right" connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                          <bone aliases="avatar_mHandThumb3Right" connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                         </bone>                                      </bone>                                   </bone>                                </bone>                             </bone>                          </bone> -                        <bone connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                           <bone connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                              <bone connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                 <bone connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                    <bone connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                    <bone connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                        <bone aliases="avatar_mWingsRoot" connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                           <bone aliases="avatar_mWing1Left" connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                              <bone aliases="avatar_mWing2Left" connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                 <bone aliases="avatar_mWing3Left" connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                    <bone aliases="avatar_mWing4Left" connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mWing4FanLeft" connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                   </bone>                                </bone>                             </bone> -                           <bone connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                              <bone connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                 <bone connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                                    <bone connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -                                    <bone connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                           <bone aliases="avatar_mWing1Right" connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                              <bone aliases="avatar_mWing2Right" connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                 <bone aliases="avatar_mWing3Right" connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                                    <bone aliases="avatar_mWing4Right" connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +                                    <bone aliases="avatar_mWing4FanRight" connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                                   </bone>                                </bone>                             </bone> @@ -200,30 +200,30 @@              </bone>           </bone>        </bone> -      <bone connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -         <bone connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -            <bone connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -               <bone connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                  <bone connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                     <bone connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +      <bone aliases="avatar_mTail1" connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +         <bone aliases="avatar_mTail2" connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +            <bone aliases="avatar_mTail3" connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +               <bone aliases="avatar_mTail4" connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                  <bone aliases="avatar_mTail5" connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                     <bone aliases="avatar_mTail6" connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                    </bone>                 </bone>              </bone>           </bone>        </bone> -      <bone connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> -      <bone connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -         <bone connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -            <bone connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -               <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                  <bone connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +      <bone aliases="avatar_mGroin" connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +      <bone aliases="avatar_mHindLimbsRoot" connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +         <bone aliases="avatar_mHindLimb1Left" connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +            <bone aliases="avatar_mHindLimb2Left" connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +               <bone aliases="avatar_mHindLimb3Left" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                  <bone aliases="avatar_mHindLimb4Left" connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                 </bone>              </bone>           </bone> -         <bone connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -            <bone connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -               <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> -                  <bone connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/> +         <bone aliases="avatar_mHindLimb1Right" connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +            <bone aliases="avatar_mHindLimb2Right" connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +               <bone aliases="avatar_mHindLimb3Right" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"> +                  <bone aliases="avatar_mHindLimb4Right" connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>                 </bone>              </bone>           </bone> diff --git a/indra/newview/cube.dae b/indra/newview/cube.dae new file mode 100644 index 0000000000..085b2c7309 --- /dev/null +++ b/indra/newview/cube.dae @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8"?> +<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1"> + <asset> +  <contributor> +   modified from https://gist.github.com/wtsnz/bfa11c40e04594b260255b5dc7956f26 +  </contributor> +  <created>2018-10-25T16:29:03Z</created> +  <modified>2022-02-18T00:00:00Z</modified> +  <unit meter="1.000000"/> +  <up_axis>Y_UP</up_axis> + </asset> + + <library_materials> +  <material id="Blue" name="Blue"> +   <instance_effect url="#effect_Blue"/> +  </material> + </library_materials> + + + <library_effects> +  <effect id="effect_Blue"> +   <profile_COMMON> +    <technique sid="common"> +     <phong> +      <ambient> +       <color>0 0 0 1</color> +      </ambient> +      <diffuse> +       <color>0.137255 0.403922 0.870588 1</color> +      </diffuse> +      <specular> +       <color>0.5 0.5 0.5 1</color> +      </specular> +      <shininess> +       <float>16</float> +      </shininess> +      <transparent opaque="A_ONE"> +       <color>0 0 0 1</color> +      </transparent> +      <transparency> +       <float>1</float> +      </transparency> +      <index_of_refraction> +       <float>1</float> +      </index_of_refraction> +     </phong> +    </technique> +   </profile_COMMON> +  </effect> + </library_effects> + + + <library_geometries> +  <geometry id="F1" name="default_physics_shape"> +   <mesh> + +    <source id="cube-vertex-positions"> +     <float_array id="ID2-array" count="72">-0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 </float_array> +     <technique_common> +      <accessor source="#ID2-array" count="24" stride="3"> +       <param name="X" type="float"/> +       <param name="Y" type="float"/> +       <param name="Z" type="float"/> +      </accessor> +     </technique_common> +    </source> + +    <vertices id="cube-vertices"> +     <input semantic="POSITION" source="#cube-vertex-positions"/> +    </vertices> + +    <triangles count="12" material="geometryElement5"> +     <input semantic="VERTEX" offset="0" source="#cube-vertices"/> +     <p>0 1 2 0 2 3 4 5 6 4 6 7 8 9 10 8 10 11 12 13 14 12 14 15 16 17 18 16 18 19 20 21 22 20 22 23 </p> +    </triangles> +     +   </mesh> +  </geometry> + </library_geometries> + <library_visual_scenes> + + +  <visual_scene id="reportScene"> +  <!-- No Spaces allowed in Name --> +   <node id="F1" name="Face1"> +    <instance_geometry url="#F1"> +     <bind_material> +      <technique_common> +       <instance_material symbol="geometryElement5" target="#Blue"/> +      </technique_common> +     </bind_material> +    </instance_geometry> +   </node> +  </visual_scene> + </library_visual_scenes> + + + <scene> +  <instance_visual_scene url="#reportScene"/> + </scene> + + +</COLLADA> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3bcd4f9a49..979a888814 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -557,7 +557,7 @@ static void settings_to_globals()  	gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");  	gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); -	LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale"); +    LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale"));  #if LL_DARWIN  	gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); @@ -3455,7 +3455,7 @@ void LLAppViewer::cleanupSavedSettings()  		}  	} -	gSavedSettings.setF32("MapScale", LLWorldMapView::sMapScale ); +    gSavedSettings.setF32("MapScale", LLWorldMapView::getScaleSetting());  	// Some things are cached in LLAgent.  	if (gAgent.isInitialized()) diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index a3037ed651..edfed832bc 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -294,7 +294,7 @@ BOOL LLFloaterBvhPreview::postBuild()  		loaderp->serialize(dp);  		dp.reset();  		LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL; -		BOOL success = motionp && motionp->deserialize(dp, mMotionID); +		BOOL success = motionp && motionp->deserialize(dp, mMotionID, false);  		LL_INFOS("BVH") << "Done" << LL_ENDL;  		delete []buffer; diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp index 6b1d9306fb..5b50fd7677 100644 --- a/indra/newview/llfloatercreatelandmark.cpp +++ b/indra/newview/llfloatercreatelandmark.cpp @@ -46,19 +46,60 @@  typedef std::pair<LLUUID, std::string> folder_pair_t; -class LLLandmarksInventoryObserver : public LLInventoryAddedObserver +class LLLandmarksInventoryObserver : public LLInventoryObserver  {  public:  	LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) :  		mFloater(create_landmark_floater)  	{} +    void changed(U32 mask) override +    { +        if (mFloater->getItem()) +        { +            checkChanged(mask); +        } +        else +        { +            checkCreated(mask); +        } +    } +  protected: -	/*virtual*/ void done() +	void checkCreated(U32 mask)  	{ +        if (gInventory.getAddedIDs().empty()) +        { +            return; +        } + +        if (!(mask & LLInventoryObserver::ADD) || +            !(mask & LLInventoryObserver::CREATE) || +            !(mask & LLInventoryObserver::UPDATE_CREATE)) +        { +            return; +        } +  		mFloater->setItem(gInventory.getAddedIDs());  	} +    void checkChanged(U32 mask) +    { +        if (gInventory.getChangedIDs().empty()) +        { +            return; +        } + +        if ((mask & LLInventoryObserver::LABEL) || +            (mask & LLInventoryObserver::INTERNAL) || +            (mask & LLInventoryObserver::REMOVE) || +            (mask & LLInventoryObserver::STRUCTURE) || +            (mask & LLInventoryObserver::REBUILD)) +        { +            mFloater->updateItem(gInventory.getChangedIDs(), mask); +        } +    } +  private:  	LLFloaterCreateLandmark* mFloater;  }; @@ -85,6 +126,9 @@ BOOL LLFloaterCreateLandmark::postBuild()  	getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this));  	getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this)); +    mLandmarkTitleEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); }); +    mNotesEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); }); +  	mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);  	return TRUE; @@ -204,6 +248,29 @@ void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id)  	}  } +void LLFloaterCreateLandmark::onCommitTextChanges() +{ +    std::string current_title_value = mLandmarkTitleEditor->getText(); +    std::string item_title_value = mItem->getName(); +    std::string current_notes_value = mNotesEditor->getText(); +    std::string item_notes_value = mItem->getDescription(); + +    LLStringUtil::trim(current_title_value); +    LLStringUtil::trim(current_notes_value); + +    if (!current_title_value.empty() && +        (item_title_value != current_title_value || item_notes_value != current_notes_value)) +    { +        LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem); +        new_item->rename(current_title_value); +        new_item->setDescription(current_notes_value); +        LLPointer<LLInventoryCallback> cb; +        LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0); +        gInventory.accountForUpdate(up); +        update_inventory_item(new_item, cb); +    } +} +  void LLFloaterCreateLandmark::onCreateFolderClicked()  {  	LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(), @@ -278,6 +345,8 @@ void LLFloaterCreateLandmark::onSaveClicked()  		new_item->updateParentOnServer(FALSE);  	} +    removeObserver(); +  	gInventory.updateItem(new_item);  	gInventory.notifyObservers(); @@ -286,6 +355,7 @@ void LLFloaterCreateLandmark::onSaveClicked()  void LLFloaterCreateLandmark::onCancelClicked()  { +    removeObserver();  	if (!mItem.isNull())  	{  		LLUUID item_id = mItem->getUUID(); @@ -314,10 +384,59 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)  		{  			if(!getItem())  			{ -				removeObserver();  				mItem = item; +                mAssetID = mItem->getAssetUUID(); +                setVisibleAndFrontmost(true);  				break;  			}  		}  	}  } + +void LLFloaterCreateLandmark::updateItem(const uuid_set_t& items, U32 mask) +{ +    if (!getItem()) +    { +        return; +    } + +    LLUUID landmark_id = getItem()->getUUID(); + +    for (uuid_set_t::const_iterator item_iter = items.begin(); +        item_iter != items.end(); +        ++item_iter) +    { +        const LLUUID& item_id = (*item_iter); +        if (landmark_id == item_id) +        { +            if (getItem() != gInventory.getItem(item_id)) +            { +                // item is obsolete or removed +                closeFloater(); +            } + +            LLUUID folder_id = mFolderCombo->getValue().asUUID(); +            if (folder_id != mItem->getParentUUID()) +            { +                // user moved landmark in inventory, +                // assume that we are done all other changes should already be commited +                closeFloater(); +            } + +            if ((mask & LLInventoryObserver::INTERNAL) && mAssetID != mItem->getAssetUUID()) +            { +                closeFloater(); +            } + +            if (mask & LLInventoryObserver::LABEL) +            { +                mLandmarkTitleEditor->setText(mItem->getName()); +            } + +            if (mask & LLInventoryObserver::INTERNAL) +            { +                mNotesEditor->setText(mItem->getDescription()); +            } +        } +    } +} diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h index 74ac5e651c..d84f5ae1fc 100644 --- a/indra/newview/llfloatercreatelandmark.h +++ b/indra/newview/llfloatercreatelandmark.h @@ -49,6 +49,7 @@ public:  	void onOpen(const LLSD& key);  	void setItem(const uuid_set_t& items); +    void updateItem(const uuid_set_t& items, U32 mask);  	LLInventoryItem* getItem() { return mItem; } @@ -56,6 +57,7 @@ private:  	void setLandmarkInfo(const LLUUID &folder_id);  	void removeObserver();  	void populateFoldersList(const LLUUID &folder_id = LLUUID::null); +    void onCommitTextChanges();  	void onCreateFolderClicked();  	void onSaveClicked();  	void onCancelClicked(); @@ -66,6 +68,7 @@ private:  	LLLineEditor*	mLandmarkTitleEditor;  	LLTextEditor*	mNotesEditor;  	LLUUID			mLandmarksID; +    LLUUID			mAssetID;  	LLLandmarksInventoryObserver*	mInventoryObserver;  	LLPointer<LLInventoryItem>		mItem; diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp index 42c5e40761..a00fc4aa84 100644 --- a/indra/newview/llfloaterhoverheight.cpp +++ b/indra/newview/llfloaterhoverheight.cpp @@ -100,11 +100,14 @@ void LLFloaterHoverHeight::onClose(bool app_quitting)  // static  void LLFloaterHoverHeight::onSliderMoved(LLUICtrl* ctrl, void* userData)  { -	LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); -	F32 value = sldrCtrl->getValueF32(); -	LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z)); -	LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL; -	gAgentAvatarp->setHoverOffset(offset, false); +    if (isAgentAvatarValid()) +    { +        LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl); +        F32 value = sldrCtrl->getValueF32(); +        LLVector3 offset(0.0, 0.0, llclamp(value, MIN_HOVER_Z, MAX_HOVER_Z)); +        LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL; +        gAgentAvatarp->setHoverOffset(offset, false); +    }  }  // Do send-to-the-server work when slider drag completes, or new diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 04133f2710..ff2384e382 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -3054,7 +3054,8 @@ BOOL LLPanelLandCovenant::postBuild()  {  	mLastRegionID = LLUUID::null;  	mNextUpdateTime = 0; - +    mTextEstateOwner = getChild<LLTextBox>("estate_owner_text"); +    mTextEstateOwner->setIsFriendCallback(LLAvatarActions::isFriend);  	return TRUE;  } @@ -3162,8 +3163,7 @@ void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name)  	LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant();  	if (self)  	{ -		LLTextBox* editor = self->getChild<LLTextBox>("estate_owner_text"); -		if (editor) editor->setText(name); +		self->mTextEstateOwner->setText(name);  	}  } diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 5d9b411f04..684950d88b 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -413,6 +413,7 @@ protected:  private:  	LLUUID mLastRegionID;  	F64 mNextUpdateTime; //seconds since client start +    LLTextBox* mTextEstateOwner;  };  #endif diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index fc2da772f3..fd1af7ccc0 100644..100755 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -51,7 +51,7 @@  // The minor cardinal direction labels are hidden if their height is more  // than this proportion of the map. -const F32 MAP_MINOR_DIR_THRESHOLD = 0.07f; +const F32 MAP_MINOR_DIR_THRESHOLD = 0.035f;  //  // Member functions @@ -77,35 +77,44 @@ LLFloaterMap::~LLFloaterMap()  BOOL LLFloaterMap::postBuild()  { -	mMap = getChild<LLNetMap>("Net Map"); -	if (gSavedSettings.getBOOL("DoubleClickTeleport")) -	{ -		mMap->setToolTipMsg(getString("AltToolTipMsg")); -	} -	else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap")) -	{ -		mMap->setToolTipMsg(getString("ToolTipMsg")); -	} -	sendChildToBack(mMap); -	 -	mTextBoxNorth = getChild<LLTextBox> ("floater_map_north"); -	mTextBoxEast = getChild<LLTextBox> ("floater_map_east"); -	mTextBoxWest = getChild<LLTextBox> ("floater_map_west"); -	mTextBoxSouth = getChild<LLTextBox> ("floater_map_south"); -	mTextBoxSouthEast = getChild<LLTextBox> ("floater_map_southeast"); -	mTextBoxNorthEast = getChild<LLTextBox> ("floater_map_northeast"); -	mTextBoxSouthWest = getChild<LLTextBox> ("floater_map_southwest"); -	mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest"); - -	updateMinorDirections(); - -	// Get the drag handle all the way in back -	sendChildToBack(getDragHandle()); - -	// keep onscreen -	gFloaterView->adjustToFitScreen(this, FALSE); - -	return TRUE; +    mMap = getChild<LLNetMap>("Net Map"); +    mMap->setToolTipMsg(getString("ToolTipMsg")); +    mMap->setParcelNameMsg(getString("ParcelNameMsg")); +    mMap->setParcelSalePriceMsg(getString("ParcelSalePriceMsg")); +    mMap->setParcelSaleAreaMsg(getString("ParcelSaleAreaMsg")); +    mMap->setParcelOwnerMsg(getString("ParcelOwnerMsg")); +    mMap->setRegionNameMsg(getString("RegionNameMsg")); +    mMap->setToolTipHintMsg(getString("ToolTipHintMsg")); +    mMap->setAltToolTipHintMsg(getString("AltToolTipHintMsg")); +    sendChildToBack(mMap); + +    mTextBoxNorth     = getChild<LLTextBox>("floater_map_north"); +    mTextBoxEast      = getChild<LLTextBox>("floater_map_east"); +    mTextBoxWest      = getChild<LLTextBox>("floater_map_west"); +    mTextBoxSouth     = getChild<LLTextBox>("floater_map_south"); +    mTextBoxSouthEast = getChild<LLTextBox>("floater_map_southeast"); +    mTextBoxNorthEast = getChild<LLTextBox>("floater_map_northeast"); +    mTextBoxSouthWest = getChild<LLTextBox>("floater_map_southwest"); +    mTextBoxNorthWest = getChild<LLTextBox>("floater_map_northwest"); + +    mTextBoxNorth->reshapeToFitText(); +    mTextBoxEast->reshapeToFitText(); +    mTextBoxWest->reshapeToFitText(); +    mTextBoxSouth->reshapeToFitText(); +    mTextBoxSouthEast->reshapeToFitText(); +    mTextBoxNorthEast->reshapeToFitText(); +    mTextBoxSouthWest->reshapeToFitText(); +    mTextBoxNorthWest->reshapeToFitText(); + +    updateMinorDirections(); + +    // Get the drag handle all the way in back +    sendChildToBack(getDragHandle()); + +    // keep onscreen +    gFloaterView->adjustToFitScreen(this, false); + +    return true;  }  BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask) @@ -138,23 +147,44 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)  	return TRUE;  } -void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation ) +void LLFloaterMap::setDirectionPos(LLTextBox *text_box, F32 rotation)  { -	// Rotation is in radians. -	// Rotation of 0 means x = 1, y = 0 on the unit circle. - -	F32 map_half_height = (F32)(getRect().getHeight() / 2) - getHeaderHeight()/2; -	F32 map_half_width = (F32)(getRect().getWidth() / 2) ; -	F32 text_half_height = (F32)(text_box->getRect().getHeight() / 2); -	F32 text_half_width = (F32)(text_box->getRect().getWidth() / 2); -	F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width ); - -	// Inset by a little to account for position display. -	radius -= 8.f; - -	text_box->setOrigin(  -		ll_round(map_half_width - text_half_width + radius * cos( rotation )), -		ll_round(map_half_height - text_half_height + radius * sin( rotation )) ); +    // Rotation is in radians. +    // Rotation of 0 means x = 1, y = 0 on the unit circle. + +    F32 map_half_height  = (F32) (getRect().getHeight() / 2) - (getHeaderHeight() / 2); +    F32 map_half_width   = (F32) (getRect().getWidth() / 2); +    F32 text_half_height = (F32) (text_box->getRect().getHeight() / 2); +    F32 text_half_width  = (F32) (text_box->getRect().getWidth() / 2); +    F32 extra_padding    = (F32) (mTextBoxNorth->getRect().getWidth() / 2); +    F32 pos_half_height  = map_half_height - text_half_height - extra_padding; +    F32 pos_half_width   = map_half_width - text_half_width - extra_padding; + +    F32 corner_angle               = atan2(pos_half_height, pos_half_width); +    F32 rotation_mirrored_into_top = abs(fmodf(rotation, F_PI)); +    if (rotation < 0) +    { +        rotation_mirrored_into_top = F_PI - rotation_mirrored_into_top; +    } +    F32  rotation_mirrored_into_top_right = (F_PI_BY_TWO - abs(rotation_mirrored_into_top - F_PI_BY_TWO)); +    bool at_left_right_edge               = rotation_mirrored_into_top_right < corner_angle; + +    F32 part_x = cos(rotation); +    F32 part_y = sin(rotation); +    F32 y; +    F32 x; +    if (at_left_right_edge) +    { +        x = std::copysign(pos_half_width, part_x); +        y = x * part_y / part_x; +    } +    else +    { +        y = std::copysign(pos_half_height, part_y); +        x = y * part_x / part_y; +    } + +    text_box->setOrigin(ll_round(map_half_width + x - text_half_width), ll_round(map_half_height + y - text_half_height));  }  void LLFloaterMap::updateMinorDirections() @@ -218,32 +248,6 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)  	updateMinorDirections();  } -void LLFloaterMap::handleZoom(const LLSD& userdata) -{ -	std::string level = userdata.asString(); -	 -	F32 scale = 0.0f; -	if (level == std::string("default")) -	{ -		LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale"); -		if(pvar) -		{ -			pvar->resetToDefault(); -			scale = gSavedSettings.getF32("MiniMapScale"); -		} -	} -	else if (level == std::string("close")) -		scale = LLNetMap::MAP_SCALE_MAX; -	else if (level == std::string("medium")) -		scale = LLNetMap::MAP_SCALE_MID; -	else if (level == std::string("far")) -		scale = LLNetMap::MAP_SCALE_MIN; -	if (scale != 0.0f) -	{ -		mMap->setScale(scale); -	} -} -  LLFloaterMap* LLFloaterMap::getInstance()  {  	return LLFloaterReg::getTypedInstance<LLFloaterMap>("mini_map"); diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h index ff2fb20535..929b1795aa 100644 --- a/indra/newview/llfloatermap.h +++ b/indra/newview/llfloatermap.h @@ -48,7 +48,6 @@ public:  	/*virtual*/ void	draw();  private: -	void handleZoom(const LLSD& userdata);  	void setDirectionPos( LLTextBox* text_box, F32 rotation );  	void updateMinorDirections(); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index fe5120376c..aae0883564 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -467,22 +467,25 @@ void LLFloaterModelPreview::loadHighLodModel()  	loadModel(3);  } -void LLFloaterModelPreview::loadModel(S32 lod) +void LLFloaterModelPreview::prepareToLoadModel(S32 lod)  {  	mModelPreview->mLoading = true;  	if (lod == LLModel::LOD_PHYSICS)  	{  		// loading physics from file  		mModelPreview->mPhysicsSearchLOD = lod; +		mModelPreview->mWarnOfUnmatchedPhyicsMeshes = false;  	} - +} +void LLFloaterModelPreview::loadModel(S32 lod) +{ +	prepareToLoadModel(lod);  	(new LLMeshFilePicker(mModelPreview, lod))->getFile();  }  void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm)  { -	mModelPreview->mLoading = true; - +	prepareToLoadModel(lod);  	mModelPreview->loadModel(file_name, lod, force_disable_slm);  } @@ -1063,11 +1066,18 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata)  	}  	S32 file_mode = iface->getItemCount() - 1; -	if (which_mode < file_mode) +	S32 cube_mode = file_mode - 1; +	if (which_mode < cube_mode)  	{  		S32 which_lod = num_lods - which_mode;  		sInstance->mModelPreview->setPhysicsFromLOD(which_lod);  	} +	else if (which_mode == cube_mode) +	{ +		std::string path = gDirUtilp->getAppRODataDir(); +		gDirUtilp->append(path, "cube.dae"); +		sInstance->loadModel(LLModel::LOD_PHYSICS, path); +	}  	LLModelPreview *model_preview = sInstance->mModelPreview;  	if (model_preview) @@ -1662,15 +1672,15 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL  void LLFloaterModelPreview::setCtrlLoadFromFile(S32 lod)  {      if (lod == LLModel::LOD_PHYSICS) -    { +	{          LLComboBox* lod_combo = findChild<LLComboBox>("physics_lod_combo");          if (lod_combo)          { -            lod_combo->setCurrentByIndex(5); +            lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1);          }      }      else -{ +	{          LLComboBox* lod_combo = findChild<LLComboBox>("lod_source_" + lod_name[lod]);          if (lod_combo)  	{ diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 1e147cd555..bda042186b 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -221,6 +221,7 @@ private:  	void resetUploadOptions();  	void clearLogTab(); +	void prepareToLoadModel(S32 lod);  	void createSmoothComboBox(LLComboBox* combo_box, float min, float max); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 19080f05c0..1390f56ea7 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -47,6 +47,7 @@  #include "llagent.h"  #include "llappviewer.h" +#include "llavataractions.h"  #include "llavatarname.h"  #include "llfloateravatarpicker.h"  #include "llbutton.h"  @@ -1826,7 +1827,7 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)  	setCtrlsEnabled(god || owner || manager);  	getChildView("apply_btn")->setEnabled(FALSE); - +    getChildView("estate_owner")->setEnabled(TRUE);  	getChildView("message_estate_btn")->setEnabled(god || owner || manager);  	getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager); @@ -1888,6 +1889,8 @@ BOOL LLPanelEstateInfo::postBuild()  	getChild<LLUICtrl>("externally_visible_radio")->setFocus(TRUE); +    getChild<LLTextBox>("estate_owner")->setIsFriendCallback(LLAvatarActions::isFriend); +  	return LLPanelRegionInfo::postBuild();  } @@ -2132,6 +2135,7 @@ BOOL LLPanelEstateCovenant::postBuild()  {  	mEstateNameText = getChild<LLTextBox>("estate_name_text");  	mEstateOwnerText = getChild<LLTextBox>("estate_owner_text"); +    mEstateOwnerText->setIsFriendCallback(LLAvatarActions::isFriend);  	mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text");  	mEditor = getChild<LLViewerTextEditor>("covenant_editor");  	LLButton* reset_button = getChild<LLButton>("reset_covenant"); diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 2c84cd1f93..e7b1efb41d 100644..100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -81,7 +81,6 @@  //---------------------------------------------------------------------------  // Constants  //--------------------------------------------------------------------------- -static const F32 MAP_ZOOM_TIME = 0.2f;  // Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed  // width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across @@ -284,7 +283,7 @@ void* LLFloaterWorldMap::createWorldMapView(void* data)  BOOL LLFloaterWorldMap::postBuild()  { -	mPanel = getChild<LLPanel>("objects_mapview"); +    mMapView = dynamic_cast<LLWorldMapView*>(getChild<LLPanel>("objects_mapview"));  	LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");  	avatar_combo->selectFirstItem(); @@ -305,13 +304,11 @@ BOOL LLFloaterWorldMap::postBuild()  	landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );  	mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo); -	mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f); -	getChild<LLUICtrl>("zoom slider")->setValue(mCurZoomVal); +    F32 slider_zoom = mMapView->getZoom(); +    getChild<LLUICtrl>("zoom slider")->setValue(slider_zoom);  	setDefaultBtn(NULL); -	mZoomTimer.stop(); -	  	onChangeMaturity();  	return TRUE; @@ -321,7 +318,7 @@ BOOL LLFloaterWorldMap::postBuild()  LLFloaterWorldMap::~LLFloaterWorldMap()  {  	// All cleaned up by LLView destructor -	mPanel = NULL; +    mMapView = NULL;  	// Inventory deletes all observers on shutdown  	mInventory = NULL; @@ -359,17 +356,15 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)  	mIsClosing = FALSE; -	LLWorldMapView* map_panel; -	map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel; -	map_panel->clearLastClick(); +    mMapView->clearLastClick();  	{  		// reset pan on show, so it centers on you again  		if (!center_on_target)  		{ -			LLWorldMapView::setPan(0, 0, TRUE); +            mMapView->setPan(0, 0, true);  		} -		map_panel->updateVisibleBlocks(); +        mMapView->updateVisibleBlocks();  		// Reload items as they may have changed  		LLWorldMap::getInstance()->reloadItems(); @@ -417,18 +412,21 @@ BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask)  BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks)  { -	if (!isMinimized() && isFrontmost()) -	{ -		if(mPanel->pointInView(x, y)) -		{ -			F32 slider_value = (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal(); -			slider_value += ((F32)clicks * -0.3333f); -			getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_value)); -			return TRUE; -		} -	} -	 -	return LLFloater::handleScrollWheel(x, y, clicks); +    if (!isMinimized() && isFrontmost()) +    { +        S32 map_x = x - mMapView->getRect().mLeft; +        S32 map_y = y - mMapView->getRect().mBottom; +        if (mMapView->pointInView(map_x, map_y)) +        { +            F32 old_slider_zoom = (F32) getChild<LLUICtrl>("zoom slider")->getValue().asReal(); +            F32 slider_zoom     = old_slider_zoom + ((F32) clicks * -0.3333f); +            getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_zoom)); +            mMapView->zoomWithPivot(slider_zoom, map_x, map_y); +            return true; +        } +    } + +    return LLFloater::handleScrollWheel(x, y, clicks);  } @@ -507,26 +505,13 @@ void LLFloaterWorldMap::draw()  	setMouseOpaque(TRUE);  	getDragHandle()->setMouseOpaque(TRUE); -	 -	//RN: snaps to zoom value because interpolation caused jitter in the text rendering -	if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal()) -	{ -		mZoomTimer.start(); -	} -	F32 interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME; -	if (interp > 1.f) -	{ -		interp = 1.f; -		mZoomTimer.stop(); -	} -	mCurZoomVal = lerp(mCurZoomVal, (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal(), interp); -	F32 map_scale = 256.f*pow(2.f, mCurZoomVal); -	LLWorldMapView::setScale( map_scale ); + +    mMapView->zoom((F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal());  	// Enable/disable checkboxes depending on the zoom level  	// If above threshold level (i.e. low res) -> Disable all checkboxes  	// If under threshold level (i.e. high res) -> Enable all checkboxes -	bool enable = LLWorldMapView::showRegionInfo(); +    bool enable = mMapView->showRegionInfo();  	getChildView("people_chk")->setEnabled(enable);  	getChildView("infohub_chk")->setEnabled(enable);  	getChildView("telehub_chk")->setEnabled(enable); @@ -1025,9 +1010,7 @@ void LLFloaterWorldMap::adjustZoomSliderBounds()  	S32 world_height_regions = MAX_VISIBLE_REGIONS;  	// Find how much space we have to display the world -	LLWorldMapView* map_panel; -	map_panel = (LLWorldMapView*)mPanel; -	LLRect view_rect = map_panel->getRect(); +    LLRect view_rect = mMapView->getRect();  	// View size in pixels  	S32 view_width = view_rect.getWidth(); @@ -1295,9 +1278,9 @@ void LLFloaterWorldMap::onShowTargetBtn()  void LLFloaterWorldMap::onShowAgentBtn()  { -	LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate -	// Set flag so user's location will be displayed if not tracking anything else -	mSetToUserPosition = TRUE;	 +    mMapView->setPan(0, 0, false);  // false == animate +    // Set flag so user's location will be displayed if not tracking anything else +    mSetToUserPosition = true;  }  void LLFloaterWorldMap::onClickTeleportBtn() @@ -1349,9 +1332,10 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)  		pos_global.clearVec();  	} -	LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),  -						   -llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)), -						   !animate); +    F64 map_scale = (F64)mMapView->getScale(); +    mMapView->setPan(-llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)), +                           -llfloor((F32)(pos_global.mdV[VY] * map_scale / REGION_WIDTH_METERS)), +                           !animate);  	mWaitingForTracker = FALSE;  } @@ -1581,7 +1565,7 @@ void LLFloaterWorldMap::onTeleportFinished()  {      if(isInVisibleChain())      { -        LLWorldMapView::setPan(0, 0, TRUE); +        mMapView->setPan(0, 0, TRUE);      }  } @@ -1656,9 +1640,8 @@ void LLFloaterWorldMap::onChangeMaturity()  void LLFloaterWorldMap::onFocusLost()  { -	gViewerWindow->showCursor(); -	LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel; -	map_panel->mPanning = FALSE; +    gViewerWindow->showCursor(); +    mMapView->mPanning = false;  }  LLPanelHideBeacon::LLPanelHideBeacon() : diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index 14a9c26fb9..378339d0ad 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -44,6 +44,7 @@ class LLInventoryObserver;  class LLItemInfo;  class LLLineEditor;  class LLTabContainer; +class LLWorldMapView;  class LLFloaterWorldMap : public LLFloater  { @@ -154,11 +155,7 @@ protected:      void            onTeleportFinished();  private: -	LLPanel*			mPanel;		// Panel displaying the map - -	// Ties to LLWorldMapView::sMapScale, in pixels per region -	F32						mCurZoomVal; -	LLFrameTimer			mZoomTimer; +    LLWorldMapView* mMapView; // Panel displaying the map  	// update display of teleport destination coordinates - pos is in global coordinates  	void updateTeleportCoordsDisplay( const LLVector3d& pos ); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index a0de3a2af1..62dfaafed1 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3798,7 +3798,20 @@ void LLFolderBridge::perform_pasteFromClipboard()  				{  					if (item && can_move_to_landmarks(item))  					{ -						dropToFavorites(item); +                        if (LLClipboard::instance().isCutMode()) +                        { +                            LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item); +                            llassert(viitem); +                            if (viitem) +                            { +                                //changeItemParent() implicity calls dirtyFilter +                                changeItemParent(model, viitem, parent_id, FALSE); +                            } +                        } +                        else +                        { +                            dropToFavorites(item); +                        }  					}  				}  				else if (LLClipboard::instance().isCutMode()) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 859d987fc3..d012a9b328 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -86,6 +86,7 @@ static const LLColor4 PREVIEW_DEG_FILL_COL(1.f, 0.f, 0.f, 0.5f);  static const F32 PREVIEW_DEG_EDGE_WIDTH(3.f);  static const F32 PREVIEW_DEG_POINT_SIZE(8.f);  static const F32 PREVIEW_ZOOM_LIMIT(10.f); +static const std::string DEFAULT_PHYSICS_MESH_NAME = "default_physics_shape";  const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f; @@ -432,6 +433,20 @@ void LLModelPreview::rebuildUploadData()                          LLFloaterModelPreview::addStringToLog(out, false);                      }                  } +                if (mWarnOfUnmatchedPhyicsMeshes && !lod_model && (i == LLModel::LOD_PHYSICS)) +                { +                    // Despite the various strategies above, if we don't now have a physics model, we're going to end up with decomposition. +                    // That's ok, but might not what they wanted. Use default_physics_shape if found. +                    std::ostringstream out; +                    out << "No physics model specified for " << instance.mLabel; +                    if (mDefaultPhysicsShapeP) +                    { +                        out << " - using: " << DEFAULT_PHYSICS_MESH_NAME; +                        lod_model = mDefaultPhysicsShapeP; +                    } +                    LL_WARNS() << out.str() << LL_ENDL; +                    LLFloaterModelPreview::addStringToLog(out, !mDefaultPhysicsShapeP); // Flash log tab if no default. +                }                  if (lod_model)                  { @@ -994,6 +1009,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)          }          else          { +            if (loaded_lod == LLModel::LOD_PHYSICS) +            {   // Explicitly loading physics. See if there is a default mesh. +                LLMatrix4 ignored_transform; // Each mesh that uses this will supply their own. +                mDefaultPhysicsShapeP = nullptr; +                FindModel(mScene[loaded_lod], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(loaded_lod), mDefaultPhysicsShapeP, ignored_transform); +                mWarnOfUnmatchedPhyicsMeshes = true; +            }              BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");              if (!legacyMatching)              { @@ -1064,7 +1086,6 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)                                      LL_WARNS() << out.str() << LL_ENDL;                                      LLFloaterModelPreview::addStringToLog(out, false);                                  } -                                  mModel[loaded_lod][idx]->mLabel = name;                              }                          } diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index 9e32215e6a..18e04914e5 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -224,6 +224,21 @@ private:      LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; }      // Count amount of original models, excluding sub-models      static U32 countRootModels(LLModelLoader::model_list models); +    /// Indicates whether we should warn of high-lod meshes that do not have a corresponding physics mesh. +    /// Reset when resetting the modelpreview (i.e., when the uploader dialog is created or reset), and when +    /// about to process a physics file. Set to true immediately after the file is loaded (before rebuildUploadData()). +    /// +    /// (The rules for mapping the correspondence of high-lod meshes to physics meshes are complex. When +    /// lod rendering meshes are used, there is never an unmatched mesh. Nor is there a mismatch when +    /// the high-lod file and physics file have ony one mesh each. In these cases, this value is moot. +    /// When there are multiple meshes in each file, they are matched by name or order, and some meshes +    /// are broken up by limitations into multiple objects, and thus there can be mismatches.) +    bool mWarnOfUnmatchedPhyicsMeshes{false}; +    /// A mesh to use as the default physics shape in only those cases where the physics shape is not otherwise specified. +    /// It is set only when the user chooses a physics shape file that contains a mesh with a name that matches DEFAULT_PHYSICS_MESH_NAME. +    /// It is reset when such a name is not found, and when resetting the modelpreview. +    /// Not read unless mWarnOfUnmatchedPhyicsMeshes is true. +    LLModel* mDefaultPhysicsShapeP{};      // Merges faces into single mesh, simplifies using mesh optimizer,      // then splits back into faces. diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 19dbbeb60e..e7d4ff7cdb 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -451,9 +451,9 @@ void LLNavigationBar::onLocationSelection()  			if(value.has("AssetUUID"))  			{ -				  				gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString())); -				mSaveToLocationHistory = true; +                // user teleported by manually inputting inventory landmark's name +				mSaveToLocationHistory = false;  				return;  			}  			else diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 1240ce7c0f..b34be80b07 100644..100755 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -37,6 +37,7 @@  #include "llfocusmgr.h"  #include "lllocalcliprect.h"  #include "llrender.h" +#include "llresmgr.h"  #include "llui.h"  #include "lltooltip.h" @@ -47,11 +48,16 @@  #include "llagentcamera.h"  #include "llappviewer.h" // for gDisconnected  #include "llcallingcard.h" // LLAvatarTracker +#include "llfloaterland.h"  #include "llfloaterworldmap.h" +#include "llparcel.h"  #include "lltracker.h"  #include "llsurface.h" +#include "llurlmatch.h" +#include "llurlregistry.h"  #include "llviewercamera.h"  #include "llviewercontrol.h" +#include "llviewerparcelmgr.h"  #include "llviewertexture.h"  #include "llviewertexturelist.h"  #include "llviewermenu.h" @@ -64,7 +70,10 @@  static LLDefaultChildRegistry::Register<LLNetMap> r1("net_map");  const F32 LLNetMap::MAP_SCALE_MIN = 32; -const F32 LLNetMap::MAP_SCALE_MID = 1024; +const F32 LLNetMap::MAP_SCALE_FAR = 32; +const F32 LLNetMap::MAP_SCALE_MEDIUM = 128; +const F32 LLNetMap::MAP_SCALE_CLOSE = 256; +const F32 LLNetMap::MAP_SCALE_VERY_CLOSE = 1024;  const F32 LLNetMap::MAP_SCALE_MAX = 4096;  const F32 MAP_SCALE_ZOOM_FACTOR = 1.04f; // Zoom in factor per click of scroll wheel (4%) @@ -78,13 +87,13 @@ const F64 COARSEUPDATE_MAX_Z = 1020.0f;  LLNetMap::LLNetMap (const Params & p)  :	LLUICtrl (p),  	mBackgroundColor (p.bg_color()), -	mScale( MAP_SCALE_MID ), -	mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ), +    mScale( MAP_SCALE_MEDIUM ), +    mPixelsPerMeter( MAP_SCALE_MEDIUM / REGION_WIDTH_METERS ),  	mObjectMapTPM(0.f),  	mObjectMapPixels(0.f), -	mTargetPan(0.f, 0.f),  	mCurPan(0.f, 0.f),  	mStartPan(0.f, 0.f), +    mPopupWorldPos(0.f, 0.f, 0.f),  	mMouseDown(0, 0),  	mPanning(false),  	mUpdateNow(false), @@ -97,6 +106,13 @@ LLNetMap::LLNetMap (const Params & p)  	mPopupMenu(NULL)  {  	mScale = gSavedSettings.getF32("MiniMapScale"); +    if (gAgent.isFirstLogin()) +    { +        // *HACK: On first run, set this to false for new users, otherwise the +        // default is true to maintain consistent experience for existing +        // users. +        gSavedSettings.setBOOL("MiniMapRotate", false); +    }  	mPixelsPerMeter = mScale / REGION_WIDTH_METERS;  	mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);  } @@ -107,13 +123,22 @@ LLNetMap::~LLNetMap()  BOOL LLNetMap::postBuild()  { -	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; -	 -	registrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2)); -	registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2)); - -	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -	return TRUE; +    LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commitRegistrar; +    LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enableRegistrar; + +    enableRegistrar.add("Minimap.Zoom.Check", boost::bind(&LLNetMap::isZoomChecked, this, _2)); +    commitRegistrar.add("Minimap.Zoom.Set", boost::bind(&LLNetMap::setZoom, this, _2)); +    commitRegistrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2)); +    commitRegistrar.add("Minimap.Center.Activate", boost::bind(&LLNetMap::activateCenterMap, this, _2)); +    enableRegistrar.add("Minimap.MapOrientation.Check", boost::bind(&LLNetMap::isMapOrientationChecked, this, _2)); +    commitRegistrar.add("Minimap.MapOrientation.Set", boost::bind(&LLNetMap::setMapOrientation, this, _2)); +    commitRegistrar.add("Minimap.AboutLand", boost::bind(&LLNetMap::popupShowAboutLand, this, _2)); + +    mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, +                                                                          LLViewerMenuHolderGL::child_registry_t::instance()); +    mPopupMenu->setItemEnabled("Re-center map", false); + +    return true;  }  void LLNetMap::setScale( F32 scale ) @@ -158,18 +183,32 @@ void LLNetMap::draw()  	static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);  	//static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);  	static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white); -	static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white); +	static LLUIColor map_parcel_outline_color = LLUIColorTable::instance().getColor("MapParcelOutlineColor", LLColor4(LLColor3(LLColor4::yellow), 0.5f));  	if (mObjectImagep.isNull())  	{  		createObjectImage();  	} -	static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true); -	if (auto_center) +    static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true); +    bool auto_centering = auto_center && !mPanning; +    mCentering = mCentering && !mPanning; + +    if (auto_centering || mCentering)  	{ -		mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f)); +        mCurPan = lerp(mCurPan, LLVector2(0.0f, 0.0f) , LLSmoothInterpolation::getInterpolant(0.1f));  	} +    bool centered = abs(mCurPan.mV[VX]) < 0.5f && abs(mCurPan.mV[VY]) < 0.5f; +    if (centered) +    { +        mCurPan.mV[0] = 0.0f; +        mCurPan.mV[1] = 0.0f; +        mCentering = false; +    } + +    bool can_recenter_map = !(centered || mCentering || auto_centering); +    mPopupMenu->setItemEnabled("Re-center map", can_recenter_map); +    updateAboutLandPopupButton();  	// Prepare a scissor region  	F32 rotation = 0; @@ -216,7 +255,8 @@ void LLNetMap::draw()  		}  		// figure out where agent is -		S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters()); +		const S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters()); +        const F32 scale_pixels_per_meter = mScale / region_width;  		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();  			 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -225,8 +265,8 @@ void LLNetMap::draw()  			// Find x and y position relative to camera's center.  			LLVector3 origin_agent = regionp->getOriginAgent();  			LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); -			F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale; -			F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale; +			F32 relative_x = rel_region_pos.mV[0] * scale_pixels_per_meter; +			F32 relative_y = rel_region_pos.mV[1] * scale_pixels_per_meter;  			// background region rectangle  			F32 bottom =	relative_y; @@ -249,6 +289,7 @@ void LLNetMap::draw()  			} +  			// Draw using texture.  			gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture());  			gGL.begin(LLRender::QUADS); @@ -310,8 +351,8 @@ void LLNetMap::draw()  		LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);  		LLVector3 camera_position = gAgentCamera.getCameraPositionAgent();  		map_center_agent -= camera_position; -		map_center_agent.mV[VX] *= mScale/region_width; -		map_center_agent.mV[VY] *= mScale/region_width; +		map_center_agent.mV[VX] *= scale_pixels_per_meter; +		map_center_agent.mV[VY] *= scale_pixels_per_meter;  		gGL.getTexUnit(0)->bind(mObjectImagep);  		F32 image_half_width = 0.5f*mObjectMapPixels; @@ -327,6 +368,13 @@ void LLNetMap::draw()  			gGL.texCoord2f(1.f, 1.f);  			gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]);  		gGL.end(); +         +		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); +			 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) +		{ +			LLViewerRegion* regionp = *iter; +            regionp->renderPropertyLinesOnMinimap(scale_pixels_per_meter, map_parcel_outline_color.get().mV); +        }  		gGL.popMatrix(); @@ -451,41 +499,34 @@ void LLNetMap::draw()  		F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();  		F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();  		F32 far_clip_pixels = far_clip_meters * meters_to_pixels; - -		F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); -		F32 half_width_pixels = half_width_meters * meters_to_pixels; -		F32 ctr_x = (F32)center_sw_left; -		F32 ctr_y = (F32)center_sw_bottom; - - -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - -		if( rotate_map ) -		{ -			gGL.color4fv((map_frustum_color()).mV); - -			gGL.begin( LLRender::TRIANGLES  ); -				gGL.vertex2f( ctr_x, ctr_y ); -				gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); -				gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); -			gGL.end(); -		} -		else -		{ -			gGL.color4fv((map_frustum_rotating_color()).mV); -			 -			// If we don't rotate the map, we have to rotate the frustum. -			gGL.pushMatrix(); -				gGL.translatef( ctr_x, ctr_y, 0 ); -				gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); -				gGL.begin( LLRender::TRIANGLES  ); -					gGL.vertex2f( 0, 0 ); -					gGL.vertex2f( -half_width_pixels, far_clip_pixels ); -					gGL.vertex2f(  half_width_pixels, far_clip_pixels ); -				gGL.end(); -			gGL.popMatrix(); -		} +        F32 ctr_x = (F32)center_sw_left; +        F32 ctr_y = (F32)center_sw_bottom; + +        const F32 steps_per_circle = 40.0f; +        const F32 steps_per_radian = steps_per_circle / F_TWO_PI; +        const F32 arc_start = -(horiz_fov / 2.0f) + F_PI_BY_TWO; +        const F32 arc_end = (horiz_fov / 2.0f) + F_PI_BY_TWO; +        const S32 steps = llmax(1, (S32)((horiz_fov * steps_per_radian) + 0.5f)); + +        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + +        if( rotate_map ) +        { +            gGL.pushMatrix(); +                gGL.translatef( ctr_x, ctr_y, 0 ); +                gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color()); +            gGL.popMatrix(); +        } +        else +        { +            gGL.pushMatrix(); +                gGL.translatef( ctr_x, ctr_y, 0 ); +                // If we don't rotate the map, we have to rotate the frustum. +                gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); +                gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color()); +            gGL.popMatrix(); +        }  	}  	gGL.popMatrix(); @@ -552,6 +593,65 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color,  	}  } +bool LLNetMap::isMouseOnPopupMenu() +{ +    if (!mPopupMenu->isOpen()) +    { +        return false; +    } + +    S32 popup_x; +    S32 popup_y; +    LLUI::getInstance()->getMousePositionLocal(mPopupMenu, &popup_x, &popup_y); +    // *NOTE: Tolerance is larger than it needs to be because the context menu is offset from the mouse when the menu is opened from certain +    // directions. This may be a quirk of LLMenuGL::showPopup. -Cosmic,2022-03-22 +    constexpr S32 tolerance = 10; +    // Test tolerance from all four corners, as the popup menu can appear from a different direction if there's not enough space. +    // Assume the size of the popup menu is much larger than the provided tolerance. +    // In practice, this is a [tolerance]px margin around the popup menu. +    for (S32 sign_x = -1; sign_x <= 1; sign_x += 2) +    { +        for (S32 sign_y = -1; sign_y <= 1; sign_y += 2) +        { +            if (mPopupMenu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance))) +            { +                return true; +            } +        } +    } +    return false; +} + +void LLNetMap::updateAboutLandPopupButton() +{ +    if (!mPopupMenu->isOpen()) +    { +        return; +    } + +    LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mPopupWorldPos); +    if (!region) +    { +        mPopupMenu->setItemEnabled("About Land", false); +    } +    else +    { +        // Check if the mouse is in the bounds of the popup. If so, it's safe to assume no other hover function will be called, so the hover +        // parcel can be used to check if location-sensitive tooltip options are available. +        if (isMouseOnPopupMenu()) +        { +            LLViewerParcelMgr::getInstance()->setHoverParcel(mPopupWorldPos); +            LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel(); +            bool      valid_parcel = false; +            if (hover_parcel) +            { +                valid_parcel = hover_parcel->getOwnerID().notNull(); +            } +            mPopupMenu->setItemEnabled("About Land", valid_parcel); +        } +    } +} +  LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )  {  	x -= ll_round(getRect().getWidth() / 2 + mCurPan.mV[VX]); @@ -579,66 +679,152 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )  BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks)  { -	// note that clicks are reversed from what you'd think: i.e. > 0  means zoom out, < 0 means zoom in -	F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks); +    // note that clicks are reversed from what you'd think: i.e. > 0  means zoom out, < 0 means zoom in +    F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);  	F32 old_scale = mScale; -	setScale(new_scale); +    setScale(new_scale); -	static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true); -	if (!auto_center) -	{ -		// Adjust pan to center the zoom on the mouse pointer -		LLVector2 zoom_offset; -		zoom_offset.mV[VX] = x - getRect().getWidth() / 2; -		zoom_offset.mV[VY] = y - getRect().getHeight() / 2; -		mCurPan -= zoom_offset * mScale / old_scale - zoom_offset; -	} +    static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true); +    if (!auto_center) +    { +        // Adjust pan to center the zoom on the mouse pointer +        LLVector2 zoom_offset; +        zoom_offset.mV[VX] = x - getRect().getWidth() / 2; +        zoom_offset.mV[VY] = y - getRect().getHeight() / 2; +        mCurPan -= zoom_offset * mScale / old_scale - zoom_offset; +    } -	return TRUE; +    return true;  } -BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask ) +BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask)  { -	if (gDisconnected) -	{ -		return FALSE; -	} +    if (gDisconnected) +    { +        return false; +    } -	// If the cursor is near an avatar on the minimap, a mini-inspector will be -	// shown for the avatar, instead of the normal map tooltip. -	if (handleToolTipAgent(mClosestAgentToCursor)) -	{ -		return TRUE; -	} +    // If the cursor is near an avatar on the minimap, a mini-inspector will be +    // shown for the avatar, instead of the normal map tooltip. +    if (handleToolTipAgent(mClosestAgentToCursor)) +    { +        return true; +    } -	LLRect sticky_rect; -	std::string region_name; -	LLViewerRegion*	region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) ); -	if(region) -	{ -		// set sticky_rect -		S32 SLOP = 4; -		localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom)); -		sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP; -		sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP; - -		region_name = region->getName(); -		if (!region_name.empty()) -		{ -			region_name += "\n"; -		} -	} +    // The popup menu uses the hover parcel when it is open and the mouse is on +    // top of it, with some additional tolerance. Returning early here prevents +    // fighting over that hover parcel when getting tooltip info in the +    // tolerance region. +    if (isMouseOnPopupMenu()) +    { +        return false; +    } -	LLStringUtil::format_map_t args; -	args["[REGION]"] = region_name; -	std::string msg = mToolTipMsg; -	LLStringUtil::format(msg, args); -	LLToolTipMgr::instance().show(LLToolTip::Params() -		.message(msg) -		.sticky_rect(sticky_rect)); -		 -	return TRUE; +    LLRect sticky_rect; +    S32 SLOP = 4; +    localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom)); +    sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP; +    sticky_rect.mTop   = sticky_rect.mBottom + 2 * SLOP; + +    std::string parcel_name_msg; +    std::string parcel_sale_price_msg; +    std::string parcel_sale_area_msg; +    std::string parcel_owner_msg; +    std::string region_name_msg; + +    LLVector3d      posGlobal = viewPosToGlobal(x, y); +    LLViewerRegion *region    = LLWorld::getInstance()->getRegionFromPosGlobal(posGlobal); +    if (region) +    { +        std::string region_name = region->getName(); +        if (!region_name.empty()) +        { +            region_name_msg = mRegionNameMsg; +            LLStringUtil::format(region_name_msg, {{"[REGION_NAME]", region_name}}); +        } + +        // Only show parcel information in the tooltip if property lines are visible. Otherwise, the parcel the tooltip is referring to is +        // ambiguous. +        if (gSavedSettings.getBOOL("MiniMapShowPropertyLines")) +        { +            LLViewerParcelMgr::getInstance()->setHoverParcel(posGlobal); +            LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel(); +            if (hover_parcel) +            { +                std::string parcel_name = hover_parcel->getName(); +                if (!parcel_name.empty()) +                { +                    parcel_name_msg = mParcelNameMsg; +                    LLStringUtil::format(parcel_name_msg, {{"[PARCEL_NAME]", parcel_name}}); +                } + +                const LLUUID      parcel_owner          = hover_parcel->getOwnerID(); +                std::string       parcel_owner_name_url = LLSLURL("agent", parcel_owner, "inspect").getSLURLString(); +                static LLUrlMatch parcel_owner_name_url_match; +                LLUrlRegistry::getInstance()->findUrl(parcel_owner_name_url, parcel_owner_name_url_match); +                if (!parcel_owner_name_url_match.empty()) +                { +                    parcel_owner_msg              = mParcelOwnerMsg; +                    std::string parcel_owner_name = parcel_owner_name_url_match.getLabel(); +                    LLStringUtil::format(parcel_owner_msg, {{"[PARCEL_OWNER]", parcel_owner_name}}); +                } + +                if (hover_parcel->getForSale()) +                { +                    const LLUUID auth_buyer_id = hover_parcel->getAuthorizedBuyerID(); +                    const LLUUID agent_id      = gAgent.getID(); +                    bool         show_for_sale = auth_buyer_id.isNull() || auth_buyer_id == agent_id || parcel_owner == agent_id; +                    if (show_for_sale) +                    { +                        S32 price        = hover_parcel->getSalePrice(); +                        S32 area         = hover_parcel->getArea(); +                        F32 cost_per_sqm = 0.0f; +                        if (area > 0) +                        { +                            cost_per_sqm = F32(price) / area; +                        } +                        std::string formatted_price          = LLResMgr::getInstance()->getMonetaryString(price); +                        std::string formatted_cost_per_meter = llformat("%.1f", cost_per_sqm); +                        parcel_sale_price_msg                = mParcelSalePriceMsg; +                        LLStringUtil::format(parcel_sale_price_msg, +                                             {{"[PRICE]", formatted_price}, {"[PRICE_PER_SQM]", formatted_cost_per_meter}}); +                        std::string formatted_area = llformat("%d", area); +                        parcel_sale_area_msg       = mParcelSaleAreaMsg; +                        LLStringUtil::format(parcel_sale_area_msg, {{"[AREA]", formatted_area}}); +                    } +                } +            } +        } +    } + +    std::string tool_tip_hint_msg; +    if (gSavedSettings.getBOOL("DoubleClickTeleport")) +    { +        tool_tip_hint_msg = mAltToolTipHintMsg; +    } +    else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap")) +    { +        tool_tip_hint_msg = mToolTipHintMsg; +    } + +    LLStringUtil::format_map_t args; +    args["[PARCEL_NAME_MSG]"]       = parcel_name_msg.empty() ? "" : parcel_name_msg + '\n'; +    args["[PARCEL_SALE_PRICE_MSG]"] = parcel_sale_price_msg.empty() ? "" : parcel_sale_price_msg + '\n'; +    args["[PARCEL_SALE_AREA_MSG]"]  = parcel_sale_area_msg.empty() ? "" : parcel_sale_area_msg + '\n'; +    args["[PARCEL_OWNER_MSG]"]      = parcel_owner_msg.empty() ? "" : parcel_owner_msg + '\n'; +    args["[REGION_NAME_MSG]"]       = region_name_msg.empty() ? "" : region_name_msg + '\n'; +    args["[TOOL_TIP_HINT_MSG]"]     = tool_tip_hint_msg.empty() ? "" : tool_tip_hint_msg + '\n'; + +    std::string msg                 = mToolTipMsg; +    LLStringUtil::format(msg, args); +    if (msg.back() == '\n') +    { +        msg.resize(msg.size() - 1); +    } +    LLToolTipMgr::instance().show(LLToolTip::Params().message(msg).sticky_rect(sticky_rect)); + +    return true;  }  BOOL LLNetMap::handleToolTipAgent(const LLUUID& avatar_id) @@ -811,59 +997,58 @@ void LLNetMap::createObjectImage()  	mUpdateNow = true;  } -BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask ) +BOOL LLNetMap::handleMouseDown(S32 x, S32 y, MASK mask)  { -	if (!(mask & MASK_SHIFT)) return FALSE; - -	// Start panning -	gFocusMgr.setMouseCapture(this); +    // Start panning +    gFocusMgr.setMouseCapture(this); -	mStartPan = mCurPan; -	mMouseDown.mX = x; -	mMouseDown.mY = y; -	return TRUE; +    mStartPan     = mCurPan; +    mMouseDown.mX = x; +    mMouseDown.mY = y; +    return true;  } -BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask ) +BOOL LLNetMap::handleMouseUp(S32 x, S32 y, MASK mask)  { -	if(abs(mMouseDown.mX-x)<3 && abs(mMouseDown.mY-y)<3) -		handleClick(x,y,mask); +    if (abs(mMouseDown.mX - x) < 3 && abs(mMouseDown.mY - y) < 3) +    { +        handleClick(x, y, mask); +    } -	if (hasMouseCapture()) -	{ -		if (mPanning) -		{ -			// restore mouse cursor -			S32 local_x, local_y; -			local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]); -			local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]); -			LLRect clip_rect = getRect(); -			clip_rect.stretch(-8); -			clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y); -			LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y); - -			// finish the pan -			mPanning = false; - -			mMouseDown.set(0, 0); - -			// auto centre -			mTargetPan.setZero(); -		} -		gViewerWindow->showCursor(); -		gFocusMgr.setMouseCapture(NULL); -		return TRUE; -	} -	return FALSE; +    if (hasMouseCapture()) +    { +        if (mPanning) +        { +            // restore mouse cursor +            S32 local_x, local_y; +            local_x          = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]); +            local_y          = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]); +            LLRect clip_rect = getRect(); +            clip_rect.stretch(-8); +            clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y); +            LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y); + +            // finish the pan +            mPanning = false; + +            mMouseDown.set(0, 0); +        } +        gViewerWindow->showCursor(); +        gFocusMgr.setMouseCapture(NULL); +        return true; +    } + +    return false;  }  BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)  {  	if (mPopupMenu)  	{ +        mPopupWorldPos = viewPosToGlobal(x, y);  		mPopupMenu->buildDrawLabels();  		mPopupMenu->updateParent(LLMenuGL::sMenuContainer); -		mPopupMenu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0)); +		mPopupMenu->setItemEnabled("Stop tracking", LLTracker::isTracking(0));  		LLMenuGL::showPopup(this, mPopupMenu, x, y);  	}  	return TRUE; @@ -911,6 +1096,27 @@ BOOL LLNetMap::handleDoubleClick(S32 x, S32 y, MASK mask)  	return TRUE;  } +F32 LLNetMap::getScaleForName(std::string scale_name) +{ +    if (scale_name == "very close") +    { +        return LLNetMap::MAP_SCALE_VERY_CLOSE; +    } +    else if (scale_name == "close") +    { +        return LLNetMap::MAP_SCALE_CLOSE; +    } +    else if (scale_name == "medium") +    { +        return LLNetMap::MAP_SCALE_MEDIUM; +    } +    else if (scale_name == "far") +    { +        return LLNetMap::MAP_SCALE_FAR; +    } +    return 0.0f; +} +  // static  bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop )  { @@ -928,7 +1134,7 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )  		{  			if (!mPanning)  			{ -				// just started panning, so hide cursor +                // Just started panning. Hide cursor.  				mPanning = true;  				gViewerWindow->hideCursor();  			} @@ -938,61 +1144,89 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )  			// Set pan to value at start of drag + offset  			mCurPan += delta; -			mTargetPan = mCurPan;  			gViewerWindow->moveCursorToCenter();  		} - -		// Doesn't really matter, cursor should be hidden -		gViewerWindow->setCursor( UI_CURSOR_TOOLPAN ); -	} -	else -	{ -		if (mask & MASK_SHIFT) -		{ -			// If shift is held, change the cursor to hint that the map can be dragged -			gViewerWindow->setCursor( UI_CURSOR_TOOLPAN ); -		} -		else -		{ -			gViewerWindow->setCursor( UI_CURSOR_CROSS ); -		}  	} +    if (mask & MASK_SHIFT) +    { +        // If shift is held, change the cursor to hint that the map can be +        // dragged. However, holding shift is not required to drag the map. +        gViewerWindow->setCursor( UI_CURSOR_TOOLPAN ); +    } +    else +    { +        gViewerWindow->setCursor( UI_CURSOR_CROSS ); +    } +  	return TRUE;  } -void LLNetMap::handleZoom(const LLSD& userdata) +bool LLNetMap::isZoomChecked(const LLSD &userdata)  { -	std::string level = userdata.asString(); -	 -	F32 scale = 0.0f; -	if (level == std::string("default")) -	{ -		LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale"); -		if(pvar) -		{ -			pvar->resetToDefault(); -			scale = gSavedSettings.getF32("MiniMapScale"); -		} -	} -	else if (level == std::string("close")) -		scale = LLNetMap::MAP_SCALE_MAX; -	else if (level == std::string("medium")) -		scale = LLNetMap::MAP_SCALE_MID; -	else if (level == std::string("far")) -		scale = LLNetMap::MAP_SCALE_MIN; -	if (scale != 0.0f) -	{ -		setScale(scale); -	} +    std::string level = userdata.asString(); +    F32         scale = getScaleForName(level); +    return scale == mScale; +} + +void LLNetMap::setZoom(const LLSD &userdata) +{ +    std::string level = userdata.asString(); +    F32         scale = getScaleForName(level); +    if (scale != 0.0f) +    { +        setScale(scale); +    }  }  void LLNetMap::handleStopTracking (const LLSD& userdata)  {  	if (mPopupMenu)  	{ -		mPopupMenu->setItemEnabled ("Stop Tracking", false); +		mPopupMenu->setItemEnabled ("Stop tracking", false);  		LLTracker::stopTracking (LLTracker::isTracking(NULL));  	}  } + +void LLNetMap::activateCenterMap(const LLSD &userdata) { mCentering = true; } + +bool LLNetMap::isMapOrientationChecked(const LLSD &userdata) +{ +    const std::string command_name = userdata.asString(); +    const bool        rotate_map   = gSavedSettings.getBOOL("MiniMapRotate"); +    if (command_name == "north_at_top") +    { +        return !rotate_map; +    } + +    if (command_name == "camera_at_top") +    { +        return rotate_map; +    } + +    return false; +} + +void LLNetMap::setMapOrientation(const LLSD &userdata) +{ +    const std::string command_name = userdata.asString(); +    if (command_name == "north_at_top") +    { +        gSavedSettings.setBOOL("MiniMapRotate", false); +    } +    else if (command_name == "camera_at_top") +    { +        gSavedSettings.setBOOL("MiniMapRotate", true); +    } +} + +void LLNetMap::popupShowAboutLand(const LLSD &userdata) +{ +    // Update parcel selection. It's important to deselect land first so the "About Land" floater doesn't refresh with the old selection. +    LLViewerParcelMgr::getInstance()->deselectLand(); +    LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt(mPopupWorldPos); +    gMenuHolder->setParcelSelection(selection); + +    LLFloaterReg::showInstance("about_land", LLSD(), false); +} diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index 1f7e7d68c6..fe1aca65a9 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -62,9 +62,12 @@ protected:  public:  	virtual ~LLNetMap(); -	static const F32 MAP_SCALE_MIN; -	static const F32 MAP_SCALE_MID; -	static const F32 MAP_SCALE_MAX; +    static const F32 MAP_SCALE_MIN; +    static const F32 MAP_SCALE_FAR; +    static const F32 MAP_SCALE_MEDIUM; +    static const F32 MAP_SCALE_CLOSE; +    static const F32 MAP_SCALE_VERY_CLOSE; +    static const F32 MAP_SCALE_MAX;  	/*virtual*/ void	draw();  	/*virtual*/ BOOL	handleScrollWheel(S32 x, S32 y, S32 clicks); @@ -79,8 +82,17 @@ public:  	/*virtual*/ BOOL	handleClick(S32 x, S32 y, MASK mask);  	/*virtual*/ BOOL	handleDoubleClick( S32 x, S32 y, MASK mask ); -	void			setScale( F32 scale ); -	void			setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; } +    void            setScale(F32 scale); + +    void            setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; } +    void            setParcelNameMsg(const std::string& msg) { mParcelNameMsg = msg; } +    void            setParcelSalePriceMsg(const std::string& msg) { mParcelSalePriceMsg = msg; } +    void            setParcelSaleAreaMsg(const std::string& msg) { mParcelSaleAreaMsg = msg; } +    void            setParcelOwnerMsg(const std::string& msg) { mParcelOwnerMsg = msg; } +    void            setRegionNameMsg(const std::string& msg) { mRegionNameMsg = msg; } +    void            setToolTipHintMsg(const std::string& msg) { mToolTipHintMsg = msg; } +    void            setAltToolTipHintMsg(const std::string& msg) { mAltToolTipHintMsg = msg; } +  	void			renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius );  private: @@ -94,11 +106,14 @@ private:  	void			drawTracking( const LLVector3d& pos_global,   								  const LLColor4& color,  								  BOOL draw_arrow = TRUE); +    bool            isMouseOnPopupMenu(); +    void            updateAboutLandPopupButton();  	BOOL			handleToolTipAgent(const LLUUID& avatar_id);  	static void		showAvatarInspector(const LLUUID& avatar_id);  	void			createObjectImage(); +    F32             getScaleForName(std::string scale_name);  	static bool		outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop);  private: @@ -112,11 +127,12 @@ private:  	F32				mObjectMapPixels;		// Width of object map in pixels  	F32				mDotRadius;				// Size of avatar markers -	bool			mPanning;			// map is being dragged -	LLVector2		mTargetPan; -	LLVector2		mCurPan; -	LLVector2		mStartPan;		// pan offset at start of drag -	LLCoordGL		mMouseDown;			// pointer position at start of drag +    bool            mPanning; // map is being dragged +    bool            mCentering; // map is being re-centered around the agent +    LLVector2       mCurPan; +    LLVector2       mStartPan; // pan offset at start of drag +    LLVector3d      mPopupWorldPos; // world position picked under mouse when context menu is opened +    LLCoordGL       mMouseDown; // pointer position at start of drag  	LLVector3d		mObjectImageCenterGlobal;  	LLPointer<LLImageRaw> mObjectRawImagep; @@ -125,14 +141,26 @@ private:  	LLUUID			mClosestAgentToCursor;  	LLUUID			mClosestAgentAtLastRightClick; -	std::string		mToolTipMsg; +    std::string     mToolTipMsg; +    std::string     mParcelNameMsg; +    std::string     mParcelSalePriceMsg; +    std::string     mParcelSaleAreaMsg; +    std::string     mParcelOwnerMsg; +    std::string     mRegionNameMsg; +    std::string     mToolTipHintMsg; +    std::string     mAltToolTipHintMsg;  public:  	void			setSelected(uuid_vec_t uuids) { gmSelected=uuids; };  private: -	void handleZoom(const LLSD& userdata); -	void handleStopTracking (const LLSD& userdata); +    bool isZoomChecked(const LLSD& userdata); +    void setZoom(const LLSD& userdata); +    void handleStopTracking(const LLSD& userdata); +    void activateCenterMap(const LLSD& userdata); +    bool isMapOrientationChecked(const LLSD& userdata); +    void setMapOrientation(const LLSD& userdata); +    void popupShowAboutLand(const LLSD& userdata);  	LLMenuGL*		mPopupMenu;  	uuid_vec_t		gmSelected; diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp index 5bfe5c9941..9603ee6329 100644 --- a/indra/newview/llphysicsshapebuilderutil.cpp +++ b/indra/newview/llphysicsshapebuilderutil.cpp @@ -29,7 +29,7 @@  #include "llphysicsshapebuilderutil.h"  /* static */ -void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut ) +void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut)  {  	const LLProfileParams& profile_params = volume_params.getProfileParams();  	const LLPathParams& path_params = volume_params.getPathParams(); @@ -191,6 +191,7 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara  	if ( volume_params.shouldForceConvex() )  	{ +        // Server distinguishes between convex of a prim vs isSculpt, but we don't care.  		specOut.mType = PhysicsShapeSpecification::USER_CONVEX;  	}	  	// Make a simpler convex shape if we can. @@ -199,6 +200,16 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara  	{  		specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX;  	} +    else if (volume_params.isMeshSculpt() && +             // Check overall dimensions, not individual triangles. +             (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || +              scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || +              scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE +              ) ) +    { +        // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't. +        specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; +    }  	else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy)  	{  		specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT; diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h index bd5b7d799c..b3b100296f 100644 --- a/indra/newview/llphysicsshapebuilderutil.h +++ b/indra/newview/llphysicsshapebuilderutil.h @@ -47,6 +47,7 @@ const F32 SHAPE_BUILDER_ENTRY_SNAP_SCALE_BIN_SIZE = 0.15f;  const F32 SHAPE_BUILDER_ENTRY_SNAP_PARAMETER_BIN_SIZE = 0.010f;  const F32 SHAPE_BUILDER_CONVEXIFICATION_SIZE = 2.f * COLLISION_TOLERANCE;  const F32 SHAPE_BUILDER_MIN_GEOMETRY_SIZE = 0.5f * COLLISION_TOLERANCE; +const F32 SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE = 0.5f;  class LLPhysicsVolumeParams : public LLVolumeParams  { diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 3f7e8531fb..14fae8d035 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -50,6 +50,10 @@  #include "llpreviewnotecard.h"  #include "llpreviewgesture.h"  #include "llcoproceduremanager.h" +#include "llthread.h" +#include "llkeyframemotion.h" +#include "lldatapacker.h" +#include "llvoavatarself.h"  void dialog_refresh_all(); @@ -450,9 +454,62 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()          errorLabel = "DoNotSupportBulkAnimationUpload";          error = true;      } -    else if (assetType == LLAssetType::AT_ANIMATION) +    else if (exten == "anim") +    { +		// Default unless everything succeeds +		errorLabel = "ProblemWithFile"; +		error = true; + +        // read from getFileName() +		LLAPRFile infile; +		infile.open(getFileName(),LL_APR_RB); +		if (!infile.getFileHandle()) +		{ +			LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL; +			errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str()); +		} +		else +		{ +			S32 size = LLAPRFile::size(getFileName()); +			U8* buffer = new U8[size]; +			S32 size_read = infile.read(buffer,size); +			if (size_read != size) +			{ +				errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read); +			} +			else +			{ +				LLDataPackerBinaryBuffer dp(buffer, size); +				LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId()); +				motionp->setCharacter(gAgentAvatarp); +				if (motionp->deserialize(dp, getAssetId(), false)) +				{ +					// write to temp file +					bool succ = motionp->dumpToFile(filename); +					if (succ) +					{ +						assetType = LLAssetType::AT_ANIMATION; +						errorLabel = ""; +						error = false; +					} +					else +					{ +						errorMessage = "Failed saving temporary animation file"; +					} +				} +				else +				{ +					errorMessage = "Failed reading animation file"; +				} +			} +		} +    } +    else      { -        filename = getFileName(); +        // Unknown extension +        errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str()); +        errorLabel = "ErrorMessage"; +        error = TRUE;;      }      if (error) @@ -863,6 +920,7 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res      {          args["FILE"] = uploadInfo->getDisplayName();          args["REASON"] = reason; +        args["ERROR"] = reason;      }      LLNotificationsUtil::add(label, args); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a886303563..685913587b 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -33,6 +33,7 @@  #include "llavataractions.h"  #include "llavatarnamecache.h"		// IDEVO HACK  #include "lleventtimer.h" +#include "llfloatercreatelandmark.h"  #include "llfloaterreg.h"  #include "llfolderview.h"  #include "llfollowcamparams.h" @@ -1560,6 +1561,17 @@ bool highlight_offered_object(const LLUUID& obj_id)  		}  	} +    if (obj->getType() == LLAssetType::AT_LANDMARK) +    { +        LLFloaterCreateLandmark *floater = LLFloaterReg::findTypedInstance<LLFloaterCreateLandmark>("add_landmark"); +        if (floater && floater->getItem() && floater->getItem()->getUUID() == obj_id) +        { +            // LLFloaterCreateLandmark is supposed to handle this, +            // keep landmark creation floater at the front +            return false; +        } +    } +  	return true;  } diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index e69b0347f8..3bd504709b 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1591,6 +1591,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use      else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID)      {          // new agent parcel +        // *TODO: Does it really make sense to set the agent parcel to this +        // parcel if the client doesn't know what kind of parcel data this is?          parcel_mgr.mAgentParcelSequenceID = sequence_id;          parcel = parcel_mgr.mAgentParcel;      } diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 02f7bbeed8..4d1a7e0ba3 100644..100755 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -908,8 +908,8 @@ S32 LLViewerParcelOverlay::renderPropertyLines	()  	// Always fudge a little vertically.  	pull_toward_camera.mV[VZ] += 0.01f; -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.pushMatrix(); +    gGL.matrixMode(LLRender::MM_MODELVIEW); +    gGL.pushMatrix();  	// Move to appropriate region coords  	LLVector3 origin = mRegion->getOriginAgent(); @@ -1014,7 +1014,65 @@ S32 LLViewerParcelOverlay::renderPropertyLines	()  	} -	gGL.popMatrix(); +    gGL.popMatrix();  	return drawn;  } + +// Draw half of a single cell (no fill) in a grid drawn from left to right and from bottom to top +void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F32 bottom, bool has_left, bool has_bottom) +{ +    gGL.begin(LLRender::LINES); + +    if (has_left) +    { +        gGL.vertex2f(left, bottom); +        gGL.vertex2f(left, top); +    } +    if (has_bottom) +    { +        gGL.vertex2f(left, bottom); +        gGL.vertex2f(right, bottom); +    } + +    gGL.end(); +} + +void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color) +{ +    if (!mOwnership) +    { +        return; +    } +    if (!gSavedSettings.getBOOL("MiniMapShowPropertyLines")) +    { +        return; +    } + +    LLVector3 origin_agent     = mRegion->getOriginAgent(); +    LLVector3 rel_region_pos   = origin_agent - gAgentCamera.getCameraPositionAgent(); +    F32       region_left      = rel_region_pos.mV[0] * scale_pixels_per_meter; +    F32       region_bottom    = rel_region_pos.mV[1] * scale_pixels_per_meter; +    F32       map_parcel_width = PARCEL_GRID_STEP_METERS * scale_pixels_per_meter; +    const S32 GRIDS_PER_EDGE   = mParcelGridsPerEdge; + +    gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +    glLineWidth(1.0f); +    gGL.color4fv(parcel_outline_color); +    for (S32 i = 0; i < GRIDS_PER_EDGE + 1; i++) +    { +        F32 bottom = region_bottom + (i * map_parcel_width); +        F32 top    = bottom + map_parcel_width; +        for (S32 j = 0; j < GRIDS_PER_EDGE + 1; j++) +        { +            F32 left    = region_left + (j * map_parcel_width); +            F32 right   = left + map_parcel_width; +            U8  overlay = mOwnership[(i * GRIDS_PER_EDGE) + j]; +            // The property line vertices are three-dimensional, but here we only care about the x and y coordinates, as we are drawing on a +            // 2D map +            const bool has_left   = i != GRIDS_PER_EDGE && (j == GRIDS_PER_EDGE || (overlay & PARCEL_WEST_LINE)); +            const bool has_bottom = j != GRIDS_PER_EDGE && (i == GRIDS_PER_EDGE || (overlay & PARCEL_SOUTH_LINE)); +            grid_2d_part_lines(left, top, right, bottom, has_left, has_bottom); +        } +    } +} diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index e30dbf17b3..053f69ba4c 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -69,6 +69,7 @@ public:  	// Returns the number of vertices drawn  	S32				renderPropertyLines(); +    void			renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);  	U8				ownership( const LLVector3& pos) const;  	U8				parcelLineFlags( const LLVector3& pos) const; @@ -82,7 +83,7 @@ public:  	void	idleUpdate(bool update_now = false);  	void	updateGL(); - +      private:  	// This is in parcel rows and columns, not grid rows and columns  	// Stored in bottom three bits. diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 67ad72e997..33ad463538 100644..100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1080,6 +1080,15 @@ S32 LLViewerRegion::renderPropertyLines()  	}  } +void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color) +{ +    if (mParcelOverlay) +    { +        mParcelOverlay->renderPropertyLinesOnMinimap(scale_pixels_per_meter, parcel_outline_color); +    } +} + +  // This gets called when the height field changes.  void LLViewerRegion::dirtyHeights()  { diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index fcbf56c81f..b6c8f5c583 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -154,6 +154,8 @@ public:  	// Draw lines in the dirt showing ownership. Return number of   	// vertices drawn.  	S32 renderPropertyLines(); +    void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color); +  	// Call this whenever you change the height data in the region.  	// (Automatically called by LLSurfacePatch's update routine) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 314c22eb6c..37851ce99b 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -6184,7 +6184,21 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )  	if (iter == mJointMap.end() || iter->second == NULL)  	{   //search for joint and cache found joint in lookup table -		jointp = mRoot->findJoint(name); +		if (mJointAliasMap.empty()) +		{ +			getJointAliases(); +		} +		joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name); +		std::string canonical_name; +		if (alias_iter != mJointAliasMap.end()) +		{ +			canonical_name = alias_iter->second; +		} +		else +		{ +			canonical_name = name; +		} +		jointp = mRoot->findJoint(canonical_name);  		mJointMap[name] = jointp;  	}  	else diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 59ac4554d7..2ac4b30d2e 100644..100755 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -58,9 +58,15 @@  #include "llglheaders.h" +// # Constants +static const F32 MAP_DEFAULT_SCALE = 128.f; +static const F32 MAP_ITERP_TIME_CONSTANT = 0.75f; +static const F32 MAP_ZOOM_ACCELERATION_TIME = 0.3f; +static const F32 MAP_ZOOM_MAX_INTERP = 0.5f; +static const F32 MAP_SCALE_SNAP_THRESHOLD = 0.005f; +  // Basically a C++ implementation of the OCEAN_COLOR defined in mapstitcher.py   // Please ensure consistency between those 2 files (TODO: would be better to get that color from an asset source...) -// # Constants  // OCEAN_COLOR = "#1D475F"  const F32 OCEAN_RED   = (F32)(0x1D)/255.f;  const F32 OCEAN_GREEN = (F32)(0x47)/255.f; @@ -92,14 +98,12 @@ LLUIImagePtr LLWorldMapView::sClassifiedsImage = NULL;  LLUIImagePtr LLWorldMapView::sForSaleImage = NULL;  LLUIImagePtr LLWorldMapView::sForSaleAdultImage = NULL; -F32 LLWorldMapView::sPanX = 0.f; -F32 LLWorldMapView::sPanY = 0.f; -F32 LLWorldMapView::sTargetPanX = 0.f; -F32 LLWorldMapView::sTargetPanY = 0.f;  S32 LLWorldMapView::sTrackingArrowX = 0;  S32 LLWorldMapView::sTrackingArrowY = 0;  bool LLWorldMapView::sVisibleTilesLoaded = false; -F32 LLWorldMapView::sMapScale = 128.f; +F32 LLWorldMapView::sMapScaleSetting = MAP_DEFAULT_SCALE; +LLVector2 LLWorldMapView::sZoomPivot = LLVector2(0.0f, 0.0f); +LLFrameTimer LLWorldMapView::sZoomTimer = LLFrameTimer();  std::map<std::string,std::string> LLWorldMapView::sStringsMap; @@ -166,20 +170,26 @@ void LLWorldMapView::cleanupClass()  	sForSaleAdultImage = NULL;  } -LLWorldMapView::LLWorldMapView() -:	LLPanel(), -	mBackgroundColor( LLColor4( OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f ) ), -	mItemPicked(FALSE), -	mPanning( FALSE ), -	mMouseDownPanX( 0 ), -	mMouseDownPanY( 0 ), -	mMouseDownX( 0 ), -	mMouseDownY( 0 ), -	mSelectIDStart(0) +LLWorldMapView::LLWorldMapView() : +    LLPanel(), +    mBackgroundColor(LLColor4(OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f)), +    mItemPicked(FALSE), +    mPanX(0.f), +    mPanY(0.f), +    mTargetPanX(0.f), +    mTargetPanY(0.f), +    mPanning(FALSE), +    mMouseDownPanX(0), +    mMouseDownPanY(0), +    mMouseDownX(0), +    mMouseDownY(0), +    mSelectIDStart(0), +    mMapScale(0.f), +    mTargetMapScale(0.f)  { -	//LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL; +    // LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL; -	clearLastClick(); +    clearLastClick();  }  BOOL LLWorldMapView::postBuild() @@ -210,6 +220,9 @@ BOOL LLWorldMapView::postBuild()  	mTextBoxNorthEast ->reshapeToFitText();  	mTextBoxSouthWest->reshapeToFitText();  	mTextBoxNorthWest ->reshapeToFitText(); +     +    sZoomTimer.stop(); +    setScale(sMapScaleSetting, true);  	return true;  } @@ -227,59 +240,103 @@ void LLWorldMapView::cleanupTextures()  {  } +void LLWorldMapView::zoom(F32 zoom) +{ +    mTargetMapScale = scaleFromZoom(zoom); +    if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) +    { +        sZoomPivot = LLVector2(0, 0); +        sZoomTimer.start(); +    } +} -// static -void LLWorldMapView::setScale( F32 scale ) +void LLWorldMapView::zoomWithPivot(F32 zoom, S32 x, S32 y)  { -	if (scale != sMapScale) -	{ -		F32 old_scale = sMapScale; +    mTargetMapScale = scaleFromZoom(zoom); +    sZoomPivot      = LLVector2(x, y); +    if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) +    { +        sZoomTimer.start(); +    } +} -		sMapScale = scale; -		if (sMapScale <= 0.f) -		{ -			sMapScale = 0.1f; -		} +F32 LLWorldMapView::getZoom() { return LLWorldMapView::zoomFromScale(mMapScale); } -		F32 ratio = (scale / old_scale); -		sPanX *= ratio; -		sPanY *= ratio; -		sTargetPanX = sPanX; -		sTargetPanY = sPanY; -		sVisibleTilesLoaded = false; -	} -} +F32 LLWorldMapView::getScale() { return mMapScale; } +// static +void LLWorldMapView::setScaleSetting(F32 scaleSetting) { sMapScaleSetting = scaleSetting; }  // static -void LLWorldMapView::translatePan( S32 delta_x, S32 delta_y ) +F32 LLWorldMapView::getScaleSetting() { return sMapScaleSetting; } + +void LLWorldMapView::setScale(F32 scale, bool snap)  { -	sPanX += delta_x; -	sPanY += delta_y; -	sTargetPanX = sPanX; -	sTargetPanY = sPanY; -	sVisibleTilesLoaded = false; +    if (scale != mMapScale) +    { +        F32 old_scale = mMapScale; + +        mMapScale = scale; +        // Set the scale used when saving the setting +        sMapScaleSetting = scale; +        if (mMapScale <= 0.f) +        { +            mMapScale = 0.1f; +        } + +        F32 ratio = (scale / old_scale); +        mPanX *= ratio; +        mPanY *= ratio; +        mTargetPanX         = mPanX; +        mTargetPanY         = mPanY; +        sVisibleTilesLoaded = false; + +        // If we are zooming relative to somewhere else rather than the center of the map, compensate for the difference in panning here +        if (!sZoomPivot.isExactlyZero()) +        { +            LLVector2 relative_pivot; +            relative_pivot.mV[VX]     = sZoomPivot.mV[VX] - (getRect().getWidth() / 2.0); +            relative_pivot.mV[VY]     = sZoomPivot.mV[VY] - (getRect().getHeight() / 2.0); +            LLVector2 zoom_pan_offset = relative_pivot - (relative_pivot * scale / old_scale); +            mPanX += zoom_pan_offset.mV[VX]; +            mPanY += zoom_pan_offset.mV[VY]; +            mTargetPanX += zoom_pan_offset.mV[VX]; +            mTargetPanY += zoom_pan_offset.mV[VY]; +        } +    } + +    if (snap) +    { +        mTargetMapScale = scale; +    }  } -  // static -void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap ) +void LLWorldMapView::translatePan(S32 delta_x, S32 delta_y)  { -	sTargetPanX = (F32)x; -	sTargetPanY = (F32)y; -	if (snap) -	{ -		sPanX = sTargetPanX; -		sPanY = sTargetPanY; -	} -	sVisibleTilesLoaded = false; +    mPanX += delta_x; +    mPanY += delta_y; +    mTargetPanX         = mPanX; +    mTargetPanY         = mPanY; +    sVisibleTilesLoaded = false;  } -bool LLWorldMapView::showRegionInfo() + +// static +void LLWorldMapView::setPan(S32 x, S32 y, BOOL snap)  { -	return (LLWorldMipmap::scaleToLevel(sMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); +    mTargetPanX = (F32) x; +    mTargetPanY = (F32) y; +    if (snap) +    { +        mPanX = mTargetPanX; +        mPanY = mTargetPanY; +    } +    sVisibleTilesLoaded = false;  } +bool LLWorldMapView::showRegionInfo() { return (LLWorldMipmap::scaleToLevel(mMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); } +  ///////////////////////////////////////////////////////////////////////////////////  // HELPERS @@ -301,8 +358,27 @@ void LLWorldMapView::draw()  	mVisibleRegions.clear();  	// animate pan if necessary -	sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(0.1f)); -	sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(0.1f)); +    mPanX = lerp(mPanX, mTargetPanX, LLSmoothInterpolation::getInterpolant(MAP_ITERP_TIME_CONSTANT)); +	mPanY = lerp(mPanY, mTargetPanY, LLSmoothInterpolation::getInterpolant(MAP_ITERP_TIME_CONSTANT)); +     +    //RN: snaps to zoom value because interpolation caused jitter in the text rendering +    if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) +    { +        sZoomTimer.start(); +    } +    bool snap_scale = false; +    F32 interp = llmin(MAP_ZOOM_MAX_INTERP, sZoomTimer.getElapsedTimeF32() / MAP_ZOOM_ACCELERATION_TIME); +    F32 current_zoom_val = zoomFromScale(mMapScale); +    F32 target_zoom_val = zoomFromScale(mTargetMapScale); +    F32 new_zoom_val = lerp(current_zoom_val, target_zoom_val, interp); +    if (abs(new_zoom_val - current_zoom_val) < MAP_SCALE_SNAP_THRESHOLD) +    { +        sZoomTimer.stop(); +        snap_scale = true; +        new_zoom_val = target_zoom_val; +    } +    F32 map_scale = scaleFromZoom(new_zoom_val); +    setScale(map_scale, snap_scale);  	const S32 width = getRect().getWidth();  	const S32 height = getRect().getHeight(); @@ -310,7 +386,7 @@ void LLWorldMapView::draw()  	const F32 half_height = F32(height) / 2.0f;  	LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); -	S32 level = LLWorldMipmap::scaleToLevel(sMapScale); +	S32 level = LLWorldMipmap::scaleToLevel(mMapScale);  	LLLocalClipRect clip(getLocalRect());  	{ @@ -347,15 +423,15 @@ void LLWorldMapView::draw()  		// Find x and y position relative to camera's center.  		LLVector3d rel_region_pos = origin_global - camera_global; -		F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale; -		F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale; +		F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * mMapScale; +		F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * mMapScale;  		// Coordinates of the sim in pixels in the UI panel  		// When the view isn't panned, 0,0 = center of rectangle -		F32 bottom =    sPanY + half_height + relative_y; -		F32 left =      sPanX + half_width + relative_x; -		F32 top =       bottom + sMapScale ; -		F32 right =     left + sMapScale ; +		F32 bottom =    mPanY + half_height + relative_y; +		F32 left =      mPanX + half_width + relative_x; +		F32 top =       bottom + mMapScale ; +		F32 right =     left + mMapScale ;  		// Discard if region is outside the screen rectangle (not visible on screen)  		if ((top < 0.f)   || (bottom > height) || @@ -416,7 +492,7 @@ void LLWorldMapView::draw()  			if (overlayimage)  			{  				// Inform the fetch mechanism of the size we need -				S32 draw_size = ll_round(sMapScale); +				S32 draw_size = ll_round(mMapScale);  				overlayimage->setKnownDrawSize(ll_round(draw_size * LLUI::getScaleFactor().mV[VX]), ll_round(draw_size * LLUI::getScaleFactor().mV[VY]));  				// Draw something whenever we have enough info  				if (overlayimage->hasGLTexture()) @@ -444,7 +520,7 @@ void LLWorldMapView::draw()  		}  		// Draw the region name in the lower left corner -		if (sMapScale >= DRAW_TEXT_THRESHOLD) +		if (mMapScale >= DRAW_TEXT_THRESHOLD)  		{  			LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Small", LLFontGL::BOLD));  			std::string mesg; @@ -464,7 +540,7 @@ void LLWorldMapView::draw()  					LLColor4::white,  					LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW,  					S32_MAX, //max_chars -					sMapScale, //max_pixels +					mMapScale, //max_pixels  					NULL,  					TRUE); //use ellipses  			} @@ -591,7 +667,7 @@ void LLWorldMapView::setVisible(BOOL visible)  void LLWorldMapView::drawMipmap(S32 width, S32 height)  {  	// Compute the level of the mipmap to use for the current scale level -	S32 level = LLWorldMipmap::scaleToLevel(sMapScale); +	S32 level = LLWorldMipmap::scaleToLevel(mMapScale);  	// Set the tile boost level so that unused tiles get to 0  	LLWorldMap::getInstance()->equalizeBoostLevels(); @@ -874,7 +950,7 @@ void LLWorldMapView::drawAgents()  void LLWorldMapView::drawFrustum()  {  	// Draw frustum -	F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS; +	F32 meters_to_pixels = mMapScale/ REGION_WIDTH_METERS;  	F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();  	F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); @@ -884,8 +960,8 @@ void LLWorldMapView::drawFrustum()  	F32 half_width_pixels = half_width_meters * meters_to_pixels;  	// Compute the frustum coordinates. Take the UI scale into account. -    F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX)  * LLUI::getScaleFactor().mV[VX]); -    F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]); +    F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + mPanX)  * LLUI::getScaleFactor().mV[VX]); +    F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + mPanY) * LLUI::getScaleFactor().mV[VY]);  	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -942,13 +1018,13 @@ LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos )  	LLVector3 pos_local;  	pos_local.setVec(relative_pos_global);  // convert to floats from doubles -	pos_local.mV[VX] *= sMapScale / REGION_WIDTH_METERS; -	pos_local.mV[VY] *= sMapScale / REGION_WIDTH_METERS; +	pos_local.mV[VX] *= mMapScale / REGION_WIDTH_METERS; +	pos_local.mV[VY] *= mMapScale / REGION_WIDTH_METERS;  	// leave Z component in meters -	pos_local.mV[VX] += getRect().getWidth() / 2 + sPanX; -	pos_local.mV[VY] += getRect().getHeight() / 2 + sPanY; +	pos_local.mV[VX] += getRect().getWidth() / 2 + mPanX; +	pos_local.mV[VY] += getRect().getHeight() / 2 + mPanY;  	return pos_local;  } @@ -1019,12 +1095,12 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&  // If you change this, then you need to change LLTracker::getTrackedPositionGlobal() as well  LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y )  { -	x -= llfloor((getRect().getWidth() / 2 + sPanX)); -	y -= llfloor((getRect().getHeight() / 2 + sPanY)); +	x -= llfloor((getRect().getWidth() / 2 + mPanX)); +	y -= llfloor((getRect().getHeight() / 2 + mPanY));  	LLVector3 pos_local( (F32)x, (F32)y, 0.f ); -	pos_local *= ( REGION_WIDTH_METERS / sMapScale ); +	pos_local *= ( REGION_WIDTH_METERS / mMapScale );  	LLVector3d pos_global;  	pos_global.setVec( pos_local ); @@ -1481,7 +1557,7 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,  	LLWorldMap::getInstance()->cancelTracking(); -	S32 level = LLWorldMipmap::scaleToLevel(sMapScale); +	S32 level = LLWorldMipmap::scaleToLevel(mMapScale);  	// If the zoom level is not too far out already, test hits  	if (level <= DRAW_SIMINFO_THRESHOLD)  	{ @@ -1598,8 +1674,8 @@ BOOL LLWorldMapView::handleMouseDown( S32 x, S32 y, MASK mask )  {  	gFocusMgr.setMouseCapture( this ); -	mMouseDownPanX = ll_round(sPanX); -	mMouseDownPanY = ll_round(sPanY); +	mMouseDownPanX = ll_round(mPanX); +	mMouseDownPanY = ll_round(mPanY);  	mMouseDownX = x;  	mMouseDownY = y;  	sHandledLastClick = TRUE; @@ -1614,8 +1690,8 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask )  		{  			// restore mouse cursor  			S32 local_x, local_y; -			local_x = mMouseDownX + llfloor(sPanX - mMouseDownPanX); -			local_y = mMouseDownY + llfloor(sPanY - mMouseDownPanY); +			local_x = mMouseDownX + llfloor(mPanX - mMouseDownPanX); +			local_y = mMouseDownY + llfloor(mPanY - mMouseDownPanY);  			LLRect clip_rect = getRect();  			clip_rect.stretch(-8);  			clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y); @@ -1643,7 +1719,7 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask )  void LLWorldMapView::updateVisibleBlocks()  { -	if (LLWorldMipmap::scaleToLevel(sMapScale) > DRAW_SIMINFO_THRESHOLD) +	if (LLWorldMipmap::scaleToLevel(mMapScale) > DRAW_SIMINFO_THRESHOLD)  	{  		// If we're zoomed out too much, we just don't load all those sim info: too much!  		return; @@ -1659,16 +1735,16 @@ void LLWorldMapView::updateVisibleBlocks()  	const F32 half_height = F32(height) / 2.0f;  	// Compute center into sim grid coordinates -	S32 world_center_x = S32((-sPanX / sMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); -	S32 world_center_y = S32((-sPanY / sMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); +	S32 world_center_x = S32((-mPanX / mMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); +	S32 world_center_y = S32((-mPanY / mMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS));  	// Compute the boundaries into sim grid coordinates -	S32 world_left   = world_center_x - S32(half_width  / sMapScale) - 1; -	S32 world_right  = world_center_x + S32(half_width  / sMapScale) + 1; -	S32 world_bottom = world_center_y - S32(half_height / sMapScale) - 1; -	S32 world_top    = world_center_y + S32(half_height / sMapScale) + 1; +	S32 world_left   = world_center_x - S32(half_width  / mMapScale) - 1; +	S32 world_right  = world_center_x + S32(half_width  / mMapScale) + 1; +	S32 world_bottom = world_center_y - S32(half_height / mMapScale) - 1; +	S32 world_top    = world_center_y + S32(half_height / mMapScale) + 1; -	//LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : sMapScale = " << sMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom  = " << world_bottom << ", top = " << world_top << LL_ENDL; +	//LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : mMapScale = " << mMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom  = " << world_bottom << ", top = " << world_top << LL_ENDL;  	LLWorldMap::getInstance()->updateRegions(world_left, world_bottom, world_right, world_top);  } @@ -1689,10 +1765,10 @@ BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask )  			F32 delta_y = (F32)(gViewerWindow->getCurrentMouseDY());  			// Set pan to value at start of drag + offset -			sPanX += delta_x; -			sPanY += delta_y; -			sTargetPanX = sPanX; -			sTargetPanY = sPanY; +			mPanX += delta_x; +			mPanY += delta_y; +			mTargetPanX = mPanX; +			mTargetPanY = mPanY;  			gViewerWindow->moveCursorToCenter();  		} @@ -1789,4 +1865,8 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )  	return FALSE;  } +// static +F32 LLWorldMapView::scaleFromZoom(F32 zoom) { return exp2(zoom) * 256.0f; } +// static +F32 LLWorldMapView::zoomFromScale(F32 scale) { return log2(scale / 256.f); } diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h index a2a6dc53fb..edbdded120 100644 --- a/indra/newview/llworldmapview.h +++ b/indra/newview/llworldmapview.h @@ -67,12 +67,21 @@ public:  	bool			checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bool track);  	void			handleClick(S32 x, S32 y, MASK mask, S32* hit_type, LLUUID* id); -	// Scale and pan are shared across all instances! (i.e. Terrain and Objects maps are always registered) -	static void		setScale( F32 scale ); -	static void		translatePan( S32 delta_x, S32 delta_y ); -	static void		setPan( S32 x, S32 y, BOOL snap = TRUE ); +    // Scale, aka zoom, is shared across all instances! (i.e. Terrain and Objects maps are always registered) +    // Zoom is used for UI and will interpolate the map scale over multiple frames. +    void zoom(F32 zoom); +    void zoomWithPivot(F32 zoom, S32 x, S32 y); +    F32 getZoom(); +    // Scale is a linear scaling factor of in-world coordinates +    F32 getScale(); +    // setScaleSetting/getScaleSetting are for the default map setting on login +    static void setScaleSetting(F32 scaleSetting); +    static F32 getScaleSetting(); +    // Pan is in pixels relative to the center of the map. +	void translatePan( S32 delta_x, S32 delta_y ); +    void setPan( S32 x, S32 y, BOOL snap = TRUE );  	// Return true if the current scale level is above the threshold for accessing region info -	static bool		showRegionInfo(); +    bool showRegionInfo();  	LLVector3		globalPosToView(const LLVector3d& global_pos);  	LLVector3d		viewPosToGlobal(S32 x,S32 y); @@ -153,14 +162,12 @@ public:  	static LLUIImagePtr	sForSaleImage;  	static LLUIImagePtr	sForSaleAdultImage; -	static F32		sMapScale;				// scale = size of a region in pixels -  	BOOL			mItemPicked; -	static F32		sPanX;		// in pixels -	static F32		sPanY;		// in pixels -	static F32		sTargetPanX;		// in pixels -	static F32		sTargetPanY;		// in pixels +    F32 mPanX; // in pixels +    F32 mPanY; // in pixels +    F32 mTargetPanX; // in pixels +    F32 mTargetPanY; // in pixels  	static S32		sTrackingArrowX;  	static S32		sTrackingArrowY;  	static bool		sVisibleTilesLoaded; @@ -194,6 +201,17 @@ public:  private:  	void drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right); + +    void setScale(F32 scale, bool snap = true); + +    static F32 scaleFromZoom(F32 zoom); +    static F32 zoomFromScale(F32 scale); + +    F32 mMapScale; +    F32 mTargetMapScale; +    static F32 sMapScaleSetting; +    static LLVector2 sZoomPivot; +    static LLFrameTimer sZoomTimer;  };  #endif diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 7beb013fba..eb25fd14a6 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -514,8 +514,8 @@       name="MapFrustumColor"       reference="White_10" />      <color -     name="MapFrustumRotatingColor" -     value="1 1 1 0.2" /> +     name="MapParcelOutlineColor" +     value="1 1 0 0.5" />      <color       name="MapTrackColor"       reference="Red" /> @@ -607,10 +607,10 @@       value="0 0 0 1" />      <color       name="NetMapGroupOwnAboveWater" -     reference="Purple" /> +     value="0.85 0 0.85 1" />      <color       name="NetMapGroupOwnBelowWater" -     value="0.78 0 0.78 1" /> +     value="0.63 0 0.63 1" />      <color       name="NetMapOtherOwnAboveWater"       value="0.24 0.24 0.24 1" /> @@ -619,10 +619,10 @@       value="0.12 0.12 0.12 1" />      <color       name="NetMapYouOwnAboveWater" -     value="0 1 1 1" /> +     value="0 0.85 0.85 1" />      <color       name="NetMapYouOwnBelowWater" -     value="0 0.78 0.78 1" /> +     value="0 0.63 0.63 1" />      <color       name="NotifyBoxColor"       value="LtGray" /> diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml index bba30626b2..632daaec7e 100644 --- a/indra/newview/skins/default/xui/en/floater_create_landmark.xml +++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml @@ -88,6 +88,7 @@       spellcheck="true"       text_readonly_color="white"       text_type="ascii_with_newline" +     commit_on_focus_lost="true"       top_pad="5"       width="290"       wrap="true" /> diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml index b8893e11d9..9639e70544 100644 --- a/indra/newview/skins/default/xui/en/floater_map.xml +++ b/indra/newview/skins/default/xui/en/floater_map.xml @@ -16,11 +16,35 @@   width="200">      <floater.string       name="ToolTipMsg"> -        [REGION](Double-click to open Map, shift-drag to pan) +        [PARCEL_NAME_MSG][PARCEL_SALE_PRICE_MSG][PARCEL_SALE_AREA_MSG][PARCEL_OWNER_MSG][REGION_NAME_MSG][TOOL_TIP_HINT_MSG] +    </floater.string> +    <floater.string +     name="ParcelNameMsg"> +        [PARCEL_NAME] +    </floater.string> +    <floater.string +     name="ParcelSalePriceMsg"> +        Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²) +    </floater.string> +    <floater.string +     name="ParcelSaleAreaMsg"> +        Area: [AREA]m² +    </floater.string> +    <floater.string +     name="ParcelOwnerMsg"> +        Owner: [PARCEL_OWNER] +    </floater.string> +    <floater.string +     name="RegionNameMsg"> +        Region: [REGION_NAME]      </floater.string>  	<floater.string -     name="AltToolTipMsg"> -		[REGION](Double-click to teleport, shift-drag to pan) +     name="ToolTipHintMsg"> +        Double-click to open map +	</floater.string> +	<floater.string +     name="AltToolTipHintMsg"> +        Double-click to teleport  	</floater.string>  	<floater.string name="mini_map_caption">  	Mini-map @@ -37,105 +61,73 @@      <text       type="string"       length="1" -     bottom="218"       label="N"       layout="topleft" -     left="0"       name="floater_map_north" -     right="10" -     text_color="1 1 1 0.7" -     top="189"> +     text_color="1 1 1 0.7">          N      </text>      <text       type="string"       length="1" -     bottom="218"       label="E"       layout="topleft" -     left="0"       name="floater_map_east" -     right="10" -     text_color="1 1 1 0.7" -     top="189"> +     text_color="1 1 1 0.7">          E      </text>      <text       type="string"       length="1" -     bottom="205"       label="W"       layout="topleft" -     left="0"       name="floater_map_west" -     right="11" -     text_color="1 1 1 0.7" -     top="175"> +     text_color="1 1 1 0.7">          W      </text>      <text       type="string"       length="1" -     bottom="218"       label="S"       layout="topleft" -     left="0"       name="floater_map_south" -     right="10" -     text_color="1 1 1 0.7" -     top="189"> +     text_color="1 1 1 0.7">          S      </text>      <text       type="string"       length="1" -     bottom="218"       label="SE"       layout="topleft" -     left="0"       name="floater_map_southeast" -     right="20" -     text_color="1 1 1 0.7" -     top="189"> +     text_color="1 1 1 0.7">          SE      </text>      <text       type="string"       length="1" -     bottom="218"       label="NE"       layout="topleft" -     left="0"       name="floater_map_northeast" -     right="20" -     text_color="1 1 1 0.7" -     top="189"> +     text_color="1 1 1 0.7">          NE      </text>      <text       type="string"       length="1" -     bottom="218"       label="SW"       layout="topleft" -     left="0"       name="floater_map_southwest" -     right="20" -     text_color="1 1 1 0.7" -     top="189"> +     text_color="1 1 1 0.7">          SW      </text>      <text       type="string"       length="1" -     bottom="218"       label="NW"       layout="topleft" -     left="0"       name="floater_map_northwest" -     right="20" -     text_color="1 1 1 0.7" -     top="189"> +     text_color="1 1 1 0.7">          NW      </text>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index e499ddbc2f..21c894d3af 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -830,6 +830,7 @@                          <combo_item name="physics_medium"> Medium </combo_item>                          <combo_item name="physics_low">    Low    </combo_item>                          <combo_item name="physics_lowest"> Lowest </combo_item> +                        <combo_item name="physics_bounding_box"> Bounding Box </combo_item>                          <combo_item name="load_from_file"> From file   </combo_item>                      </combo_box>                      <line_editor diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index 83407069d2..eb633e50e7 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -677,6 +677,7 @@       name="zoom_icon"       top_pad="7"       width="16" ></icon> +    <!-- NOTE: min_val for zoom slider is hardcoded for performance reasons -->      <slider       follows="left|bottom"       height="16" @@ -684,7 +685,7 @@       initial_value="-2"       left_pad="0"       layout="topleft" -     max_val="0" +     max_val="4"       min_val="-8"       name="zoom slider"       show_text="false" diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml index ea263d05ce..2715c916d4 100644 --- a/indra/newview/skins/default/xui/en/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml @@ -8,63 +8,109 @@   top="724"   visible="false"   width="128"> -	<menu_item_call -     label="Zoom Close" -     name="Zoom Close"> -        <menu_item_call.on_click -         function="Minimap.Zoom" +    <menu_item_check +     label="Zoom very close" +     name="Zoom very close"> +        <menu_item_check.on_check +         function="Minimap.Zoom.Check" +         parameter="very close" /> +        <menu_item_check.on_click +         function="Minimap.Zoom.Set" +         parameter="very close" /> +    </menu_item_check> +    <menu_item_check +     label="Zoom close" +     name="Zoom close"> +        <menu_item_check.on_check +         function="Minimap.Zoom.Check"           parameter="close" /> -    </menu_item_call> -    <menu_item_call -     label="Zoom Medium" -     name="Zoom Medium"> -        <menu_item_call.on_click -         function="Minimap.Zoom" +        <menu_item_check.on_click +         function="Minimap.Zoom.Set" +         parameter="close" /> +    </menu_item_check> +    <menu_item_check +     label="Zoom medium" +     name="Zoom medium"> +        <menu_item_check.on_check +         function="Minimap.Zoom.Check"           parameter="medium" /> -    </menu_item_call> -    <menu_item_call -     label="Zoom Far" -     name="Zoom Far"> -        <menu_item_call.on_click -         function="Minimap.Zoom" +        <menu_item_check.on_click +         function="Minimap.Zoom.Set" +         parameter="medium" /> +    </menu_item_check> +    <menu_item_check +     label="Zoom far" +     name="Zoom far"> +        <menu_item_check.on_check +         function="Minimap.Zoom.Check"           parameter="far" /> -    </menu_item_call> -	<menu_item_call -     label="Zoom Default" -     name="Zoom Default"> -		<menu_item_call.on_click -         function="Minimap.Zoom" -         parameter="default" /> -	</menu_item_call> +        <menu_item_check.on_click +         function="Minimap.Zoom.Set" +         parameter="far" /> +    </menu_item_check>  	<menu_item_separator />      <menu_item_check -       label="Rotate Map" -       name="Rotate Map"> +       label="North at top" +       name="North at top">            <menu_item_check.on_check -             control="MiniMapRotate" /> +             function="Minimap.MapOrientation.Check" +             parameter="north_at_top" />            <menu_item_check.on_click -             function="ToggleControl" -             parameter="MiniMapRotate" /> +             function="Minimap.MapOrientation.Set" +             parameter="north_at_top" />      </menu_item_check>      <menu_item_check -       label="Auto Center" -       name="Auto Center"> +       label="Camera at top" +       name="Camera at top">            <menu_item_check.on_check -             control="MiniMapAutoCenter" /> +             function="Minimap.MapOrientation.Check" +             parameter="camera_at_top" />            <menu_item_check.on_click -             function="ToggleControl" -             parameter="MiniMapAutoCenter" /> +             function="Minimap.MapOrientation.Set" +             parameter="camera_at_top" /> +    </menu_item_check> +	<menu_item_separator /> +    <menu_item_check +     label="Show parcel boundaries" +     name="Show parcel boundaries"> +        <menu_item_check.on_check +         control="MiniMapShowPropertyLines" /> +        <menu_item_check.on_click +         function="ToggleControl" +         parameter="MiniMapShowPropertyLines" />      </menu_item_check>      <menu_item_separator /> +    <menu_item_check +     label="Auto-center map" +     name="Auto-center map"> +        <menu_item_check.on_check +         control="MiniMapAutoCenter" /> +        <menu_item_check.on_click +         function="ToggleControl" +         parameter="MiniMapAutoCenter" /> +    </menu_item_check> +    <menu_item_separator /> +    <menu_item_call +     label="Re-center map" +     name="Re-center map"> +        <menu_item_call.on_click +         function="Minimap.Center.Activate" /> +    </menu_item_call>      <menu_item_call -     label="Stop Tracking" -     name="Stop Tracking"> +     label="Stop tracking" +     name="Stop tracking">          <menu_item_call.on_click           function="Minimap.Tracker"           parameter="task_properties" />      </menu_item_call>      <menu_item_separator />      <menu_item_call +     label="About Land" +     name="About Land"> +        <menu_item_call.on_click +         function="Minimap.AboutLand" /> +    </menu_item_call> +    <menu_item_call       label="World Map"       name="World Map">          <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml index aa1b929412..54f038c24f 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -155,6 +155,7 @@       right="-3"       mouse_opaque="true"       name="speaking_indicator" +     tool_tip="Voice volume"       visible="true"       width="20" />  </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml index 5e3de180f9..331ba889d8 100644 --- a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml @@ -14,7 +14,7 @@  				<label name="favorites_bar_label" tool_tip="Перетаскивайте сюда закладки, чтобы было удобнее переходить в любимые места в Second Life!">  					Избранное  				</label> -				<more_button name=">>" tool_tip="Показать больше избранного"> +				<more_button name=">>" tool_tip="Показать больше избранного" width="60">  					Больше ▼  				</more_button>  			</favorites_bar> diff --git a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml index 8d43e3fb5a..ae9bc33bfa 100644 --- a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml @@ -14,7 +14,7 @@  				<label name="favorites_bar_label" tool_tip="Second Life içerisinde sık kullandığınız yerlere hızla erişmek için Yer İmlerini buraya sürükleyin!">  					Favoriler Çubuğu  				</label> -				<more_button name=">>" tool_tip="Favorilerimden daha çok göster"> +				<more_button name=">>" tool_tip="Favorilerimden daha çok göster" width="65">  					Daha Fazla ▼  				</more_button>  			</favorites_bar> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index de5ac5ed3d..59eb18b734 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -568,6 +568,7 @@ class WindowsManifest(ViewerManifest):          self.path(src="licenses-win32.txt", dst="licenses.txt")          self.path("featuretable.txt") +        self.path("cube.dae")          with self.prefix(src=pkgdir):              self.path("ca-bundle.crt") @@ -954,6 +955,7 @@ class DarwinManifest(ViewerManifest):                  self.path("licenses-mac.txt", dst="licenses.txt")                  self.path("featuretable_mac.txt") +                self.path("cube.dae")                  self.path("SecondLife.nib")                  with self.prefix(src=pkgdir,dst=""): @@ -1427,6 +1429,7 @@ class LinuxManifest(ViewerManifest):              print("Skipping llcommon.so (assuming llcommon was linked statically)")          self.path("featuretable_linux.txt") +        self.path("cube.dae")          with self.prefix(src=pkgdir):              self.path("ca-bundle.crt") | 
