371 lines
11 KiB
C++
371 lines
11 KiB
C++
/**
|
|
* @file llfloaterpathfindinglinksets.cpp
|
|
* @author William Todd Stinson
|
|
* @brief "Pathfinding linksets" floater, allowing manipulation of the Havok AI pathfinding settings.
|
|
*
|
|
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
|
* Second Life Viewer Source Code
|
|
* Copyright (C) 2010, 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 "llfloaterpathfindinglinksets.h"
|
|
#include "llsd.h"
|
|
#include "llagent.h"
|
|
#include "llfloater.h"
|
|
#include "llfloaterreg.h"
|
|
#include "llscrolllistctrl.h"
|
|
#include "llresmgr.h"
|
|
#include "llviewerregion.h"
|
|
#include "llhttpclient.h"
|
|
#include "lltextbase.h"
|
|
|
|
//---------------------------------------------------------------------------
|
|
// NavmeshDataGetResponder
|
|
//---------------------------------------------------------------------------
|
|
|
|
class NavmeshDataGetResponder : public LLHTTPClient::Responder
|
|
{
|
|
public:
|
|
NavmeshDataGetResponder(const std::string& pNavmeshDataGetURL, LLFloaterPathfindingLinksets *pLinksetsFloater);
|
|
virtual ~NavmeshDataGetResponder();
|
|
|
|
virtual void result(const LLSD& pContent);
|
|
virtual void error(U32 pStatus, const std::string& pReason);
|
|
|
|
private:
|
|
NavmeshDataGetResponder(const NavmeshDataGetResponder& pOther);
|
|
|
|
std::string mNavmeshDataGetURL;
|
|
LLFloaterPathfindingLinksets *mLinksetsFloater;
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
// LLFloaterPathfindingLinksets
|
|
//---------------------------------------------------------------------------
|
|
|
|
BOOL LLFloaterPathfindingLinksets::postBuild()
|
|
{
|
|
childSetAction("refresh_linksets_list", boost::bind(&LLFloaterPathfindingLinksets::onRefreshLinksetsClicked, this));
|
|
childSetAction("select_all_linksets", boost::bind(&LLFloaterPathfindingLinksets::onSelectAllLinksetsClicked, this));
|
|
childSetAction("select_none_linksets", boost::bind(&LLFloaterPathfindingLinksets::onSelectNoneLinksetsClicked, this));
|
|
|
|
mLinksetsScrollList = findChild<LLScrollListCtrl>("pathfinding_linksets");
|
|
llassert(mLinksetsScrollList != NULL);
|
|
mLinksetsScrollList->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onLinksetsSelectionChange, this));
|
|
mLinksetsScrollList->setCommitOnSelectionChange(true);
|
|
|
|
mLinksetsStatus = findChild<LLTextBase>("linksets_status");
|
|
llassert(mLinksetsStatus != NULL);
|
|
|
|
setFetchState(kFetchInitial);
|
|
|
|
return LLFloater::postBuild();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::onOpen(const LLSD& pKey)
|
|
{
|
|
sendNavmeshDataGetRequest();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::openLinksetsEditor()
|
|
{
|
|
LLFloaterReg::toggleInstanceOrBringToFront("pathfinding_linksets");
|
|
}
|
|
|
|
LLFloaterPathfindingLinksets::EFetchState LLFloaterPathfindingLinksets::getFetchState() const
|
|
{
|
|
return mFetchState;
|
|
}
|
|
|
|
BOOL LLFloaterPathfindingLinksets::isFetchInProgress() const
|
|
{
|
|
BOOL retVal;
|
|
switch (getFetchState())
|
|
{
|
|
case kFetchStarting :
|
|
case kFetchInProgress :
|
|
case kFetchInProgress_MultiRequested :
|
|
case kFetchReceived :
|
|
retVal = true;
|
|
break;
|
|
default :
|
|
retVal = false;
|
|
break;
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed)
|
|
: LLFloater(pSeed),
|
|
mFetchState(kFetchInitial),
|
|
mLinksetsScrollList(NULL),
|
|
mLinksetsStatus(NULL)
|
|
{
|
|
}
|
|
|
|
LLFloaterPathfindingLinksets::~LLFloaterPathfindingLinksets()
|
|
{
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::sendNavmeshDataGetRequest()
|
|
{
|
|
if (isFetchInProgress())
|
|
{
|
|
if (getFetchState() == kFetchInProgress)
|
|
{
|
|
setFetchState(kFetchInProgress_MultiRequested);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
setFetchState(kFetchStarting);
|
|
clearLinksetsList();
|
|
|
|
LLViewerRegion* region = gAgent.getRegion();
|
|
if (region != NULL)
|
|
{
|
|
std::string navmeshDataURL = region->getCapability("ObjectNavmesh");
|
|
if (navmeshDataURL.empty())
|
|
{
|
|
setFetchState(kFetchComplete);
|
|
llwarns << "cannot query navmesh data from current region '" << region->getName() << "'" << llendl;
|
|
}
|
|
else
|
|
{
|
|
setFetchState(kFetchInProgress);
|
|
LLHTTPClient::get(navmeshDataURL, new NavmeshDataGetResponder(navmeshDataURL, this));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::handleNavmeshDataGetReply(const LLSD& pNavmeshData)
|
|
{
|
|
setFetchState(kFetchReceived);
|
|
clearLinksetsList();
|
|
|
|
const LLVector3& avatarPosition = gAgent.getPositionAgent();
|
|
|
|
for (LLSD::map_const_iterator itemsIter = pNavmeshData.beginMap();
|
|
itemsIter != pNavmeshData.endMap(); ++itemsIter)
|
|
{
|
|
const std::string& uuid = itemsIter->first;
|
|
const LLSD& itemData = itemsIter->second;
|
|
|
|
const LLSD::String& itemName = itemData.get("name").asString();
|
|
const LLSD::String& itemDescription = itemData.get("description").asString();
|
|
LLSD::Integer itemLandImpact = itemData.get("landimpact").asInteger();
|
|
LLSD::Boolean isItemFixed = itemData.get("fixed").asBoolean();
|
|
LLSD::Boolean isItemWalkable = true; // XXX stinson: walkable data not coming from service yet
|
|
LLSD::Boolean isItemPhantom = itemData.get("phantom").asBoolean();
|
|
LLSD::Real itemA = itemData.get("A").asReal();
|
|
LLSD::Real itemB = itemData.get("B").asReal();
|
|
LLSD::Real itemC = itemData.get("C").asReal();
|
|
LLSD::Real itemD = itemData.get("D").asReal();
|
|
|
|
F32 location_x = 50.0f, location_y = 50.0f, location_z = 50.0f; // XXX stinson: use real location later
|
|
LLVector3 itemLocation(location_x, location_y, location_z);
|
|
F32 itemDistance = dist_vec(avatarPosition, itemLocation);
|
|
|
|
LLSD columns;
|
|
|
|
columns[0]["column"] = "name";
|
|
columns[0]["value"] = itemName;
|
|
columns[0]["font"] = "SANSSERIF";
|
|
|
|
columns[1]["column"] = "description";
|
|
columns[1]["value"] = itemDescription;
|
|
columns[1]["font"] = "SANSSERIF";
|
|
|
|
columns[2]["column"] = "land_impact";
|
|
columns[2]["value"] = llformat("%1d m", itemLandImpact);
|
|
columns[2]["font"] = "SANSSERIF";
|
|
|
|
columns[3]["column"] = "dist_from_you";
|
|
columns[3]["value"] = llformat("%1.0f m", itemDistance);
|
|
columns[3]["font"] = "SANSSERIF";
|
|
|
|
columns[4]["column"] = "is_fixed";
|
|
columns[4]["value"] = getString(isItemFixed ? "linkset_is_fixed" : "linkset_is_not_fixed");
|
|
columns[4]["font"] = "SANSSERIF";
|
|
|
|
columns[5]["column"] = "is_walkable";
|
|
columns[5]["value"] = getString(isItemWalkable ? "linkset_is_walkable" : "linkset_is_not_walkable");
|
|
columns[5]["font"] = "SANSSERIF";
|
|
|
|
columns[6]["column"] = "is_phantom";
|
|
columns[6]["value"] = getString(isItemPhantom ? "linkset_is_phantom" : "linkset_is_not_phantom");
|
|
columns[6]["font"] = "SANSSERIF";
|
|
|
|
columns[7]["column"] = "a_percent";
|
|
columns[7]["value"] = llformat("%2.0f", itemA);
|
|
columns[7]["font"] = "SANSSERIF";
|
|
|
|
columns[8]["column"] = "b_percent";
|
|
columns[8]["value"] = llformat("%2.0f", itemB);
|
|
columns[8]["font"] = "SANSSERIF";
|
|
|
|
columns[9]["column"] = "c_percent";
|
|
columns[9]["value"] = llformat("%2.0f", itemC);
|
|
columns[9]["font"] = "SANSSERIF";
|
|
|
|
columns[10]["column"] = "d_percent";
|
|
columns[10]["value"] = llformat("%2.0f", itemD);
|
|
columns[10]["font"] = "SANSSERIF";
|
|
|
|
LLSD element;
|
|
element["id"] = uuid;
|
|
element["column"] = columns;
|
|
|
|
mLinksetsScrollList->addElement(element);
|
|
}
|
|
|
|
setFetchState(kFetchComplete);
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::handleNavmeshDataGetError(const std::string& pURL, const std::string& pErrorReason)
|
|
{
|
|
setFetchState(kFetchError);
|
|
clearLinksetsList();
|
|
llwarns << "Error fetching navmesh data from URL '" << pURL << "' because " << pErrorReason << llendl;
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::setFetchState(EFetchState pFetchState)
|
|
{
|
|
mFetchState = pFetchState;
|
|
updateLinksetsStatusMessage();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::onLinksetsSelectionChange()
|
|
{
|
|
updateLinksetsStatusMessage();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::onRefreshLinksetsClicked()
|
|
{
|
|
sendNavmeshDataGetRequest();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::onSelectAllLinksetsClicked()
|
|
{
|
|
selectAllLinksets();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::onSelectNoneLinksetsClicked()
|
|
{
|
|
selectNoneLinksets();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::clearLinksetsList()
|
|
{
|
|
mLinksetsScrollList->deleteAllItems();
|
|
updateLinksetsStatusMessage();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::selectAllLinksets()
|
|
{
|
|
mLinksetsScrollList->selectAll();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::selectNoneLinksets()
|
|
{
|
|
mLinksetsScrollList->deselectAllItems();
|
|
}
|
|
|
|
void LLFloaterPathfindingLinksets::updateLinksetsStatusMessage()
|
|
{
|
|
static const LLColor4 warningColor = LLUIColorTable::instance().getColor("DrYellow");
|
|
|
|
std::string statusText("");
|
|
LLStyle::Params styleParams;
|
|
|
|
switch (getFetchState())
|
|
{
|
|
case kFetchStarting :
|
|
statusText = getString("linksets_fetching_starting");
|
|
break;
|
|
case kFetchInProgress :
|
|
statusText = getString("linksets_fetching_inprogress");
|
|
break;
|
|
case kFetchInProgress_MultiRequested :
|
|
statusText = getString("linksets_fetching_inprogress_multi_request");
|
|
break;
|
|
case kFetchReceived :
|
|
statusText = getString("linksets_fetching_received");
|
|
break;
|
|
case kFetchError :
|
|
statusText = getString("linksets_fetching_error");
|
|
styleParams.color = warningColor;
|
|
break;
|
|
case kFetchComplete :
|
|
if (mLinksetsScrollList->isEmpty())
|
|
{
|
|
statusText = getString("linksets_fetching_done_none_found");
|
|
}
|
|
else
|
|
{
|
|
S32 numItems = mLinksetsScrollList->getItemCount();
|
|
S32 numSelectedItems = mLinksetsScrollList->getNumSelected();
|
|
|
|
LLLocale locale(LLStringUtil::getLocale());
|
|
std::string numItemsString;
|
|
LLResMgr::getInstance()->getIntegerString(numItemsString, numItems);
|
|
|
|
std::string numSelectedItemsString;
|
|
LLResMgr::getInstance()->getIntegerString(numSelectedItemsString, numSelectedItems);
|
|
|
|
LLStringUtil::format_map_t string_args;
|
|
string_args["[NUM_SELECTED]"] = numSelectedItemsString;
|
|
string_args["[NUM_TOTAL]"] = numItemsString;
|
|
statusText = getString("linksets_fetching_done_available", string_args);
|
|
}
|
|
break;
|
|
case kFetchInitial:
|
|
default:
|
|
statusText = getString("linksets_fetching_initial");
|
|
break;
|
|
}
|
|
|
|
mLinksetsStatus->setText((LLStringExplicit)statusText, styleParams);
|
|
}
|
|
|
|
NavmeshDataGetResponder::NavmeshDataGetResponder(const std::string& pNavmeshDataGetURL, LLFloaterPathfindingLinksets *pLinksetsFloater)
|
|
: mNavmeshDataGetURL(pNavmeshDataGetURL),
|
|
mLinksetsFloater(pLinksetsFloater)
|
|
{
|
|
}
|
|
|
|
NavmeshDataGetResponder::~NavmeshDataGetResponder()
|
|
{
|
|
mLinksetsFloater = NULL;
|
|
}
|
|
|
|
void NavmeshDataGetResponder::result(const LLSD& pContent)
|
|
{
|
|
mLinksetsFloater->handleNavmeshDataGetReply(pContent);
|
|
}
|
|
|
|
void NavmeshDataGetResponder::error(U32 status, const std::string& reason)
|
|
{
|
|
mLinksetsFloater->handleNavmeshDataGetError(mNavmeshDataGetURL, reason);
|
|
}
|