diff options
37 files changed, 732 insertions, 56 deletions
@@ -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 ®ion_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 ®ion_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 |