Add Pathfinding UI from v3

Added libpathing to LLPHYSICSEXTENSIONS_INCLUDE_DIRS
llviewermenu updated a bit to be closer to v-d/rlva. Best viewed without space changes.
Updated llresmgr.cpp from v-d to "handle special case of input value being zero"
pipeline update: hideObject, restoreHiddenObject, hideDrawable, and unhideDrawable added.

Thanks to Henri Beauchamp for some UI code touchups, thanks to Zi Ree for Rebake notification.
Thanks to Mobius Ryba and Ansariel Hiller for the V1-style pathfinding icons.

Note: When opening from pie menu object selection is lost, unless the floater is already open..
This provides a more reliable reproduction of the bug we've been having with inspect.
This commit is contained in:
Lirusaito
2013-03-08 03:17:11 -05:00
parent 95bd81ee7e
commit 78e1804381
26 changed files with 3811 additions and 95 deletions

View File

@@ -68,6 +68,7 @@ set(cmake_SOURCE_FILES
LLPhysicsExtensions.cmake
LLPlugin.cmake
LLPrimitive.cmake
LLPhysicsExtensions.cmake
LLQtWebkit.cmake
LLRender.cmake
LLUI.cmake

View File

@@ -1,7 +1,7 @@
# -*- cmake -*-
set(LLPHYSICSEXTENSIONS_LIBRARIES nd_hacdConvexDecomposition hacd nd_Pathing )
set(LLPHYSICSEXTENSIONS_INCLUDE_DIRS ${LIBS_OPEN_DIR}/libndhacd )
set(LLPHYSICSEXTENSIONS_INCLUDE_DIRS ${LIBS_OPEN_DIR}/libndhacd ${LIBS_OPEN_DIR}/libpathing)

View File

@@ -383,6 +383,13 @@ std::string LLResMgr::getMonetaryString( S32 input ) const
void LLResMgr::getIntegerString( std::string& output, S32 input ) const
{
// handle special case of input value being zero
if (input == 0)
{
output = "0";
return;
}
S32 fraction = 0;
std::string fraction_string;
S32 remaining_count = input;

View File

@@ -232,6 +232,9 @@ set(viewer_SOURCE_FILES
llfloateropenobject.cpp
llfloateroutbox.cpp
llfloaterparcel.cpp
llfloaterpathfindingcharacters.cpp
llfloaterpathfindinglinksets.cpp
llfloaterpathfindingobjects.cpp
llfloaterpermissionsmgr.cpp
llfloaterperms.cpp
llfloaterpostcard.cpp
@@ -731,6 +734,9 @@ set(viewer_HEADER_FILES
llfloateropenobject.h
llfloateroutbox.h
llfloaterparcel.h
llfloaterpathfindingcharacters.h
llfloaterpathfindinglinksets.h
llfloaterpathfindingobjects.h
llfloaterpermissionsmgr.h
llfloaterperms.h
llfloaterpostcard.h

View File

@@ -0,0 +1,309 @@
/**
* @file llfloaterpathfindingcharacters.cpp
* @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage.
* @author Stinson@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 "llfloaterpathfindingcharacters.h"
#include <string>
#include "llcheckboxctrl.h"
#include "llfloaterpathfindingobjects.h"
#include "llhandle.h"
#include "llpathfindingcharacter.h"
#include "llpathfindingcharacterlist.h"
#include "llpathfindingmanager.h"
#include "llpathfindingobject.h"
#include "llpathfindingobjectlist.h"
#include "llpathinglib.h"
#include "llquaternion.h"
#include "llsd.h"
#include "llui.h"
#include "lluictrlfactory.h"
#include "lluuid.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "pipeline.h"
#include "v3math.h"
#include "v4color.h"
//---------------------------------------------------------------------------
// LLFloaterPathfindingCharacters
//---------------------------------------------------------------------------
void LLFloaterPathfindingCharacters::onClose(bool pIsAppQuitting)
{
// Hide any capsule that might be showing on floater close
hideCapsule();
LLFloaterPathfindingObjects::onClose( pIsAppQuitting );
}
BOOL LLFloaterPathfindingCharacters::isShowPhysicsCapsule() const
{
return mShowPhysicsCapsuleCheckBox->get();
}
void LLFloaterPathfindingCharacters::setShowPhysicsCapsule(BOOL pIsShowPhysicsCapsule)
{
mShowPhysicsCapsuleCheckBox->set(pIsShowPhysicsCapsule && (LLPathingLib::getInstance() != NULL));
}
BOOL LLFloaterPathfindingCharacters::isPhysicsCapsuleEnabled(LLUUID& id, LLVector3& pos, LLQuaternion& rot) const
{
id = mSelectedCharacterId;
// Physics capsule is enable if the checkbox is enabled and if we can get the required render
// parameters for any selected object
return (isShowPhysicsCapsule() && getCapsuleRenderData(pos, rot ));
}
void LLFloaterPathfindingCharacters::openCharactersWithSelectedObjects()
{
LLFloaterPathfindingCharacters* charactersFloater = getInstance();
charactersFloater->showFloaterWithSelectionObjects();
}
LLFloaterPathfindingCharacters::LLFloaterPathfindingCharacters(const LLSD& pSeed)
: LLFloaterPathfindingObjects(/*pSeed*/),
mShowPhysicsCapsuleCheckBox(NULL),
mSelectedCharacterId(),
mBeaconColor()
{
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_pathfinding_characters.xml");
}
LLFloaterPathfindingCharacters::~LLFloaterPathfindingCharacters()
{
}
BOOL LLFloaterPathfindingCharacters::postBuild()
{
mBeaconColor = LLUI::sColorsGroup->getColor("PathfindingCharacterBeaconColor");
mShowPhysicsCapsuleCheckBox = getChild<LLCheckBoxCtrl>("show_physics_capsule");
llassert(mShowPhysicsCapsuleCheckBox != NULL);
mShowPhysicsCapsuleCheckBox->setCommitCallback(boost::bind(&LLFloaterPathfindingCharacters::onShowPhysicsCapsuleClicked, this));
mShowPhysicsCapsuleCheckBox->setEnabled(LLPathingLib::getInstance() != NULL);
return LLFloaterPathfindingObjects::postBuild();
}
void LLFloaterPathfindingCharacters::requestGetObjects()
{
LLPathfindingManager::getInstance()->requestGetCharacters(getNewRequestId(), boost::bind(&LLFloaterPathfindingCharacters::handleNewObjectList, this, _1, _2, _3));
}
void LLFloaterPathfindingCharacters::buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr)
{
llassert(pObjectListPtr != NULL);
llassert(!pObjectListPtr->isEmpty());
for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter)
{
const LLPathfindingObjectPtr objectPtr = objectIter->second;
const LLPathfindingCharacter *characterPtr = dynamic_cast<const LLPathfindingCharacter *>(objectPtr.get());
llassert(characterPtr != NULL);
LLSD scrollListItemData = buildCharacterScrollListItemData(characterPtr);
addObjectToScrollList(objectPtr, scrollListItemData);
}
}
void LLFloaterPathfindingCharacters::updateControlsOnScrollListChange()
{
LLFloaterPathfindingObjects::updateControlsOnScrollListChange();
updateStateOnDisplayControls();
showSelectedCharacterCapsules();
}
S32 LLFloaterPathfindingCharacters::getNameColumnIndex() const
{
return 0;
}
S32 LLFloaterPathfindingCharacters::getOwnerNameColumnIndex() const
{
return 2;
}
std::string LLFloaterPathfindingCharacters::getOwnerName(const LLPathfindingObject *pObject) const
{
return (pObject->hasOwner()
? (pObject->hasOwnerName()
? (pObject->isGroupOwned()
? (pObject->getOwnerName() + " " + getString("character_owner_group"))
: pObject->getOwnerName())
: getString("character_owner_loading"))
: getString("character_owner_unknown"));
}
const LLColor4 &LLFloaterPathfindingCharacters::getBeaconColor() const
{
return mBeaconColor;
}
LLPathfindingObjectListPtr LLFloaterPathfindingCharacters::getEmptyObjectList() const
{
LLPathfindingObjectListPtr objectListPtr(new LLPathfindingCharacterList());
return objectListPtr;
}
void LLFloaterPathfindingCharacters::onShowPhysicsCapsuleClicked()
{
if (LLPathingLib::getInstance() == NULL)
{
if (isShowPhysicsCapsule())
{
setShowPhysicsCapsule(FALSE);
}
}
else
{
if (mSelectedCharacterId.notNull() && isShowPhysicsCapsule())
{
showCapsule();
}
else
{
hideCapsule();
}
}
}
LLSD LLFloaterPathfindingCharacters::buildCharacterScrollListItemData(const LLPathfindingCharacter *pCharacterPtr) const
{
LLSD columns = LLSD::emptyArray();
columns[0]["column"] = "name";
columns[0]["value"] = pCharacterPtr->getName();
columns[1]["column"] = "description";
columns[1]["value"] = pCharacterPtr->getDescription();
columns[2]["column"] = "owner";
columns[2]["value"] = getOwnerName(pCharacterPtr);
S32 cpuTime = llround(pCharacterPtr->getCPUTime());
std::string cpuTimeString = llformat("%d", cpuTime);
LLStringUtil::format_map_t string_args;
string_args["[CPU_TIME]"] = cpuTimeString;
columns[3]["column"] = "cpu_time";
columns[3]["value"] = getString("character_cpu_time", string_args);
columns[4]["column"] = "altitude";
columns[4]["value"] = llformat("%1.0f m", pCharacterPtr->getLocation()[2]);
return columns;
}
void LLFloaterPathfindingCharacters::updateStateOnDisplayControls()
{
int numSelectedItems = getNumSelectedObjects();;
bool isEditEnabled = ((numSelectedItems == 1) && (LLPathingLib::getInstance() != NULL));
mShowPhysicsCapsuleCheckBox->setEnabled(isEditEnabled);
if (!isEditEnabled)
{
setShowPhysicsCapsule(FALSE);
}
}
void LLFloaterPathfindingCharacters::showSelectedCharacterCapsules()
{
// Hide any previous capsule
hideCapsule();
// Get the only selected object, or set the selected object to null if we do not have exactly
// one object selected
if (getNumSelectedObjects() == 1)
{
LLPathfindingObjectPtr selectedObjectPtr = getFirstSelectedObject();
mSelectedCharacterId = selectedObjectPtr->getUUID();
}
else
{
mSelectedCharacterId.setNull();
}
// Show any capsule if enabled
showCapsule();
}
void LLFloaterPathfindingCharacters::showCapsule() const
{
if (mSelectedCharacterId.notNull() && isShowPhysicsCapsule())
{
LLPathfindingObjectPtr objectPtr = getFirstSelectedObject();
llassert(objectPtr != NULL);
if (objectPtr != NULL)
{
const LLPathfindingCharacter *character = dynamic_cast<const LLPathfindingCharacter *>(objectPtr.get());
llassert(mSelectedCharacterId == character->getUUID());
if (LLPathingLib::getInstance() != NULL)
{
LLPathingLib::getInstance()->createPhysicsCapsuleRep(character->getLength(), character->getRadius(),
character->isHorizontal(), character->getUUID());
}
}
gPipeline.hideObject(mSelectedCharacterId);
}
}
void LLFloaterPathfindingCharacters::hideCapsule() const
{
if (mSelectedCharacterId.notNull())
{
gPipeline.restoreHiddenObject(mSelectedCharacterId);
}
if (LLPathingLib::getInstance() != NULL)
{
LLPathingLib::getInstance()->cleanupPhysicsCapsuleRepResiduals();
}
}
bool LLFloaterPathfindingCharacters::getCapsuleRenderData(LLVector3& pPosition, LLQuaternion& rot) const
{
bool result = false;
// If we have a selected object, find the object on the viewer object list and return its
// position. Else, return false indicating that we either do not have a selected object
// or we cannot find the selected object on the viewer object list
if (mSelectedCharacterId.notNull())
{
LLViewerObject *viewerObject = gObjectList.findObject(mSelectedCharacterId);
if ( viewerObject != NULL )
{
rot = viewerObject->getRotation() ;
pPosition = viewerObject->getRenderPosition();
result = true;
}
}
return result;
}

View File

@@ -0,0 +1,94 @@
/**
* @file llfloaterpathfindingcharacters.h
* @brief "Pathfinding characters" floater, allowing for identification of pathfinding characters and their cpu usage.
* @author Stinson@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$
*/
#ifndef LL_LLFLOATERPATHFINDINGCHARACTERS_H
#define LL_LLFLOATERPATHFINDINGCHARACTERS_H
#include "llfloaterpathfindingobjects.h"
#include "llpathfindingobjectlist.h"
#include "lluuid.h"
#include "v4color.h"
class LLCheckBoxCtrl;
class LLPathfindingCharacter;
class LLQuaternion;
class LLSD;
class LLVector3;
class LLFloaterPathfindingCharacters : public LLFloaterPathfindingObjects, public LLFloaterSingleton<LLFloaterPathfindingCharacters>
{
public:
virtual void onClose(bool pIsAppQuitting);
BOOL isShowPhysicsCapsule() const;
void setShowPhysicsCapsule(BOOL pIsShowPhysicsCapsule);
BOOL isPhysicsCapsuleEnabled(LLUUID& id, LLVector3& pos, LLQuaternion& rot) const;
static void openCharactersWithSelectedObjects();
LLFloaterPathfindingCharacters(const LLSD& pSeed);
virtual ~LLFloaterPathfindingCharacters();
protected:
// friend class LLFloaterReg;
virtual BOOL postBuild();
virtual void requestGetObjects();
virtual void buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr);
virtual void updateControlsOnScrollListChange();
virtual S32 getNameColumnIndex() const;
virtual S32 getOwnerNameColumnIndex() const;
virtual std::string getOwnerName(const LLPathfindingObject *pObject) const;
virtual const LLColor4 &getBeaconColor() const;
virtual LLPathfindingObjectListPtr getEmptyObjectList() const;
private:
void onShowPhysicsCapsuleClicked();
LLSD buildCharacterScrollListItemData(const LLPathfindingCharacter *pCharacterPtr) const;
void updateStateOnDisplayControls();
void showSelectedCharacterCapsules();
void showCapsule() const;
void hideCapsule() const;
bool getCapsuleRenderData(LLVector3& pPosition, LLQuaternion& rot) const;
LLCheckBoxCtrl *mShowPhysicsCapsuleCheckBox;
LLUUID mSelectedCharacterId;
LLColor4 mBeaconColor;
};
#endif // LL_LLFLOATERPATHFINDINGCHARACTERS_H

View File

@@ -0,0 +1,806 @@
/**
* @file llfloaterpathfindinglinksets.cpp
* @brief "Pathfinding linksets" floater, allowing manipulation of the linksets on the current region.
* @author Stinson@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 "llfloaterpathfindinglinksets.h"
#include <string>
#include <boost/bind.hpp>
#include "llagent.h"
#include "llbutton.h"
#include "llcombobox.h"
#include "llfloaterpathfindingobjects.h"
#include "lllineeditor.h"
#include "llnotificationsutil.h"
#include "llpathfindinglinkset.h"
#include "llpathfindinglinksetlist.h"
#include "llpathfindingmanager.h"
#include "llscrolllistctrl.h"
#include "llsd.h"
#include "lltextbox.h"
#include "llui.h"
#include "lluictrlfactory.h"
#include "lluictrl.h"
#include "v3math.h"
#include "v4color.h"
#define XUI_LINKSET_USE_NONE 0
#define XUI_LINKSET_USE_WALKABLE 1
#define XUI_LINKSET_USE_STATIC_OBSTACLE 2
#define XUI_LINKSET_USE_DYNAMIC_OBSTACLE 3
#define XUI_LINKSET_USE_MATERIAL_VOLUME 4
#define XUI_LINKSET_USE_EXCLUSION_VOLUME 5
#define XUI_LINKSET_USE_DYNAMIC_PHANTOM 6
//---------------------------------------------------------------------------
// LLFloaterPathfindingLinksets
//---------------------------------------------------------------------------
void LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects()
{
LLFloaterPathfindingLinksets* linksetsFloater = getInstance();
linksetsFloater->clearFilters();
linksetsFloater->showFloaterWithSelectionObjects();
}
LLFloaterPathfindingLinksets::LLFloaterPathfindingLinksets(const LLSD& pSeed)
: LLFloaterPathfindingObjects(/*pSeed*/),
mFilterByName(NULL),
mFilterByDescription(NULL),
mFilterByLinksetUse(NULL),
mEditLinksetUse(NULL),
mEditLinksetUseWalkable(NULL),
mEditLinksetUseStaticObstacle(NULL),
mEditLinksetUseDynamicObstacle(NULL),
mEditLinksetUseMaterialVolume(NULL),
mEditLinksetUseExclusionVolume(NULL),
mEditLinksetUseDynamicPhantom(NULL),
mLabelWalkabilityCoefficients(NULL),
mLabelEditA(NULL),
mLabelSuggestedUseA(NULL),
mEditA(NULL),
mLabelEditB(NULL),
mLabelSuggestedUseB(NULL),
mEditB(NULL),
mLabelEditC(NULL),
mLabelSuggestedUseC(NULL),
mEditC(NULL),
mLabelEditD(NULL),
mLabelSuggestedUseD(NULL),
mEditD(NULL),
mApplyEditsButton(NULL),
mBeaconColor(),
mPreviousValueA(LLPathfindingLinkset::MAX_WALKABILITY_VALUE),
mPreviousValueB(LLPathfindingLinkset::MAX_WALKABILITY_VALUE),
mPreviousValueC(LLPathfindingLinkset::MAX_WALKABILITY_VALUE),
mPreviousValueD(LLPathfindingLinkset::MAX_WALKABILITY_VALUE)
{
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_pathfinding_linksets.xml");
}
LLFloaterPathfindingLinksets::~LLFloaterPathfindingLinksets()
{
}
BOOL LLFloaterPathfindingLinksets::postBuild()
{
mBeaconColor = LLUI::sColorsGroup->getColor("PathfindingLinksetBeaconColor");
mFilterByName = getChild<LLLineEditor>("filter_by_name");
llassert(mFilterByName != NULL);
mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
mFilterByName->setSelectAllonFocusReceived(true);
mFilterByName->setCommitOnFocusLost(true);
mFilterByDescription = getChild<LLLineEditor>("filter_by_description");
llassert(mFilterByDescription != NULL);
mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
mFilterByDescription->setSelectAllonFocusReceived(true);
mFilterByDescription->setCommitOnFocusLost(true);
mFilterByLinksetUse = getChild<LLComboBox>("filter_by_linkset_use");
llassert(mFilterByLinksetUse != NULL);
mFilterByLinksetUse->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
childSetAction("apply_filters", boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
childSetAction("clear_filters", boost::bind(&LLFloaterPathfindingLinksets::onClearFiltersClicked, this));
mEditLinksetUse = getChild<LLComboBox>("edit_linkset_use");
llassert(mEditLinksetUse != NULL);
mEditLinksetUse->clearRows();
mEditLinksetUseUnset = mEditLinksetUse->add(getString("linkset_choose_use"), XUI_LINKSET_USE_NONE);
llassert(mEditLinksetUseUnset != NULL);
mEditLinksetUseWalkable = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kWalkable), XUI_LINKSET_USE_WALKABLE);
llassert(mEditLinksetUseWalkable != NULL);
mEditLinksetUseStaticObstacle = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kStaticObstacle), XUI_LINKSET_USE_STATIC_OBSTACLE);
llassert(mEditLinksetUseStaticObstacle != NULL);
mEditLinksetUseDynamicObstacle = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kDynamicObstacle), XUI_LINKSET_USE_DYNAMIC_OBSTACLE);
llassert(mEditLinksetUseDynamicObstacle != NULL);
mEditLinksetUseMaterialVolume = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kMaterialVolume), XUI_LINKSET_USE_MATERIAL_VOLUME);
llassert(mEditLinksetUseMaterialVolume != NULL);
mEditLinksetUseExclusionVolume = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kExclusionVolume), XUI_LINKSET_USE_EXCLUSION_VOLUME);
llassert(mEditLinksetUseExclusionVolume != NULL);
mEditLinksetUseDynamicPhantom = mEditLinksetUse->add(getLinksetUseString(LLPathfindingLinkset::kDynamicPhantom), XUI_LINKSET_USE_DYNAMIC_PHANTOM);
llassert(mEditLinksetUseDynamicPhantom != NULL);
mEditLinksetUse->selectFirstItem();
mLabelWalkabilityCoefficients = getChild<LLTextBox>("walkability_coefficients_label");
llassert(mLabelWalkabilityCoefficients != NULL);
mLabelEditA = getChild<LLTextBox>("edit_a_label");
llassert(mLabelEditA != NULL);
mLabelSuggestedUseA = getChild<LLTextBox>("suggested_use_a_label");
llassert(mLabelSuggestedUseA != NULL);
mEditA = getChild<LLLineEditor>("edit_a_value");
llassert(mEditA != NULL);
mEditA->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
mEditA->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueA));
mLabelEditB = getChild<LLTextBox>("edit_b_label");
llassert(mLabelEditB != NULL);
mLabelSuggestedUseB = getChild<LLTextBox>("suggested_use_b_label");
llassert(mLabelSuggestedUseB != NULL);
mEditB = getChild<LLLineEditor>("edit_b_value");
llassert(mEditB != NULL);
mEditB->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
mEditB->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueB));
mLabelEditC = getChild<LLTextBox>("edit_c_label");
llassert(mLabelEditC != NULL);
mLabelSuggestedUseC = getChild<LLTextBox>("suggested_use_c_label");
llassert(mLabelSuggestedUseC != NULL);
mEditC = getChild<LLLineEditor>("edit_c_value");
llassert(mEditC != NULL);
mEditC->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
mEditC->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueC));
mLabelEditD = getChild<LLTextBox>("edit_d_label");
llassert(mLabelEditD != NULL);
mLabelSuggestedUseD = getChild<LLTextBox>("suggested_use_d_label");
llassert(mLabelSuggestedUseD != NULL);
mEditD = getChild<LLLineEditor>("edit_d_value");
llassert(mEditD != NULL);
mEditD->setPrevalidate(LLLineEditor::prevalidateNonNegativeS32);
mEditD->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered, this, _1, mPreviousValueD));
mApplyEditsButton = getChild<LLButton>("apply_edit_values");
llassert(mApplyEditsButton != NULL);
mApplyEditsButton->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyChangesClicked, this));
return LLFloaterPathfindingObjects::postBuild();
}
void LLFloaterPathfindingLinksets::requestGetObjects()
{
LLPathfindingManager::getInstance()->requestGetLinksets(getNewRequestId(), boost::bind(&LLFloaterPathfindingLinksets::handleNewObjectList, this, _1, _2, _3));
}
void LLFloaterPathfindingLinksets::buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr)
{
llassert(pObjectListPtr != NULL);
llassert(!pObjectListPtr->isEmpty());
std::string nameFilter = mFilterByName->getText();
std::string descriptionFilter = mFilterByDescription->getText();
LLPathfindingLinkset::ELinksetUse linksetUseFilter = getFilterLinksetUse();
bool isFilteringName = !nameFilter.empty();
bool isFilteringDescription = !descriptionFilter.empty();
bool isFilteringLinksetUse = (linksetUseFilter != LLPathfindingLinkset::kUnknown);
const LLVector3& avatarPosition = gAgent.getPositionAgent();
if (isFilteringName || isFilteringDescription || isFilteringLinksetUse)
{
LLStringUtil::toUpper(nameFilter);
LLStringUtil::toUpper(descriptionFilter);
for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter)
{
const LLPathfindingObjectPtr objectPtr = objectIter->second;
const LLPathfindingLinkset *linksetPtr = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
llassert(linksetPtr != NULL);
std::string linksetName = (linksetPtr->isTerrain() ? getString("linkset_terrain_name") : linksetPtr->getName());
std::string linksetDescription = linksetPtr->getDescription();
LLStringUtil::toUpper(linksetName);
LLStringUtil::toUpper(linksetDescription);
if ((!isFilteringName || (linksetName.find(nameFilter) != std::string::npos)) &&
(!isFilteringDescription || (linksetDescription.find(descriptionFilter) != std::string::npos)) &&
(!isFilteringLinksetUse || (linksetPtr->getLinksetUse() == linksetUseFilter)))
{
LLSD scrollListItemData = buildLinksetScrollListItemData(linksetPtr, avatarPosition);
addObjectToScrollList(objectPtr, scrollListItemData);
}
}
}
else
{
for (LLPathfindingObjectList::const_iterator objectIter = pObjectListPtr->begin(); objectIter != pObjectListPtr->end(); ++objectIter)
{
const LLPathfindingObjectPtr objectPtr = objectIter->second;
const LLPathfindingLinkset *linksetPtr = dynamic_cast<const LLPathfindingLinkset *>(objectPtr.get());
llassert(linksetPtr != NULL);
LLSD scrollListItemData = buildLinksetScrollListItemData(linksetPtr, avatarPosition);
addObjectToScrollList(objectPtr, scrollListItemData);
}
}
}
void LLFloaterPathfindingLinksets::updateControlsOnScrollListChange()
{
LLFloaterPathfindingObjects::updateControlsOnScrollListChange();
updateEditFieldValues();
updateStateOnEditFields();
updateStateOnEditLinksetUse();
}
S32 LLFloaterPathfindingLinksets::getNameColumnIndex() const
{
return 0;
}
S32 LLFloaterPathfindingLinksets::getOwnerNameColumnIndex() const
{
return 2;
}
std::string LLFloaterPathfindingLinksets::getOwnerName(const LLPathfindingObject *pObject) const
{
return (pObject->hasOwner()
? (pObject->hasOwnerName()
? (pObject->isGroupOwned()
? (pObject->getOwnerName() + " " + getString("linkset_owner_group"))
: pObject->getOwnerName())
: getString("linkset_owner_loading"))
: getString("linkset_owner_unknown"));
}
const LLColor4 &LLFloaterPathfindingLinksets::getBeaconColor() const
{
return mBeaconColor;
}
LLPathfindingObjectListPtr LLFloaterPathfindingLinksets::getEmptyObjectList() const
{
LLPathfindingObjectListPtr objectListPtr(new LLPathfindingLinksetList());
return objectListPtr;
}
void LLFloaterPathfindingLinksets::requestSetLinksets(LLPathfindingObjectListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD)
{
LLPathfindingManager::getInstance()->requestSetLinksets(getNewRequestId(), pLinksetList, pLinksetUse, pA, pB, pC, pD, boost::bind(&LLFloaterPathfindingLinksets::handleUpdateObjectList, this, _1, _2, _3));
}
void LLFloaterPathfindingLinksets::onApplyAllFilters()
{
rebuildObjectsScrollList();
}
void LLFloaterPathfindingLinksets::onClearFiltersClicked()
{
clearFilters();
rebuildObjectsScrollList();
}
void LLFloaterPathfindingLinksets::onWalkabilityCoefficientEntered(LLUICtrl *pUICtrl, LLSD &pPreviousValue)
{
LLLineEditor *pLineEditor = static_cast<LLLineEditor *>(pUICtrl);
llassert(pLineEditor != NULL);
const std::string &valueString = pLineEditor->getText();
S32 intValue;
LLSD value;
bool doResetValue = false;
if (valueString.empty())
{
value = pPreviousValue;
doResetValue = true;
}
else if (LLStringUtil::convertToS32(valueString, intValue))
{
doResetValue = ((intValue < LLPathfindingLinkset::MIN_WALKABILITY_VALUE) || (intValue > LLPathfindingLinkset::MAX_WALKABILITY_VALUE));
value = LLSD(llclamp(intValue, LLPathfindingLinkset::MIN_WALKABILITY_VALUE, LLPathfindingLinkset::MAX_WALKABILITY_VALUE));
}
else
{
value = LLSD(LLPathfindingLinkset::MAX_WALKABILITY_VALUE);
doResetValue = true;
}
if (doResetValue)
{
pLineEditor->setValue(value);
}
pPreviousValue = value;
}
void LLFloaterPathfindingLinksets::onApplyChangesClicked()
{
applyEdit();
}
void LLFloaterPathfindingLinksets::clearFilters()
{
mFilterByName->clear();
mFilterByDescription->clear();
setFilterLinksetUse(LLPathfindingLinkset::kUnknown);
}
void LLFloaterPathfindingLinksets::updateEditFieldValues()
{
int numSelectedObjects = getNumSelectedObjects();
if (numSelectedObjects <= 0)
{
mEditLinksetUse->selectFirstItem();
mEditA->clear();
mEditB->clear();
mEditC->clear();
mEditD->clear();
}
else
{
LLPathfindingObjectPtr firstSelectedObjectPtr = getFirstSelectedObject();
llassert(firstSelectedObjectPtr != NULL);
const LLPathfindingLinkset *linkset = dynamic_cast<const LLPathfindingLinkset *>(firstSelectedObjectPtr.get());
setEditLinksetUse(linkset->getLinksetUse());
mPreviousValueA = LLSD(linkset->getWalkabilityCoefficientA());
mPreviousValueB = LLSD(linkset->getWalkabilityCoefficientB());
mPreviousValueC = LLSD(linkset->getWalkabilityCoefficientC());
mPreviousValueD = LLSD(linkset->getWalkabilityCoefficientD());
mEditA->setValue(mPreviousValueA);
mEditB->setValue(mPreviousValueB);
mEditC->setValue(mPreviousValueC);
mEditD->setValue(mPreviousValueD);
}
}
LLSD LLFloaterPathfindingLinksets::buildLinksetScrollListItemData(const LLPathfindingLinkset *pLinksetPtr, const LLVector3 &pAvatarPosition) const
{
llassert(pLinksetPtr != NULL);
LLSD columns = LLSD::emptyArray();
if (pLinksetPtr->isTerrain())
{
columns[0]["column"] = "name";
columns[0]["value"] = getString("linkset_terrain_name");
columns[1]["column"] = "description";
columns[1]["value"] = getString("linkset_terrain_description");
columns[2]["column"] = "owner";
columns[2]["value"] = getString("linkset_terrain_owner");
columns[3]["column"] = "scripted";
columns[3]["value"] = getString("linkset_terrain_scripted");
columns[4]["column"] = "land_impact";
columns[4]["value"] = getString("linkset_terrain_land_impact");
columns[5]["column"] = "dist_from_you";
columns[5]["value"] = getString("linkset_terrain_dist_from_you");
}
else
{
columns[0]["column"] = "name";
columns[0]["value"] = pLinksetPtr->getName();
columns[1]["column"] = "description";
columns[1]["value"] = pLinksetPtr->getDescription();
columns[2]["column"] = "owner";
columns[2]["value"] = getOwnerName(pLinksetPtr);
columns[3]["column"] = "scripted";
columns[3]["value"] = (pLinksetPtr->hasIsScripted()
? (pLinksetPtr->isScripted()
? getString("linkset_is_scripted")
: getString("linkset_is_not_scripted"))
: getString("linkset_is_unknown_scripted"));
columns[4]["column"] = "land_impact";
columns[4]["value"] = llformat("%1d", pLinksetPtr->getLandImpact());
columns[5]["column"] = "dist_from_you";
columns[5]["value"] = llformat("%1.0f m", dist_vec(pAvatarPosition, pLinksetPtr->getLocation()));
}
columns[6]["column"] = "linkset_use";
std::string linksetUse = getLinksetUseString(pLinksetPtr->getLinksetUse());
if (pLinksetPtr->isTerrain())
{
linksetUse += (" " + getString("linkset_is_terrain"));
}
else if (!pLinksetPtr->isModifiable() && pLinksetPtr->canBeVolume())
{
linksetUse += (" " + getString("linkset_is_restricted_state"));
}
else if (pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume())
{
linksetUse += (" " + getString("linkset_is_non_volume_state"));
}
else if (!pLinksetPtr->isModifiable() && !pLinksetPtr->canBeVolume())
{
linksetUse += (" " + getString("linkset_is_restricted_non_volume_state"));
}
columns[6]["value"] = linksetUse;
columns[7]["column"] = "a_percent";
columns[7]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientA());
columns[8]["column"] = "b_percent";
columns[8]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientB());
columns[9]["column"] = "c_percent";
columns[9]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientC());
columns[10]["column"] = "d_percent";
columns[10]["value"] = llformat("%3d", pLinksetPtr->getWalkabilityCoefficientD());
return columns;
}
/* Singu-Note: Unused function
LLSD LLFloaterPathfindingLinksets::buildLinksetUseScrollListData(const std::string &pLabel, S32 pValue) const
{
LLSD columns;
columns[0]["column"] = "name";
columns[0]["value"] = pLabel;
columns[0]["font"] = "SANSSERIF";
LLSD element;
element["value"] = pValue;
element["column"] = columns;
return element;
}
*/
bool LLFloaterPathfindingLinksets::isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
{
bool isShowWarning = false;
if (pLinksetUse != LLPathfindingLinkset::kUnknown)
{
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
{
const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
isShowWarning = linksetList->isShowUnmodifiablePhantomWarning(pLinksetUse);
}
}
return isShowWarning;
}
bool LLFloaterPathfindingLinksets::isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
{
bool isShowWarning = false;
if (pLinksetUse != LLPathfindingLinkset::kUnknown)
{
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
{
const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
isShowWarning = linksetList->isShowPhantomToggleWarning(pLinksetUse);
}
}
return isShowWarning;
}
bool LLFloaterPathfindingLinksets::isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
{
bool isShowWarning = false;
if (pLinksetUse != LLPathfindingLinkset::kUnknown)
{
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
{
const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
isShowWarning = linksetList->isShowCannotBeVolumeWarning(pLinksetUse);
}
}
return isShowWarning;
}
void LLFloaterPathfindingLinksets::updateStateOnEditFields()
{
int numSelectedItems = getNumSelectedObjects();
bool isEditEnabled = (numSelectedItems > 0);
mEditLinksetUse->setEnabled(isEditEnabled);
mLabelWalkabilityCoefficients->setEnabled(isEditEnabled);
mLabelEditA->setEnabled(isEditEnabled);
mLabelEditB->setEnabled(isEditEnabled);
mLabelEditC->setEnabled(isEditEnabled);
mLabelEditD->setEnabled(isEditEnabled);
mLabelSuggestedUseA->setEnabled(isEditEnabled);
mLabelSuggestedUseB->setEnabled(isEditEnabled);
mLabelSuggestedUseC->setEnabled(isEditEnabled);
mLabelSuggestedUseD->setEnabled(isEditEnabled);
mEditA->setEnabled(isEditEnabled);
mEditB->setEnabled(isEditEnabled);
mEditC->setEnabled(isEditEnabled);
mEditD->setEnabled(isEditEnabled);
mApplyEditsButton->setEnabled(isEditEnabled && (getMessagingState() == kMessagingComplete));
}
void LLFloaterPathfindingLinksets::updateStateOnEditLinksetUse()
{
BOOL useWalkable = FALSE;
BOOL useStaticObstacle = FALSE;
BOOL useDynamicObstacle = FALSE;
BOOL useMaterialVolume = FALSE;
BOOL useExclusionVolume = FALSE;
BOOL useDynamicPhantom = FALSE;
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
{
const LLPathfindingLinksetList *linksetList = dynamic_cast<const LLPathfindingLinksetList *>(selectedObjects.get());
linksetList->determinePossibleStates(useWalkable, useStaticObstacle, useDynamicObstacle, useMaterialVolume, useExclusionVolume, useDynamicPhantom);
}
mEditLinksetUseWalkable->setEnabled(useWalkable);
mEditLinksetUseStaticObstacle->setEnabled(useStaticObstacle);
mEditLinksetUseDynamicObstacle->setEnabled(useDynamicObstacle);
mEditLinksetUseMaterialVolume->setEnabled(useMaterialVolume);
mEditLinksetUseExclusionVolume->setEnabled(useExclusionVolume);
mEditLinksetUseDynamicPhantom->setEnabled(useDynamicPhantom);
}
void LLFloaterPathfindingLinksets::applyEdit()
{
LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse();
bool showPhantomToggleWarning = isShowPhantomToggleWarning(linksetUse);
bool showUnmodifiablePhantomWarning = isShowUnmodifiablePhantomWarning(linksetUse);
bool showCannotBeVolumeWarning = isShowCannotBeVolumeWarning(linksetUse);
if (showPhantomToggleWarning || showUnmodifiablePhantomWarning || showCannotBeVolumeWarning)
{
LLPathfindingLinkset::ELinksetUse restrictedLinksetUse = LLPathfindingLinkset::getLinksetUseWithToggledPhantom(linksetUse);
LLSD substitutions;
substitutions["REQUESTED_TYPE"] = getLinksetUseString(linksetUse);
substitutions["RESTRICTED_TYPE"] = getLinksetUseString(restrictedLinksetUse);
// Build one of the following notifications names
// - PathfindingLinksets_WarnOnPhantom
// - PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted
// - PathfindingLinksets_WarnOnPhantom_MismatchOnVolume
// - PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume
// - PathfindingLinksets_MismatchOnRestricted
// - PathfindingLinksets_MismatchOnVolume
// - PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume
std::string notificationName = "PathfindingLinksets";
if (showPhantomToggleWarning)
{
notificationName += "_WarnOnPhantom";
}
if (showUnmodifiablePhantomWarning)
{
notificationName += "_MismatchOnRestricted";
}
if (showCannotBeVolumeWarning)
{
notificationName += "_MismatchOnVolume";
}
LLNotificationsUtil::add(notificationName, substitutions, LLSD(), boost::bind(&LLFloaterPathfindingLinksets::handleApplyEdit, this, _1, _2));
}
else
{
doApplyEdit();
}
}
void LLFloaterPathfindingLinksets::handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse)
{
if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
{
doApplyEdit();
}
}
void LLFloaterPathfindingLinksets::doApplyEdit()
{
LLPathfindingObjectListPtr selectedObjects = getSelectedObjects();
if ((selectedObjects != NULL) && !selectedObjects->isEmpty())
{
LLPathfindingLinkset::ELinksetUse linksetUse = getEditLinksetUse();
const std::string &aString = mEditA->getText();
const std::string &bString = mEditB->getText();
const std::string &cString = mEditC->getText();
const std::string &dString = mEditD->getText();
S32 aValue = static_cast<S32>(atoi(aString.c_str()));
S32 bValue = static_cast<S32>(atoi(bString.c_str()));
S32 cValue = static_cast<S32>(atoi(cString.c_str()));
S32 dValue = static_cast<S32>(atoi(dString.c_str()));
requestSetLinksets(selectedObjects, linksetUse, aValue, bValue, cValue, dValue);
}
}
std::string LLFloaterPathfindingLinksets::getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
{
std::string linksetUse;
switch (pLinksetUse)
{
case LLPathfindingLinkset::kWalkable :
linksetUse = getString("linkset_use_walkable");
break;
case LLPathfindingLinkset::kStaticObstacle :
linksetUse = getString("linkset_use_static_obstacle");
break;
case LLPathfindingLinkset::kDynamicObstacle :
linksetUse = getString("linkset_use_dynamic_obstacle");
break;
case LLPathfindingLinkset::kMaterialVolume :
linksetUse = getString("linkset_use_material_volume");
break;
case LLPathfindingLinkset::kExclusionVolume :
linksetUse = getString("linkset_use_exclusion_volume");
break;
case LLPathfindingLinkset::kDynamicPhantom :
linksetUse = getString("linkset_use_dynamic_phantom");
break;
case LLPathfindingLinkset::kUnknown :
default :
linksetUse = getString("linkset_use_dynamic_obstacle");
llassert(0);
break;
}
return linksetUse;
}
LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getFilterLinksetUse() const
{
return convertToLinksetUse(mFilterByLinksetUse->getValue());
}
void LLFloaterPathfindingLinksets::setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse)
{
mFilterByLinksetUse->setValue(convertToXuiValue(pLinksetUse));
}
LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::getEditLinksetUse() const
{
return convertToLinksetUse(mEditLinksetUse->getValue());
}
void LLFloaterPathfindingLinksets::setEditLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse)
{
mEditLinksetUse->setValue(convertToXuiValue(pLinksetUse));
}
LLPathfindingLinkset::ELinksetUse LLFloaterPathfindingLinksets::convertToLinksetUse(LLSD pXuiValue) const
{
LLPathfindingLinkset::ELinksetUse linkUse;
switch (pXuiValue.asInteger())
{
case XUI_LINKSET_USE_NONE :
linkUse = LLPathfindingLinkset::kUnknown;
break;
case XUI_LINKSET_USE_WALKABLE :
linkUse = LLPathfindingLinkset::kWalkable;
break;
case XUI_LINKSET_USE_STATIC_OBSTACLE :
linkUse = LLPathfindingLinkset::kStaticObstacle;
break;
case XUI_LINKSET_USE_DYNAMIC_OBSTACLE :
linkUse = LLPathfindingLinkset::kDynamicObstacle;
break;
case XUI_LINKSET_USE_MATERIAL_VOLUME :
linkUse = LLPathfindingLinkset::kMaterialVolume;
break;
case XUI_LINKSET_USE_EXCLUSION_VOLUME :
linkUse = LLPathfindingLinkset::kExclusionVolume;
break;
case XUI_LINKSET_USE_DYNAMIC_PHANTOM :
linkUse = LLPathfindingLinkset::kDynamicPhantom;
break;
default :
linkUse = LLPathfindingLinkset::kUnknown;
llassert(0);
break;
}
return linkUse;
}
LLSD LLFloaterPathfindingLinksets::convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const
{
LLSD xuiValue;
switch (pLinksetUse)
{
case LLPathfindingLinkset::kUnknown :
xuiValue = XUI_LINKSET_USE_NONE;
break;
case LLPathfindingLinkset::kWalkable :
xuiValue = XUI_LINKSET_USE_WALKABLE;
break;
case LLPathfindingLinkset::kStaticObstacle :
xuiValue = XUI_LINKSET_USE_STATIC_OBSTACLE;
break;
case LLPathfindingLinkset::kDynamicObstacle :
xuiValue = XUI_LINKSET_USE_DYNAMIC_OBSTACLE;
break;
case LLPathfindingLinkset::kMaterialVolume :
xuiValue = XUI_LINKSET_USE_MATERIAL_VOLUME;
break;
case LLPathfindingLinkset::kExclusionVolume :
xuiValue = XUI_LINKSET_USE_EXCLUSION_VOLUME;
break;
case LLPathfindingLinkset::kDynamicPhantom :
xuiValue = XUI_LINKSET_USE_DYNAMIC_PHANTOM;
break;
default :
xuiValue = XUI_LINKSET_USE_NONE;
llassert(0);
break;
}
return xuiValue;
}

View File

@@ -0,0 +1,142 @@
/**
* @file llfloaterpathfindinglinksets.h
* @brief "Pathfinding linksets" floater, allowing manipulation of the linksets on the current region.
* @author Stinson@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$
*/
#ifndef LL_LLFLOATERPATHFINDINGLINKSETS_H
#define LL_LLFLOATERPATHFINDINGLINKSETS_H
#include <string>
#include "llfloaterpathfindingobjects.h"
#include "llpathfindinglinkset.h"
#include "llpathfindingobjectlist.h"
#include "v4color.h"
class LLButton;
class LLComboBox;
class LLLineEditor;
class LLScrollListItem;
class LLSD;
class LLTextBox;
class LLUICtrl;
class LLVector3;
class LLFloaterPathfindingLinksets : public LLFloaterPathfindingObjects, public LLFloaterSingleton<LLFloaterPathfindingLinksets>
{
public:
static void openLinksetsWithSelectedObjects();
LLFloaterPathfindingLinksets(const LLSD& pSeed);
virtual ~LLFloaterPathfindingLinksets();
protected:
// friend class LLFloaterReg;
virtual BOOL postBuild();
virtual void requestGetObjects();
virtual void buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr);
virtual void updateControlsOnScrollListChange();
virtual S32 getNameColumnIndex() const;
virtual S32 getOwnerNameColumnIndex() const;
virtual std::string getOwnerName(const LLPathfindingObject *pObject) const;
virtual const LLColor4 &getBeaconColor() const;
virtual LLPathfindingObjectListPtr getEmptyObjectList() const;
private:
void requestSetLinksets(LLPathfindingObjectListPtr pLinksetList, LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD);
void onApplyAllFilters();
void onClearFiltersClicked();
void onWalkabilityCoefficientEntered(LLUICtrl *pUICtrl, LLSD &pPreviousValue);
void onApplyChangesClicked();
void clearFilters();
void updateEditFieldValues();
LLSD buildLinksetScrollListItemData(const LLPathfindingLinkset *pLinksetPtr, const LLVector3 &pAvatarPosition) const;
LLSD buildLinksetUseScrollListData(const std::string &pLabel, S32 pValue) const;
bool isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
bool isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
bool isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
void updateStateOnEditFields();
void updateStateOnEditLinksetUse();
void applyEdit();
void handleApplyEdit(const LLSD &pNotification, const LLSD &pResponse);
void doApplyEdit();
std::string getLinksetUseString(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
LLPathfindingLinkset::ELinksetUse getFilterLinksetUse() const;
void setFilterLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse);
LLPathfindingLinkset::ELinksetUse getEditLinksetUse() const;
void setEditLinksetUse(LLPathfindingLinkset::ELinksetUse pLinksetUse);
LLPathfindingLinkset::ELinksetUse convertToLinksetUse(LLSD pXuiValue) const;
LLSD convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
LLLineEditor *mFilterByName;
LLLineEditor *mFilterByDescription;
LLComboBox *mFilterByLinksetUse;
LLComboBox *mEditLinksetUse;
LLScrollListItem *mEditLinksetUseUnset;
LLScrollListItem *mEditLinksetUseWalkable;
LLScrollListItem *mEditLinksetUseStaticObstacle;
LLScrollListItem *mEditLinksetUseDynamicObstacle;
LLScrollListItem *mEditLinksetUseMaterialVolume;
LLScrollListItem *mEditLinksetUseExclusionVolume;
LLScrollListItem *mEditLinksetUseDynamicPhantom;
LLTextBox *mLabelWalkabilityCoefficients;
LLTextBox *mLabelEditA;
LLTextBox *mLabelSuggestedUseA;
LLLineEditor *mEditA;
LLTextBox *mLabelEditB;
LLTextBox *mLabelSuggestedUseB;
LLLineEditor *mEditB;
LLTextBox *mLabelEditC;
LLTextBox *mLabelSuggestedUseC;
LLLineEditor *mEditC;
LLTextBox *mLabelEditD;
LLTextBox *mLabelSuggestedUseD;
LLLineEditor *mEditD;
LLButton *mApplyEditsButton;
LLColor4 mBeaconColor;
LLSD mPreviousValueA;
LLSD mPreviousValueB;
LLSD mPreviousValueC;
LLSD mPreviousValueD;
};
#endif // LL_LLFLOATERPATHFINDINGLINKSETS_H

View File

@@ -0,0 +1,878 @@
/**
* @file llfloaterpathfindingobjects.cpp
* @brief Base class for both the pathfinding linksets and characters floater.
* @author Stinson@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 "llfloaterpathfindingobjects.h"
#include <string>
#include <map>
#include <vector>
#include <boost/bind.hpp>
#include <boost/signals2.hpp>
#include "llagent.h"
#include "llavatarname.h"
#include "llavatarnamecache.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llenvmanager.h"
#include "llfloater.h"
#include "llfontgl.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llpathfindingmanager.h"
#include "llresmgr.h"
#include "llscrolllistctrl.h"
#include "llselectmgr.h"
#include "llsd.h"
#include "llstring.h"
#include "llstyle.h"
#include "lltextbox.h"
#include "llui.h"
#include "llviewermenu.h"
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
#include "v3dmath.h"
#include "v3math.h"
#include "v4color.h"
#define DEFAULT_BEACON_WIDTH 6
//---------------------------------------------------------------------------
// LLFloaterPathfindingObjects
//---------------------------------------------------------------------------
void LLFloaterPathfindingObjects::onOpen(/*const LLSD &pKey*/)
{
LLFloater::onOpen(/*pKey*/);
selectNoneObjects();
mObjectsScrollList->setCommitOnSelectionChange(TRUE);
if (!mSelectionUpdateSlot.connected())
{
mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterPathfindingObjects::onInWorldSelectionListChanged, this));
}
if (!mRegionBoundaryCrossingSlot.connected())
{
mRegionBoundaryCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLFloaterPathfindingObjects::onRegionBoundaryCrossed, this));
}
if (!mGodLevelChangeSlot.connected())
{
mGodLevelChangeSlot = gAgent.registerGodLevelChanageListener(boost::bind(&LLFloaterPathfindingObjects::onGodLevelChange, this, _1));
}
requestGetObjects();
}
void LLFloaterPathfindingObjects::onClose(bool pIsAppQuitting)
{
if (mGodLevelChangeSlot.connected())
{
mGodLevelChangeSlot.disconnect();
}
if (mRegionBoundaryCrossingSlot.connected())
{
mRegionBoundaryCrossingSlot.disconnect();
}
if (mSelectionUpdateSlot.connected())
{
mSelectionUpdateSlot.disconnect();
}
mObjectsScrollList->setCommitOnSelectionChange(FALSE);
selectNoneObjects();
if (mObjectsSelection.notNull())
{
mObjectsSelection.clear();
}
if (pIsAppQuitting)
{
clearAllObjects();
destroy();
}
else
{
setVisible(false);
}
}
void LLFloaterPathfindingObjects::draw()
{
LLFloater::draw();
if (isShowBeacons())
{
std::vector<LLScrollListItem *> selectedItems = mObjectsScrollList->getAllSelected();
if (!selectedItems.empty())
{
int numSelectedItems = selectedItems.size();
S32 nameColumnIndex = getNameColumnIndex();
const LLColor4 &beaconColor = getBeaconColor();
const LLColor4 &beaconTextColor = getBeaconTextColor();
S32 beaconWidth = getBeaconWidth();
std::vector<LLViewerObject *> viewerObjects;
viewerObjects.reserve(numSelectedItems);
for (std::vector<LLScrollListItem *>::const_iterator selectedItemIter = selectedItems.begin();
selectedItemIter != selectedItems.end(); ++selectedItemIter)
{
const LLScrollListItem *selectedItem = *selectedItemIter;
LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID());
if (viewerObject != NULL)
{
const std::string &objectName = selectedItem->getColumn(nameColumnIndex)->getValue().asString();
gObjectList.addDebugBeacon(viewerObject->getPositionAgent(), objectName, beaconColor, beaconTextColor, beaconWidth);
}
}
}
}
}
LLFloaterPathfindingObjects::LLFloaterPathfindingObjects(/*const LLSD &pSeed*/)
: LLFloater(/*pSeed*/),
mObjectsScrollList(NULL),
mMessagingStatus(NULL),
mRefreshListButton(NULL),
mSelectAllButton(NULL),
mSelectNoneButton(NULL),
mShowBeaconCheckBox(NULL),
mTakeButton(NULL),
mTakeCopyButton(NULL),
mReturnButton(NULL),
mDeleteButton(NULL),
mTeleportButton(NULL),
mDefaultBeaconColor(),
mDefaultBeaconTextColor(),
mErrorTextColor(),
mWarningTextColor(),
mMessagingState(kMessagingUnknown),
mMessagingRequestId(0U),
mMissingNameObjectsScrollListItems(),
mObjectList(),
mObjectsSelection(),
mHasObjectsToBeSelected(false),
mObjectsToBeSelected(),
mSelectionUpdateSlot(),
mRegionBoundaryCrossingSlot()
{
}
LLFloaterPathfindingObjects::~LLFloaterPathfindingObjects()
{
clearAllObjects();
}
BOOL LLFloaterPathfindingObjects::postBuild()
{
mDefaultBeaconColor = LLUI::sColorsGroup->getColor("PathfindingDefaultBeaconColor");
mDefaultBeaconTextColor = LLUI::sColorsGroup->getColor("PathfindingDefaultBeaconTextColor");
mErrorTextColor = LLUI::sColorsGroup->getColor("PathfindingErrorColor");
mWarningTextColor = LLUI::sColorsGroup->getColor("PathfindingWarningColor");
mObjectsScrollList = getChild<LLScrollListCtrl>("objects_scroll_list");
llassert(mObjectsScrollList != NULL);
mObjectsScrollList->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onScrollListSelectionChanged, this));
mObjectsScrollList->sortByColumnIndex(static_cast<U32>(getNameColumnIndex()), TRUE);
mMessagingStatus = getChild<LLTextBox>("messaging_status");
llassert(mMessagingStatus != NULL);
mRefreshListButton = getChild<LLButton>("refresh_objects_list");
llassert(mRefreshListButton != NULL);
mRefreshListButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onRefreshObjectsClicked, this));
mSelectAllButton = getChild<LLButton>("select_all_objects");
llassert(mSelectAllButton != NULL);
mSelectAllButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onSelectAllObjectsClicked, this));
mSelectNoneButton = getChild<LLButton>("select_none_objects");
llassert(mSelectNoneButton != NULL);
mSelectNoneButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onSelectNoneObjectsClicked, this));
mShowBeaconCheckBox = getChild<LLCheckBoxCtrl>("show_beacon");
llassert(mShowBeaconCheckBox != NULL);
mTakeButton = getChild<LLButton>("take_objects");
llassert(mTakeButton != NULL);
mTakeButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onTakeClicked, this));
mTakeCopyButton = getChild<LLButton>("take_copy_objects");
llassert(mTakeCopyButton != NULL);
mTakeCopyButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onTakeCopyClicked, this));
mReturnButton = getChild<LLButton>("return_objects");
llassert(mReturnButton != NULL);
mReturnButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onReturnClicked, this));
mDeleteButton = getChild<LLButton>("delete_objects");
llassert(mDeleteButton != NULL);
mDeleteButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onDeleteClicked, this));
mTeleportButton = getChild<LLButton>("teleport_me_to_object");
llassert(mTeleportButton != NULL);
mTeleportButton->setCommitCallback(boost::bind(&LLFloaterPathfindingObjects::onTeleportClicked, this));
return LLFloater::postBuild();
}
void LLFloaterPathfindingObjects::requestGetObjects()
{
llassert(0);
}
LLPathfindingManager::request_id_t LLFloaterPathfindingObjects::getNewRequestId()
{
return ++mMessagingRequestId;
}
void LLFloaterPathfindingObjects::handleNewObjectList(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pRequestStatus, LLPathfindingObjectListPtr pObjectList)
{
llassert(pRequestId <= mMessagingRequestId);
if (pRequestId == mMessagingRequestId)
{
switch (pRequestStatus)
{
case LLPathfindingManager::kRequestStarted :
setMessagingState(kMessagingGetRequestSent);
break;
case LLPathfindingManager::kRequestCompleted :
mObjectList = pObjectList;
rebuildObjectsScrollList();
setMessagingState(kMessagingComplete);
break;
case LLPathfindingManager::kRequestNotEnabled :
clearAllObjects();
setMessagingState(kMessagingNotEnabled);
break;
case LLPathfindingManager::kRequestError :
clearAllObjects();
setMessagingState(kMessagingGetError);
break;
default :
clearAllObjects();
setMessagingState(kMessagingGetError);
llassert(0);
break;
}
}
}
void LLFloaterPathfindingObjects::handleUpdateObjectList(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pRequestStatus, LLPathfindingObjectListPtr pObjectList)
{
// We current assume that handleUpdateObjectList is called only when objects are being SET
llassert(pRequestId <= mMessagingRequestId);
if (pRequestId == mMessagingRequestId)
{
switch (pRequestStatus)
{
case LLPathfindingManager::kRequestStarted :
setMessagingState(kMessagingSetRequestSent);
break;
case LLPathfindingManager::kRequestCompleted :
if (mObjectList == NULL)
{
mObjectList = pObjectList;
}
else
{
mObjectList->update(pObjectList);
}
rebuildObjectsScrollList();
setMessagingState(kMessagingComplete);
break;
case LLPathfindingManager::kRequestNotEnabled :
clearAllObjects();
setMessagingState(kMessagingNotEnabled);
break;
case LLPathfindingManager::kRequestError :
clearAllObjects();
setMessagingState(kMessagingSetError);
break;
default :
clearAllObjects();
setMessagingState(kMessagingSetError);
llassert(0);
break;
}
}
}
void LLFloaterPathfindingObjects::rebuildObjectsScrollList()
{
if (!mHasObjectsToBeSelected)
{
std::vector<LLScrollListItem*> selectedItems = mObjectsScrollList->getAllSelected();
int numSelectedItems = selectedItems.size();
if (numSelectedItems > 0)
{
mObjectsToBeSelected.reserve(selectedItems.size());
for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin();
itemIter != selectedItems.end(); ++itemIter)
{
const LLScrollListItem *listItem = *itemIter;
mObjectsToBeSelected.push_back(listItem->getUUID());
}
}
}
S32 origScrollPosition = mObjectsScrollList->getScrollPos();
mObjectsScrollList->deleteAllItems();
mMissingNameObjectsScrollListItems.clear();
if ((mObjectList != NULL) && !mObjectList->isEmpty())
{
buildObjectsScrollList(mObjectList);
mObjectsScrollList->selectMultiple(mObjectsToBeSelected);
if (mHasObjectsToBeSelected)
{
mObjectsScrollList->scrollToShowSelected();
}
else
{
mObjectsScrollList->setScrollPos(origScrollPosition);
}
}
mObjectsToBeSelected.clear();
mHasObjectsToBeSelected = false;
updateControlsOnScrollListChange();
}
void LLFloaterPathfindingObjects::buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr)
{
llassert(0);
}
void LLFloaterPathfindingObjects::addObjectToScrollList(const LLPathfindingObjectPtr pObjectPtr, const LLSD &pScrollListItemData)
{
LLSD rowParams;
rowParams["id"] = pObjectPtr->getUUID();
llassert(pScrollListItemData.isArray());
S32 idx = 0;
for (LLSD::array_const_iterator cellIter = pScrollListItemData.beginArray();
cellIter != pScrollListItemData.endArray(); ++cellIter)
{
rowParams["columns"][idx] = *cellIter;
idx++;
}
LLScrollListItem *scrollListItem = mObjectsScrollList->addElement(rowParams);
if (pObjectPtr->hasOwner() && !pObjectPtr->hasOwnerName())
{
mMissingNameObjectsScrollListItems.insert(std::make_pair<std::string, LLScrollListItem *>(pObjectPtr->getUUID().asString(), scrollListItem));
pObjectPtr->registerOwnerNameListener(boost::bind(&LLFloaterPathfindingObjects::handleObjectNameResponse, this, _1));
}
}
void LLFloaterPathfindingObjects::updateControlsOnScrollListChange()
{
updateMessagingStatus();
updateStateOnListControls();
selectScrollListItemsInWorld();
updateStateOnActionControls();
}
void LLFloaterPathfindingObjects::updateControlsOnInWorldSelectionChange()
{
updateStateOnActionControls();
}
S32 LLFloaterPathfindingObjects::getNameColumnIndex() const
{
return 0;
}
S32 LLFloaterPathfindingObjects::getOwnerNameColumnIndex() const
{
return 2;
}
std::string LLFloaterPathfindingObjects::getOwnerName(const LLPathfindingObject *pObject) const
{
llassert(0);
std::string returnVal;
return returnVal;
}
const LLColor4 &LLFloaterPathfindingObjects::getBeaconColor() const
{
return mDefaultBeaconColor;
}
const LLColor4 &LLFloaterPathfindingObjects::getBeaconTextColor() const
{
return mDefaultBeaconTextColor;
}
S32 LLFloaterPathfindingObjects::getBeaconWidth() const
{
return DEFAULT_BEACON_WIDTH;
}
void LLFloaterPathfindingObjects::showFloaterWithSelectionObjects()
{
mObjectsToBeSelected.clear();
LLObjectSelectionHandle selectedObjectsHandle = LLSelectMgr::getInstance()->getSelection();
if (selectedObjectsHandle.notNull())
{
LLObjectSelection *selectedObjects = selectedObjectsHandle.get();
if (!selectedObjects->isEmpty())
{
for (LLObjectSelection::valid_iterator objectIter = selectedObjects->valid_begin();
objectIter != selectedObjects->valid_end(); ++objectIter)
{
LLSelectNode *object = *objectIter;
LLViewerObject *viewerObject = object->getObject();
mObjectsToBeSelected.push_back(viewerObject->getID());
}
}
}
mHasObjectsToBeSelected = true;
if (!getVisible())
{
open();
setVisibleAndFrontmost();
}
else
{
rebuildObjectsScrollList();
if (isMinimized())
{
setMinimized(FALSE);
}
setVisibleAndFrontmost();
}
setFocus(TRUE);
}
BOOL LLFloaterPathfindingObjects::isShowBeacons() const
{
return mShowBeaconCheckBox->get();
}
void LLFloaterPathfindingObjects::clearAllObjects()
{
selectNoneObjects();
mObjectsScrollList->deleteAllItems();
mMissingNameObjectsScrollListItems.clear();
mObjectList.reset();
}
void LLFloaterPathfindingObjects::selectAllObjects()
{
mObjectsScrollList->selectAll();
}
void LLFloaterPathfindingObjects::selectNoneObjects()
{
mObjectsScrollList->deselectAllItems();
}
void LLFloaterPathfindingObjects::teleportToSelectedObject()
{
std::vector<LLScrollListItem*> selectedItems = mObjectsScrollList->getAllSelected();
llassert(selectedItems.size() == 1);
if (selectedItems.size() == 1)
{
std::vector<LLScrollListItem*>::const_reference selectedItemRef = selectedItems.front();
const LLScrollListItem *selectedItem = selectedItemRef;
llassert(mObjectList != NULL);
LLVector3d teleportLocation;
LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID());
if (viewerObject == NULL)
{
// If we cannot find the object in the viewer list, teleport to the last reported position
const LLPathfindingObjectPtr objectPtr = mObjectList->find(selectedItem->getUUID().asString());
teleportLocation = gAgent.getPosGlobalFromAgent(objectPtr->getLocation());
}
else
{
// If we can find the object in the viewer list, teleport to the known current position
teleportLocation = viewerObject->getPositionGlobal();
}
gAgent.teleportViaLocationLookAt(teleportLocation);
}
}
LLPathfindingObjectListPtr LLFloaterPathfindingObjects::getEmptyObjectList() const
{
llassert(0);
LLPathfindingObjectListPtr objectListPtr(new LLPathfindingObjectList());
return objectListPtr;
}
int LLFloaterPathfindingObjects::getNumSelectedObjects() const
{
return mObjectsScrollList->getNumSelected();
}
LLPathfindingObjectListPtr LLFloaterPathfindingObjects::getSelectedObjects() const
{
LLPathfindingObjectListPtr selectedObjects = getEmptyObjectList();
std::vector<LLScrollListItem*> selectedItems = mObjectsScrollList->getAllSelected();
if (!selectedItems.empty())
{
for (std::vector<LLScrollListItem*>::const_iterator itemIter = selectedItems.begin();
itemIter != selectedItems.end(); ++itemIter)
{
LLPathfindingObjectPtr objectPtr = findObject(*itemIter);
if (objectPtr != NULL)
{
selectedObjects->update(objectPtr);
}
}
}
return selectedObjects;
}
LLPathfindingObjectPtr LLFloaterPathfindingObjects::getFirstSelectedObject() const
{
LLPathfindingObjectPtr objectPtr;
std::vector<LLScrollListItem*> selectedItems = mObjectsScrollList->getAllSelected();
if (!selectedItems.empty())
{
objectPtr = findObject(selectedItems.front());
}
return objectPtr;
}
LLFloaterPathfindingObjects::EMessagingState LLFloaterPathfindingObjects::getMessagingState() const
{
return mMessagingState;
}
void LLFloaterPathfindingObjects::setMessagingState(EMessagingState pMessagingState)
{
mMessagingState = pMessagingState;
updateControlsOnScrollListChange();
}
void LLFloaterPathfindingObjects::onRefreshObjectsClicked()
{
requestGetObjects();
}
void LLFloaterPathfindingObjects::onSelectAllObjectsClicked()
{
selectAllObjects();
}
void LLFloaterPathfindingObjects::onSelectNoneObjectsClicked()
{
selectNoneObjects();
}
void LLFloaterPathfindingObjects::onTakeClicked()
{
handle_take();
requestGetObjects();
}
void LLFloaterPathfindingObjects::onTakeCopyClicked()
{
handle_take_copy();
}
void LLFloaterPathfindingObjects::onReturnClicked()
{
LLNotification::Params params("PathfindingReturnMultipleItems");
params.functor(boost::bind(&LLFloaterPathfindingObjects::handleReturnItemsResponse, this, _1, _2));
LLSD substitutions;
int numItems = getNumSelectedObjects();
substitutions["NUM_ITEMS"] = static_cast<LLSD::Integer>(numItems);
params.substitutions = substitutions;
if (numItems == 1)
{
LLNotifications::getInstance()->forceResponse(params, 0);
}
else if (numItems > 1)
{
LLNotifications::getInstance()->add(params);
}
}
void LLFloaterPathfindingObjects::onDeleteClicked()
{
LLNotification::Params params("PathfindingDeleteMultipleItems");
params.functor(boost::bind(&LLFloaterPathfindingObjects::handleDeleteItemsResponse, this, _1, _2));
LLSD substitutions;
int numItems = getNumSelectedObjects();
substitutions["NUM_ITEMS"] = static_cast<LLSD::Integer>(numItems);
params.substitutions = substitutions;
if (numItems == 1)
{
LLNotifications::getInstance()->forceResponse(params, 0);
}
else if (numItems > 1)
{
LLNotifications::getInstance()->add(params);
}
}
void LLFloaterPathfindingObjects::onTeleportClicked()
{
teleportToSelectedObject();
}
void LLFloaterPathfindingObjects::onScrollListSelectionChanged()
{
updateControlsOnScrollListChange();
}
void LLFloaterPathfindingObjects::onInWorldSelectionListChanged()
{
updateControlsOnInWorldSelectionChange();
}
void LLFloaterPathfindingObjects::onRegionBoundaryCrossed()
{
requestGetObjects();
}
void LLFloaterPathfindingObjects::onGodLevelChange(U8 pGodLevel)
{
requestGetObjects();
}
void LLFloaterPathfindingObjects::handleObjectNameResponse(const LLPathfindingObject *pObject)
{
llassert(pObject != NULL);
const std::string uuid = pObject->getUUID().asString();
scroll_list_item_map::iterator scrollListItemIter = mMissingNameObjectsScrollListItems.find(uuid);
if (scrollListItemIter != mMissingNameObjectsScrollListItems.end())
{
LLScrollListItem *scrollListItem = scrollListItemIter->second;
llassert(scrollListItem != NULL);
LLScrollListCell *scrollListCell = scrollListItem->getColumn(getOwnerNameColumnIndex());
LLSD ownerName = getOwnerName(pObject);
scrollListCell->setValue(ownerName);
mMissingNameObjectsScrollListItems.erase(scrollListItemIter);
}
}
void LLFloaterPathfindingObjects::updateMessagingStatus()
{
std::string statusText("");
LLColor4 color;
switch (getMessagingState())
{
case kMessagingUnknown:
statusText = getString("messaging_initial");
color = mErrorTextColor;
break;
case kMessagingGetRequestSent :
statusText = getString("messaging_get_inprogress");
color = mWarningTextColor;
break;
case kMessagingGetError :
statusText = getString("messaging_get_error");
color = mErrorTextColor;
break;
case kMessagingSetRequestSent :
statusText = getString("messaging_set_inprogress");
color = mWarningTextColor;
break;
case kMessagingSetError :
statusText = getString("messaging_set_error");
color = mErrorTextColor;
break;
case kMessagingComplete :
if (mObjectsScrollList->isEmpty())
{
statusText = getString("messaging_complete_none_found");
}
else
{
S32 numItems = mObjectsScrollList->getItemCount();
S32 numSelectedItems = mObjectsScrollList->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("messaging_complete_available", string_args);
}
color = LLUI::sColorsGroup->getColor("PathfindingGoodColor");
break;
case kMessagingNotEnabled :
statusText = getString("messaging_not_enabled");
color = mErrorTextColor;
break;
default:
statusText = getString("messaging_initial");
color = mErrorTextColor;
llassert(0);
break;
}
mMessagingStatus->setText((LLStringExplicit)statusText);
mMessagingStatus->setColor(color);
}
void LLFloaterPathfindingObjects::updateStateOnListControls()
{
switch (getMessagingState())
{
case kMessagingUnknown:
case kMessagingGetRequestSent :
case kMessagingSetRequestSent :
mRefreshListButton->setEnabled(FALSE);
mSelectAllButton->setEnabled(FALSE);
mSelectNoneButton->setEnabled(FALSE);
break;
case kMessagingGetError :
case kMessagingSetError :
case kMessagingNotEnabled :
mRefreshListButton->setEnabled(TRUE);
mSelectAllButton->setEnabled(FALSE);
mSelectNoneButton->setEnabled(FALSE);
break;
case kMessagingComplete :
{
int numItems = mObjectsScrollList->getItemCount();
int numSelectedItems = mObjectsScrollList->getNumSelected();
mRefreshListButton->setEnabled(TRUE);
mSelectAllButton->setEnabled(numSelectedItems < numItems);
mSelectNoneButton->setEnabled(numSelectedItems > 0);
}
break;
default:
llassert(0);
break;
}
}
void LLFloaterPathfindingObjects::updateStateOnActionControls()
{
int numSelectedItems = mObjectsScrollList->getNumSelected();
bool isEditEnabled = (numSelectedItems > 0);
mShowBeaconCheckBox->setEnabled(isEditEnabled);
mTakeButton->setEnabled(isEditEnabled && visible_take_object());
mTakeCopyButton->setEnabled(isEditEnabled && enable_object_take_copy());
mReturnButton->setEnabled(isEditEnabled && enable_object_return());
mDeleteButton->setEnabled(isEditEnabled && enable_object_delete());
mTeleportButton->setEnabled(numSelectedItems == 1);
}
void LLFloaterPathfindingObjects::selectScrollListItemsInWorld()
{
mObjectsSelection.clear();
LLSelectMgr::getInstance()->deselectAll();
std::vector<LLScrollListItem *> selectedItems = mObjectsScrollList->getAllSelected();
if (!selectedItems.empty())
{
int numSelectedItems = selectedItems.size();
std::vector<LLViewerObject *>viewerObjects;
viewerObjects.reserve(numSelectedItems);
for (std::vector<LLScrollListItem *>::const_iterator selectedItemIter = selectedItems.begin();
selectedItemIter != selectedItems.end(); ++selectedItemIter)
{
const LLScrollListItem *selectedItem = *selectedItemIter;
LLViewerObject *viewerObject = gObjectList.findObject(selectedItem->getUUID());
if (viewerObject != NULL)
{
viewerObjects.push_back(viewerObject);
}
}
if (!viewerObjects.empty())
{
mObjectsSelection = LLSelectMgr::getInstance()->selectObjectAndFamily(viewerObjects);
}
}
}
void LLFloaterPathfindingObjects::handleReturnItemsResponse(const LLSD &pNotification, const LLSD &pResponse)
{
if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
{
handle_object_return();
requestGetObjects();
}
}
void LLFloaterPathfindingObjects::handleDeleteItemsResponse(const LLSD &pNotification, const LLSD &pResponse)
{
if (LLNotificationsUtil::getSelectedOption(pNotification, pResponse) == 0)
{
handle_object_delete();
requestGetObjects();
}
}
LLPathfindingObjectPtr LLFloaterPathfindingObjects::findObject(const LLScrollListItem *pListItem) const
{
LLPathfindingObjectPtr objectPtr;
LLUUID uuid = pListItem->getUUID();
const std::string &uuidString = uuid.asString();
llassert(mObjectList != NULL);
objectPtr = mObjectList->find(uuidString);
return objectPtr;
}

View File

@@ -0,0 +1,179 @@
/**
* @file llfloaterpathfindingobjects.h
* @brief Base class for both the pathfinding linksets and characters floater.
* @author Stinson@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$
*/
#ifndef LL_LLFLOATERPATHFINDINGOBJECTS_H
#define LL_LLFLOATERPATHFINDINGOBJECTS_H
#include <string>
#include <map>
#include <boost/signals2.hpp>
#include "llagent.h"
#include "llfloater.h"
#include "llpathfindingmanager.h"
#include "llpathfindingobject.h"
#include "llpathfindingobjectlist.h"
#include "llselectmgr.h"
#include "lluuid.h"
#include "v4color.h"
class LLAvatarName;
class LLButton;
class LLCheckBoxCtrl;
class LLScrollListCtrl;
class LLScrollListItem;
class LLSD;
class LLTextBox;
class LLFloaterPathfindingObjects : public LLFloater
{
public:
virtual void onOpen(/*const LLSD &pKey*/);
virtual void onClose(bool pIsAppQuitting);
virtual void draw();
protected:
// friend class LLFloaterReg;
typedef enum
{
kMessagingUnknown,
kMessagingGetRequestSent,
kMessagingGetError,
kMessagingSetRequestSent,
kMessagingSetError,
kMessagingComplete,
kMessagingNotEnabled
} EMessagingState;
LLFloaterPathfindingObjects(/*const LLSD &pSeed*/);
virtual ~LLFloaterPathfindingObjects();
virtual BOOL postBuild();
virtual void requestGetObjects();
LLPathfindingManager::request_id_t getNewRequestId();
void handleNewObjectList(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pRequestStatus, LLPathfindingObjectListPtr pObjectList);
void handleUpdateObjectList(LLPathfindingManager::request_id_t pRequestId, LLPathfindingManager::ERequestStatus pRequestStatus, LLPathfindingObjectListPtr pObjectList);
void rebuildObjectsScrollList();
virtual void buildObjectsScrollList(const LLPathfindingObjectListPtr pObjectListPtr);
void addObjectToScrollList(const LLPathfindingObjectPtr pObjectPr, const LLSD &pScrollListItemData);
virtual void updateControlsOnScrollListChange();
virtual void updateControlsOnInWorldSelectionChange();
virtual S32 getNameColumnIndex() const;
virtual S32 getOwnerNameColumnIndex() const;
virtual std::string getOwnerName(const LLPathfindingObject *pObject) const;
virtual const LLColor4 &getBeaconColor() const;
virtual const LLColor4 &getBeaconTextColor() const;
virtual S32 getBeaconWidth() const;
void showFloaterWithSelectionObjects();
BOOL isShowBeacons() const;
void clearAllObjects();
void selectAllObjects();
void selectNoneObjects();
void teleportToSelectedObject();
virtual LLPathfindingObjectListPtr getEmptyObjectList() const;
int getNumSelectedObjects() const;
LLPathfindingObjectListPtr getSelectedObjects() const;
LLPathfindingObjectPtr getFirstSelectedObject() const;
EMessagingState getMessagingState() const;
private:
LLFloaterPathfindingObjects(const LLFloaterPathfindingObjects &pOther);
void setMessagingState(EMessagingState pMessagingState);
void onRefreshObjectsClicked();
void onSelectAllObjectsClicked();
void onSelectNoneObjectsClicked();
void onTakeClicked();
void onTakeCopyClicked();
void onReturnClicked();
void onDeleteClicked();
void onTeleportClicked();
void onScrollListSelectionChanged();
void onInWorldSelectionListChanged();
void onRegionBoundaryCrossed();
void onGodLevelChange(U8 pGodLevel);
void handleObjectNameResponse(const LLPathfindingObject *pObject);
void updateMessagingStatus();
void updateStateOnListControls();
void updateStateOnActionControls();
void selectScrollListItemsInWorld();
void handleReturnItemsResponse(const LLSD &pNotification, const LLSD &pResponse);
void handleDeleteItemsResponse(const LLSD &pNotification, const LLSD &pResponse);
LLPathfindingObjectPtr findObject(const LLScrollListItem *pListItem) const;
LLScrollListCtrl *mObjectsScrollList;
LLTextBox *mMessagingStatus;
LLButton *mRefreshListButton;
LLButton *mSelectAllButton;
LLButton *mSelectNoneButton;
LLCheckBoxCtrl *mShowBeaconCheckBox;
LLButton *mTakeButton;
LLButton *mTakeCopyButton;
LLButton *mReturnButton;
LLButton *mDeleteButton;
LLButton *mTeleportButton;
LLColor4 mDefaultBeaconColor;
LLColor4 mDefaultBeaconTextColor;
LLColor4 mErrorTextColor;
LLColor4 mWarningTextColor;
EMessagingState mMessagingState;
LLPathfindingManager::request_id_t mMessagingRequestId;
typedef std::map<std::string, LLScrollListItem *> scroll_list_item_map;
scroll_list_item_map mMissingNameObjectsScrollListItems;
LLPathfindingObjectListPtr mObjectList;
LLObjectSelectionHandle mObjectsSelection;
bool mHasObjectsToBeSelected;
uuid_vec_t mObjectsToBeSelected;
boost::signals2::connection mSelectionUpdateSlot;
boost::signals2::connection mRegionBoundaryCrossingSlot;
LLAgent::god_level_change_slot_t mGodLevelChangeSlot;
};
#endif // LL_LLFLOATERPATHFINDINGOBJECTS_H

View File

@@ -48,7 +48,7 @@
#include "llpathfindingnavmesh.h"
#include "llpathfindingnavmeshstatus.h"
#include "llpathfindingobject.h"
//#include "llpathinglib.h"
#include "llpathinglib.h"
#include "llsingleton.h"
#include "llsd.h"
#include "lltrans.h"
@@ -318,24 +318,23 @@ LLPathfindingManager::~LLPathfindingManager()
void LLPathfindingManager::initSystem()
{
/*if (LLPathingLib::getInstance() == NULL)
if (LLPathingLib::getInstance() == NULL)
{
LLPathingLib::initSystem();
}*/
}
}
void LLPathfindingManager::quitSystem()
{
/*if (LLPathingLib::getInstance() != NULL)
if (LLPathingLib::getInstance() != NULL)
{
LLPathingLib::quitSystem();
}*/
}
}
bool LLPathfindingManager::isPathfindingViewEnabled() const
{
return false;
//return (LLPathingLib::getInstance() != NULL);
return (LLPathingLib::getInstance() != NULL);
}
bool LLPathfindingManager::isPathfindingEnabledForCurrentRegion() const

View File

@@ -38,7 +38,7 @@
#include "llagent.h"
#include "llbutton.h"
#include "llcommandhandler.h"
#include "llviewercontrol.h"
#include "llenvmanager.h"
#include "llfloaterbuycurrency.h"
#include "llfloaterchat.h"
#include "llfloaterdirectory.h" // to spawn search
@@ -51,7 +51,10 @@
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "llmenugl.h"
#include "llmenuoptionpathfindingrebakenavmesh.h"
#include "llnotify.h"
#include "llpathfindingmanager.h"
#include "llpathfindingnavmeshstatus.h"
#include "llimview.h"
#include "lltextbox.h"
#include "llui.h"
@@ -64,6 +67,7 @@
#include "llresmgr.h"
#include "llworld.h"
#include "llstatgraph.h"
#include "llviewercontrol.h"
#include "llviewermenu.h" // for gMenuBarView
#include "llviewerparcelmgr.h"
#include "llviewerthrottle.h"
@@ -122,6 +126,8 @@ static void onClickFly(void*);
static void onClickPush(void*);
static void onClickVoice(void*);
static void onClickBuild(void*);
static void onClickPFDirty(void*);
static void onClickPFDisabled(void*);
static void onClickSeeAV(void*);
static void onClickScripts(void*);
static void onClickBuyLand(void*);
@@ -136,7 +142,10 @@ LLStatusBar::LLStatusBar(const std::string& name, const LLRect& rect)
mBalance(0),
mHealth(100),
mSquareMetersCredit(0),
mSquareMetersCommitted(0)
mSquareMetersCommitted(0),
mRegionCrossingSlot(),
mNavMeshSlot(),
mIsNavMeshDirty(false)
{
// status bar can possible overlay menus?
setMouseOpaque(FALSE);
@@ -169,6 +178,8 @@ mSquareMetersCommitted(0)
childSetAction("buyland", onClickBuyLand, this );
childSetAction("buycurrency", onClickBuyCurrency, this );
childSetAction("no_build", onClickBuild, this );
childSetAction("pf_dirty", onClickPFDirty, this);
childSetAction("pf_disabled", onClickPFDisabled, this);
childSetAction("status_SeeAV", onClickSeeAV, this );
childSetAction("no_scripts", onClickScripts, this );
childSetAction("restrictpush", onClickPush, this );
@@ -188,7 +199,10 @@ mSquareMetersCommitted(0)
// that don't support currency yet -- MC
LLButton* buybtn = getChild<LLButton>("buycurrency");
buybtn->setLabelArg("[CURRENCY]", gHippoGridManager->getConnectedGrid()->getCurrencySymbol());
mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLStatusBar::createNavMeshStatusListenerForCurrentRegion, this));
createNavMeshStatusListenerForCurrentRegion();
// Adding Net Stat Graph
S32 x = getRect().getWidth() - 2;
S32 y = 0;
@@ -232,6 +246,9 @@ LLStatusBar::~LLStatusBar()
delete mHealthTimer;
mHealthTimer = NULL;
mRegionCrossingSlot.disconnect();
mNavMeshSlot.disconnect();
// LLView destructor cleans up children
}
@@ -457,6 +474,22 @@ void LLStatusBar::refresh()
x += buttonRect.getWidth();
}
if (region)
{
bool pf_disabled = !region->dynamicPathfindingEnabled();
getChild<LLUICtrl>("pf_dirty")->setVisible(mIsNavMeshDirty);
getChild<LLUICtrl>("pf_disabled")->setVisible(pf_disabled);
const std::string pf_icon = mIsNavMeshDirty ? "pf_dirty" : pf_disabled ? "pf_disabled" : "";
if (!pf_icon.empty())
{
x += 6;
childGetRect(pf_icon, buttonRect);
r.setOriginAndSize(x, y, buttonRect.getWidth(), buttonRect.getHeight());
childSetRect(pf_icon, r);
x += buttonRect.getWidth();
}
}
BOOL canBuyLand = parcel
&& !parcel->isPublic()
&& LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, false);
@@ -767,6 +800,47 @@ static void onClickBuild(void*)
LLNotificationsUtil::add("NoBuild");
}
static bool rebakeRegionCallback(const LLSD& n, const LLSD& r)
{
if(!LLNotificationsUtil::getSelectedOption(n, r)) //0 is Yes
{
LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh();
return true;
}
return false;
}
static void onClickPFDirty(void*)
{
LLNotificationsUtil::add("PathfindingDirty", LLSD(), LLSD(), rebakeRegionCallback);
}
static void onClickPFDisabled(void*)
{
LLNotificationsUtil::add("DynamicPathfindingDisabled");
}
void LLStatusBar::createNavMeshStatusListenerForCurrentRegion()
{
if (mNavMeshSlot.connected())
{
mNavMeshSlot.disconnect();
}
LLViewerRegion *currentRegion = gAgent.getRegion();
if (currentRegion != NULL)
{
mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLStatusBar::onNavMeshStatusChange, this, _2));
LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true);
}
}
void LLStatusBar::onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus)
{
mIsNavMeshDirty = pNavMeshStatus.isValid() && (pNavMeshStatus.getStatus() != LLPathfindingNavMeshStatus::kComplete);
refresh();
}
static void onClickSeeAV(void*)
{
LLNotificationsUtil::add("SeeAvatars");

View File

@@ -34,6 +34,7 @@
#define LL_LLSTATUSBAR_H
#include "llpanel.h"
#include "llpathfindingnavmesh.h"
// "Constants" loaded from settings.xml at start time
extern S32 STATUS_BAR_HEIGHT;
@@ -47,6 +48,7 @@ class LLUICtrl;
class LLUUID;
class LLFrameTimer;
class LLStatGraph;
class LLPathfindingNavMeshStatus;
class LLStatusBar
: public LLPanel
@@ -91,6 +93,10 @@ private:
static void onClickSearch(void* data);
static void onClickStatGraph(void* data);
void onRegionBoundaryCrossed();
void createNavMeshStatusListenerForCurrentRegion();
void onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus);
private:
LLTextBox *mTextBalance;
LLTextBox *mTextHealth;
@@ -109,6 +115,9 @@ private:
S32 mSquareMetersCommitted;
LLFrameTimer* mBalanceTimer;
LLFrameTimer* mHealthTimer;
boost::signals2::connection mRegionCrossingSlot;
LLPathfindingNavMesh::navmesh_slot_t mNavMeshSlot;
bool mIsNavMeshDirty;
static std::vector<std::string> sDays;
static std::vector<std::string> sMonths;

View File

@@ -141,6 +141,8 @@
#include "llfloatermute.h"
#include "llfloateropenobject.h"
#include "llfloateroutbox.h"
#include "llfloaterpathfindingcharacters.h"
#include "llfloaterpathfindinglinksets.h"
#include "llfloaterpermissionsmgr.h"
#include "llfloaterperms.h"
#include "llfloaterpostprocess.h"
@@ -2864,16 +2866,50 @@ class LLObjectMeasure : public view_listener_t
}
};
class LLObjectPFLinksetsSelected : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects();
return true;
}
};
bool enable_object_select_in_pathfinding_linksets()
{
return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetEditableLinksets();
}
class LLObjectEnablePFLinksetsSelected : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
return enable_object_select_in_pathfinding_linksets();
}
};
class LLObjectPFCharactersSelected : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
LLFloaterPathfindingCharacters::openCharactersWithSelectedObjects();
return true;
}
};
bool enable_object_select_in_pathfinding_characters()
{
return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetViewableCharacters();
}
class LLObjectEnablePFCharactersSelected : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
return enable_object_select_in_pathfinding_characters();
}
};
class LLAvatarAnims : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
@@ -4814,7 +4850,14 @@ class LLToolsTakeCopy : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true;
handle_take_copy();
return true;
}
};
void handle_take_copy()
{
if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return;
// [RLVa:KB] - Checked: 2010-03-07 (RLVa-1.2.0c) | Modified: RLVa-1.2.0a
if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStand()) )
{
@@ -4822,16 +4865,13 @@ class LLToolsTakeCopy : public view_listener_t
LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection();
RlvSelectIsSittingOn f(gAgentAvatarp);
if ( (hSel.notNull()) && (hSel->getFirstRootNode(&f, TRUE) != NULL) )
return true;
return;
}
// [/RLVa:KB]
const LLUUID& category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id);
return true;
}
};
const LLUUID& category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id);
}
// You can return an object to its owner if it is on your land.
class LLObjectReturn : public view_listener_t
@@ -5119,6 +5159,11 @@ class LLToolsBuyOrTake : public view_listener_t
}
};
bool visible_take_object()
{
return !is_selection_buy_not_take() && enable_take();
}
class LLToolsEnableBuyOrTake : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
@@ -5755,31 +5800,42 @@ class LLEditDelete : public view_listener_t
}
};
bool enable_object_return()
{
return (!LLSelectMgr::getInstance()->getSelection()->isEmpty() &&
(gAgent.isGodlike() || can_derez(DRD_RETURN_TO_OWNER)));
}
class LLObjectEnableDelete : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
bool new_value =
#ifdef HACKED_GODLIKE_VIEWER
TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
(!LLViewerLogin::getInstance()->isInProductionGrid()
&& gAgent.isGodlike()) ||
# endif
LLSelectMgr::getInstance()->canDoDelete();
#endif
// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b)
if ( (new_value) && (rlv_handler_t::isEnabled()) )
{
new_value = rlvCanDeleteOrReturn();
}
// [/RLVa:KB]
gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
gMenuHolder->findControl(userdata["control"].asString())->setValue(enable_object_delete());
return true;
}
};
bool enable_object_delete()
{
bool new_value =
#ifdef HACKED_GODLIKE_VIEWER
TRUE;
#else
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
(!LLViewerLogin::getInstance()->isInProductionGrid()
&& gAgent.isGodlike()) ||
# endif
LLSelectMgr::getInstance()->canDoDelete();
#endif
// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b)
if ( (new_value) && (rlv_handler_t::isEnabled()) )
{
new_value = rlvCanDeleteOrReturn();
}
// [/RLVa:KB]
return new_value;
}
class LLEditSearch : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
@@ -5789,6 +5845,49 @@ class LLEditSearch : public view_listener_t
}
};
class LLObjectsReturnPackage
{
public:
LLObjectsReturnPackage() : mObjectSelection(), mReturnableObjects(), mError(), mFirstRegion(NULL) {};
~LLObjectsReturnPackage()
{
mObjectSelection.clear();
mReturnableObjects.clear();
mError.clear();
mFirstRegion = NULL;
};
LLObjectSelectionHandle mObjectSelection;
LLDynamicArray<LLViewerObjectPtr> mReturnableObjects;
std::string mError;
LLViewerRegion *mFirstRegion;
};
static void return_objects(LLObjectsReturnPackage *objectsReturnPackage, const LLSD& notification, const LLSD& response)
{
if (LLNotificationsUtil::getSelectedOption(notification, response) == 0)
{
// Ignore category ID for this derez destination.
derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, objectsReturnPackage->mFirstRegion, objectsReturnPackage->mError, &objectsReturnPackage->mReturnableObjects);
}
delete objectsReturnPackage;
}
void handle_object_return()
{
if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
{
LLObjectsReturnPackage *objectsReturnPackage = new LLObjectsReturnPackage();
objectsReturnPackage->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
// Save selected objects, so that we still know what to return after the confirmation dialog resets selection.
get_derezzable_objects(DRD_RETURN_TO_OWNER, objectsReturnPackage->mError, objectsReturnPackage->mFirstRegion, &objectsReturnPackage->mReturnableObjects);
LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&return_objects, objectsReturnPackage, _1, _2));
}
}
class LLObjectDelete : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
@@ -5799,7 +5898,13 @@ class LLObjectDelete : public view_listener_t
return true;
}
// [/RLVa:KB]
handle_object_delete();
return true;
}
};
void handle_object_delete()
{
if (LLSelectMgr::getInstance())
{
LLSelectMgr::getInstance()->doDelete();
@@ -5811,9 +5916,8 @@ class LLObjectDelete : public view_listener_t
// When deleting an object we may not actually be done
// Keep selection so we know what to delete when confirmation is needed about the delete
gPieObject->hide(TRUE);
return true;
}
};
return;
}
void handle_force_delete(void*)
{
@@ -6715,6 +6819,14 @@ class LLShowFloater : public view_listener_t
{
LLFloaterOutbox::toggleInstance(LLSD());
}
else if (floater_name == "pathfinding_linksets")
{
LLFloaterPathfindingLinksets::toggleInstance(LLSD());
}
else if (floater_name == "pathfinding_characters")
{
LLFloaterPathfindingCharacters::toggleInstance(LLSD());
}
else // Simple codeless floater
{
LLFloater* floater = LLUICtrlFactory::getInstance()->getBuiltFloater(floater_name);
@@ -6801,6 +6913,14 @@ class LLFloaterVisible : public view_listener_t
{
new_value = LLFloaterOutbox::instanceVisible(LLSD());
}
else if (floater_name == "pathfinding_linksets")
{
new_value = LLFloaterPathfindingLinksets::instanceVisible(LLSD());
}
else if (floater_name == "pathfinding_characters")
{
new_value = LLFloaterPathfindingCharacters::instanceVisible(LLSD());
}
gMenuHolder->findControl(control_name)->setValue(new_value);
return true;
}
@@ -8017,8 +8137,17 @@ class LLToolsEnableTakeCopy : public view_listener_t
{
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
bool all_valid = false;
if (LLSelectMgr::getInstance())
gMenuHolder->findControl(userdata["control"].asString())->setValue(enable_object_take_copy());
return true;
}
};
bool enable_object_take_copy()
{
bool all_valid = false;
if (LLSelectMgr::getInstance())
{
if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
{
all_valid = true;
#ifndef HACKED_GODLIKE_VIEWER
@@ -8032,10 +8161,9 @@ class LLToolsEnableTakeCopy : public view_listener_t
virtual bool apply(LLViewerObject* obj)
{
// return (!obj->permCopy() || obj->isAttachment());
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g)
// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.2.0c) | Modified: RLVa-1.0.0g
return (!obj->permCopy() || obj->isAttachment()) ||
( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (gAgentAvatarp) &&
(gAgentAvatarp->getRoot() == obj) );
( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (isAgentAvatarValid()) && (gAgentAvatarp->getRoot() == obj) );
// [/RLVa:KB]
}
} func;
@@ -8045,11 +8173,10 @@ class LLToolsEnableTakeCopy : public view_listener_t
}
#endif // HACKED_GODLIKE_VIEWER
}
gMenuHolder->findControl(userdata["control"].asString())->setValue(all_valid);
return true;
}
};
return all_valid;
}
// <edit>
class LLToolsEnableAdminDelete : public view_listener_t
@@ -9695,6 +9822,11 @@ void initialize_menus()
addMenu(new LLEnablePayObject(), "EnablePayObject");
addMenu(new LLEnableEdit(), "EnableEdit");
addMenu(new LLObjectPFLinksetsSelected(), "Pathfinding.Linksets.Select");
addMenu(new LLObjectEnablePFLinksetsSelected(), "EnableSelectInPathfindingLinksets");
addMenu(new LLObjectPFCharactersSelected(), "Pathfinding.Characters.Select");
addMenu(new LLObjectEnablePFCharactersSelected(), "EnableSelectInPathfindingCharacters");
addMenu(new LLFloaterVisible(), "FloaterVisible");
addMenu(new LLSomethingSelected(), "SomethingSelected");
addMenu(new LLSomethingSelectedNoHUD(), "SomethingSelectedNoHUD");

View File

@@ -99,7 +99,18 @@ void handle_gestures(void*);
void handle_sit_down(void*);
void handle_object_build(void*);
bool visible_take_object();
bool enable_object_take_copy();
bool enable_object_return();
bool enable_object_delete();
// Buy either contents or object itself
void handle_buy();
void handle_take();
void handle_take_copy();
void handle_object_return();
void handle_object_delete();
// Can anyone take a free copy of the object?
// *TODO: Move to separate file
bool anyone_copy_selection(LLSelectNode* nodep);
@@ -121,11 +132,6 @@ bool handle_go_to();
// Export to XML or Collada
void handle_export_selected( void * );
// Pass in an empty string and this function will build a string that
// describes buyer permissions.
class LLSaleInfo;
class LLPermissions;
class LLViewerMenuHolderGL : public LLMenuHolderGL
{
public:

View File

@@ -4359,12 +4359,12 @@ void LLPipeline::renderDebug()
{
assertInitialized();
gGL.color4f(1,1,1,1);
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
gGL.setColorMask(true, false);
bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD);
if (!hud_only && !mDebugBlips.empty())
@@ -9971,3 +9971,70 @@ void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color)
mDebugBlips.push_back(blip);
}
void LLPipeline::hideObject( const LLUUID& id )
{
LLViewerObject *pVO = gObjectList.findObject( id );
if ( pVO )
{
LLDrawable *pDrawable = pVO->mDrawable;
if ( pDrawable )
{
hideDrawable( pDrawable );
}
}
}
void LLPipeline::hideDrawable( LLDrawable *pDrawable )
{
pDrawable->setState( LLDrawable::FORCE_INVISIBLE );
markRebuild( pDrawable, LLDrawable::REBUILD_ALL, TRUE );
//hide the children
LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren();
for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
iter != child_list.end(); iter++ )
{
LLViewerObject* child = *iter;
LLDrawable* drawable = child->mDrawable;
if ( drawable )
{
drawable->setState( LLDrawable::FORCE_INVISIBLE );
markRebuild( drawable, LLDrawable::REBUILD_ALL, TRUE );
}
}
}
void LLPipeline::unhideDrawable( LLDrawable *pDrawable )
{
pDrawable->clearState( LLDrawable::FORCE_INVISIBLE );
markRebuild( pDrawable, LLDrawable::REBUILD_ALL, TRUE );
//restore children
LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren();
for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
iter != child_list.end(); iter++)
{
LLViewerObject* child = *iter;
LLDrawable* drawable = child->mDrawable;
if ( drawable )
{
drawable->clearState( LLDrawable::FORCE_INVISIBLE );
markRebuild( drawable, LLDrawable::REBUILD_ALL, TRUE );
}
}
}
void LLPipeline::restoreHiddenObject( const LLUUID& id )
{
LLViewerObject *pVO = gObjectList.findObject( id );
if ( pVO )
{
LLDrawable *pDrawable = pVO->mDrawable;
if ( pDrawable )
{
unhideDrawable( pDrawable );
}
}
}

View File

@@ -397,6 +397,9 @@ public:
void addDebugBlip(const LLVector3& position, const LLColor4& color);
void hideObject( const LLUUID& id );
void restoreHiddenObject( const LLUUID& id );
private:
void unloadShaders();
void addToQuickLookup( LLDrawPool* new_poolp );
@@ -404,7 +407,8 @@ private:
BOOL updateDrawableGeom(LLDrawable* drawable, BOOL priority);
void assertInitializedDoError();
bool assertInitialized() { const bool is_init = isInit(); if (!is_init) assertInitializedDoError(); return is_init; };
void hideDrawable( LLDrawable *pDrawable );
void unhideDrawable( LLDrawable *pDrawable );
public:
enum {GPU_CLASS_MAX = 3 };

View File

@@ -223,4 +223,14 @@
<!-- Mesh upload colors -->
<MeshImportTableNormalColor value="255, 255, 255, 255"/>
<MeshImportTableHighlightColor value="51, 205, 255, 255"/>
<!-- Pathfinding colors -->
<PathfindingErrorColor value="255, 51, 51, 255" />
<PathfindingWarningColor value="255, 219, 0, 255" />
<PathfindingGoodColor value="51, 255, 51, 255" />
<PathfindingDefaultBeaconColor value="255, 0, 0, 204" />
<PathfindingDefaultBeaconTextColor value="255, 255, 255, 255" />
<PathfindingLinksetBeaconColor value="0, 0, 255, 204" />
<PathfindingCharacterBeaconColor value="255, 0, 0, 204" />
</settings>

Binary file not shown.

After

Width:  |  Height:  |  Size: 963 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,226 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
positioning="cascading"
can_close="true"
can_minimize="true"
can_resize="true"
can_tear_off="false"
height="273"
width="635"
min_height="273"
min_width="635"
layout="topleft"
name="floater_pathfinding_characters"
help_topic="floater_pathfinding_characters"
reuse_instance="true"
save_rect="false"
single_instance="true"
title="Pathfinding characters">
<string name="messaging_initial"></string>
<string name="messaging_get_inprogress">Querying for pathfinding characters ...</string>
<string name="messaging_get_error">Error detected while querying for pathfinding characters.</string>
<string name="messaging_set_inprogress"></string>
<string name="messaging_set_error"></string>
<string name="messaging_complete_none_found">No pathfinding characters.</string>
<string name="messaging_complete_available">[NUM_SELECTED] characters selected out of [NUM_TOTAL].</string>
<string name="messaging_not_enabled">This region is not enabled for pathfinding.</string>
<string name="character_cpu_time">[CPU_TIME] µs</string>
<string name="character_owner_loading">[Loading]</string>
<string name="character_owner_unknown">[Unknown]</string>
<string name="character_owner_group">[group]</string>
<panel
border="false"
bevel_style="none"
follows="left|top|right|bottom"
layout="topleft"
height="191"
mouse_opaque="false"
bottom_delta="-220"
width="635">
<scroll_list
column_padding="0"
draw_heading="true"
follows="all"
height="135"
layout="topleft"
left="18"
top_pad="10"
tab_stop="false"
multi_select="true"
name="objects_scroll_list"
width="600">
<column
label="Name"
name="name"
dynamicwidth="true" />
<column
label="Description"
name="description"
width="172" />
<column
label="Owner"
name="owner"
width="141" />
<column
label="CPU"
name="cpu_time"
width="60" />
<column
label="Altitude"
name="altitude"
width="64" />
</scroll_list>
<text
height="26"
word_wrap="true"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
length="1"
follows="left|bottom|right"
layout="topleft"
name="messaging_status"
bottom_delta="-40"
width="238">
Characters:
</text>
<button
follows="right|bottom"
height="21"
label="Refresh list"
layout="topleft"
name="refresh_objects_list"
top_pad="-29"
left_pad="0"
left_delta="238"
bottom_delta="10"
width="115"/>
<button
follows="right|bottom"
height="21"
label="Select all"
layout="topleft"
name="select_all_objects"
top_pad="-21"
left_delta="123"
bottom_delta="0"
width="115"/>
<button
follows="right|bottom"
height="21"
label="Select none"
layout="topleft"
name="select_none_objects"
top_pad="-21"
left_delta="123"
bottom_delta="0"
width="115"/>
</panel>
<view_border
bevel_style="none"
follows="left|right|bottom"
height="0"
layout="topleft"
name="horiz_separator"
top_pad="0"
left="18"
bottom_delta="10"
width="600"/>
<panel
border="false"
bevel_style="none"
follows="left|right|bottom"
layout="topleft"
left="0"
height="67"
mouse_opaque="false"
width="635">
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
text_readonly_color="LabelDisabledColor"
length="1"
follows="left|bottom|right"
layout="topleft"
name="actions_label"
left="18"
top_pad="8"
width="242">
Actions on selected characters:
</text>
<check_box
height="19"
follows="left|bottom"
label="Show beacon"
layout="topleft"
name="show_beacon"
top_pad="-16"
left_delta="242"
bottom_delta="-5"
width="150" />
<check_box
height="19"
follows="left|bottom"
label="Show physics capsule"
layout="topleft"
name="show_physics_capsule"
top_pad="-19"
left_delta="150"
bottom_delta="0"
width="150" />
<button
follows="left|bottom"
height="22"
label="Take"
layout="topleft"
name="take_objects"
top_pad="9"
left="18"
bottom_delta="-25"
width="94"/>
<button
follows="left|bottom"
height="22"
label="Take copy"
layout="topleft"
name="take_copy_objects"
top_pad="-22"
left_delta="100"
bottom_delta="0"
width="94"/>
<button
follows="left|bottom"
height="22"
label="Teleport me to it"
layout="topleft"
name="teleport_me_to_object"
tool_tip="Enabled only when one character is selected."
top_pad="-22"
left_delta="120"
bottom_delta="0"
width="159"/>
<button
follows="right|bottom"
height="22"
label="Return"
layout="topleft"
name="return_objects"
top_pad="-22"
left_delta="185"
bottom_delta="0"
width="94"/>
<button
follows="right|bottom"
height="22"
label="Delete"
layout="topleft"
name="delete_objects"
top_pad="-22"
left_delta="100"
bottom_delta="0"
width="94"/>
</panel>
</floater>

View File

@@ -0,0 +1,640 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
positioning="cascading"
can_close="true"
can_minimize="true"
can_resize="true"
height="395"
width="1075"
min_height="395"
min_width="990"
layout="topleft"
name="floater_pathfinding_linksets"
title="Pathfinding linksets">
<string name="messaging_initial"></string>
<string name="messaging_get_inprogress">Querying for pathfinding linksets ...</string>
<string name="messaging_get_error">Error detected while querying for pathfinding linksets.</string>
<string name="messaging_set_inprogress">Modifying selected pathfinding linksets ...</string>
<string name="messaging_set_error">Error detected while modifying selected pathfinding linksets.</string>
<string name="messaging_complete_none_found">No pathfinding linksets.</string>
<string name="messaging_complete_available">[NUM_SELECTED] linksets selected out of [NUM_TOTAL].</string>
<string name="messaging_not_enabled">This region is not enabled for pathfinding.</string>
<string name="linkset_terrain_name">[Terrain]</string>
<string name="linkset_terrain_description">--</string>
<string name="linkset_terrain_owner">--</string>
<string name="linkset_terrain_scripted">--</string>
<string name="linkset_terrain_land_impact">--</string>
<string name="linkset_terrain_dist_from_you">--</string>
<string name="linkset_owner_loading">[Loading]</string>
<string name="linkset_owner_unknown">[Unknown]</string>
<string name="linkset_owner_group">[group]</string>
<string name="linkset_is_scripted">Yes</string>
<string name="linkset_is_not_scripted">No</string>
<string name="linkset_is_unknown_scripted">Unknown</string>
<string name="linkset_use_walkable">Walkable</string>
<string name="linkset_use_static_obstacle">Static obstacle</string>
<string name="linkset_use_dynamic_obstacle">Movable obstacle</string>
<string name="linkset_use_material_volume">Material volume</string>
<string name="linkset_use_exclusion_volume">Exclusion volume</string>
<string name="linkset_use_dynamic_phantom">Movable phantom</string>
<string name="linkset_is_terrain">[unmodifiable]</string>
<string name="linkset_is_restricted_state">[restricted]</string>
<string name="linkset_is_non_volume_state">[concave]</string>
<string name="linkset_is_restricted_non_volume_state">[restricted,concave]</string>
<string name="linkset_choose_use">Choose linkset use...</string>
<panel
bottom="160"
border="false"
bevel_style="none"
follows="left|top|right|bottom"
layout="topleft"
height="226"
mouse_opaque="false"
width="1059">
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
length="1"
follows="left|top"
layout="topleft"
left="20"
bottom_delta="-34"
width="67">
Filter by:
</text>
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
length="1"
follows="left|top"
layout="topleft"
left_delta="67"
bottom_delta="0"
width="62">
Name
</text>
<line_editor
border_style="line"
border_thickness="1"
follows="left|top"
height="20"
layout="topleft"
left_delta="62"
top_pad="-18"
max_length_chars="255"
name="filter_by_name"
bottom_delta="-5"
width="161" />
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
length="1"
follows="left|top"
layout="topleft"
left_delta="183"
top_pad="-15"
bottom_delta="5"
width="88">
Description
</text>
<line_editor
border_style="line"
border_thickness="1"
follows="left|top"
height="20"
layout="topleft"
left_delta="88"
top_pad="-17"
max_length_chars="255"
name="filter_by_description"
bottom_delta="-5"
width="162" />
<combo_box
height="20"
layout="topleft"
follows="left|top"
name="filter_by_linkset_use"
left_delta="194"
top_pad="-20"
bottom_delta="0"
width="199">
<combo_item
name="filter_by_linkset_use_none"
value="0">
Filter by linkset use...
</combo_item>
<combo_item
name="filter_by_linkset_use_walkable"
value="1">
Walkable
</combo_item>
<combo_item
name="filter_by_linkset_use_static_obstacle"
value="2">
Static obstacle
</combo_item>
<combo_item
name="filter_by_linkset_use_dynamic_obstacle"
value="3">
Movable obstacle
</combo_item>
<combo_item
name="filter_by_linkset_use_material_volume"
value="4">
Material volume
</combo_item>
<combo_item
name="filter_by_linkset_use_exclusion_volume"
value="5">
Exclusion volume
</combo_item>
<combo_item
name="filter_by_linkset_use_dynamic_phantom"
value="6">
Movable phantom
</combo_item>
</combo_box>
<button
follows="right|top"
height="21"
label="Apply"
layout="topleft"
name="apply_filters"
top_pad="-21"
left_delta="290"
bottom_delta="0"
width="73"/>
<button
follows="right|top"
height="21"
label="Clear"
layout="topleft"
name="clear_filters"
top_pad="-21"
left_delta="81"
bottom_delta="0"
width="73"/>
<scroll_list
column_padding="0"
draw_heading="true"
follows="all"
height="135"
layout="topleft"
left="18"
bottom_delta="-150"
top_pad="15"
tab_stop="false"
multi_select="true"
name="objects_scroll_list"
width="1040">
<column
label="Name (root prim)"
name="name"
dynamicwidth="true" />
<column
label="Description (root prim)"
name="description"
width="158" />
<column
label="Owner"
name="owner"
width="141" />
<column
label="Scripted"
name="scripted"
width="65" />
<column
label="Impact"
name="land_impact"
width="60" />
<column
label="Distance"
name="dist_from_you"
width="70" />
<column
label="Linkset use"
name="linkset_use"
width="236" />
<column
label="A%"
name="a_percent"
width="44" />
<column
label="B%"
name="b_percent"
width="44" />
<column
label="C%"
name="c_percent"
width="44" />
<column
label="D%"
name="d_percent"
width="44" />
</scroll_list>
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
length="1"
follows="left|bottom|right"
layout="topleft"
name="messaging_status"
bottom_delta="-23"
width="679">
Linksets:
</text>
<button
follows="right|bottom"
height="21"
label="Refresh list"
layout="topleft"
name="refresh_objects_list"
top_pad="-16"
left_delta="685"
bottom_delta="-5"
width="115"/>
<button
follows="right|bottom"
height="21"
label="Select all"
layout="topleft"
name="select_all_objects"
top_pad="-21"
left_pad="8"
left_delta="120"
bottom_delta="0"
width="115"/>
<button
follows="right|bottom"
height="21"
label="Select none"
layout="topleft"
name="select_none_objects"
top_pad="-21"
left_pad="8"
left_delta="120"
bottom_delta="0"
width="115"/>
</panel>
<view_border
bevel_style="none"
follows="left|bottom|right"
height="0"
layout="topleft"
name="horiz_separator"
top_pad="0"
left="18"
width="1039"/>
<panel
border="false"
bevel_style="none"
follows="left|right|bottom"
layout="topleft"
left="0"
height="67"
mouse_opaque="false"
width="1010">
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
text_readonly_color="LabelDisabledColor"
length="1"
left="18"
follows="left|bottom|right"
layout="topleft"
top_pad="8"
width="580">
Actions on selected linksets (If a linkset is removed from the world, its attributes may be lost):
</text>
<check_box
height="19"
follows="left|bottom"
label="Show beacon"
layout="topleft"
name="show_beacon"
left_delta="625"
top_pad="-16"
bottom_delta="-5"
width="90" />
<button
follows="left|bottom"
height="21"
label="Take"
layout="topleft"
name="take_objects"
top_pad="9"
left="18"
bottom_delta="-29"
width="95"/>
<button
follows="left|bottom"
height="21"
label="Take copy"
layout="topleft"
name="take_copy_objects"
top_pad="-21"
left_delta="100"
bottom_delta="0"
width="95"/>
<button
follows="left|bottom"
height="21"
label="Teleport me to it"
layout="topleft"
name="teleport_me_to_object"
top_pad="-21"
left_delta="334"
bottom_delta="0"
width="160"/>
<button
follows="right|bottom"
height="21"
label="Return"
layout="topleft"
name="return_objects"
top_pad="-21"
left_delta="412"
bottom_delta="0"
width="95"/>
<button
follows="right|bottom"
height="21"
label="Delete"
layout="topleft"
name="delete_objects"
top_pad="-21"
left_delta="100"
bottom_delta="0"
width="95"/>
</panel>
<view_border
bevel_style="none"
follows="left|bottom|right"
height="0"
layout="topleft"
name="horiz_separator"
top_pad="0"
left="18"
width="1039"/>
<panel
border="false"
bevel_style="none"
follows="left|right|bottom"
layout="topleft"
left="0"
height="75"
mouse_opaque="false"
width="1010">
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
length="1"
follows="left|bottom"
layout="topleft"
left="18"
top_pad="8"
bottom_delta="-20"
width="972">
Edit attributes of selected linksets and press the button to apply changes
</text>
<combo_box
height="20"
layout="topleft"
follows="left|top"
name="edit_linkset_use"
left="18"
top_pad="17"
bottom_delta="-34"
width="199">
</combo_box>
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
text_readonly_color="LabelDisabledColor"
name="walkability_coefficients_label"
length="1"
follows="left|bottom"
layout="topleft"
left_delta="235"
top_pad="-17"
bottom_delta="4"
width="110">
Walkability:
</text>
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
text_readonly_color="LabelDisabledColor"
name="edit_a_label"
length="1"
follows="left|bottom"
layout="topleft"
left_delta="110"
bottom_delta="0"
width="18">
A
</text>
<line_editor
border_style="line"
border_thickness="1"
follows="left|bottom"
height="21"
layout="topleft"
left_delta="18"
top_pad="-19"
max_length_chars="3"
name="edit_a_value"
tool_tip="Walkability for characters of type A. Example character type is humanoid."
bottom_delta="-4"
width="45" />
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
text_readonly_color="LabelDisabledColor"
name="edit_b_label"
length="1"
follows="left|bottom"
layout="topleft"
left_delta="95"
top_pad="-15"
bottom_delta="4"
width="18">
B
</text>
<line_editor
border_style="line"
border_thickness="1"
follows="left|bottom"
height="21"
layout="topleft"
left_delta="18"
top_pad="-19"
max_length_chars="3"
name="edit_b_value"
tool_tip="Walkability for characters of type B. Example character type is creature."
bottom_delta="-4"
width="45" />
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
text_readonly_color="LabelDisabledColor"
name="edit_c_label"
length="1"
follows="left|bottom"
layout="topleft"
left_delta="95"
top_pad="-15"
bottom_delta="4"
width="18">
C
</text>
<line_editor
border_style="line"
border_thickness="1"
follows="left|bottom"
height="21"
layout="topleft"
left_delta="18"
top_pad="-19"
max_length_chars="3"
name="edit_c_value"
tool_tip="Walkability for characters of type C. Example character type is mechanical."
bottom_delta="-4"
width="45" />
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
text_readonly_color="LabelDisabledColor"
name="edit_d_label"
length="1"
follows="left|bottom"
layout="topleft"
left_delta="95"
top_pad="-15"
bottom_delta="4"
width="18">
D
</text>
<line_editor
border_style="line"
border_thickness="1"
follows="left|bottom"
height="21"
layout="topleft"
left_delta="18"
top_pad="-19"
max_length_chars="3"
name="edit_d_value"
tool_tip="Walkability for characters of type D. Example character type is other."
bottom_delta="-4"
width="45" />
<button
follows="left|bottom"
height="21"
label="Apply changes"
layout="topleft"
name="apply_edit_values"
top_pad="-21"
left_delta="95"
bottom_delta="0"
width="160"/>
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
text_readonly_color="LabelDisabledColor"
name="suggested_use_a_label"
length="1"
follows="left|bottom"
layout="topleft"
left="375"
top_pad="5"
bottom_delta="-15"
width="107">
(Humanoid)
</text>
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
text_readonly_color="LabelDisabledColor"
name="suggested_use_b_label"
length="1"
follows="left|bottom"
layout="topleft"
left_delta="112"
bottom_delta="0"
width="107">
(Creature)
</text>
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
text_readonly_color="LabelDisabledColor"
name="suggested_use_c_label"
length="1"
follows="left|bottom"
layout="topleft"
left_delta="112"
bottom_delta="0"
width="107">
(Mechanical)
</text>
<text
height="13"
word_wrap="false"
use_ellipses="false"
type="string"
text_color="LabelTextColor"
text_readonly_color="LabelDisabledColor"
name="suggested_use_d_label"
length="1"
follows="left|bottom"
layout="topleft"
left_delta="112"
bottom_delta="0"
width="107">
(Other)
</text>
</panel>
</floater>

View File

@@ -93,6 +93,16 @@
<on_click function="Object.ReportAbuse" />
<on_enable function="Object.EnableReportAbuse" />
</menu_item_call>
<pie_menu label="Pathfinding &gt;" name="PF Menu">
<menu_item_call label="Show in linksets" name="show_in_linksets">
<on_click function="Pathfinding.Linksets.Select" />
<on_enable function="EnableSelectInPathfindingLinksets"/>
</menu_item_call>
<menu_item_call label="Show in characters" name="show_in_characters">
<on_click function="Pathfinding.Characters.Select" />
<on_enable function="EnableSelectInPathfindingCharacters"/>
</menu_item_call>
</pie_menu>
</pie_menu>
<menu_item_call enabled="false" label="Buy..." mouse_opaque="true" name="Buy...">
<on_click function="Object.Buy" />

View File

@@ -856,13 +856,25 @@
<on_click function="Tools.ScriptDelete" />
<on_enable function="Tools.EnableScriptDelete" />
</menu_item_call>
<menu_item_call bottom="-525" enabled="false" height="19"
<menu create_jump_keys="true" label="Pathfinding" name="Pathfinding" opaque="true" tear_off="true">
<menu_item_check label="Linksets..." name="pathfinding_linksets_menu_item">
<on_click function="ShowFloater" userdata="pathfinding_linksets"/>
<on_check function="FloaterVisible" userdata="pathfinding_linksets"/>
<on_enable function="Tools.EnablePathfinding"/>
</menu_item_check>
<menu_item_check label="Characters..." name="pathfinding_characters_menu_item">
<on_click function="ShowFloater" userdata="pathfinding_characters"/>
<on_check function="FloaterVisible" userdata="pathfinding_characters"/>
<on_enable function="Tools.EnablePathfinding"/>
</menu_item_check>
<menu_item_call bottom="-525" enabled="false" height="19"
label="Rebake region" left="0"
mouse_opaque="true" name="pathfinding_rebake_navmesh_item"
width="250">
<on_click function="Tools.DoPathfindingRebakeRegion" />
<on_enable function="Tools.EnablePathfindingRebakeRegion" />
</menu_item_call>
<on_click function="Tools.DoPathfindingRebakeRegion" />
<on_enable function="Tools.EnablePathfindingRebakeRegion" />
</menu_item_call>
</menu>
</menu>
<menu bottom="219" create_jump_keys="true" drop_shadow="true" enabled="true"
height="317" label="Help" left="227" mouse_opaque="false" name="Help"

View File

@@ -6306,11 +6306,15 @@ You cannot create objects here.
</notification>
<notification
icon="notify.tga"
icon="alert.tga"
name="PathfindingDirty"
type="notify">
type="alert">
<unique/>
The region has pending pathfinding changes. If you have build rights, you may rebake the region by clicking on the “Rebake region” button.
The region has pending pathfinding changes. If you have build rights, you may rebake the region by clicking “Rebake”.
<usetemplate
name="okcancelbuttons"
yestext="Rebake"
notext="Close" />
</notification>
<notification
@@ -6321,26 +6325,6 @@ You cannot create objects here.
Dynamic pathfinding is not enabled on this region. Scripted objects using pathfinding LSL calls may not operate as expected on this region.
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingRebakeNavmesh"
type="alertmodal">
<unique/>
Changing certain objects in this region could cause other moving objects to behave incorrectly. To make moving objects behave correctly, click the “Rebake region” button. Choose “Help” for more information.
<url
option="1"
name="url"
target = "_external">
http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
</url>
<usetemplate
name="okhelpignore"
ignoretext="Changing certain objects in this region could cause other moving objects to behave incorrectly."
yestext="OK"
helptext="Help"
/>
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingCannotRebakeNavmesh"
@@ -7504,19 +7488,6 @@ You uploaded a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] second
You locally updated a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds.
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingLinksets_ChangeToFlexiblePath"
type="alertmodal">
The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh.
<tag>confirm</tag>
<usetemplate
ignoretext="The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh."
name="okcancelignore"
notext="Cancel"
yestext="OK"/>
</notification>
<notification
icon="notify.tga"
name="FirstAO"
@@ -7646,6 +7617,134 @@ Only textures will upload as temporary on Agni and Aditi.
canceltext="Cancel"/>
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingLinksets_WarnOnPhantom"
type="alertmodal">
Some selected linksets will have the Phantom flag toggled.
Do you wish to continue?
<tag>confirm</tag>
<usetemplate
ignoretext="Some selected linksets phantom flag will be toggled."
name="okcancelignore"
notext="Cancel"
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingLinksets_MismatchOnRestricted"
type="alertmodal">
Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead.
Do you wish to continue?
<tag>confirm</tag>
<usetemplate
ignoretext="Some selected linksets cannot be set because of permission restrictions on the linkset."
name="okcancelignore"
notext="Cancel"
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingLinksets_MismatchOnVolume"
type="alertmodal">
Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because the shape is non-convex.
Do you wish to continue?
<tag>confirm</tag>
<usetemplate
ignoretext="Some selected linksets cannot be set because the shape is non-convex"
name="okcancelignore"
notext="Cancel"
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted"
type="alertmodal">
Some selected linksets will have the Phantom flag toggled.
Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead.
Do you wish to continue?
<tag>confirm</tag>
<usetemplate
ignoretext="Some selected linksets phantom flag will be toggled and others cannot be set because of permission restrictions on the linkset."
name="okcancelignore"
notext="Cancel"
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingLinksets_WarnOnPhantom_MismatchOnVolume"
type="alertmodal">
Some selected linksets will have the Phantom flag toggled.
Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because the shape is non-convex.
Do you wish to continue?
<tag>confirm</tag>
<usetemplate
ignoretext="Some selected linksets phantom flag will be toggled and others cannot be set because the shape is non-convex"
name="okcancelignore"
notext="Cancel"
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingLinksets_MismatchOnRestricted_MismatchOnVolume"
type="alertmodal">
Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead.
Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because the shape is non-convex. These linksets&apos; use types will not change.
Do you wish to continue?
<tag>confirm</tag>
<usetemplate
ignoretext="Some selected linksets cannot be set because of permission restrictions on the linkset and because the shape is non-convex."
name="okcancelignore"
notext="Cancel"
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingLinksets_WarnOnPhantom_MismatchOnRestricted_MismatchOnVolume"
type="alertmodal">
Some selected linksets will have the Phantom flag toggled.
Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because of permission restrictions on the linkset. These linksets will be set to be '[RESTRICTED_TYPE]' instead.
Some selected linksets cannot be set to be '[REQUESTED_TYPE]' because the shape is non-convex. These linksets&apos; use types will not change.
Do you wish to continue?
<tag>confirm</tag>
<usetemplate
ignoretext="Some selected linksets phantom flag will be toggled and others cannot be set because of permission restrictions on the linkset and because the shape is non-convex."
name="okcancelignore"
notext="Cancel"
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="PathfindingLinksets_ChangeToFlexiblePath"
type="alertmodal">
The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh.
<tag>confirm</tag>
<usetemplate
ignoretext="The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh."
name="okcancelignore"
notext="Cancel"
yestext="OK"/>
</notification>
<global name="UnsupportedGLRequirements">
You do not appear to have the proper hardware requirements for [APP_NAME]. The viewer requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system.
</global>

View File

@@ -86,6 +86,12 @@
image_unselected="status_SeeAVsOff.tga" label="" label_selected=""
left="600" mouse_opaque="true" name="status_SeeAV" scale_image="false"
tool_tip="Parcel has Avatar privacy" visible="false" width="24" />
<button bottom="-17" follows="right|bottom" height="16" label="" width="24" left="624" mouse_opaque="true"
image_unselected="Pathfinding_Dirty.png" image_selected="Pathfinding_Dirty.png" scale_image="false"
name="pf_dirty" tool_tip="Objects that move may not behave correctly in this region until the region is rebaked."/>
<button bottom="-17" follows="right|bottom" height="16" label="" width="24" left="624" mouse_opaque="true"
image_unselected="Pathfinding_Disabled.png" image_selected="Pathfinding_Disabled.png" scale_image="false"
name="pf_disabled" tool_tip="Dynamic pathfinding is not enabled on this region."/>
<button bottom="-17" enabled="true" follows="right|bottom" font="SansSerif"
halign="center" height="16" image_selected="status_buy_land_pressed.tga"
image_unselected="status_buy_land.tga" label="" label_selected=""