PATH-304,PATH-205: Initial reworking of the navmesh download functionality.

master
Todd Stinson 2012-03-02 19:17:16 -08:00
parent e1e13bcab9
commit a33e24413e
12 changed files with 616 additions and 323 deletions

View File

@ -333,7 +333,6 @@ set(viewer_SOURCE_FILES
llnameeditor.cpp
llnamelistctrl.cpp
llnavigationbar.cpp
llnavmeshstation.cpp
llnearbychat.cpp
llnearbychatbar.cpp
llnearbychathandler.cpp
@ -421,6 +420,7 @@ set(viewer_SOURCE_FILES
llpathfindinglinkset.cpp
llpathfindinglinksetlist.cpp
llpathfindingmanager.cpp
llpathfindingnavmesh.cpp
llphysicsmotion.cpp
llphysicsshapebuilderutil.cpp
llplacesinventorybridge.cpp
@ -898,7 +898,6 @@ set(viewer_HEADER_FILES
llnameeditor.h
llnamelistctrl.h
llnavigationbar.h
llnavmeshstation.h
llnearbychat.h
llnearbychatbar.h
llnearbychathandler.h
@ -975,6 +974,7 @@ set(viewer_HEADER_FILES
llpathfindinglinkset.h
llpathfindinglinksetlist.h
llpathfindingmanager.h
llpathfindingnavmesh.h
llphysicsmotion.h
llphysicsshapebuilderutil.h
llplacesinventorybridge.h

View File

@ -66,7 +66,7 @@ void LLFloaterPathfindingBasic::onOpen(const LLSD& pKey)
if (!mAgentStateSlot.connected())
{
mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateSignal(boost::bind(&LLFloaterPathfindingBasic::onAgentStateCB, this, _1));
mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLFloaterPathfindingBasic::onAgentStateCB, this, _1));
}
setAgentState(LLPathfindingManager::getInstance()->getAgentState());
}

View File

@ -33,6 +33,7 @@
#include "llsd.h"
#include "llhandle.h"
#include "llagent.h"
#include "llpanel.h"
#include "llbutton.h"
#include "llradiogroup.h"
#include "llsliderctrl.h"
@ -40,12 +41,12 @@
#include "lltextbase.h"
#include "lltabcontainer.h"
#include "llcombobox.h"
#include "llnavmeshstation.h"
#include "llfloaterreg.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
#include "llpathfindingnavmesh.h"
#include "llpathfindingmanager.h"
#include "LLPathingLib.h"
@ -104,6 +105,12 @@ BOOL LLFloaterPathfindingConsole::postBuild()
mEditTestTabContainer = findChild<LLTabContainer>("edit_test_tab_container");
llassert(mEditTestTabContainer != NULL);
mEditTab = findChild<LLPanel>("edit_panel");
llassert(mEditTab != NULL);
mTestTab = findChild<LLPanel>("test_panel");
llassert(mTestTab != NULL);
mUnfreezeLabel = findChild<LLTextBase>("unfreeze_label");
llassert(mUnfreezeLabel != NULL);
@ -157,14 +164,18 @@ void LLFloaterPathfindingConsole::onOpen(const LLSD& pKey)
}
if ( LLPathingLib::getInstance() == NULL )
{
std::string str = getString("navmesh_library_not_implemented");
LLStyle::Params styleParams;
styleParams.color = LLUIColorTable::instance().getColor("DrYellow");
mPathfindingStatus->setText((LLStringExplicit)str, styleParams);
setConsoleState(kConsoleStateLibraryNotImplemented);
llwarns <<"Errror: cannout find pathing library implementation."<<llendl;
}
else
{
{
LLPathfindingManager *pathfindingManagerInstance = LLPathfindingManager::getInstance();
if (!mNavMeshSlot.connected())
{
pathfindingManagerInstance->registerNavMeshListenerForCurrentRegion(boost::bind(&LLFloaterPathfindingConsole::onNavMeshDownloadCB, this, _1, _2, _3, _4));
}
pathfindingManagerInstance->requestGetNavMeshForCurrentRegion();
#if 0
LLPathingLib::getInstance()->cleanupResidual();
mCurrentMDO = 0;
@ -232,12 +243,14 @@ void LLFloaterPathfindingConsole::onOpen(const LLSD& pKey)
llinfos<<"Region has does not required caps of type ["<<capability<<"]"<<llendl;
}
}
#endif
}
if (!mAgentStateSlot.connected())
{
LLPathfindingManager::getInstance()->registerAgentStateSignal(boost::bind(&LLFloaterPathfindingConsole::onAgentStateCB, this, _1));
LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLFloaterPathfindingConsole::onAgentStateCB, this, _1));
}
setAgentState(LLPathfindingManager::getInstance()->getAgentState());
updatePathTestStatus();
}
@ -248,9 +261,16 @@ void LLFloaterPathfindingConsole::onClose(bool pIsAppQuitting)
{
mAgentStateSlot.disconnect();
}
LLPathingLib::getInstance()->cleanupResidual();
if (mNavMeshSlot.connected())
{
mNavMeshSlot.disconnect();
}
clearNavMesh();
LLFloater::onClose(pIsAppQuitting);
setHeartBeat( false );
setConsoleState(kConsoleStateUnknown);
}
BOOL LLFloaterPathfindingConsole::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down)
@ -496,6 +516,7 @@ void LLFloaterPathfindingConsole::setCharacterType(ECharacterType pCharacterType
mCharacterTypeRadioGroup->setValue(radioGroupValue);
}
#if 0
void LLFloaterPathfindingConsole::setHasNavMeshReceived()
{
std::string str = getString("navmesh_fetch_complete_available");
@ -513,6 +534,7 @@ void LLFloaterPathfindingConsole::setHasNoNavMesh()
std::string str = getString("navmesh_fetch_complete_none");
mPathfindingStatus->setText((LLStringExplicit)str);
}
#endif
LLFloaterPathfindingConsole::LLFloaterPathfindingConsole(const LLSD& pSeed)
: LLFloater(pSeed),
@ -527,6 +549,8 @@ LLFloaterPathfindingConsole::LLFloaterPathfindingConsole(const LLSD& pSeed)
mPathfindingStatus(NULL),
mViewCharactersButton(NULL),
mEditTestTabContainer(NULL),
mEditTab(NULL),
mTestTab(NULL),
mUnfreezeLabel(NULL),
mUnfreezeButton(NULL),
mLinksetsLabel(NULL),
@ -537,38 +561,33 @@ LLFloaterPathfindingConsole::LLFloaterPathfindingConsole(const LLSD& pSeed)
mCharacterTypeRadioGroup(NULL),
mPathTestingStatus(NULL),
mClearPathButton(NULL),
mNavMeshSlot(),
mAgentStateSlot(),
mConsoleState(kConsoleStateUnknown),
mHasNavMesh(false),
mNavMeshRegionVersion(0U),
mNavMeshRegionUUID(),
#if 0
mNavMeshCnt(0),
mNeighboringRegion( CURRENT_REGION ),
#endif
mHasStartPoint(false),
mHasEndPoint(false),
mNeighboringRegion( CURRENT_REGION ),
mHeartBeat( false )
{
mSelfHandle.bind(this);
#if 0
for (int i=0;i<MAX_OBSERVERS;++i)
{
mNavMeshDownloadObserver[i].setPathfindingConsole(this);
}
#endif
}
LLFloaterPathfindingConsole::~LLFloaterPathfindingConsole()
{
}
std::string LLFloaterPathfindingConsole::getCurrentRegionCapabilityURL() const
{
std::string capURL("");
LLViewerRegion *region = gAgent.getRegion();
if (region != NULL)
{
capURL = region->getCapability("RetrieveNavMeshSrc");
}
return capURL;
}
void LLFloaterPathfindingConsole::onShowWalkabilitySet()
{
switch (getRenderHeatmapType())
@ -686,17 +705,76 @@ void LLFloaterPathfindingConsole::onClearPathClicked()
updatePathTestStatus();
}
void LLFloaterPathfindingConsole::onNavMeshDownloadCB(LLPathfindingNavMesh::ENavMeshRequestStatus pNavMeshRequestStatus, const LLUUID &pRegionUUID, U32 pNavMeshVersion, const LLSD::Binary &pNavMeshData)
{
switch (pNavMeshRequestStatus)
{
case LLPathfindingNavMesh::kNavMeshRequestStarted :
setConsoleState(kConsoleStateDownloading);
break;
case LLPathfindingNavMesh::kNavMeshRequestCompleted :
updateNavMesh(pRegionUUID, pNavMeshVersion, pNavMeshData);
setConsoleState(kConsoleStateHasNavMesh);
break;
case LLPathfindingNavMesh::kNavMeshRequestNotEnabled :
clearNavMesh();
setConsoleState(kConsoleStateRegionNotEnabled);
break;
case LLPathfindingNavMesh::kNavMeshRequestMessageError :
clearNavMesh();
setConsoleState(kConsoleStateDownloadError);
break;
case LLPathfindingNavMesh::kNavMeshRequestFormatError :
clearNavMesh();
setConsoleState(kConsoleStateNavMeshError);
break;
case LLPathfindingNavMesh::kNavMeshRequestUnknown :
default:
clearNavMesh();
setConsoleState(kConsoleStateUnknown);
llassert(0);
break;
}
}
void LLFloaterPathfindingConsole::updateNavMesh(const LLUUID &pRegionUUID, U32 pNavMeshVersion, const LLSD::Binary &pNavMeshData)
{
if (!mHasNavMesh || (mNavMeshRegionUUID != pRegionUUID) || (mNavMeshRegionVersion != pNavMeshVersion))
{
llassert(!pNavMeshData.empty());
mHasNavMesh = true;
mNavMeshRegionUUID = pRegionUUID;
mNavMeshRegionVersion = pNavMeshVersion;
LLPathingLib::getInstance()->extractNavMeshSrcFromLLSD(pNavMeshData, CURRENT_REGION);
}
}
void LLFloaterPathfindingConsole::clearNavMesh()
{
mHasNavMesh = false;
LLPathingLib::getInstance()->cleanupResidual();
}
void LLFloaterPathfindingConsole::onAgentStateCB(LLPathfindingManager::EAgentState pAgentState)
{
setAgentState(pAgentState);
}
void LLFloaterPathfindingConsole::setAgentState(LLPathfindingManager::EAgentState pAgentState)
void LLFloaterPathfindingConsole::setConsoleState(EConsoleState pConsoleState)
{
switch (pAgentState)
mConsoleState = pConsoleState;
updateControlsOnConsoleState();
updateStatusOnConsoleState();
}
void LLFloaterPathfindingConsole::updateControlsOnConsoleState()
{
switch (mConsoleState)
{
case LLPathfindingManager::kAgentStateUnknown :
case LLPathfindingManager::kAgentStateNotEnabled :
case kConsoleStateUnknown :
case kConsoleStateLibraryNotImplemented :
case kConsoleStateRegionNotEnabled :
mShowNavMeshCheckBox->setEnabled(FALSE);
mShowNavMeshWalkabilityComboBox->setEnabled(FALSE);
mShowWalkablesCheckBox->setEnabled(FALSE);
@ -705,16 +783,35 @@ void LLFloaterPathfindingConsole::setAgentState(LLPathfindingManager::EAgentStat
mShowExclusionVolumesCheckBox->setEnabled(FALSE);
mShowWorldCheckBox->setEnabled(FALSE);
mViewCharactersButton->setEnabled(FALSE);
mEditTestTabContainer->setEnabled(FALSE);
mEditTestTabContainer->selectTab(0);
mTestTab->setEnabled(FALSE);
mCharacterWidthSlider->setEnabled(FALSE);
mCharacterTypeRadioGroup->setEnabled(FALSE);
mClearPathButton->setEnabled(FALSE);
mEditTestTabContainer->selectTab(0);
mHasStartPoint = false;
mHasEndPoint = false;
break;
default :
case kConsoleStateDownloading :
case kConsoleStateDownloadError :
case kConsoleStateNavMeshError :
mShowNavMeshCheckBox->setEnabled(FALSE);
mShowNavMeshWalkabilityComboBox->setEnabled(FALSE);
mShowWalkablesCheckBox->setEnabled(FALSE);
mShowStaticObstaclesCheckBox->setEnabled(FALSE);
mShowMaterialVolumesCheckBox->setEnabled(FALSE);
mShowExclusionVolumesCheckBox->setEnabled(FALSE);
mShowWorldCheckBox->setEnabled(FALSE);
mViewCharactersButton->setEnabled(TRUE);
mEditTestTabContainer->selectTab(0);
mTestTab->setEnabled(FALSE);
mCharacterWidthSlider->setEnabled(FALSE);
mCharacterTypeRadioGroup->setEnabled(FALSE);
mClearPathButton->setEnabled(FALSE);
mHasStartPoint = false;
mHasEndPoint = false;
break;
case kConsoleStateHasNavMesh :
case kConsoleStateHasNavMeshDownloading :
mShowNavMeshCheckBox->setEnabled(TRUE);
mShowNavMeshWalkabilityComboBox->setEnabled(TRUE);
mShowWalkablesCheckBox->setEnabled(TRUE);
@ -723,17 +820,71 @@ void LLFloaterPathfindingConsole::setAgentState(LLPathfindingManager::EAgentStat
mShowExclusionVolumesCheckBox->setEnabled(TRUE);
mShowWorldCheckBox->setEnabled(TRUE);
mViewCharactersButton->setEnabled(TRUE);
mEditTestTabContainer->setEnabled(TRUE);
mTestTab->setEnabled(TRUE);
mCharacterWidthSlider->setEnabled(TRUE);
mCharacterTypeRadioGroup->setEnabled(TRUE);
mClearPathButton->setEnabled(TRUE);
mTestTab->setEnabled(TRUE);
break;
default :
llassert(0);
break;
}
}
void LLFloaterPathfindingConsole::updateStatusOnConsoleState()
{
static const LLColor4 warningColor = LLUIColorTable::instance().getColor("DrYellow");
std::string statusText("");
LLStyle::Params styleParams;
switch (mConsoleState)
{
case kConsoleStateUnknown :
statusText = getString("navmesh_status_unknown");
break;
case kConsoleStateLibraryNotImplemented :
statusText = getString("navmesh_status_library_not_implemented");
styleParams.color = warningColor;
break;
case kConsoleStateRegionNotEnabled :
statusText = getString("navmesh_status_region_not_enabled");
styleParams.color = warningColor;
break;
case kConsoleStateDownloading :
statusText = getString("navmesh_status_downloading");
break;
case kConsoleStateHasNavMesh :
statusText = getString("navmesh_status_has_navmesh");
break;
case kConsoleStateHasNavMeshDownloading :
statusText = getString("navmesh_status_has_navmesh_downloading");
break;
case kConsoleStateDownloadError :
statusText = getString("navmesh_status_download_error");
styleParams.color = warningColor;
break;
case kConsoleStateNavMeshError :
statusText = getString("navmesh_status_navmesh_error");
styleParams.color = warningColor;
break;
default :
statusText = getString("navmesh_status_unknown");
llassert(0);
break;
}
mPathfindingStatus->setText((LLStringExplicit)statusText, styleParams);
}
void LLFloaterPathfindingConsole::setAgentState(LLPathfindingManager::EAgentState pAgentState)
{
switch (LLPathfindingManager::getInstance()->getLastKnownNonErrorAgentState())
{
case LLPathfindingManager::kAgentStateUnknown :
case LLPathfindingManager::kAgentStateNotEnabled :
mEditTab->setEnabled(FALSE);
mUnfreezeLabel->setEnabled(FALSE);
mUnfreezeButton->setEnabled(FALSE);
mLinksetsLabel->setEnabled(FALSE);
@ -742,6 +893,7 @@ void LLFloaterPathfindingConsole::setAgentState(LLPathfindingManager::EAgentStat
mFreezeButton->setEnabled(FALSE);
break;
case LLPathfindingManager::kAgentStateFrozen :
mEditTab->setEnabled(TRUE);
mUnfreezeLabel->setEnabled(TRUE);
mUnfreezeButton->setEnabled(TRUE);
mLinksetsLabel->setEnabled(FALSE);
@ -750,6 +902,7 @@ void LLFloaterPathfindingConsole::setAgentState(LLPathfindingManager::EAgentStat
mFreezeButton->setEnabled(FALSE);
break;
case LLPathfindingManager::kAgentStateUnfrozen :
mEditTab->setEnabled(TRUE);
mUnfreezeLabel->setEnabled(FALSE);
mUnfreezeButton->setEnabled(FALSE);
mLinksetsLabel->setEnabled(TRUE);
@ -803,36 +956,36 @@ void LLFloaterPathfindingConsole::updatePathTestStatus()
}
BOOL LLFloaterPathfindingConsole::isRenderAnyShapes() const
{
if ( isRenderWalkables() || isRenderStaticObstacles() ||
isRenderMaterialVolumes() || isRenderExclusionVolumes() )
{
return true;
}
return false;
}
U32 LLFloaterPathfindingConsole::getRenderShapeFlags()
{
resetShapeRenderFlags();
if ( isRenderWalkables() )
{
setShapeRenderFlag( LLPathingLib::LLST_WalkableObjects );
}
if ( isRenderStaticObstacles() )
{
setShapeRenderFlag( LLPathingLib::LLST_ObstacleObjects );
}
if ( isRenderMaterialVolumes() )
{
setShapeRenderFlag( LLPathingLib::LLST_MaterialPhantoms );
}
if ( isRenderExclusionVolumes() )
{
setShapeRenderFlag( LLPathingLib::LLST_ExclusionPhantoms );
}
return mShapeRenderFlags;
}
BOOL LLFloaterPathfindingConsole::isRenderAnyShapes() const
{
if ( isRenderWalkables() || isRenderStaticObstacles() ||
isRenderMaterialVolumes() || isRenderExclusionVolumes() )
{
return true;
}
return false;
}
U32 LLFloaterPathfindingConsole::getRenderShapeFlags()
{
resetShapeRenderFlags();
if ( isRenderWalkables() )
{
setShapeRenderFlag( LLPathingLib::LLST_WalkableObjects );
}
if ( isRenderStaticObstacles() )
{
setShapeRenderFlag( LLPathingLib::LLST_ObstacleObjects );
}
if ( isRenderMaterialVolumes() )
{
setShapeRenderFlag( LLPathingLib::LLST_MaterialPhantoms );
}
if ( isRenderExclusionVolumes() )
{
setShapeRenderFlag( LLPathingLib::LLST_ExclusionPhantoms );
}
return mShapeRenderFlags;
}

View File

@ -30,11 +30,12 @@
#include "llfloater.h"
#include "llhandle.h"
#include "llnavmeshstation.h"
#include "LLPathingLib.h"
#include "llpathfindingmanager.h"
#include "llpathfindingnavmesh.h"
class LLSD;
class LLPanel;
class LLRadioGroup;
class LLSliderCtrl;
class LLLineEditor;
@ -108,22 +109,29 @@ public:
ECharacterType getCharacterType() const;
void setCharacterType(ECharacterType pCharacterType);
void setHasNavMeshReceived();
void setHasNoNavMesh();
bool getHeartBeat() const { return mHeartBeat;}
void setHeartBeat( bool state ) { mHeartBeat=state; }
protected:
private:
typedef enum
{
kConsoleStateUnknown,
kConsoleStateLibraryNotImplemented,
kConsoleStateRegionNotEnabled,
kConsoleStateDownloading,
kConsoleStateHasNavMesh,
kConsoleStateHasNavMeshDownloading,
kConsoleStateDownloadError,
kConsoleStateNavMeshError
} EConsoleState;
// Does its own instance management, so clients not allowed
// to allocate or destroy.
LLFloaterPathfindingConsole(const LLSD& pSeed);
virtual ~LLFloaterPathfindingConsole();
std::string getCurrentRegionCapabilityURL() const;
void onShowWalkabilitySet();
void onShowWorldToggle();
void onCharacterWidthSet();
@ -133,8 +141,16 @@ private:
void onFreezeClicked();
void onViewEditLinksetClicked();
void onClearPathClicked();
void onNavMeshDownloadCB(LLPathfindingNavMesh::ENavMeshRequestStatus pNavMeshRequestStatus, const LLUUID &pRegionUUID, U32 pNavMeshVersion, const LLSD::Binary &pNavMeshData);
void onAgentStateCB(LLPathfindingManager::EAgentState pAgentState);
void setConsoleState(EConsoleState pConsoleState);
void updateNavMesh(const LLUUID &pRegionUUID, U32 pNavMeshVersion, const LLSD::Binary &pNavMeshData);
void clearNavMesh();
void updateControlsOnConsoleState();
void updateStatusOnConsoleState();
void setAgentState(LLPathfindingManager::EAgentState pAgentState);
void generatePath();
@ -153,6 +169,8 @@ private:
LLTextBase *mPathfindingStatus;
LLButton *mViewCharactersButton;
LLTabContainer *mEditTestTabContainer;
LLPanel *mEditTab;
LLPanel *mTestTab;
LLTextBase *mUnfreezeLabel;
LLButton *mUnfreezeButton;
LLTextBase *mLinksetsLabel;
@ -163,12 +181,19 @@ private:
LLRadioGroup *mCharacterTypeRadioGroup;
LLTextBase *mPathTestingStatus;
LLButton *mClearPathButton;
LLPathfindingNavMesh::navmesh_slot_t mNavMeshSlot;
LLPathfindingManager::agent_state_slot_t mAgentStateSlot;
EConsoleState mConsoleState;
bool mHasNavMesh;
U32 mNavMeshRegionVersion;
LLUUID mNavMeshRegionUUID;
#if 0
LLNavMeshDownloadObserver mNavMeshDownloadObserver[10];
int mCurrentMDO;
int mNavMeshCnt;
U32 mNeighboringRegion;
#endif
//Container that is populated and subsequently submitted to the LLPathingSystem for processing
LLPathingLib::PathingPacket mPathData;
bool mHasStartPoint;

View File

@ -211,7 +211,7 @@ void LLFloaterPathfindingLinksets::onOpen(const LLSD& pKey)
if (!mAgentStateSlot.connected())
{
LLPathfindingManager::getInstance()->registerAgentStateSignal(boost::bind(&LLFloaterPathfindingLinksets::onAgentStateCB, this, _1));
LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLFloaterPathfindingLinksets::onAgentStateCB, this, _1));
}
if (!mSelectionUpdateSlot.connected())

View File

@ -1,134 +0,0 @@
/**
* @file llnavmeshstation.cpp
* @brief
*
* $LicenseInfo:firstyear=2005&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 "llnavmeshstation.h"
#include "llcurl.h"
#include "LLPathingLib.h"
#include "llagent.h"
#include "llviewerregion.h"
#include "llsdutil.h"
#include "llfloaterpathfindingconsole.h"
#include "llsdserialize.h"
//===============================================================================
LLNavMeshStation::LLNavMeshStation()
{
}
//===============================================================================
class LLNavMeshDownloadResponder : public LLCurl::Responder
{
public:
LLNavMeshDownloadResponder( const LLHandle<LLNavMeshDownloadObserver>& observer_handle, int dir )
: mObserverHandle( observer_handle )
, mDir( dir )
{
}
void error( U32 statusNum, const std::string& reason )
{
llwarns << "Transport error "<<reason<<llendl;
}
void result( const LLSD& content )
{
llinfos<<"Content received"<<llendl;
if ( content.has("error") )
{
llwarns << "Error on fetched data"<< llendl;
//llinfos<<"LLsd buffer on error"<<ll_pretty_print_sd(content)<<llendl;
}
else
{
LLNavMeshDownloadObserver* pObserver = mObserverHandle.get();
if ( pObserver )
{
if ( content.has("navmesh_data") )
{
const std::vector<U8>& value = content["navmesh_data"].asBinary();
unsigned int binSize = value.size();
U8* pBinBuffer = new U8[binSize];
memcpy( &pBinBuffer[0], &value[0], binSize );
std::string newStr((char*) pBinBuffer, binSize );
std::istringstream streamdecomp( newStr );
unsigned int decompBinSize = 0;
bool valid = false;
if ( pBinBuffer )
{
delete [] pBinBuffer ;
}
U8* pUncompressedNavMeshContainer = unzip_llsdNavMesh( valid, decompBinSize, streamdecomp, binSize ) ;
if ( !valid )
{
if ( pUncompressedNavMeshContainer )
{
free( pUncompressedNavMeshContainer );
}
llwarns << "Unable to decompress the navmesh llsd." << llendl;
pObserver->getPathfindingConsole()->setHasNoNavMesh();
return;
}
else
{
if ( pUncompressedNavMeshContainer )
{
std::vector<U8> lsd;
lsd.resize( decompBinSize );
memcpy( &lsd[0], &pUncompressedNavMeshContainer[0], decompBinSize );
LLPathingLib::getInstance()->extractNavMeshSrcFromLLSD( lsd, mDir );
pObserver->getPathfindingConsole()->setHasNavMeshReceived();
free( pUncompressedNavMeshContainer );
}
}
}
else
{
llwarns<<"No mesh data received"<<llendl;
pObserver->getPathfindingConsole()->setHasNoNavMesh();
}
}
}
}
private:
//Observer handle
LLHandle<LLNavMeshDownloadObserver> mObserverHandle;
int mDir;
};
//===============================================================================
void LLNavMeshStation::downloadNavMeshSrc( const LLHandle<LLNavMeshDownloadObserver>& observerHandle, int dir )
{
if ( mNavMeshDownloadURL.empty() )
{
llinfos << "Unable to upload navmesh because of missing URL" << llendl;
}
else
{
LLSD data;
data["agent_id"] = gAgent.getID();
data["region_id"] = gAgent.getRegion()->getRegionID();
LLHTTPClient::post(mNavMeshDownloadURL, data, new LLNavMeshDownloadResponder( observerHandle, dir ) );
}
}
//===============================================================================

View File

@ -1,101 +0,0 @@
/**
* @file llnavmeshstation.h
* @brief Client-side navmesh support
*
* $LicenseInfo:firstyear=2001&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$
*/
#ifndef LL_NAV_MESH_STATION_H
#define LL_NAV_MESH_STATION_H
//===============================================================================
#include "llhandle.h"
//===============================================================================
class LLCurlRequest;
class LLFloaterPathfindingConsole;
//===============================================================================
class LLNavMeshObserver
{
public:
//Ctor
LLNavMeshObserver()
: mPathfindingConsole(NULL)
{ mObserverHandle.bind(this); }
//Dtor
virtual ~LLNavMeshObserver() {}
//Accessor for the observers handle
const LLHandle<LLNavMeshObserver>& getObserverHandle() const { return mObserverHandle; }
LLFloaterPathfindingConsole *getPathfindingConsole() {return mPathfindingConsole;}
void setPathfindingConsole(LLFloaterPathfindingConsole *pPathfindingConsole) {mPathfindingConsole = pPathfindingConsole;}
protected:
LLRootHandle<LLNavMeshObserver> mObserverHandle;
LLFloaterPathfindingConsole *mPathfindingConsole;
};
//===============================================================================
class LLNavMeshDownloadObserver
{
public:
//Ctor
LLNavMeshDownloadObserver() { mObserverHandle.bind(this); }
//Dtor
virtual ~LLNavMeshDownloadObserver() {}
//Accessor for the observers handle
const LLHandle<LLNavMeshDownloadObserver>& getObserverHandle() const { return mObserverHandle; }
LLFloaterPathfindingConsole *getPathfindingConsole() {return mPathfindingConsole;}
void setPathfindingConsole(LLFloaterPathfindingConsole *pPathfindingConsole) {mPathfindingConsole = pPathfindingConsole;}
protected:
LLRootHandle<LLNavMeshDownloadObserver> mObserverHandle;
LLFloaterPathfindingConsole *mPathfindingConsole;
};
//===============================================================================
class LLNavMeshStation : public LLSingleton<LLNavMeshStation>
{
public:
//Ctor
LLNavMeshStation();
//Facilitates the posting of a prepopulated llsd block to an existing url
bool postNavMeshToServer( LLSD& data, const LLHandle<LLNavMeshObserver>& observerHandle );
//Setter for the navmesh upload url
void setNavMeshUploadURL( std::string& url ) { mNavMeshUploadURL = url; }
//Setter for the navmesh download url
void setNavMeshDownloadURL( std::string& url ) { mNavMeshDownloadURL = url; }
//Callback to handle the requested src data for this regions navmesh src
static void processNavMeshSrc( LLMessageSystem* msg, void** );
//Initiate download of the navmesh source from the server
void downloadNavMeshSrc( const LLHandle<LLNavMeshDownloadObserver>& observerHandle, int dir );
protected:
//Curl object to facilitate posts to server
LLCurlRequest* mCurlRequest;
//Maximum time in seconds to execute an uploading request.
S32 mMeshUploadTimeOut ;
//URL used for uploading viewer generated navmesh
std::string mNavMeshUploadURL;
//URL used for download the src data for a navmesh
std::string mNavMeshDownloadURL;
};
//===============================================================================
#endif //LL_NAV_MESH_STATION_H

View File

@ -33,6 +33,7 @@
#include "llhttpclient.h"
#include "llagent.h"
#include "llviewerregion.h"
#include "llpathfindingnavmesh.h"
#include "llpathfindinglinkset.h"
#include "llpathfindinglinksetlist.h"
@ -47,6 +48,27 @@
#define CAP_SERVICE_OBJECT_LINKSETS "ObjectNavMeshProperties"
#define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties"
//---------------------------------------------------------------------------
// NavMeshResponder
//---------------------------------------------------------------------------
class NavMeshResponder : public LLHTTPClient::Responder
{
public:
NavMeshResponder(const std::string &pCapabilityURL, U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr);
virtual ~NavMeshResponder();
virtual void result(const LLSD &pContent);
virtual void error(U32 pStatus, const std::string& pReason);
protected:
private:
std::string mCapabilityURL;
U32 mNavMeshVersion;
LLPathfindingNavMeshPtr mNavMeshPtr;
};
//---------------------------------------------------------------------------
// AgentStateResponder
//---------------------------------------------------------------------------
@ -152,6 +174,8 @@ private:
LLPathfindingManager::LLPathfindingManager()
: LLSingleton<LLPathfindingManager>(),
mNavMeshMap(),
mNavMeshVersionXXX(0),
mAgentStateSignal(),
mAgentState(kAgentStateUnknown),
mLastKnownNonErrorAgentState(kAgentStateUnknown)
@ -179,7 +203,49 @@ bool LLPathfindingManager::isAllowViewTerrainProperties() const
return (gAgent.isGodlike() || ((region != NULL) && region->canManageEstate()));
}
LLPathfindingManager::agent_state_slot_t LLPathfindingManager::registerAgentStateSignal(agent_state_callback_t pAgentStateCallback)
LLPathfindingNavMesh::navmesh_slot_t LLPathfindingManager::registerNavMeshListenerForCurrentRegion(LLPathfindingNavMesh::navmesh_callback_t pNavMeshCallback)
{
LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForCurrentRegion();
return navMeshPtr->registerNavMeshListener(pNavMeshCallback);
}
void LLPathfindingManager::requestGetNavMeshForCurrentRegion()
{
LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForCurrentRegion();
if (navMeshPtr->hasNavMeshVersion(mNavMeshVersionXXX))
{
navMeshPtr->handleRefresh();
}
else
{
LLViewerRegion *region = getCurrentRegion();
if (region == NULL)
{
navMeshPtr->handleNavMeshNotEnabled();
}
else
{
std::string navMeshURL = getRetrieveNavMeshURLForCurrentRegion();
if (navMeshURL.empty())
{
navMeshPtr->handleNavMeshNotEnabled();
}
else
{
navMeshPtr->handleNavMeshStart(mNavMeshVersionXXX);
LLHTTPClient::ResponderPtr responder = new NavMeshResponder(navMeshURL, mNavMeshVersionXXX, navMeshPtr);
LLSD postData;
postData["agent_id"] = gAgent.getID();
postData["region_id"] = region->getRegionID();
LLHTTPClient::post(navMeshURL, postData, responder);
}
}
}
}
LLPathfindingManager::agent_state_slot_t LLPathfindingManager::registerAgentStateListener(agent_state_callback_t pAgentStateCallback)
{
return mAgentStateSignal.connect(pAgentStateCallback);
}
@ -301,6 +367,31 @@ LLPathfindingManager::ELinksetsRequestStatus LLPathfindingManager::requestSetLin
return status;
}
LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForCurrentRegion()
{
LLUUID regionUUID;
LLViewerRegion *region = getCurrentRegion();
if (region != NULL)
{
regionUUID = region->getRegionID();
}
LLPathfindingNavMeshPtr navMeshPtr;
NavMeshMap::iterator navMeshIter = mNavMeshMap.find(regionUUID);
if (navMeshIter == mNavMeshMap.end())
{
navMeshPtr = LLPathfindingNavMeshPtr(new LLPathfindingNavMesh(regionUUID));
mNavMeshMap.insert(std::pair<LLUUID, LLPathfindingNavMeshPtr>(regionUUID, navMeshPtr));
}
else
{
navMeshPtr = navMeshIter->second;
}
return navMeshPtr;
}
bool LLPathfindingManager::isValidAgentState(EAgentState pAgentState)
{
return ((pAgentState == kAgentStateFrozen) || (pAgentState == kAgentStateUnfrozen));
@ -398,6 +489,31 @@ LLViewerRegion *LLPathfindingManager::getCurrentRegion() const
return gAgent.getRegion();
}
//---------------------------------------------------------------------------
// NavMeshResponder
//---------------------------------------------------------------------------
NavMeshResponder::NavMeshResponder(const std::string &pCapabilityURL, U32 pNavMeshVersion, LLPathfindingNavMeshPtr pNavMeshPtr)
: mCapabilityURL(pCapabilityURL),
mNavMeshVersion(pNavMeshVersion),
mNavMeshPtr(pNavMeshPtr)
{
}
NavMeshResponder::~NavMeshResponder()
{
}
void NavMeshResponder::result(const LLSD &pContent)
{
mNavMeshPtr->handleNavMeshResult(pContent, mNavMeshVersion);
}
void NavMeshResponder::error(U32 pStatus, const std::string& pReason)
{
mNavMeshPtr->handleNavMeshError(pStatus, pReason, mCapabilityURL, mNavMeshVersion);
}
//---------------------------------------------------------------------------
// AgentStateResponder
//---------------------------------------------------------------------------

View File

@ -28,15 +28,18 @@
#ifndef LL_LLPATHFINDINGMANAGER_H
#define LL_LLPATHFINDINGMANAGER_H
#include "llsingleton.h"
#include "lluuid.h"
#include "llpathfindingnavmesh.h"
#include "llpathfindinglinkset.h"
#include "llpathfindinglinksetlist.h"
#include <string>
#include <map>
#include <boost/function.hpp>
#include <boost/signals2.hpp>
#include "llsingleton.h"
#include "llpathfindinglinkset.h"
#include "llpathfindinglinksetlist.h"
class LLFloater;
class LLViewerRegion;
@ -44,6 +47,8 @@ class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
{
friend class AgentStateResponder;
public:
typedef std::map<LLUUID, LLPathfindingNavMeshPtr> NavMeshMap;
typedef enum {
kAgentStateUnknown,
kAgentStateFrozen,
@ -73,7 +78,10 @@ public:
bool isAllowAlterPermanent();
bool isAllowViewTerrainProperties() const;
agent_state_slot_t registerAgentStateSignal(agent_state_callback_t pAgentStateCallback);
LLPathfindingNavMesh::navmesh_slot_t registerNavMeshListenerForCurrentRegion(LLPathfindingNavMesh::navmesh_callback_t pNavMeshCallback);
void requestGetNavMeshForCurrentRegion();
agent_state_slot_t registerAgentStateListener(agent_state_callback_t pAgentStateCallback);
EAgentState getAgentState();
EAgentState getLastKnownNonErrorAgentState() const;
void requestSetAgentState(EAgentState pAgentState);
@ -84,6 +92,8 @@ public:
protected:
private:
LLPathfindingNavMeshPtr getNavMeshForCurrentRegion();
static bool isValidAgentState(EAgentState pAgentState);
void requestGetAgentState();
@ -96,9 +106,12 @@ private:
std::string getObjectLinksetsURLForCurrentRegion() const;
std::string getTerrainLinksetsURLForCurrentRegion() const;
std::string getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const;
std::string getCapabilityURLForCurrentRegion(const std::string &pCapabilityName) const;
LLViewerRegion *getCurrentRegion() const;
NavMeshMap mNavMeshMap;
U32 mNavMeshVersionXXX; // XXX stinson 03/02/2012 : a hacky way of doing versions for now
agent_state_signal_t mAgentStateSignal;
EAgentState mAgentState;
EAgentState mLastKnownNonErrorAgentState;

View File

@ -0,0 +1,133 @@
/**
* @file llpathfindingnavmesh.cpp
* @author William Todd Stinson
* @brief A class for representing the navmesh of a pathfinding region.
*
* $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 "lluuid.h"
#include "llpathfindingnavmesh.h"
#include "llsdserialize.h"
#include <string>
//---------------------------------------------------------------------------
// LLPathfindingNavMesh
//---------------------------------------------------------------------------
LLPathfindingNavMesh::LLPathfindingNavMesh(const LLUUID &pRegionUUID)
: mRegionUUID(pRegionUUID),
mNavMeshRequestStatus(kNavMeshRequestUnknown),
mNavMeshSignal(),
mNavMeshData(),
mNavMeshVersion(0U)
{
}
LLPathfindingNavMesh::~LLPathfindingNavMesh()
{
}
LLPathfindingNavMesh::navmesh_slot_t LLPathfindingNavMesh::registerNavMeshListener(navmesh_callback_t pNavMeshCallback)
{
return mNavMeshSignal.connect(pNavMeshCallback);
}
bool LLPathfindingNavMesh::hasNavMeshVersion(U32 pNavMeshVersion) const
{
return (((mNavMeshRequestStatus == kNavMeshRequestStarted) || (mNavMeshRequestStatus == kNavMeshRequestCompleted)) && (mNavMeshVersion == pNavMeshVersion));
}
void LLPathfindingNavMesh::handleRefresh()
{
mNavMeshSignal(mNavMeshRequestStatus, mRegionUUID, mNavMeshVersion, mNavMeshData);
}
void LLPathfindingNavMesh::handleNavMeshStart(U32 pNavMeshVersion)
{
mNavMeshVersion = pNavMeshVersion;
setRequestStatus(kNavMeshRequestStarted);
}
void LLPathfindingNavMesh::handleNavMeshResult(const LLSD &pContent, U32 pNavMeshVersion)
{
llassert(mNavMeshVersion == pNavMeshVersion);
if (mNavMeshVersion == pNavMeshVersion)
{
if ( pContent.has("navmesh_data") )
{
const LLSD::Binary &value = pContent["navmesh_data"].asBinary();
unsigned int binSize = value.size();
std::string newStr(reinterpret_cast<const char *>(&value[0]), binSize);
std::istringstream streamdecomp( newStr );
unsigned int decompBinSize = 0;
bool valid = false;
U8* pUncompressedNavMeshContainer = unzip_llsdNavMesh( valid, decompBinSize, streamdecomp, binSize ) ;
if ( !valid )
{
llwarns << "Unable to decompress the navmesh llsd." << llendl;
setRequestStatus(kNavMeshRequestFormatError);
}
else
{
llassert(pUncompressedNavMeshContainer);
mNavMeshData.resize( decompBinSize );
memcpy( &mNavMeshData[0], &pUncompressedNavMeshContainer[0], decompBinSize );
setRequestStatus(kNavMeshRequestCompleted);
}
if ( pUncompressedNavMeshContainer )
{
free( pUncompressedNavMeshContainer );
}
}
else
{
llwarns << "No mesh data received" << llendl;
setRequestStatus(kNavMeshRequestMessageError);
}
}
}
void LLPathfindingNavMesh::handleNavMeshNotEnabled()
{
mNavMeshData.clear();
setRequestStatus(kNavMeshRequestNotEnabled);
}
void LLPathfindingNavMesh::handleNavMeshError(U32 pStatus, const std::string &pReason, const std::string &pURL, U32 pNavMeshVersion)
{
llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
llassert(mNavMeshVersion == pNavMeshVersion);
mNavMeshData.clear();
if (mNavMeshVersion == pNavMeshVersion)
{
setRequestStatus(kNavMeshRequestMessageError);
}
}
void LLPathfindingNavMesh::setRequestStatus(ENavMeshRequestStatus pNavMeshRequestStatus)
{
mNavMeshRequestStatus = pNavMeshRequestStatus;
mNavMeshSignal(mNavMeshRequestStatus, mRegionUUID, mNavMeshVersion, mNavMeshData);
}

View File

@ -0,0 +1,86 @@
/**
* @file llpathfindingnavmesh.h
* @author William Todd Stinson
* @brief A class for representing the navmesh of a pathfinding region.
*
* $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$
*/
#ifndef LL_LLPATHFINDINGNAVMESH_H
#define LL_LLPATHFINDINGNAVMESH_H
#include "llsd.h"
#include "lluuid.h"
#include <string>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <boost/signals2.hpp>
class LLSD;
class LLPathfindingNavMesh;
typedef boost::shared_ptr<LLPathfindingNavMesh> LLPathfindingNavMeshPtr;
class LLPathfindingNavMesh
{
public:
typedef enum {
kNavMeshRequestUnknown,
kNavMeshRequestStarted,
kNavMeshRequestCompleted,
kNavMeshRequestNotEnabled,
kNavMeshRequestMessageError,
kNavMeshRequestFormatError
} ENavMeshRequestStatus;
typedef boost::function<void (ENavMeshRequestStatus, const LLUUID &, U32, const LLSD::Binary &)> navmesh_callback_t;
typedef boost::signals2::signal<void (ENavMeshRequestStatus, const LLUUID &, U32, const LLSD::Binary &)> navmesh_signal_t;
typedef boost::signals2::connection navmesh_slot_t;
LLPathfindingNavMesh(const LLUUID &pRegionUUID);
virtual ~LLPathfindingNavMesh();
navmesh_slot_t registerNavMeshListener(navmesh_callback_t pNavMeshCallback);
bool hasNavMeshVersion(U32 pNavMeshVersion) const;
void handleRefresh();
void handleNavMeshStart(U32 pNavMeshVersion);
void handleNavMeshResult(const LLSD &pContent, U32 pNavMeshVersion);
void handleNavMeshNotEnabled();
void handleNavMeshError(U32 pStatus, const std::string &pReason, const std::string &pURL, U32 pNavMeshVersion);
protected:
private:
void setRequestStatus(ENavMeshRequestStatus pNavMeshRequestStatus);
LLUUID mRegionUUID;
ENavMeshRequestStatus mNavMeshRequestStatus;
navmesh_signal_t mNavMeshSignal;
LLSD::Binary mNavMeshData;
U32 mNavMeshVersion;
};
#endif // LL_LLPATHFINDINGNAVMESH_H

View File

@ -11,12 +11,14 @@
single_instance="true"
title="Pathfinding edit / test"
width="456">
<floater.string name="navmesh_fetch_initial"></floater.string>
<floater.string name="navmesh_fetch_inprogress">Downloading the navmesh ...</floater.string>
<floater.string name="navmesh_fetch_complete_available">Navmesh received.</floater.string>
<floater.string name="navmesh_fetch_complete_none">No navmesh for region.</floater.string>
<floater.string name="navmesh_region_not_enabled">This region is not enabled for pathfinding.</floater.string>
<floater.string name="navmesh_library_not_implemented">Cannot find pathing library implementation.</floater.string>
<floater.string name="navmesh_status_unknown"></floater.string>
<floater.string name="navmesh_status_library_not_implemented">Cannot find pathing library implementation.</floater.string>
<floater.string name="navmesh_status_region_not_enabled">This region is not enabled for pathfinding.</floater.string>
<floater.string name="navmesh_status_downloading">Downloading the navmesh ...</floater.string>
<floater.string name="navmesh_status_has_navmesh">Navmesh received.</floater.string>
<floater.string name="navmesh_status_has_navmesh_downloading">Downloading the latest navmesh ...</floater.string>
<floater.string name="navmesh_status_download_error">Unable to download navmesh successfully.</floater.string>
<floater.string name="navmesh_status_navmesh_error">Unable to understand data format of the navmesh.</floater.string>
<floater.string name="pathing_choose_start_and_end_points">Please choose start and end points.</floater.string>
<floater.string name="pathing_choose_start_point">Please choose start point.</floater.string>
<floater.string name="pathing_choose_end_point">Please choose end point.</floater.string>