diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 6f049c585..fafe4e4e8 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -312,6 +312,7 @@ set(viewer_SOURCE_FILES llmediaremotectrl.cpp llmemoryview.cpp llmenucommands.cpp + llmenuoptionpathfindingrebakenavmesh.cpp llmeshrepository.cpp llmimetypes.cpp llmorphview.cpp @@ -366,7 +367,6 @@ set(viewer_SOURCE_FILES llpanelnetwork.cpp llpanelobject.cpp llpanelobjectinventory.cpp - llpanelpathfindingrebakenavmesh.cpp llpanelpermissions.cpp llpanelpick.cpp llpanelplace.cpp @@ -818,6 +818,7 @@ set(viewer_HEADER_FILES llmediactrl.h llmediaremotectrl.h llmemoryview.h + llmenuoptionpathfindingrebakenavmesh.h llmenucommands.h llmeshrepository.h llmimetypes.h @@ -873,7 +874,6 @@ set(viewer_HEADER_FILES llpanelnetwork.h llpanelobject.h llpanelobjectinventory.h - llpanelpathfindingrebakenavmesh.h llpanelpermissions.h llpanelpick.h llpanelplace.h diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 38d77b8fc..3e8aa837b 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -50,7 +50,6 @@ #include "llmoveview.h" #include "llchatbar.h" #include "llnotificationsutil.h" -#include "llpanelpathfindingrebakenavmesh.h" #include "llparcel.h" #include "llrendersphere.h" #include "llsdmessage.h" @@ -1866,7 +1865,6 @@ void LLAgent::endAnimationUpdateUI() gMenuBarView->setVisible(TRUE); gStatusBar->setVisibleForMouselook(true); - LLPanelPathfindingRebakeNavmesh::getInstance()->setVisible(TRUE); LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); @@ -1960,7 +1958,6 @@ void LLAgent::endAnimationUpdateUI() gMenuBarView->setVisible(FALSE); gStatusBar->setVisibleForMouselook(false); - LLPanelPathfindingRebakeNavmesh::getInstance()->setVisible(FALSE); // clear out camera lag effect gAgentCamera.clearCameraLag(); diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp new file mode 100644 index 000000000..dd5f1ea68 --- /dev/null +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp @@ -0,0 +1,238 @@ +/** +* @file llmenuoptionpathfindingrebakenavmesh.cpp +* @brief Implementation of llmenuoptionpathfindingrebakenavmesh +* @author Prep@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, 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 "llmenuoptionpathfindingrebakenavmesh.h" + +#include +#include + +#include "llagent.h" +#include "llenvmanager.h" +#include "llnotificationsutil.h" +#include "llpathfindingmanager.h" +#include "llpathfindingnavmesh.h" +#include "llpathfindingnavmeshstatus.h" +#include "llviewerregion.h" + +LLMenuOptionPathfindingRebakeNavmesh::LLMenuOptionPathfindingRebakeNavmesh() + : LLSingleton(), + mIsInitialized(false), + mCanRebakeRegion(false), + mRebakeNavMeshMode(kRebakeNavMesh_Default), + mNavMeshSlot(), + mRegionCrossingSlot(), + mAgentStateSlot() +{ +} + +LLMenuOptionPathfindingRebakeNavmesh::~LLMenuOptionPathfindingRebakeNavmesh() +{ + if (mRebakeNavMeshMode == kRebakeNavMesh_RequestSent) + { + LL_WARNS("navmeshRebaking") << "During destruction of the LLMenuOptionPathfindingRebakeNavmesh " + << "singleton, the mode indicates that a request has been sent for which a response has yet " + << "to be received. This could contribute to a crash on exit." << LL_ENDL; + } + + llassert(!mIsInitialized); + if (mIsInitialized) + { + quit(); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::initialize() +{ + llassert(!mIsInitialized); + if (!mIsInitialized) + { + mIsInitialized = true; + + setMode(kRebakeNavMesh_Default); + + createNavMeshStatusListenerForCurrentRegion(); + + if ( !mRegionCrossingSlot.connected() ) + { + mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this)); + } + + if (!mAgentStateSlot.connected()) + { + mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleAgentState, this, _1)); + } + LLPathfindingManager::getInstance()->requestGetAgentState(); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::quit() +{ + llassert(mIsInitialized); + if (mIsInitialized) + { + if (mNavMeshSlot.connected()) + { + mNavMeshSlot.disconnect(); + } + + if (mRegionCrossingSlot.connected()) + { + mRegionCrossingSlot.disconnect(); + } + + if (mAgentStateSlot.connected()) + { + mAgentStateSlot.disconnect(); + } + + mIsInitialized = false; + } +} + +bool LLMenuOptionPathfindingRebakeNavmesh::canRebakeRegion() const +{ + if (!mIsInitialized) + { + LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized " + << "when the ability to rebake navmesh is being requested." << LL_ENDL; + } + return mCanRebakeRegion; +} + +LLMenuOptionPathfindingRebakeNavmesh::ERebakeNavMeshMode LLMenuOptionPathfindingRebakeNavmesh::getMode() const +{ + if (!mIsInitialized) + { + LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized " + << "when the mode is being requested." << LL_ENDL; + } + return mRebakeNavMeshMode; +} + +void LLMenuOptionPathfindingRebakeNavmesh::sendRequestRebakeNavmesh() +{ + if (!mIsInitialized) + { + LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized " + << "when the request is being made to rebake the navmesh." << LL_ENDL; + } + else + { + if (!canRebakeRegion()) + { + LL_WARNS("navmeshRebaking") << "attempting to rebake navmesh when user does not have permissions " + << "on this region" << LL_ENDL; + } + if (getMode() != kRebakeNavMesh_Available) + { + LL_WARNS("navmeshRebaking") << "attempting to rebake navmesh when mode is not available" + << LL_ENDL; + } + + setMode(kRebakeNavMesh_RequestSent); + LLPathfindingManager::getInstance()->requestRebakeNavMesh(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRebakeNavMeshResponse, this, _1)); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::setMode(ERebakeNavMeshMode pRebakeNavMeshMode) +{ + mRebakeNavMeshMode = pRebakeNavMeshMode; +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleAgentState(BOOL pCanRebakeRegion) +{ + llassert(mIsInitialized); + mCanRebakeRegion = pCanRebakeRegion; +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleRebakeNavMeshResponse(bool pResponseStatus) +{ + llassert(mIsInitialized); + if (getMode() == kRebakeNavMesh_RequestSent) + { + setMode(pResponseStatus ? kRebakeNavMesh_InProgress : kRebakeNavMesh_Default); + } + + if (!pResponseStatus) + { + LLNotificationsUtil::add("PathfindingCannotRebakeNavmesh"); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleNavMeshStatus(const LLPathfindingNavMeshStatus &pNavMeshStatus) +{ + llassert(mIsInitialized); + ERebakeNavMeshMode rebakeNavMeshMode = kRebakeNavMesh_Default; + if (pNavMeshStatus.isValid()) + { + switch (pNavMeshStatus.getStatus()) + { + case LLPathfindingNavMeshStatus::kPending : + case LLPathfindingNavMeshStatus::kRepending : + rebakeNavMeshMode = kRebakeNavMesh_Available; + break; + case LLPathfindingNavMeshStatus::kBuilding : + rebakeNavMeshMode = kRebakeNavMesh_InProgress; + break; + case LLPathfindingNavMeshStatus::kComplete : + rebakeNavMeshMode = kRebakeNavMesh_NotAvailable; + break; + default : + rebakeNavMeshMode = kRebakeNavMesh_Default; + llassert(0); + break; + } + } + + setMode(rebakeNavMeshMode); +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed() +{ + llassert(mIsInitialized); + createNavMeshStatusListenerForCurrentRegion(); + mCanRebakeRegion = FALSE; + LLPathfindingManager::getInstance()->requestGetAgentState(); +} + +void LLMenuOptionPathfindingRebakeNavmesh::createNavMeshStatusListenerForCurrentRegion() +{ + if (mNavMeshSlot.connected()) + { + mNavMeshSlot.disconnect(); + } + + LLViewerRegion *currentRegion = gAgent.getRegion(); + if (currentRegion != NULL) + { + mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleNavMeshStatus, this, _2)); + LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true); + } +} diff --git a/indra/newview/llpanelpathfindingrebakenavmesh.h b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h similarity index 63% rename from indra/newview/llpanelpathfindingrebakenavmesh.h rename to indra/newview/llmenuoptionpathfindingrebakenavmesh.h index 5aa1c68d8..7b1d2873b 100644 --- a/indra/newview/llpanelpathfindingrebakenavmesh.h +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h @@ -1,6 +1,6 @@ /** -* @file llpanelpathfindingrebakenavmesh.h -* @brief Header file for llpanelpathfindingrebakenavmesh +* @file llmenuoptionpathfindingrebakenavmesh.h +* @brief Header file for llmenuoptionpathfindingrebakenavmesh * @author Prep@lindenlab.com * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ @@ -24,34 +24,22 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#ifndef LL_LLPANELPATHFINDINGREBAKENAVMESH_H -#define LL_LLPANELPATHFINDINGREBAKENAVMESH_H +#ifndef LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H +#define LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H #include -#include "llpanel.h" #include "llpathfindingmanager.h" #include "llpathfindingnavmesh.h" +#include "llsingleton.h" -class LLButton; class LLPathfindingNavMeshStatus; -class LLPanelPathfindingRebakeNavmesh : public LLPanel +class LLMenuOptionPathfindingRebakeNavmesh : public LLSingleton { - - LOG_CLASS(LLPanelPathfindingRebakeNavmesh); + LOG_CLASS(LLMenuOptionPathfindingRebakeNavmesh); public: - static LLPanelPathfindingRebakeNavmesh* getInstance(); - - virtual BOOL postBuild(); - - virtual void draw(); - virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen); - -protected: - -private: typedef enum { kRebakeNavMesh_Available, @@ -61,15 +49,21 @@ private: kRebakeNavMesh_Default = kRebakeNavMesh_NotAvailable } ERebakeNavMeshMode; - LLPanelPathfindingRebakeNavmesh(); - virtual ~LLPanelPathfindingRebakeNavmesh(); + LLMenuOptionPathfindingRebakeNavmesh(); + virtual ~LLMenuOptionPathfindingRebakeNavmesh(); - static LLPanelPathfindingRebakeNavmesh* getPanel(); + void initialize(); + void quit(); - void setMode(ERebakeNavMeshMode pRebakeNavMeshMode); + bool canRebakeRegion() const; ERebakeNavMeshMode getMode() const; - void onNavMeshRebakeClick(); + void sendRequestRebakeNavmesh(); + +protected: + +private: + void setMode(ERebakeNavMeshMode pRebakeNavMeshMode); void handleAgentState(BOOL pCanRebakeRegion); void handleRebakeNavMeshResponse(bool pResponseStatus); @@ -78,19 +72,14 @@ private: void createNavMeshStatusListenerForCurrentRegion(); - bool doDraw() const; - void updatePosition(); + bool mIsInitialized; - BOOL mCanRebakeRegion; + bool mCanRebakeRegion; ERebakeNavMeshMode mRebakeNavMeshMode; - LLButton* mNavMeshRebakeButton; - LLButton* mNavMeshSendingButton; - LLButton* mNavMeshBakingButton; - LLPathfindingNavMesh::navmesh_slot_t mNavMeshSlot; boost::signals2::connection mRegionCrossingSlot; LLPathfindingManager::agent_state_slot_t mAgentStateSlot; }; -#endif // LL_LLPANELPATHFINDINGREBAKENAVMESH_H +#endif // LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index 5522f27a4..a834e7812 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -246,19 +246,23 @@ void LLOverlayBar::layoutButtons() if (state_buttons_panel->getVisible()) { - U32 required_width=0; + U32 button_count = 0; const child_list_t& view_list = *(state_buttons_panel->getChildList()); BOOST_FOREACH(LLView* viewp, view_list) { - required_width+=viewp->getRect().getWidth(); + if(!viewp->getEnabled()) + continue; + ++button_count; } + const S32 MAX_BAR_WIDTH = 600; + S32 bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH); - const S32 MAX_BAR_WIDTH = 800; - //const S32 MAX_BUTTON_WIDTH = 150; + // calculate button widths + const S32 MAX_BUTTON_WIDTH = 150; static LLCachedControl status_bar_pad("StatusBarPad",10); - S32 usable_bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH) - (view_list.size()-1) * status_bar_pad; - F32 element_scale = (F32)usable_bar_width / (F32)required_width; + S32 segment_width = llclamp(lltrunc((F32)(bar_width) / (F32)button_count), 0, MAX_BUTTON_WIDTH); + S32 btn_width = segment_width - status_bar_pad; // Evenly space all buttons, starting from left S32 left = 0; @@ -266,13 +270,14 @@ void LLOverlayBar::layoutButtons() BOOST_REVERSE_FOREACH(LLView* viewp, view_list) { + if(!viewp->getEnabled()) + continue; LLRect r = viewp->getRect(); - S32 new_width = r.getWidth() * element_scale; //if(dynamic_cast(viewp)) // new_width = llclamp(new_width,0,MAX_BUTTON_WIDTH); - r.setOriginAndSize(left, bottom, new_width, r.getHeight()); - viewp->setShape(r,false); - left += viewp->getRect().getWidth() + status_bar_pad; + r.setOriginAndSize(left, bottom, btn_width, r.getHeight()); + viewp->setRect(r); + left += segment_width; } } } diff --git a/indra/newview/llpanelpathfindingrebakenavmesh.cpp b/indra/newview/llpanelpathfindingrebakenavmesh.cpp deleted file mode 100644 index ca4bcfb67..000000000 --- a/indra/newview/llpanelpathfindingrebakenavmesh.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/** -* @file llpanelpathfindingrebakenavmesh.cpp -* @brief Implementation of llpanelpathfindingrebakenavmesh -* @author Prep@lindenlab.com -* -* $LicenseInfo:firstyear=2012&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2012, 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 "llpanelpathfindingrebakenavmesh.h" - -#include -#include - -#include "llagent.h" -#include "llbutton.h" -#include "llenvmanager.h" -#include "llnotificationsutil.h" -#include "llpanel.h" -#include "llpathfindingmanager.h" -#include "llpathfindingnavmesh.h" -#include "llpathfindingnavmeshstatus.h" -#include "lltoolbar.h" -#include "llviewerregion.h" -#include "llviewerwindow.h" -#include "lluictrlfactory.h" - - -LLPanelPathfindingRebakeNavmesh* LLPanelPathfindingRebakeNavmesh::getInstance() -{ - static LLPanelPathfindingRebakeNavmesh* panel = getPanel(); - return panel; -} - -BOOL LLPanelPathfindingRebakeNavmesh::postBuild() -{ - //Rebake button - mNavMeshRebakeButton = getChild("navmesh_btn"); - llassert(mNavMeshRebakeButton != NULL); - mNavMeshRebakeButton->setCommitCallback(boost::bind(&LLPanelPathfindingRebakeNavmesh::onNavMeshRebakeClick, this)); - //LLHints::registerHintTarget("navmesh_btn", mNavMeshRebakeButton->getHandle()); - - //Sending rebake request - mNavMeshSendingButton = findChild("navmesh_btn_sending"); - llassert(mNavMeshSendingButton != NULL); - //LLHints::registerHintTarget("navmesh_btn_sending", mNavMeshSendingButton->getHandle()); - - //rebaking... - mNavMeshBakingButton = findChild("navmesh_btn_baking"); - llassert(mNavMeshBakingButton != NULL); - //LLHints::registerHintTarget("navmesh_btn_baking", mNavMeshBakingButton->getHandle()); - - setMode(kRebakeNavMesh_Default); - - createNavMeshStatusListenerForCurrentRegion(); - - if ( !mRegionCrossingSlot.connected() ) - { - mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLPanelPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this)); - } - - if (!mAgentStateSlot.connected()) - { - mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLPanelPathfindingRebakeNavmesh::handleAgentState, this, _1)); - } - LLPathfindingManager::getInstance()->requestGetAgentState(); - - return LLPanel::postBuild(); -} - -void LLPanelPathfindingRebakeNavmesh::draw() -{ - if (doDraw()) - { - updatePosition(); - LLPanel::draw(); - } -} - -BOOL LLPanelPathfindingRebakeNavmesh::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) -{ - gViewerWindow->unblockToolTips(); - - if (mNavMeshRebakeButton->getVisible()) - { - msg=mNavMeshRebakeButton->getToolTip(); - //LLToolTipMgr::instance().show(mNavMeshRebakeButton->getToolTip()); - } - else if (mNavMeshSendingButton->getVisible()) - { - msg=mNavMeshSendingButton->getToolTip(); - //LLToolTipMgr::instance().show(mNavMeshSendingButton->getToolTip()); - } - else if (mNavMeshBakingButton->getVisible()) - { - msg=mNavMeshBakingButton->getToolTip(); - //LLToolTipMgr::instance().show(mNavMeshBakingButton->getToolTip()); - } - - // Convert rect local to screen coordinates - localPointToScreen( - 0, 0, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - getRect().getWidth(), getRect().getHeight(), - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); - return true;//LLPanel::handleToolTip(x, y, mask); -} - -LLPanelPathfindingRebakeNavmesh::LLPanelPathfindingRebakeNavmesh() - : LLPanel(), - mCanRebakeRegion(FALSE), - mRebakeNavMeshMode(kRebakeNavMesh_Default), - mNavMeshRebakeButton(NULL), - mNavMeshSendingButton(NULL), - mNavMeshBakingButton(NULL), - mNavMeshSlot(), - mRegionCrossingSlot(), - mAgentStateSlot() -{ - // make sure we have the only instance of this class - static bool b = true; - llassert_always(b); - b=false; -} - -LLPanelPathfindingRebakeNavmesh::~LLPanelPathfindingRebakeNavmesh() -{ -} - -LLPanelPathfindingRebakeNavmesh* LLPanelPathfindingRebakeNavmesh::getPanel() -{ - LLPanelPathfindingRebakeNavmesh* panel = new LLPanelPathfindingRebakeNavmesh(); - LLUICtrlFactory::getInstance()->buildPanel(panel,"panel_navmesh_rebake.xml"); - return panel; -} - -void LLPanelPathfindingRebakeNavmesh::setMode(ERebakeNavMeshMode pRebakeNavMeshMode) -{ - if (pRebakeNavMeshMode == kRebakeNavMesh_Available) - { - LLNotificationsUtil::add("PathfindingRebakeNavmesh"); - } - mNavMeshRebakeButton->setVisible(pRebakeNavMeshMode == kRebakeNavMesh_Available); - mNavMeshSendingButton->setVisible(pRebakeNavMeshMode == kRebakeNavMesh_RequestSent); - mNavMeshBakingButton->setVisible(pRebakeNavMeshMode == kRebakeNavMesh_InProgress); - mRebakeNavMeshMode = pRebakeNavMeshMode; -} - -LLPanelPathfindingRebakeNavmesh::ERebakeNavMeshMode LLPanelPathfindingRebakeNavmesh::getMode() const -{ - return mRebakeNavMeshMode; -} - -void LLPanelPathfindingRebakeNavmesh::onNavMeshRebakeClick() -{ - setMode(kRebakeNavMesh_RequestSent); - LLPathfindingManager::getInstance()->requestRebakeNavMesh(boost::bind(&LLPanelPathfindingRebakeNavmesh::handleRebakeNavMeshResponse, this, _1)); -} - -void LLPanelPathfindingRebakeNavmesh::handleAgentState(BOOL pCanRebakeRegion) -{ - mCanRebakeRegion = pCanRebakeRegion; -} - -void LLPanelPathfindingRebakeNavmesh::handleRebakeNavMeshResponse(bool pResponseStatus) -{ - if (getMode() == kRebakeNavMesh_RequestSent) - { - setMode(pResponseStatus ? kRebakeNavMesh_InProgress : kRebakeNavMesh_Default); - } - - if (!pResponseStatus) - { - LLNotificationsUtil::add("PathfindingCannotRebakeNavmesh"); - } -} - -void LLPanelPathfindingRebakeNavmesh::handleNavMeshStatus(const LLPathfindingNavMeshStatus &pNavMeshStatus) -{ - ERebakeNavMeshMode rebakeNavMeshMode = kRebakeNavMesh_Default; - if (pNavMeshStatus.isValid()) - { - switch (pNavMeshStatus.getStatus()) - { - case LLPathfindingNavMeshStatus::kPending : - case LLPathfindingNavMeshStatus::kRepending : - rebakeNavMeshMode = kRebakeNavMesh_Available; - break; - case LLPathfindingNavMeshStatus::kBuilding : - rebakeNavMeshMode = kRebakeNavMesh_InProgress; - break; - case LLPathfindingNavMeshStatus::kComplete : - rebakeNavMeshMode = kRebakeNavMesh_NotAvailable; - break; - default : - rebakeNavMeshMode = kRebakeNavMesh_Default; - llassert(0); - break; - } - } - - setMode(rebakeNavMeshMode); -} - -void LLPanelPathfindingRebakeNavmesh::handleRegionBoundaryCrossed() -{ - createNavMeshStatusListenerForCurrentRegion(); - mCanRebakeRegion = FALSE; - LLPathfindingManager::getInstance()->requestGetAgentState(); -} - -void LLPanelPathfindingRebakeNavmesh::createNavMeshStatusListenerForCurrentRegion() -{ - if (mNavMeshSlot.connected()) - { - mNavMeshSlot.disconnect(); - } - - LLViewerRegion *currentRegion = gAgent.getRegion(); - if (currentRegion != NULL) - { - mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLPanelPathfindingRebakeNavmesh::handleNavMeshStatus, this, _2)); - LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true); - } -} - -bool LLPanelPathfindingRebakeNavmesh::doDraw() const -{ - return (mCanRebakeRegion && (mRebakeNavMeshMode != kRebakeNavMesh_NotAvailable)); -} - -void LLPanelPathfindingRebakeNavmesh::updatePosition() -{ -#if 0 - S32 y_pos = 0; - S32 bottom_tb_center = 0; - - if (LLToolBar* toolbar_bottom = gToolBarView->getChild("toolbar_bottom")) - { - y_pos = toolbar_bottom->getRect().getHeight(); - bottom_tb_center = toolbar_bottom->getRect().getCenterX(); - } - - S32 left_tb_width = 0; - if (LLToolBar* toolbar_left = gToolBarView->getChild("toolbar_left")) - { - left_tb_width = toolbar_left->getRect().getWidth(); - } - - if(LLPanel* panel_ssf_container = getRootView()->getChild("state_management_buttons_container")) - { - panel_ssf_container->setOrigin(0, y_pos); - } - - S32 x_pos = bottom_tb_center-getRect().getWidth()/2 - left_tb_width + 113 /* width of stand/fly button *//* + 10 *//* margin */; - - /*setOrigin( x_pos, 0);*/ -#endif -} diff --git a/indra/newview/llpathfindinglinkset.cpp b/indra/newview/llpathfindinglinkset.cpp index fe4daabd8..50b76378f 100644 --- a/indra/newview/llpathfindinglinkset.cpp +++ b/indra/newview/llpathfindinglinkset.cpp @@ -39,6 +39,7 @@ #define LINKSET_MODIFIABLE_FIELD "modifiable" #define LINKSET_CATEGORY_FIELD "navmesh_category" #define LINKSET_CAN_BE_VOLUME "can_be_volume" +#define LINKSET_IS_SCRIPTED_FIELD "is_scripted" #define LINKSET_PHANTOM_FIELD "phantom" #define LINKSET_WALKABILITY_A_FIELD "A" #define LINKSET_WALKABILITY_B_FIELD "B" @@ -62,6 +63,8 @@ LLPathfindingLinkset::LLPathfindingLinkset(const LLSD& pTerrainData) mLandImpact(0U), mIsModifiable(FALSE), mCanBeVolume(FALSE), + mIsScripted(FALSE), + mHasIsScripted(TRUE), mLinksetUse(kUnknown), mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE), mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE), @@ -77,6 +80,8 @@ LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD& mLandImpact(0U), mIsModifiable(TRUE), mCanBeVolume(TRUE), + mIsScripted(FALSE), + mHasIsScripted(FALSE), mLinksetUse(kUnknown), mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE), mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE), @@ -93,6 +98,8 @@ LLPathfindingLinkset::LLPathfindingLinkset(const LLPathfindingLinkset& pOther) mLandImpact(pOther.mLandImpact), mIsModifiable(pOther.mIsModifiable), mCanBeVolume(pOther.mCanBeVolume), + mIsScripted(pOther.mIsScripted), + mHasIsScripted(pOther.mHasIsScripted), mLinksetUse(pOther.mLinksetUse), mWalkabilityCoefficientA(pOther.mWalkabilityCoefficientA), mWalkabilityCoefficientB(pOther.mWalkabilityCoefficientB), @@ -113,6 +120,8 @@ LLPathfindingLinkset& LLPathfindingLinkset::operator =(const LLPathfindingLinkse mLandImpact = pOther.mLandImpact; mIsModifiable = pOther.mIsModifiable; mCanBeVolume = pOther.mCanBeVolume; + mIsScripted = pOther.mIsScripted; + mHasIsScripted = pOther.mHasIsScripted; mLinksetUse = pOther.mLinksetUse; mWalkabilityCoefficientA = pOther.mWalkabilityCoefficientA; mWalkabilityCoefficientB = pOther.mWalkabilityCoefficientB; @@ -140,6 +149,11 @@ bool LLPathfindingLinkset::isShowUnmodifiablePhantomWarning(ELinksetUse pLinkset return (!isModifiable() && (isPhantom() != isPhantom(pLinksetUse))); } +bool LLPathfindingLinkset::isShowPhantomToggleWarning(ELinksetUse pLinksetUse) const +{ + return (isModifiable() && (isPhantom() != isPhantom(pLinksetUse))); +} + bool LLPathfindingLinkset::isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const { return (!canBeVolume() && ((pLinksetUse == kMaterialVolume) || (pLinksetUse == kExclusionVolume))); @@ -193,6 +207,13 @@ void LLPathfindingLinkset::parseLinksetData(const LLSD &pLinksetData) llassert(pLinksetData.has(LINKSET_MODIFIABLE_FIELD)); llassert(pLinksetData.get(LINKSET_MODIFIABLE_FIELD).isBoolean()); mIsModifiable = pLinksetData.get(LINKSET_MODIFIABLE_FIELD).asBoolean(); + + mHasIsScripted = pLinksetData.has(LINKSET_IS_SCRIPTED_FIELD); + if (mHasIsScripted) + { + llassert(pLinksetData.get(LINKSET_IS_SCRIPTED_FIELD).isBoolean()); + mIsScripted = pLinksetData.get(LINKSET_IS_SCRIPTED_FIELD).asBoolean(); + } } void LLPathfindingLinkset::parsePathfindingData(const LLSD &pLinksetData) diff --git a/indra/newview/llpathfindinglinkset.h b/indra/newview/llpathfindinglinkset.h index 73b4d6bad..308a3a1e0 100644 --- a/indra/newview/llpathfindinglinkset.h +++ b/indra/newview/llpathfindinglinkset.h @@ -63,12 +63,16 @@ public: inline ELinksetUse getLinksetUse() const {return mLinksetUse;}; + inline BOOL isScripted() const {return mIsScripted;}; + inline BOOL hasIsScripted() const {return mHasIsScripted;}; + inline S32 getWalkabilityCoefficientA() const {return mWalkabilityCoefficientA;}; inline S32 getWalkabilityCoefficientB() const {return mWalkabilityCoefficientB;}; inline S32 getWalkabilityCoefficientC() const {return mWalkabilityCoefficientC;}; inline S32 getWalkabilityCoefficientD() const {return mWalkabilityCoefficientD;}; bool isShowUnmodifiablePhantomWarning(ELinksetUse pLinksetUse) const; + bool isShowPhantomToggleWarning(ELinksetUse pLinksetUse) const; bool isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const; LLSD encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const; @@ -98,6 +102,8 @@ private: U32 mLandImpact; BOOL mIsModifiable; BOOL mCanBeVolume; + BOOL mIsScripted; + BOOL mHasIsScripted; ELinksetUse mLinksetUse; S32 mWalkabilityCoefficientA; S32 mWalkabilityCoefficientB; diff --git a/indra/newview/llpathfindinglinksetlist.cpp b/indra/newview/llpathfindinglinksetlist.cpp index 746fa342a..b886e4676 100644 --- a/indra/newview/llpathfindinglinksetlist.cpp +++ b/indra/newview/llpathfindinglinksetlist.cpp @@ -113,6 +113,20 @@ bool LLPathfindingLinksetList::isShowUnmodifiablePhantomWarning(LLPathfindingLin return isShowWarning; } +bool LLPathfindingLinksetList::isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ + bool isShowWarning = false; + + for (const_iterator objectIter = begin(); !isShowWarning && (objectIter != end()); ++objectIter) + { + const LLPathfindingObjectPtr objectPtr = objectIter->second; + const LLPathfindingLinkset *linkset = dynamic_cast(objectPtr.get()); + isShowWarning = linkset->isShowPhantomToggleWarning(pLinksetUse); + } + + return isShowWarning; +} + bool LLPathfindingLinksetList::isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const { bool isShowWarning = false; diff --git a/indra/newview/llpathfindinglinksetlist.h b/indra/newview/llpathfindinglinksetlist.h index 77c635864..1d38e4c11 100644 --- a/indra/newview/llpathfindinglinksetlist.h +++ b/indra/newview/llpathfindinglinksetlist.h @@ -43,6 +43,7 @@ public: LLSD encodeTerrainFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const; bool isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; + bool isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; bool isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; void determinePossibleStates(BOOL &pCanBeWalkable, BOOL &pCanBeStaticObstacle, BOOL &pCanBeDynamicObstacle, diff --git a/indra/newview/llpathfindingobject.cpp b/indra/newview/llpathfindingobject.cpp index 916eceb4c..858d3203c 100644 --- a/indra/newview/llpathfindingobject.cpp +++ b/indra/newview/llpathfindingobject.cpp @@ -55,8 +55,10 @@ LLPathfindingObject::LLPathfindingObject() mOwnerUUID(), mHasOwnerName(false), mOwnerName(), + mAvatarNameCacheConnection(), mIsGroupOwned(false), - mLocation() + mLocation(), + mOwnerNameSignal() { } @@ -67,8 +69,10 @@ LLPathfindingObject::LLPathfindingObject(const std::string &pUUID, const LLSD &p mOwnerUUID(), mHasOwnerName(false), mOwnerName(), + mAvatarNameCacheConnection(), mIsGroupOwned(false), - mLocation() + mLocation(), + mOwnerNameSignal() { parseObjectData(pObjectData); } @@ -80,14 +84,17 @@ LLPathfindingObject::LLPathfindingObject(const LLPathfindingObject& pOther) mOwnerUUID(pOther.mOwnerUUID), mHasOwnerName(false), mOwnerName(), + mAvatarNameCacheConnection(), mIsGroupOwned(pOther.mIsGroupOwned), - mLocation(pOther.mLocation) + mLocation(pOther.mLocation), + mOwnerNameSignal() { fetchOwnerName(); } LLPathfindingObject::~LLPathfindingObject() { + disconnectAvatarNameCacheConnection(); } LLPathfindingObject &LLPathfindingObject::operator =(const LLPathfindingObject& pOther) @@ -115,6 +122,23 @@ std::string LLPathfindingObject::getOwnerName() const return ownerName; } +LLPathfindingObject::name_connection_t LLPathfindingObject::registerOwnerNameListener(name_callback_t pOwnerNameCallback) +{ + llassert(hasOwner()); + + name_connection_t connection; + if (hasOwnerName()) + { + pOwnerNameCallback(this); + } + else + { + connection = mOwnerNameSignal.connect(pOwnerNameCallback); + } + + return connection; +} + void LLPathfindingObject::parseObjectData(const LLSD &pObjectData) { llassert(pObjectData.has(PATHFINDING_OBJECT_NAME_FIELD)); @@ -149,7 +173,7 @@ void LLPathfindingObject::fetchOwnerName() mHasOwnerName = LLAvatarNameCache::get(mOwnerUUID, &mOwnerName); if (!mHasOwnerName) { - LLAvatarNameCache::get(mOwnerUUID, boost::bind(&LLPathfindingObject::handleAvatarNameFetch, this, _1, _2)); + mAvatarNameCacheConnection = LLAvatarNameCache::get(mOwnerUUID, boost::bind(&LLPathfindingObject::handleAvatarNameFetch, this, _1, _2)); } } } @@ -157,6 +181,19 @@ void LLPathfindingObject::fetchOwnerName() void LLPathfindingObject::handleAvatarNameFetch(const LLUUID &pOwnerUUID, const LLAvatarName &pAvatarName) { llassert(mOwnerUUID == pOwnerUUID); + mOwnerName = pAvatarName; mHasOwnerName = true; + + disconnectAvatarNameCacheConnection(); + + mOwnerNameSignal(this); +} + +void LLPathfindingObject::disconnectAvatarNameCacheConnection() +{ + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } } diff --git a/indra/newview/llpathfindingobject.h b/indra/newview/llpathfindingobject.h index d45cc554f..b8d3ca236 100644 --- a/indra/newview/llpathfindingobject.h +++ b/indra/newview/llpathfindingobject.h @@ -30,8 +30,11 @@ #include #include +#include +#include #include "llavatarname.h" +#include "llavatarnamecache.h" #include "lluuid.h" #include "v3math.h" @@ -59,6 +62,12 @@ public: inline BOOL isGroupOwned() const {return mIsGroupOwned;}; inline const LLVector3& getLocation() const {return mLocation;}; + typedef boost::function name_callback_t; + typedef boost::signals2::signal name_signal_t; + typedef boost::signals2::connection name_connection_t; + + name_connection_t registerOwnerNameListener(name_callback_t pOwnerNameCallback); + protected: private: @@ -66,15 +75,18 @@ private: void fetchOwnerName(); void handleAvatarNameFetch(const LLUUID &pOwnerUUID, const LLAvatarName &pAvatarName); + void disconnectAvatarNameCacheConnection(); - LLUUID mUUID; - std::string mName; - std::string mDescription; - LLUUID mOwnerUUID; - bool mHasOwnerName; - LLAvatarName mOwnerName; - BOOL mIsGroupOwned; - LLVector3 mLocation; + LLUUID mUUID; + std::string mName; + std::string mDescription; + LLUUID mOwnerUUID; + bool mHasOwnerName; + LLAvatarName mOwnerName; + LLAvatarNameCache::callback_connection_t mAvatarNameCacheConnection; + BOOL mIsGroupOwned; + LLVector3 mLocation; + name_signal_t mOwnerNameSignal; }; #endif // LL_LLPATHFINDINGOBJECT_H diff --git a/indra/newview/llpathfindingobjectlist.cpp b/indra/newview/llpathfindingobjectlist.cpp index 68a7e736e..f1ecb45fc 100644 --- a/indra/newview/llpathfindingobjectlist.cpp +++ b/indra/newview/llpathfindingobjectlist.cpp @@ -45,6 +45,7 @@ LLPathfindingObjectList::LLPathfindingObjectList() LLPathfindingObjectList::~LLPathfindingObjectList() { + clear(); } bool LLPathfindingObjectList::isEmpty() const @@ -52,6 +53,15 @@ bool LLPathfindingObjectList::isEmpty() const return mObjectMap.empty(); } +void LLPathfindingObjectList::clear() +{ + for (LLPathfindingObjectMap::iterator objectIter = mObjectMap.begin(); objectIter != mObjectMap.end(); ++objectIter) + { + objectIter->second.reset(); + } + mObjectMap.clear(); +} + void LLPathfindingObjectList::update(LLPathfindingObjectPtr pUpdateObjectPtr) { if (pUpdateObjectPtr != NULL) diff --git a/indra/newview/llpathfindingobjectlist.h b/indra/newview/llpathfindingobjectlist.h index 3ad8e8b09..61580582d 100644 --- a/indra/newview/llpathfindingobjectlist.h +++ b/indra/newview/llpathfindingobjectlist.h @@ -47,6 +47,8 @@ public: bool isEmpty() const; + void clear(); + void update(LLPathfindingObjectPtr pUpdateObjectPtr); void update(LLPathfindingObjectListPtr pUpdateObjectListPtr); @@ -56,7 +58,6 @@ public: const_iterator begin() const; const_iterator end() const; - protected: LLPathfindingObjectMap &getObjectMap(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 9c1dea408..d4fc9c02c 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -183,6 +183,7 @@ #include "llmenugl.h" #include "llmimetypes.h" #include "llmorphview.h" +#include "llmenuoptionpathfindingrebakenavmesh.h" #include "llmoveview.h" #include "llmutelist.h" #include "llnotify.h" @@ -5327,6 +5328,39 @@ class LLToolsEnablePathfindingView : public view_listener_t } }; +class LLToolsDoPathfindingRebakeRegion : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool hasPathfinding = (LLPathfindingManager::getInstance() != NULL); + + if (hasPathfinding) + { + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh(); + } + + return hasPathfinding; + } +}; + +class LLToolsEnablePathfindingRebakeRegion : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool returnValue = false; + + if (LLPathfindingManager::getInstance() != NULL) + { + LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance(); + returnValue = (rebakeInstance->canRebakeRegion() && + (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available)); + + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(returnValue); + return returnValue; + } +}; + // Round the position of all root objects to the grid class LLToolsSnapObjectXY : public view_listener_t { @@ -9511,7 +9545,8 @@ void initialize_menus() addMenu(new LLToolsEnablePathfinding(), "Tools.EnablePathfinding"); addMenu(new LLToolsEnablePathfindingView(), "Tools.EnablePathfindingView"); - + addMenu(new LLToolsDoPathfindingRebakeRegion(), "Tools.DoPathfindingRebakeRegion"); + addMenu(new LLToolsEnablePathfindingRebakeRegion(), "Tools.EnablePathfindingRebakeRegion"); /*addMenu(new LLToolsVisibleBuyObject(), "Tools.VisibleBuyObject"); addMenu(new LLToolsVisibleTakeObject(), "Tools.VisibleTakeObject");*/ diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index f075e7c15..202194965 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1925,5 +1925,10 @@ bool LLViewerRegion::meshRezEnabled() const return (mSimulatorFeatures.has("MeshRezEnabled") && mSimulatorFeatures["MeshRezEnabled"].asBoolean()); } + +bool LLViewerRegion::dynamicPathfindingEnabled() const +{ + return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") && + mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean()); } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index b7fd43602..78367e738 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -293,6 +293,9 @@ public: void getSimulatorFeatures(LLSD& info); void setSimulatorFeatures(const LLSD& info); + + bool dynamicPathfindingEnabled() const; + typedef enum { CACHE_MISS_TYPE_FULL = 0, diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2348fb588..5908d2d14 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -128,10 +128,10 @@ #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" +#include "llmenuoptionpathfindingrebakenavmesh.h" #include "llmodaldialog.h" #include "llmorphview.h" #include "llmoveview.h" -#include "llpanelpathfindingrebakenavmesh.h" #include "llnotify.h" #include "lloverlaybar.h" #include "llpreviewtexture.h" @@ -1959,10 +1959,11 @@ void LLViewerWindow::initWorldUI() // put behind everything else in the UI mRootView->addChildInBack(gHUDView); } - + LLPanel* panel_ssf_container = getRootView()->getChild("state_management_buttons_container"); - LLPanelPathfindingRebakeNavmesh *panel_rebake_navmesh = LLPanelPathfindingRebakeNavmesh::getInstance(); - panel_ssf_container->addChild(panel_rebake_navmesh); + panel_ssf_container->setVisible(TRUE); + + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize(); } // initWorldUI that wasn't before logging in. Some of this may require the access the 'LindenUserDir'. @@ -2041,6 +2042,9 @@ void LLViewerWindow::shutdownViews() // Delete all child views. delete mRootView; mRootView = NULL; + llinfos << "RootView deleted." << llendl ; + + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->quit(); // Automatically deleted as children of mRootView. Fix the globals. gFloaterTools = NULL; diff --git a/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/indra/newview/skins/default/xui/en-us/menu_viewer.xml index b24eeefa2..923da7855 100644 --- a/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en-us/menu_viewer.xml @@ -836,6 +836,13 @@ width="250"> + + + + - -