summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.hgtags2
-rwxr-xr-xindra/llcharacter/llcharacter.h6
-rwxr-xr-xindra/llcharacter/lljoint.cpp2
-rw-r--r--indra/llcommon/lluriparser.cpp31
-rw-r--r--indra/llcommon/lluriparser.h1
-rwxr-xr-xindra/llmessage/message_prehash.cpp2
-rwxr-xr-xindra/llmessage/message_prehash.h2
-rwxr-xr-xindra/llui/llsliderctrl.cpp15
-rwxr-xr-xindra/llui/llsliderctrl.h5
-rwxr-xr-xindra/llui/lltextbase.cpp39
-rwxr-xr-xindra/llui/lltexteditor.cpp24
-rwxr-xr-xindra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rwxr-xr-xindra/newview/app_settings/logcontrol.xml1
-rwxr-xr-xindra/newview/app_settings/settings.xml15
-rwxr-xr-xindra/newview/app_settings/settings_per_account.xml11
-rwxr-xr-xindra/newview/llavataractions.cpp14
-rwxr-xr-xindra/newview/llavataractions.h2
-rwxr-xr-xindra/newview/llfloaterhoverheight.cpp157
-rwxr-xr-xindra/newview/llfloaterhoverheight.h52
-rwxr-xr-xindra/newview/llfloaterperms.cpp11
-rwxr-xr-xindra/newview/llinspecttoast.cpp5
-rwxr-xr-xindra/newview/llpanelobjectinventory.cpp4
-rwxr-xr-xindra/newview/llstartup.cpp8
-rwxr-xr-xindra/newview/llviewerfloaterreg.cpp4
-rwxr-xr-xindra/newview/llviewermenu.cpp15
-rwxr-xr-xindra/newview/llviewerregion.cpp30
-rwxr-xr-xindra/newview/llviewerregion.h12
-rwxr-xr-xindra/newview/llvoavatar.cpp134
-rwxr-xr-xindra/newview/llvoavatar.h6
-rwxr-xr-xindra/newview/llvoavatarself.cpp103
-rwxr-xr-xindra/newview/llvoavatarself.h11
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_edit_hover_height.xml38
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_attachment_self.xml8
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_avatar_self.xml8
-rwxr-xr-xscripts/messages/message_template.msg4
-rwxr-xr-xscripts/messages/message_template.msg.sha12
37 files changed, 732 insertions, 56 deletions
diff --git a/.hgtags b/.hgtags
index 6db0a64173..2272b0118c 100755
--- a/.hgtags
+++ b/.hgtags
@@ -498,3 +498,5 @@ bc61801f614022c920cb5c3df1d7d67a9561ce1f 3.7.22-release
3be800e1afad9615442159e388d6d137be7b951e 3.7.23-release
d3d0101e980ec95043e0af9b7903045d3bc447e4 3.7.24-release
9978a8c3a2ffce4a5e1c186256581c2ac139c9dc 3.7.25-release
+000e9dda4162cbf0a83ba88558b19473654a09a9 3.7.26-release
+afd8d4756e8eda3c8f760625d1c17a2ad40ad6c8 3.7.27-release
diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h
index d4e3b76386..1a3e307663 100755
--- a/indra/llcharacter/llcharacter.h
+++ b/indra/llcharacter/llcharacter.h
@@ -261,6 +261,9 @@ public:
static std::vector< LLCharacter* > sInstances;
static BOOL sAllowInstancesChange ; //debug use
+ virtual void setHoverOffset(const LLVector3& hover_offset, bool send_update=true) { mHoverOffset = hover_offset; }
+ const LLVector3& getHoverOffset() const { return mHoverOffset; }
+
protected:
LLMotionController mMotionController;
@@ -273,7 +276,6 @@ protected:
U32 mSkeletonSerialNum;
LLAnimPauseRequest mPauseRequest;
-
private:
// visual parameter stuff
typedef std::map<S32, LLVisualParam *> visual_param_index_map_t;
@@ -284,6 +286,8 @@ private:
visual_param_name_map_t mVisualParamNameMap;
static LLStringTable sVisualParamNames;
+
+ LLVector3 mHoverOffset;
};
#endif // LL_LLCHARACTER_H
diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp
index 5bee4da7c0..8fa08a2a6c 100755
--- a/indra/llcharacter/lljoint.cpp
+++ b/indra/llcharacter/lljoint.cpp
@@ -290,7 +290,7 @@ const LLVector3& LLJoint::getPosition()
bool do_debug_joint(const std::string& name)
{
- return true;
+ return false;
}
//--------------------------------------------------------------------
diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp
index d07288f123..8270c630d8 100644
--- a/indra/llcommon/lluriparser.cpp
+++ b/indra/llcommon/lluriparser.cpp
@@ -29,7 +29,7 @@
#include "linden_common.h"
#include "lluriparser.h"
-LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mRes(0)
+LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedTmp(false), mRes(0)
{
mState.uri = &mUri;
@@ -118,17 +118,39 @@ void LLUriParser::fragment(const std::string& s)
void LLUriParser::textRangeToString(UriTextRangeA& textRange, std::string& str)
{
+ str = "";
+
+ if(&textRange == NULL)
+ {
+ return;
+ }
+
+ if(textRange.first == NULL)
+ {
+ return;
+ }
+
+ if(textRange.afterLast == NULL)
+ {
+ return;
+ }
+
S32 len = textRange.afterLast - textRange.first;
if (len)
{
- str = textRange.first;
- str = str.substr(0, len);
+ str.assign(textRange.first, len);
}
}
void LLUriParser::extractParts()
{
- if (mTmpScheme)
+ if(&mUri == NULL)
+ {
+ LL_WARNS() << "mUri is NULL for uri: " << mNormalizedUri << LL_ENDL;
+ return;
+ }
+
+ if (mTmpScheme || mNormalizedTmp)
{
mScheme.clear();
}
@@ -157,6 +179,7 @@ void LLUriParser::extractParts()
S32 LLUriParser::normalize()
{
+ mNormalizedTmp = mTmpScheme;
if (!mRes)
{
mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h
index e987bae924..561431e8f9 100644
--- a/indra/llcommon/lluriparser.h
+++ b/indra/llcommon/lluriparser.h
@@ -81,6 +81,7 @@ private:
S32 mRes;
bool mTmpScheme;
+ bool mNormalizedTmp;
};
#endif // LL_LLURIPARSER_H
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 39cfb6019e..a62b9c3227 100755
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -1383,3 +1383,5 @@ char const* const _PREHASH_GroupAVSounds = LLMessageStringTable::getInstance()->
char const* const _PREHASH_AppearanceData = LLMessageStringTable::getInstance()->getString("AppearanceData");
char const* const _PREHASH_AppearanceVersion = LLMessageStringTable::getInstance()->getString("AppearanceVersion");
char const* const _PREHASH_CofVersion = LLMessageStringTable::getInstance()->getString("CofVersion");
+char const* const _PREHASH_AppearanceHover = LLMessageStringTable::getInstance()->getString("AppearanceHover");
+char const* const _PREHASH_HoverHeight = LLMessageStringTable::getInstance()->getString("HoverHeight");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index 573e10dc0b..573c8e466f 100755
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -1383,4 +1383,6 @@ extern char const* const _PREHASH_GroupAVSounds;
extern char const* const _PREHASH_AppearanceData;
extern char const* const _PREHASH_AppearanceVersion;
extern char const* const _PREHASH_CofVersion;
+extern char const* const _PREHASH_AppearanceHover;
+extern char const* const _PREHASH_HoverHeight;
#endif
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index 62c5ecb8f1..2da39fa54b 100755
--- a/indra/llui/llsliderctrl.cpp
+++ b/indra/llui/llsliderctrl.cpp
@@ -58,7 +58,8 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
mPrecision(p.decimal_digits),
mTextEnabledColor(p.text_color()),
mTextDisabledColor(p.text_disabled_color()),
- mLabelWidth(p.label_width)
+ mLabelWidth(p.label_width),
+ mEditorCommitSignal(NULL)
{
S32 top = getRect().getHeight();
S32 bottom = 0;
@@ -196,6 +197,11 @@ LLSliderCtrl::LLSliderCtrl(const LLSliderCtrl::Params& p)
updateText();
}
+LLSliderCtrl::~LLSliderCtrl()
+{
+ delete mEditorCommitSignal;
+}
+
// static
void LLSliderCtrl::onEditorGainFocus( LLFocusableElement* caller, void *userdata )
{
@@ -308,6 +314,8 @@ void LLSliderCtrl::onEditorCommit( LLUICtrl* ctrl, const LLSD& userdata )
if( success )
{
self->onCommit();
+ if (self->mEditorCommitSignal)
+ (*(self->mEditorCommitSignal))(self, self->getValueF32());
}
else
{
@@ -421,6 +429,11 @@ boost::signals2::connection LLSliderCtrl::setSliderMouseUpCallback( const commit
return mSlider->setMouseUpCallback( cb );
}
+boost::signals2::connection LLSliderCtrl::setSliderEditorCommitCallback( const commit_signal_t::slot_type& cb )
+{
+ if (!mEditorCommitSignal) mEditorCommitSignal = new commit_signal_t();
+ return mEditorCommitSignal->connect(cb);
+}
void LLSliderCtrl::onTabInto()
{
if( mEditor )
diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h
index 5153e33f49..67cca9ef04 100755
--- a/indra/llui/llsliderctrl.h
+++ b/indra/llui/llsliderctrl.h
@@ -81,7 +81,7 @@ protected:
LLSliderCtrl(const Params&);
friend class LLUICtrlFactory;
public:
- virtual ~LLSliderCtrl() {} // Children all cleaned up by default view destructor.
+ virtual ~LLSliderCtrl();
/*virtual*/ F32 getValueF32() const { return mSlider->getValueF32(); }
void setValue(F32 v, BOOL from_event = FALSE);
@@ -112,6 +112,7 @@ public:
boost::signals2::connection setSliderMouseDownCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setSliderMouseUpCallback( const commit_signal_t::slot_type& cb );
+ boost::signals2::connection setSliderEditorCommitCallback( const commit_signal_t::slot_type& cb );
/*virtual*/ void onTabInto();
@@ -150,6 +151,8 @@ private:
LLUIColor mTextEnabledColor;
LLUIColor mTextDisabledColor;
+
+ commit_signal_t* mEditorCommitSignal;
};
#endif // LL_LLSLIDERCTRL_H
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 103c5b6047..eca57d1c23 100755
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -2796,13 +2796,13 @@ void LLTextBase::updateRects()
switch(mVAlign)
{
case LLFontGL::TOP:
- delta_pos = llmax(old_text_rect.getHeight() - mTextBoundingRect.mTop, -mTextBoundingRect.mBottom);
+ delta_pos = llmax(mVisibleTextRect.getHeight() - mTextBoundingRect.mTop, -mTextBoundingRect.mBottom);
break;
case LLFontGL::VCENTER:
- delta_pos = (llmax(old_text_rect.getHeight() - mTextBoundingRect.mTop, -mTextBoundingRect.mBottom) + (mVisibleTextRect.mBottom - mTextBoundingRect.mBottom)) / 2;
+ delta_pos = (llmax(mVisibleTextRect.getHeight() - mTextBoundingRect.mTop, -mTextBoundingRect.mBottom) + (mVisibleTextRect.mBottom - mTextBoundingRect.mBottom)) / 2;
break;
case LLFontGL::BOTTOM:
- delta_pos = old_text_rect.mBottom - mTextBoundingRect.mBottom;
+ delta_pos = mVisibleTextRect.mBottom - mTextBoundingRect.mBottom;
break;
case LLFontGL::BASELINE:
// do nothing
@@ -2863,13 +2863,44 @@ void LLTextBase::updateRects()
needsReflow();
}
+ // update mTextBoundingRect after mVisibleTextRect took scrolls into account
+ if (!mLineInfoList.empty() && mScroller)
+ {
+ S32 delta_pos = 0;
+
+ switch(mVAlign)
+ {
+ case LLFontGL::TOP:
+ delta_pos = llmax(mVisibleTextRect.getHeight() - mTextBoundingRect.mTop, -mTextBoundingRect.mBottom);
+ break;
+ case LLFontGL::VCENTER:
+ delta_pos = (llmax(mVisibleTextRect.getHeight() - mTextBoundingRect.mTop, -mTextBoundingRect.mBottom) + (mVisibleTextRect.mBottom - mTextBoundingRect.mBottom)) / 2;
+ break;
+ case LLFontGL::BOTTOM:
+ delta_pos = mVisibleTextRect.mBottom - mTextBoundingRect.mBottom;
+ break;
+ case LLFontGL::BASELINE:
+ // do nothing
+ break;
+ }
+ // move line segments to fit new visible rect
+ if (delta_pos != 0)
+ {
+ for (line_list_t::iterator it = mLineInfoList.begin(); it != mLineInfoList.end(); ++it)
+ {
+ it->mRect.translate(0, delta_pos);
+ }
+ mTextBoundingRect.translate(0, delta_pos);
+ }
+ }
+
// update document container again, using new mVisibleTextRect (that has scrollbars enabled as needed)
doc_rect.mBottom = llmin(mVisibleTextRect.mBottom, mTextBoundingRect.mBottom);
doc_rect.mLeft = 0;
doc_rect.mRight = mScroller
? llmax(mVisibleTextRect.getWidth(), mTextBoundingRect.mRight)
: mVisibleTextRect.getWidth();
- doc_rect.mTop = llmax(mVisibleTextRect.mTop, mTextBoundingRect.mTop);
+ doc_rect.mTop = llmax(mVisibleTextRect.getHeight(), mTextBoundingRect.getHeight()) + doc_rect.mBottom;
if (!mScroller)
{
// push doc rect to top of text widget
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index e8ff675d4f..1f169c3eb5 100755
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2448,12 +2448,30 @@ void LLTextEditor::updateLinkSegments()
LLTextSegment *segment = *it;
if (segment && segment->getStyle() && segment->getStyle()->isLink())
{
- // if the link's label (what the user can edit) is a valid Url,
- // then update the link's HREF to be the same as the label text.
- // This lets users edit Urls in-place.
LLStyleConstSP style = segment->getStyle();
LLStyleSP new_style(new LLStyle(*style));
LLWString url_label = wtext.substr(segment->getStart(), segment->getEnd()-segment->getStart());
+
+ segment_set_t::const_iterator next_it = mSegments.upper_bound(segment);
+ LLTextSegment *next_segment = *next_it;
+ if (next_segment)
+ {
+ LLWString next_url_label = wtext.substr(next_segment->getStart(), next_segment->getEnd()-next_segment->getStart());
+ std::string link_check = wstring_to_utf8str(url_label) + wstring_to_utf8str(next_url_label);
+ LLUrlMatch match;
+
+ if ( LLUrlRegistry::instance().findUrl(link_check, match))
+ {
+ if(match.getQuery() == wstring_to_utf8str(next_url_label))
+ {
+ continue;
+ }
+ }
+ }
+
+ // if the link's label (what the user can edit) is a valid Url,
+ // then update the link's HREF to be the same as the label text.
+ // This lets users edit Urls in-place.
if (LLUrlRegistry::instance().hasUrl(url_label))
{
std::string new_url = wstring_to_utf8str(url_label);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index a7c5dbff82..78f04dccae 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -245,6 +245,7 @@ set(viewer_SOURCE_FILES
llfloaterhandler.cpp
llfloaterhardwaresettings.cpp
llfloaterhelpbrowser.cpp
+ llfloaterhoverheight.cpp
llfloaterhud.cpp
llfloaterimagepreview.cpp
llfloaterimsessiontab.cpp
@@ -849,6 +850,7 @@ set(viewer_HEADER_FILES
llfloaterhandler.h
llfloaterhardwaresettings.h
llfloaterhelpbrowser.h
+ llfloaterhoverheight.h
llfloaterhud.h
llfloaterimagepreview.h
llfloaterimnearbychat.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index e5403775b2..7c35ff8c4b 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.7.26
+3.7.28
diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml
index 15cb5bc0eb..de3732f339 100755
--- a/indra/newview/app_settings/logcontrol.xml
+++ b/indra/newview/app_settings/logcontrol.xml
@@ -43,6 +43,7 @@
<key>tags</key>
<array>
<!-- sample entry for debugging specific items
+ <string>Avatar</string>
<string>Inventory</string>
<string>SceneLoadTiming</string>
<string>Avatar</string>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index e3ab45c53e..88d74deb08 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -665,6 +665,21 @@
<key>Value</key>
<integer>2</integer>
</map>
+ <key>AvatarPosFinalOffset</key>
+ <map>
+ <key>Comment</key>
+ <string>After-everything-else fixup for avatar position.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Vector3</string>
+ <key>Value</key>
+ <array>
+ <real>0.0</real>
+ <real>0.0</real>
+ <real>0.0</real>
+ </array>
+ </map>
<key>AvatarPickerURL</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index fc6f1f6395..d119504017 100755
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -1,5 +1,16 @@
<llsd>
<map>
+ <key>AvatarHoverOffsetZ</key>
+ <map>
+ <key>Comment</key>
+ <string>After-everything-else fixup for avatar Z position.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.0</real>
+ </map>
<key>DoNotDisturbResponseChanged</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 0e30c079ff..8dc8a2ff20 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -745,7 +745,7 @@ namespace action_give_inventory
}
std::string residents;
- LLAvatarActions::buildResidentsString(avatar_names, residents);
+ LLAvatarActions::buildResidentsString(avatar_names, residents, true);
std::string items;
build_items_string(inventory_selected_uuids, items);
@@ -777,7 +777,7 @@ namespace action_give_inventory
}
// static
-void LLAvatarActions::buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string)
+void LLAvatarActions::buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string, bool complete_name)
{
llassert(avatar_names.size() > 0);
@@ -785,7 +785,15 @@ void LLAvatarActions::buildResidentsString(std::vector<LLAvatarName> avatar_name
const std::string& separator = LLTrans::getString("words_separator");
for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; )
{
- residents_string.append((*it).getCompleteName());
+ if(complete_name)
+ {
+ residents_string.append((*it).getCompleteName());
+ }
+ else
+ {
+ residents_string.append((*it).getDisplayName());
+ }
+
if (++it == avatar_names.end())
{
break;
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 85813f2152..bd0ac24e93 100755
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -221,7 +221,7 @@ public:
* @param avatar_names - a vector of given avatar names from which resulting string is built
* @param residents_string - the resulting string
*/
- static void buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string);
+ static void buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string, bool complete_name = false);
/**
* Builds a string of residents' display names separated by "words_separator" string.
diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp
new file mode 100755
index 0000000000..8908626de6
--- /dev/null
+++ b/indra/newview/llfloaterhoverheight.cpp
@@ -0,0 +1,157 @@
+/**
+* @file llfloaterhoverheight.cpp
+* @brief Controller for self avatar hover height
+* @author vir@lindenlab.com
+*
+* $LicenseInfo:firstyear=2014&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2014, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterhoverheight.h"
+#include "llsliderctrl.h"
+#include "llviewercontrol.h"
+#include "llsdserialize.h"
+#include "llhttpclient.h"
+#include "llagent.h"
+#include "llviewerregion.h"
+#include "llvoavatarself.h"
+
+LLFloaterHoverHeight::LLFloaterHoverHeight(const LLSD& key) : LLFloater(key)
+{
+}
+
+void LLFloaterHoverHeight::syncFromPreferenceSetting(void *user_data)
+{
+ F32 value = gSavedPerAccountSettings.getF32("AvatarHoverOffsetZ");
+
+ LLFloaterHoverHeight *self = static_cast<LLFloaterHoverHeight*>(user_data);
+ LLSliderCtrl* sldrCtrl = self->getChild<LLSliderCtrl>("HoverHeightSlider");
+ sldrCtrl->setValue(value,FALSE);
+
+ if (isAgentAvatarValid())
+ {
+ LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z));
+ LL_INFOS("Avatar") << "setting hover from preference setting " << offset[2] << LL_ENDL;
+ gAgentAvatarp->setHoverOffset(offset);
+ //gAgentAvatarp->sendHoverHeight();
+ }
+}
+
+BOOL LLFloaterHoverHeight::postBuild()
+{
+ LLSliderCtrl* sldrCtrl = getChild<LLSliderCtrl>("HoverHeightSlider");
+ sldrCtrl->setMinValue(MIN_HOVER_Z);
+ sldrCtrl->setMaxValue(MAX_HOVER_Z);
+ sldrCtrl->setSliderMouseUpCallback(boost::bind(&LLFloaterHoverHeight::onFinalCommit,this));
+ sldrCtrl->setSliderEditorCommitCallback(boost::bind(&LLFloaterHoverHeight::onFinalCommit,this));
+ childSetCommitCallback("HoverHeightSlider", &LLFloaterHoverHeight::onSliderMoved, NULL);
+
+ // Initialize slider from pref setting.
+ syncFromPreferenceSetting(this);
+ // Update slider on future pref changes.
+ if (gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ"))
+ {
+ gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getCommitSignal()->connect(boost::bind(&syncFromPreferenceSetting, this));
+ }
+ else
+ {
+ LL_WARNS() << "Control not found for AvatarHoverOffsetZ" << LL_ENDL;
+ }
+
+ updateEditEnabled();
+
+ if (!mRegionChangedSlot.connected())
+ {
+ mRegionChangedSlot = gAgent.addRegionChangedCallback(boost::bind(&LLFloaterHoverHeight::onRegionChanged,this));
+ }
+ // Set up based on initial region.
+ onRegionChanged();
+
+ return TRUE;
+}
+
+void LLFloaterHoverHeight::onClose(bool app_quitting)
+{
+ if (mRegionChangedSlot.connected())
+ {
+ mRegionChangedSlot.disconnect();
+ }
+}
+
+// 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);
+}
+
+// Do send-to-the-server work when slider drag completes, or new
+// value entered as text.
+void LLFloaterHoverHeight::onFinalCommit()
+{
+ LLSliderCtrl* sldrCtrl = getChild<LLSliderCtrl>("HoverHeightSlider");
+ F32 value = sldrCtrl->getValueF32();
+ gSavedPerAccountSettings.setF32("AvatarHoverOffsetZ",value);
+
+ LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z));
+ LL_INFOS("Avatar") << "setting hover from slider final commit " << offset[2] << LL_ENDL;
+ gAgentAvatarp->setHoverOffset(offset, true); // will send update this time.
+}
+
+void LLFloaterHoverHeight::onRegionChanged()
+{
+ LLViewerRegion *region = gAgent.getRegion();
+ if (region && region->simulatorFeaturesReceived())
+ {
+ updateEditEnabled();
+ }
+ else if (region)
+ {
+ region->setSimulatorFeaturesReceivedCallback(boost::bind(&LLFloaterHoverHeight::onSimulatorFeaturesReceived,this,_1));
+ }
+}
+
+void LLFloaterHoverHeight::onSimulatorFeaturesReceived(const LLUUID &region_id)
+{
+ LLViewerRegion *region = gAgent.getRegion();
+ if (region && (region->getRegionID()==region_id))
+ {
+ updateEditEnabled();
+ }
+}
+
+void LLFloaterHoverHeight::updateEditEnabled()
+{
+ bool enabled = gAgent.getRegion() && gAgent.getRegion()->avatarHoverHeightEnabled();
+ LLSliderCtrl* sldrCtrl = getChild<LLSliderCtrl>("HoverHeightSlider");
+ sldrCtrl->setEnabled(enabled);
+ if (enabled)
+ {
+ syncFromPreferenceSetting(this);
+ }
+}
+
+
diff --git a/indra/newview/llfloaterhoverheight.h b/indra/newview/llfloaterhoverheight.h
new file mode 100755
index 0000000000..ee065bc184
--- /dev/null
+++ b/indra/newview/llfloaterhoverheight.h
@@ -0,0 +1,52 @@
+/**
+* @file llfloaterhoverheight.h
+* @brief Controller for self avatar hover height.
+* @author vir@lindenlab.com
+*
+* $LicenseInfo:firstyear=2014&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2014, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+#ifndef LL_LLFLOATERHOVERHEIGHT_H
+#define LL_LLFLOATERHOVERHEIGHT_H
+
+#include "llfloater.h"
+
+class LLFloaterHoverHeight: public LLFloater
+{
+public:
+ LLFloaterHoverHeight(const LLSD& key);
+ BOOL postBuild();
+
+ static void onSliderMoved(LLUICtrl* ctrl, void* userData);
+
+ void onFinalCommit();
+
+ static void syncFromPreferenceSetting(void *user_data);
+
+ void onRegionChanged();
+ void onSimulatorFeaturesReceived(const LLUUID &region_id);
+ void updateEditEnabled();
+
+ /*virtual*/ void onClose(bool app_quitting);
+ boost::signals2::connection mRegionChangedSlot;
+};
+
+#endif
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 0880a5f35a..849aa7cd14 100755
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -35,6 +35,8 @@
#include "llagent.h"
#include "llviewerregion.h"
#include "llnotificationsutil.h"
+#include "llsdserialize.h"
+#include "llvoavatar.h"
LLFloaterPerms::LLFloaterPerms(const LLSD& seed)
: LLFloater(seed)
@@ -171,8 +173,9 @@ public:
private:
static std::string sPreviousReason;
- void error(U32 status, const std::string& reason)
+ void httpFailure()
{
+ const std::string& reason = getReason();
// Do not display the same error more than once in a row
if (reason != sPreviousReason)
{
@@ -182,8 +185,12 @@ private:
LLNotificationsUtil::add("DefaultObjectPermissions", args);
}
}
- void result(const LLSD& content)
+
+ void httpSuccess()
{
+ //const LLSD& content = getContent();
+ //dump_sequential_xml("perms_responder_result.xml", content);
+
// Since we have had a successful POST call be sure to display the next error message
// even if it is the same as a previous one.
sPreviousReason = "";
diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp
index 0bc7bd188d..d04378daaf 100755
--- a/indra/newview/llinspecttoast.cpp
+++ b/indra/newview/llinspecttoast.cpp
@@ -89,6 +89,11 @@ void LLInspectToast::onOpen(const LLSD& notification_id)
mConnection = toast->setOnToastDestroyedCallback(boost::bind(&LLInspectToast::onToastDestroy, this, _1));
LLPanel * panel = toast->getPanel();
+ if (panel == NULL)
+ {
+ LL_WARNS() << "Could not get toast's panel." << LL_ENDL;
+ return;
+ }
panel->setVisible(TRUE);
panel->setMouseOpaque(FALSE);
if(mPanel != NULL && mPanel->getParent() == this)
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 8b927a0c6b..1ae9d916b3 100755
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -689,10 +689,6 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
else if (canOpenItem())
{
items.push_back(std::string("Task Open"));
- if (!isItemCopyable())
- {
- disabled_items.push_back(std::string("Task Open"));
- }
}
items.push_back(std::string("Task Properties"));
if(isItemRenameable())
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index b3278b2437..e519032b9e 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1353,11 +1353,11 @@ bool idle_startup()
{
LLStringUtil::format_map_t args;
args["[NUMBER]"] = llformat("%d", num_retries + 1);
- set_startup_status(0.4f, LLTrans::getString("LoginRetrySeedCapGrant", args), gAgent.mMOTD);
+ set_startup_status(0.4f, LLTrans::getString("LoginRetrySeedCapGrant", args), gAgent.mMOTD.c_str());
}
else
{
- set_startup_status(0.4f, LLTrans::getString("LoginRequestSeedCapGrant"), gAgent.mMOTD);
+ set_startup_status(0.4f, LLTrans::getString("LoginRequestSeedCapGrant"), gAgent.mMOTD.c_str());
}
}
display_startup();
@@ -2071,7 +2071,7 @@ bool idle_startup()
update_texture_fetch();
set_startup_status(0.60f + 0.30f * timeout_frac,
LLTrans::getString("LoginPrecaching"),
- gAgent.mMOTD);
+ gAgent.mMOTD.c_str());
display_startup();
}
@@ -2211,6 +2211,8 @@ bool idle_startup()
llassert(LLPathfindingManager::getInstance() != NULL);
LLPathfindingManager::getInstance()->initSystem();
+ gAgentAvatarp->sendHoverHeight();
+
return TRUE;
}
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index e19fe9ca75..fc18b20758 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -70,6 +70,7 @@
#include "llfloatergroups.h"
#include "llfloaterhardwaresettings.h"
#include "llfloaterhelpbrowser.h"
+#include "llfloaterhoverheight.h"
#include "llfloaterhud.h"
#include "llfloaterimagepreview.h"
#include "llfloaterimsession.h"
@@ -221,7 +222,8 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>);
LLFloaterReg::add("group_picker", "floater_choose_group.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGroupPicker>);
- LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);
+ LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);
+ LLFloaterReg::add("edit_hover_height", "floater_edit_hover_height.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHoverHeight>);
LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterIMSession>);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 22a032563e..9d680e23d1 100755
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3891,6 +3891,14 @@ class LLEnableEditShape : public view_listener_t
}
};
+class LLEnableHoverHeight : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ return gAgent.getRegion() && gAgent.getRegion()->avatarHoverHeightEnabled();
+ }
+};
+
class LLEnableEditPhysics : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -6088,6 +6096,11 @@ void handle_edit_shape()
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_shape"));
}
+void handle_hover_height()
+{
+ LLFloaterReg::showInstance("edit_hover_height");
+}
+
void handle_edit_physics()
{
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_physics"));
@@ -8584,10 +8597,12 @@ void initialize_menus()
view_listener_t::addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff");
view_listener_t::addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar");
view_listener_t::addMenu(new LLEnableEditShape(), "Edit.EnableEditShape");
+ view_listener_t::addMenu(new LLEnableHoverHeight(), "Edit.EnableHoverHeight");
view_listener_t::addMenu(new LLEnableEditPhysics(), "Edit.EnableEditPhysics");
commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar));
commit.add("EditOutfit", boost::bind(&handle_edit_outfit));
commit.add("EditShape", boost::bind(&handle_edit_shape));
+ commit.add("HoverHeight", boost::bind(&handle_hover_height));
commit.add("EditPhysics", boost::bind(&handle_edit_physics));
// View menu
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index bac742b0bb..75cb0d16ef 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -425,6 +425,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mCacheDirty(FALSE),
mReleaseNotesRequested(FALSE),
mCapabilitiesReceived(false),
+ mSimulatorFeaturesReceived(false),
mBitsReceived(0.f),
mPacketsReceived(0.f),
mDead(FALSE),
@@ -2038,6 +2039,26 @@ void LLViewerRegion::getInfo(LLSD& info)
info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
}
+boost::signals2::connection LLViewerRegion::setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb)
+{
+ return mSimulatorFeaturesReceivedSignal.connect(cb);
+}
+
+void LLViewerRegion::setSimulatorFeaturesReceived(bool received)
+{
+ mSimulatorFeaturesReceived = received;
+ if (received)
+ {
+ mSimulatorFeaturesReceivedSignal(getRegionID());
+ mSimulatorFeaturesReceivedSignal.disconnect_all_slots();
+ }
+}
+
+bool LLViewerRegion::simulatorFeaturesReceived() const
+{
+ return mSimulatorFeaturesReceived;
+}
+
void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features) const
{
sim_features = mSimulatorFeatures;
@@ -2051,6 +2072,9 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
LLSDSerialize::toPrettyXML(sim_features, str);
LL_INFOS() << str.str() << LL_ENDL;
mSimulatorFeatures = sim_features;
+
+ setSimulatorFeaturesReceived(true);
+
}
//this is called when the parent is not cacheable.
@@ -3099,6 +3123,12 @@ bool LLViewerRegion::dynamicPathfindingEnabled() const
return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") &&
mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean());
}
+
+bool LLViewerRegion::avatarHoverHeightEnabled() const
+{
+ return ( mSimulatorFeatures.has("AvatarHoverHeightEnabled") &&
+ mSimulatorFeatures["AvatarHoverHeightEnabled"].asBoolean());
+}
/* Static Functions */
void log_capabilities(const CapabilityMap &capmap)
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index d01e746936..c14fa5aee8 100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -309,12 +309,19 @@ public:
bool meshRezEnabled() const;
bool meshUploadEnabled() const;
+ // has region received its simulator features list? Requires an additional query after caps received.
+ void setSimulatorFeaturesReceived(bool);
+ bool simulatorFeaturesReceived() const;
+ boost::signals2::connection setSimulatorFeaturesReceivedCallback(const caps_received_signal_t::slot_type& cb);
+
void getSimulatorFeatures(LLSD& info) const;
void setSimulatorFeatures(const LLSD& info);
bool dynamicPathfindingEnabled() const;
+ bool avatarHoverHeightEnabled() const;
+
typedef enum
{
CACHE_MISS_TYPE_FULL = 0,
@@ -512,6 +519,7 @@ private:
BOOL mCacheDirty;
BOOL mAlive; // can become false if circuit disconnects
BOOL mCapabilitiesReceived;
+ BOOL mSimulatorFeaturesReceived;
BOOL mReleaseNotesRequested;
BOOL mDead; //if true, this region is in the process of deleting.
BOOL mPaused; //pause processing the objects in the region
@@ -532,11 +540,13 @@ private:
CacheMissItem::cache_miss_list_t mCacheMissList;
caps_received_signal_t mCapabilitiesReceivedSignal;
+ caps_received_signal_t mSimulatorFeaturesReceivedSignal;
+
LLSD mSimulatorFeatures;
// the materials capability throttle
LLFrameTimer mMaterialsCapThrottleTimer;
-LLFrameTimer mRenderInfoRequestTimer;
+ LLFrameTimer mRenderInfoRequestTimer;
};
inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 7292af99a4..75b81cdeed 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -111,6 +111,9 @@ extern F32 ANIM_SPEED_MAX;
extern F32 ANIM_SPEED_MIN;
extern U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG;
+const F32 MAX_HOVER_Z = 2.0;
+const F32 MIN_HOVER_Z = -2.0;
+
// #define OUTPUT_BREAST_DATA
using namespace LLAvatarAppearanceDefines;
@@ -252,6 +255,8 @@ struct LLAppearanceMessageContents
//U32 appearance_flags = 0;
std::vector<F32> mParamWeights;
std::vector<LLVisualParam*> mParams;
+ LLVector3 mHoverOffset;
+ bool mHoverOffsetWasSet;
};
struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>
@@ -721,7 +726,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mCachedInMuteList(false)
{
//VTResume(); // VTune
-
+ setHoverOffset(LLVector3(0.0, 0.0, 0.0));
+
// mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline
const BOOL needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job
mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim );
@@ -774,6 +780,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mRuthTimer.reset();
mRuthDebugTimer.reset();
mDebugExistenceTimer.reset();
+ mLastAppearanceMessageTimer.reset();
if(LLSceneMonitor::getInstance()->isEnabled())
{
@@ -1957,6 +1964,11 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
// Do base class updates...
U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
+ //LLTEContents tec;
+ //S32 te_retval = parseTEMessage(mesgsys, _PREHASH_ObjectData, block_num, tec);
+
+ LL_DEBUGS("Avatar") << avString() << update_type << LL_ENDL;
+
// Print out arrival information once we have name of avatar.
if (has_name && getNVPair("FirstName"))
{
@@ -3185,12 +3197,8 @@ bool LLVOAvatar::isInMuteList()
return muted;
}
-//------------------------------------------------------------------------
-// updateCharacter()
-// called on both your avatar and other avatars
-//------------------------------------------------------------------------
-BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
-{
+void LLVOAvatar::updateDebugText()
+{
// clear debug text
mDebugText.clear();
@@ -3227,6 +3235,22 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
debug_line += llformat(" - cof rcv:%d", last_received_cof_version);
}
debug_line += llformat(" bsz-z: %f avofs-z: %f", mBodySize[2], mAvatarOffset[2]);
+ bool hover_enabled = getRegion() && getRegion()->avatarHoverHeightEnabled();
+ debug_line += hover_enabled ? " H" : " h";
+ const LLVector3& hover_offset = getHoverOffset();
+ if (hover_offset[2] != 0.0)
+ {
+ debug_line += llformat(" hov_z: %f", hover_offset[2]);
+ debug_line += llformat(" %s", (mIsSitting ? "S" : "T"));
+ debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-"));
+ }
+ F32 elapsed = mLastAppearanceMessageTimer.getElapsedTimeF32();
+ static const char *elapsed_chars = "Xx*...";
+ U32 bucket = U32(elapsed*2);
+ if (bucket < strlen(elapsed_chars))
+ {
+ debug_line += llformat(" %c", elapsed_chars[bucket]);
+ }
addDebugText(debug_line);
}
if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
@@ -3234,7 +3258,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
if (!mBakedTextureDebugText.empty())
addDebugText(mBakedTextureDebugText);
}
-
+
if (LLVOAvatar::sShowAnimationDebug)
{
for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
@@ -3263,6 +3287,27 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
}
}
+ if (!mDebugText.size() && mText.notNull())
+ {
+ mText->markDead();
+ mText = NULL;
+ }
+ else if (mDebugText.size())
+ {
+ setDebugText(mDebugText);
+ }
+ mDebugText.clear();
+
+}
+
+//------------------------------------------------------------------------
+// updateCharacter()
+// called on both your avatar and other avatars
+//------------------------------------------------------------------------
+BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
+{
+ updateDebugText();
+
if (!mIsBuilt)
{
return FALSE;
@@ -3371,9 +3416,15 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
LLVector3 xyVel = getVelocity();
xyVel.mV[VZ] = 0.0f;
speed = xyVel.length();
-
+ // remembering the value here prevents a display glitch if the
+ // animation gets toggled during this update.
+ bool was_sit_ground_constrained = isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED);
+
if (!(mIsSitting && getParent()))
{
+ // This case includes all configurations except sitting on an
+ // object, so does include ground sit.
+
//--------------------------------------------------------------------
// get timing info
// handle initial condition case
@@ -3427,9 +3478,14 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
// correct for the fact that the pelvis is not necessarily the center
// of the agent's physical representation
root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot;
+ if (!mIsSitting && !was_sit_ground_constrained)
+ {
+ root_pos += LLVector3d(getHoverOffset());
+ }
LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos);
+
if (newPosition != mRoot->getXform()->getWorldPosition())
{
mRoot->touch();
@@ -3594,7 +3650,9 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
}
else if (mDrawable.notNull())
{
- mRoot->setPosition(mDrawable->getPosition());
+ LLVector3 pos = mDrawable->getPosition();
+ pos += getHoverOffset() * mDrawable->getRotation();
+ mRoot->setPosition(pos);
mRoot->setRotation(mDrawable->getRotation());
}
@@ -3613,7 +3671,21 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
{
updateMotions(LLCharacter::NORMAL_UPDATE);
}
-
+
+ // Special handling for sitting on ground.
+ if (!getParent() && (mIsSitting || was_sit_ground_constrained))
+ {
+
+ F32 off_z = LLVector3d(getHoverOffset()).mdV[VZ];
+ if (off_z != 0.0)
+ {
+ LLVector3 pos = mRoot->getWorldPosition();
+ pos.mV[VZ] += off_z;
+ mRoot->touch();
+ mRoot->setWorldPosition(pos);
+ }
+ }
+
// update head position
updateHeadOffset();
@@ -3697,17 +3769,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
mRoot->updateWorldMatrixChildren();
- if (!mDebugText.size() && mText.notNull())
- {
- mText->markDead();
- mText = NULL;
- }
- else if (mDebugText.size())
- {
- setDebugText(mDebugText);
- }
- mDebugText.clear();
-
//mesh vertices need to be reskinned
mNeedsSkin = TRUE;
return TRUE;
@@ -7145,6 +7206,17 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
// For future use:
//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);
}
+
+ // Parse the AppearanceData field, if any.
+ contents.mHoverOffsetWasSet = false;
+ if (mesgsys->has(_PREHASH_AppearanceHover))
+ {
+ LLVector3 hover;
+ mesgsys->getVector3Fast(_PREHASH_AppearanceHover, _PREHASH_HoverHeight, hover);
+ LL_DEBUGS("Avatar") << avString() << " hover received " << hover.mV[ VX ] << "," << hover.mV[ VY ] << "," << hover.mV[ VZ ] << LL_ENDL;
+ contents.mHoverOffset = hover;
+ contents.mHoverOffsetWasSet = true;
+ }
// Parse visual params, if any.
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
@@ -7262,6 +7334,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
return;
}
+ mLastAppearanceMessageTimer.reset();
+
ESex old_sex = getSex();
LLAppearanceMessageContents contents;
@@ -7446,6 +7520,22 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
}
}
+ if (contents.mHoverOffsetWasSet && !isSelf())
+ {
+ // Got an update for some other avatar
+ // Ignore updates for self, because we have a more authoritative value in the preferences.
+ setHoverOffset(contents.mHoverOffset);
+ LL_INFOS("Avatar") << avString() << "setting hover from message" << contents.mHoverOffset[2] << LL_ENDL;
+ }
+
+ if (!contents.mHoverOffsetWasSet && !isSelf())
+ {
+ // If we don't get a value at all, we are presumably in a
+ // region that does not support hover height.
+ LL_WARNS() << avString() << "zeroing hover because not defined in appearance message" << LL_ENDL;
+ setHoverOffset(LLVector3(0.0, 0.0, 0.0));
+ }
+
setCompositeUpdatesEnabled( TRUE );
// If all of the avatars are completely baked, release the global image caches to conserve memory.
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 7034f8349f..1c3f4f2aa7 100755
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -214,7 +214,6 @@ public:
/*virtual*/ LLVector3 getPosAgentFromGlobal(const LLVector3d &position);
virtual void updateVisualParams();
-
/** Inherited
** **
*******************************************************************************/
@@ -234,6 +233,7 @@ private: //aligned members
// Updates
//--------------------------------------------------------------------
public:
+ void updateDebugText();
virtual BOOL updateCharacter(LLAgent &agent);
void idleUpdateVoiceVisualizer(bool voice_enabled);
void idleUpdateMisc(bool detailed_update);
@@ -992,6 +992,7 @@ public:
protected:
LLFrameTimer mRuthDebugTimer; // For tracking how long it takes for av to rez
LLFrameTimer mDebugExistenceTimer; // Debugging for how long the avatar has been in memory.
+ LLFrameTimer mLastAppearanceMessageTimer; // Time since last appearance message received.
//--------------------------------------------------------------------
// COF monitoring
@@ -1024,6 +1025,9 @@ protected: // Shared with LLVOAvatarSelf
extern const F32 SELF_ADDITIONAL_PRI;
extern const S32 MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL;
+extern const F32 MAX_HOVER_Z;
+extern const F32 MIN_HOVER_Z;
+
std::string get_sequential_numbered_file_name(const std::string& prefix,
const std::string& suffix);
void dump_sequential_xml(const std::string outprefix, const LLSD& content);
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 3f3cd25f95..ae7a233876 100755
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -127,6 +127,25 @@ struct LocalTextureData
LLTextureEntry *mTexEntry;
};
+// TODO - this class doesn't really do anything, could just use a base
+// class responder if nothing else gets added.
+class LLHoverHeightResponder: public LLHTTPClient::Responder
+{
+public:
+ LLHoverHeightResponder(): LLHTTPClient::Responder() {}
+
+private:
+ void httpFailure()
+ {
+ LL_WARNS() << dumpResponse() << LL_ENDL;
+ }
+
+ void httpSuccess()
+ {
+ LL_INFOS() << dumpResponse() << LL_ENDL;
+ }
+};
+
//-----------------------------------------------------------------------------
// Callback data
//-----------------------------------------------------------------------------
@@ -159,7 +178,10 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,
mScreenp(NULL),
mLastRegionHandle(0),
mRegionCrossingCount(0),
- mInitialBakesLoaded(false)
+ mInitialBakesLoaded(false),
+ // Value outside legal range, so will always be a mismatch the
+ // first time through.
+ mLastHoverOffsetSent(LLVector3(0.0f, 0.0f, -999.0f))
{
mMotionController.mIsSelf = TRUE;
@@ -220,11 +242,40 @@ void LLVOAvatarSelf::initInstance()
return;
}
+ setHoverIfRegionEnabled();
+
//doPeriodically(output_self_av_texture_diagnostics, 30.0);
doPeriodically(update_avatar_rez_metrics, 5.0);
doPeriodically(boost::bind(&LLVOAvatarSelf::checkStuckAppearance, this), 30.0);
}
+void LLVOAvatarSelf::setHoverIfRegionEnabled()
+{
+ if (getRegion() && getRegion()->simulatorFeaturesReceived())
+ {
+ if (getRegion()->avatarHoverHeightEnabled())
+ {
+ F32 hover_z = gSavedPerAccountSettings.getF32("AvatarHoverOffsetZ");
+ setHoverOffset(LLVector3(0.0, 0.0, llclamp(hover_z,MIN_HOVER_Z,MAX_HOVER_Z)));
+ LL_INFOS("Avatar") << avString() << " set hover height from debug setting " << hover_z << LL_ENDL;
+ }
+ else
+ {
+ setHoverOffset(LLVector3(0.0, 0.0, 0.0));
+ LL_INFOS("Avatar") << avString() << " zeroing hover height, region does not support" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_INFOS("Avatar") << avString() << " region or simulator features not known, no change on hover" << LL_ENDL;
+ if (getRegion())
+ {
+ getRegion()->setSimulatorFeaturesReceivedCallback(boost::bind(&LLVOAvatarSelf::onSimulatorFeaturesReceived,this,_1));
+ }
+
+ }
+}
+
bool LLVOAvatarSelf::checkStuckAppearance()
{
const F32 CONDITIONAL_UNSTICK_INTERVAL = 300.0;
@@ -835,6 +886,12 @@ void LLVOAvatarSelf::removeMissingBakedTextures()
}
}
+void LLVOAvatarSelf::onSimulatorFeaturesReceived(const LLUUID& region_id)
+{
+ LL_INFOS("Avatar") << "simulator features received, setting hover based on region props" << LL_ENDL;
+ setHoverIfRegionEnabled();
+}
+
//virtual
void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
{
@@ -853,6 +910,17 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
//LL_INFOS() << "pos_from_old_region is " << global_pos_from_old_region
// << " while pos_from_new_region is " << pos_from_new_region
// << LL_ENDL;
+
+ // Update hover height, or schedule callback, based on whether
+ // it's supported in this region.
+ if (regionp->simulatorFeaturesReceived())
+ {
+ setHoverIfRegionEnabled();
+ }
+ else
+ {
+ regionp->setSimulatorFeaturesReceivedCallback(boost::bind(&LLVOAvatarSelf::onSimulatorFeaturesReceived,this,_1));
+ }
}
if (!regionp || (regionp->getHandle() != mLastRegionHandle))
@@ -2709,6 +2777,39 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
return success;
}
+//------------------------------------------------------------------------
+// sendHoverHeight()
+//------------------------------------------------------------------------
+void LLVOAvatarSelf::sendHoverHeight() const
+{
+ std::string url = gAgent.getRegion()->getCapability("AgentPreferences");
+
+ if (!url.empty())
+ {
+ LLSD update = LLSD::emptyMap();
+ const LLVector3& hover_offset = getHoverOffset();
+ update["hover_height"] = hover_offset[2];
+
+ LL_DEBUGS("Avatar") << avString() << "sending hover height value " << hover_offset[2] << LL_ENDL;
+ LLHTTPClient::post(url, update, new LLHoverHeightResponder);
+
+ mLastHoverOffsetSent = hover_offset;
+ }
+}
+
+void LLVOAvatarSelf::setHoverOffset(const LLVector3& hover_offset, bool send_update)
+{
+ if (getHoverOffset() != hover_offset)
+ {
+ LL_INFOS("Avatar") << avString() << " setting hover due to change " << hover_offset[2] << LL_ENDL;
+ LLVOAvatar::setHoverOffset(hover_offset, send_update);
+ }
+ if (send_update && (hover_offset != mLastHoverOffsetSent))
+ {
+ LL_INFOS("Avatar") << avString() << " sending hover due to change " << hover_offset[2] << LL_ENDL;
+ sendHoverHeight();
+ }
+}
//------------------------------------------------------------------------
// needsRenderBeam()
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 5f36872575..b8e9bbb77a 100755
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -75,6 +75,9 @@ protected:
// LLViewerObject interface and related
//--------------------------------------------------------------------
public:
+ boost::signals2::connection mRegionChangedSlot;
+
+ void onSimulatorFeaturesReceived(const LLUUID& region_id);
/*virtual*/ void updateRegion(LLViewerRegion *regionp);
/*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
@@ -328,6 +331,14 @@ public:
public:
bool sendAppearanceMessage(LLMessageSystem *mesgsys) const;
+ // -- care and feeding of hover height.
+ void setHoverIfRegionEnabled();
+ void sendHoverHeight() const;
+ /*virtual*/ void setHoverOffset(const LLVector3& hover_offset, bool send_update=true);
+
+private:
+ mutable LLVector3 mLastHoverOffsetSent;
+
/** Appearance
** **
*******************************************************************************/
diff --git a/indra/newview/skins/default/xui/en/floater_edit_hover_height.xml b/indra/newview/skins/default/xui/en/floater_edit_hover_height.xml
new file mode 100755
index 0000000000..8ec6735a01
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_edit_hover_height.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ positioning="cascading"
+ ignore_ui_scale="false"
+ legacy_header_height="225"
+ can_minimize="true"
+ can_close="true"
+ can_resize="true"
+ min_height="65"
+ min_width="515"
+ height="65"
+ layout="topleft"
+ name="HoverHeight"
+ single_instance="true"
+ help_topic="hover_height"
+ save_rect="true"
+ save_visibility="true"
+ title="SET HOVER HEIGHT"
+ width="515">
+ <slider
+ enabled="false"
+ control_name="HoverHeightSlider"
+ decimal_digits="3"
+ follows="top|left"
+ height="15"
+ increment="0.001"
+ initial_value="0.0"
+ label="Height"
+ label_width="60"
+ left="10"
+ width="501"
+ layout="topleft"
+ name="HoverHeightSlider"
+ top="35"
+ can_edit_text="true"
+ >
+ </slider>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index bcbc8d5b86..c6ae844d67 100755
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -91,6 +91,14 @@ name="Edit Outfit">
<menu_item_call.on_enable
function="Edit.EnableEditShape" />
</menu_item_call>
+ <menu_item_call label="Hover Height"
+ layout="topleft"
+ name="Hover Height">
+ <menu_item_call.on_click
+ function="HoverHeight" />
+ <menu_item_call.on_enable
+ function="Edit.EnableHoverHeight" />
+ </menu_item_call>
<menu_item_call
label="My Friends"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
index ca0c9bd5e4..d3b0b07f70 100755
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -229,6 +229,14 @@
<menu_item_call.on_enable
function="Edit.EnableEditShape" />
</menu_item_call>
+ <menu_item_call label="Hover Height"
+ layout="topleft"
+ name="Hover Height">
+ <menu_item_call.on_click
+ function="HoverHeight" />
+ <menu_item_call.on_enable
+ function="Edit.EnableHoverHeight" />
+ </menu_item_call>
<menu_item_call
label="My Friends"
layout="topleft"
diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg
index 6702de9b4a..3cec4ada1c 100755
--- a/scripts/messages/message_template.msg
+++ b/scripts/messages/message_template.msg
@@ -3594,6 +3594,10 @@ version 2.0
{ CofVersion S32 }
{ Flags U32 }
}
+ {
+ AppearanceHover Variable
+ { HoverHeight LLVector3 }
+ }
}
// AvatarSitResponse - response to a request to sit on an object
diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1
index 7a31177f11..e699efb03c 100755
--- a/scripts/messages/message_template.msg.sha1
+++ b/scripts/messages/message_template.msg.sha1
@@ -1 +1 @@
-4dbf88396c3188ad4c54c4f847a7d8817793668d \ No newline at end of file
+2286adc795b1b06eb86fdda431a71a6f0874b4f1 \ No newline at end of file