123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 |
- /**
- * @file llpathfindinglinkset.cpp
- * @brief Definition of a pathfinding linkset that contains various properties required for havok pathfinding.
- *
- * $LicenseInfo:firstyear=2012&license=viewergpl$
- *
- * Copyright (c) 2012, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "llviewerprecompiledheaders.h"
- #include "llpathfindinglinkset.h"
- #include "llsd.h"
- #define LINKSET_LAND_IMPACT_FIELD "landimpact"
- #define LINKSET_MODIFIABLE_FIELD "modifiable"
- #define LINKSET_CATEGORY_FIELD "navmesh_category"
- #define LINKSET_CAN_BE_VOLUME "can_be_volume"
- #define LINKSET_IS_SCRIPTED_FIELD "is_scripted"
- #define LINKSET_PHANTOM_FIELD "phantom"
- #define LINKSET_WALKABILITY_A_FIELD "A"
- #define LINKSET_WALKABILITY_B_FIELD "B"
- #define LINKSET_WALKABILITY_C_FIELD "C"
- #define LINKSET_WALKABILITY_D_FIELD "D"
- #define LINKSET_CATEGORY_VALUE_INCLUDE 0
- #define LINKSET_CATEGORY_VALUE_EXCLUDE 1
- #define LINKSET_CATEGORY_VALUE_IGNORE 2
- LLPathfindingLinkset::LLPathfindingLinkset(const LLSD& terrain_data)
- : LLPathfindingObject(),
- mIsTerrain(true),
- mLandImpact(0U),
- mIsModifiable(false),
- mCanBeVolume(false),
- mIsScripted(false),
- mHasIsScripted(true),
- mLinksetUse(kUnknown),
- mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE),
- mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE),
- mWalkabilityCoefficientC(MIN_WALKABILITY_VALUE),
- mWalkabilityCoefficientD(MIN_WALKABILITY_VALUE)
- {
- parsePathfindingData(terrain_data);
- }
- LLPathfindingLinkset::LLPathfindingLinkset(const LLUUID& id, const LLSD& data)
- : LLPathfindingObject(id, data),
- mIsTerrain(false),
- mLandImpact(0U),
- mIsModifiable(true),
- mCanBeVolume(true),
- mIsScripted(false),
- mHasIsScripted(false),
- mLinksetUse(kUnknown),
- mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE),
- mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE),
- mWalkabilityCoefficientC(MIN_WALKABILITY_VALUE),
- mWalkabilityCoefficientD(MIN_WALKABILITY_VALUE)
- {
- parseLinksetData(data);
- parsePathfindingData(data);
- }
- LLPathfindingLinkset::LLPathfindingLinkset(const LLPathfindingLinkset& obj)
- : LLPathfindingObject(obj),
- mIsTerrain(obj.mIsTerrain),
- mLandImpact(obj.mLandImpact),
- mIsModifiable(obj.mIsModifiable),
- mCanBeVolume(obj.mCanBeVolume),
- mIsScripted(obj.mIsScripted),
- mHasIsScripted(obj.mHasIsScripted),
- mLinksetUse(obj.mLinksetUse),
- mWalkabilityCoefficientA(obj.mWalkabilityCoefficientA),
- mWalkabilityCoefficientB(obj.mWalkabilityCoefficientB),
- mWalkabilityCoefficientC(obj.mWalkabilityCoefficientC),
- mWalkabilityCoefficientD(obj.mWalkabilityCoefficientD)
- {
- }
- LLPathfindingLinkset& LLPathfindingLinkset::operator=(const LLPathfindingLinkset& obj)
- {
- dynamic_cast<LLPathfindingObject&>(*this) = obj;
- mIsTerrain = obj.mIsTerrain;
- mLandImpact = obj.mLandImpact;
- mIsModifiable = obj.mIsModifiable;
- mCanBeVolume = obj.mCanBeVolume;
- mIsScripted = obj.mIsScripted;
- mHasIsScripted = obj.mHasIsScripted;
- mLinksetUse = obj.mLinksetUse;
- mWalkabilityCoefficientA = obj.mWalkabilityCoefficientA;
- mWalkabilityCoefficientB = obj.mWalkabilityCoefficientB;
- mWalkabilityCoefficientC = obj.mWalkabilityCoefficientC;
- mWalkabilityCoefficientD = obj.mWalkabilityCoefficientD;
- return *this;
- }
- bool LLPathfindingLinkset::isPhantom() const
- {
- return isPhantom(getLinksetUse());
- }
- LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUseWithToggledPhantom(ELinksetUse use)
- {
- bool phantom = isPhantom(use);
- ENavMeshGenerationCategory category = getNavMeshGenerationCategory(use);
- return getLinksetUse(!phantom, category);
- }
- bool LLPathfindingLinkset::showUnmodifiablePhantomWarning(ELinksetUse use) const
- {
- return !isModifiable() && isPhantom() != isPhantom(use);
- }
- bool LLPathfindingLinkset::showPhantomToggleWarning(ELinksetUse use) const
- {
- return isModifiable() && isPhantom() != isPhantom(use);
- }
- bool LLPathfindingLinkset::showCannotBeVolumeWarning(ELinksetUse use) const
- {
- return !canBeVolume() &&
- (use == kMaterialVolume || use == kExclusionVolume);
- }
- LLSD LLPathfindingLinkset::encodeAlteredFields(ELinksetUse use, S32 a, S32 b,
- S32 c, S32 d) const
- {
- LLSD data;
- if (!isTerrain() && use != kUnknown && getLinksetUse() != use &&
- (canBeVolume() || (use != kMaterialVolume && use != kExclusionVolume)))
- {
- if (isModifiable())
- {
- data[LINKSET_PHANTOM_FIELD] = isPhantom(use);
- }
- data[LINKSET_CATEGORY_FIELD] =
- convertCategoryToLLSD(getNavMeshGenerationCategory(use));
- }
- if (mWalkabilityCoefficientA != a)
- {
- data[LINKSET_WALKABILITY_A_FIELD] = llclamp(a, MIN_WALKABILITY_VALUE,
- MAX_WALKABILITY_VALUE);
- }
- if (mWalkabilityCoefficientB != b)
- {
- data[LINKSET_WALKABILITY_B_FIELD] = llclamp(b, MIN_WALKABILITY_VALUE,
- MAX_WALKABILITY_VALUE);
- }
- if (mWalkabilityCoefficientC != c)
- {
- data[LINKSET_WALKABILITY_C_FIELD] = llclamp(c, MIN_WALKABILITY_VALUE,
- MAX_WALKABILITY_VALUE);
- }
- if (mWalkabilityCoefficientD != d)
- {
- data[LINKSET_WALKABILITY_D_FIELD] = llclamp(d, MIN_WALKABILITY_VALUE,
- MAX_WALKABILITY_VALUE);
- }
- return data;
- }
- void LLPathfindingLinkset::parseLinksetData(const LLSD& data)
- {
- if (data.has(LINKSET_LAND_IMPACT_FIELD) &&
- data.get(LINKSET_LAND_IMPACT_FIELD).isInteger() &&
- data.get(LINKSET_LAND_IMPACT_FIELD).asInteger() >= 0)
- {
- mLandImpact = data.get(LINKSET_LAND_IMPACT_FIELD).asInteger();
- }
- else
- {
- llwarns << "Malformed pathfinding linkset data: no land impact"
- << llendl;
- }
- if (data.has(LINKSET_MODIFIABLE_FIELD) &&
- data.get(LINKSET_MODIFIABLE_FIELD).isBoolean())
- {
- mIsModifiable = data.get(LINKSET_MODIFIABLE_FIELD).asBoolean();
- }
- else
- {
- llwarns << "Malformed pathfinding linkset data: missing modify flag"
- << llendl;
- }
- mHasIsScripted = data.has(LINKSET_IS_SCRIPTED_FIELD);
- if (mHasIsScripted)
- {
- if (data.get(LINKSET_IS_SCRIPTED_FIELD).isBoolean())
- {
- mIsScripted = data.get(LINKSET_IS_SCRIPTED_FIELD).asBoolean();
- }
- else
- {
- llwarns << "Malformed pathfinding linkset data: bad scripted flag"
- << llendl;
- }
- }
- }
- void LLPathfindingLinkset::parsePathfindingData(const LLSD& data)
- {
- bool phantom = false;
- if (data.has(LINKSET_PHANTOM_FIELD))
- {
- if (data.get(LINKSET_PHANTOM_FIELD).isBoolean())
- {
- phantom = data.get(LINKSET_PHANTOM_FIELD).asBoolean();
- }
- else
- {
- llwarns << "Malformed pathfinding terrain data: invalid phantom flag"
- << llendl;
- }
- }
- if (data.has(LINKSET_CATEGORY_FIELD))
- {
- mLinksetUse =
- getLinksetUse(phantom,
- convertCategoryFromLLSD(data.get(LINKSET_CATEGORY_FIELD)));
- }
- else
- {
- llwarns << "Malformed pathfinding terrain data: missing category"
- << llendl;
- }
- if (data.has(LINKSET_CAN_BE_VOLUME))
- {
- if (data.get(LINKSET_CAN_BE_VOLUME).isBoolean())
- {
- mCanBeVolume = data.get(LINKSET_CAN_BE_VOLUME).asBoolean();
- }
- else
- {
- llwarns << "Malformed pathfinding terrain data: invalid volume flag"
- << llendl;
- }
- }
- if (data.has(LINKSET_WALKABILITY_A_FIELD) &&
- data.get(LINKSET_WALKABILITY_A_FIELD).isInteger())
- {
- mWalkabilityCoefficientA =
- data.get(LINKSET_WALKABILITY_A_FIELD).asInteger();
- if (mWalkabilityCoefficientA < MIN_WALKABILITY_VALUE)
- {
- llwarns << "Malformed pathfinding terrain data: Bad walkability A value (too low). Clamping to "
- << MIN_WALKABILITY_VALUE << llendl;
- mWalkabilityCoefficientA = MIN_WALKABILITY_VALUE;
- }
- if (mWalkabilityCoefficientA > MAX_WALKABILITY_VALUE)
- {
- llwarns << "Malformed pathfinding terrain data: Bad walkability A value (too high). Clamping to "
- << MAX_WALKABILITY_VALUE << llendl;
- mWalkabilityCoefficientA = MAX_WALKABILITY_VALUE;
- }
- }
- else
- {
- llwarns << "Malformed pathfinding terrain data: missing walkability A"
- << llendl;
- }
- if (data.has(LINKSET_WALKABILITY_B_FIELD) &&
- data.get(LINKSET_WALKABILITY_B_FIELD).isInteger())
- {
- mWalkabilityCoefficientB =
- data.get(LINKSET_WALKABILITY_B_FIELD).asInteger();
- if (mWalkabilityCoefficientB < MIN_WALKABILITY_VALUE)
- {
- llwarns << "Malformed pathfinding terrain data: Bad walkability B value (too low). Clamping to "
- << MIN_WALKABILITY_VALUE << llendl;
- mWalkabilityCoefficientB = MIN_WALKABILITY_VALUE;
- }
- if (mWalkabilityCoefficientB > MAX_WALKABILITY_VALUE)
- {
- llwarns << "Malformed pathfinding terrain data: Bad walkability B value (too high). Clamping to "
- << MAX_WALKABILITY_VALUE << llendl;
- mWalkabilityCoefficientB = MAX_WALKABILITY_VALUE;
- }
- }
- else
- {
- llwarns << "Malformed pathfinding terrain data: missing walkability B"
- << llendl;
- }
- if (data.has(LINKSET_WALKABILITY_C_FIELD) &&
- data.get(LINKSET_WALKABILITY_C_FIELD).isInteger())
- {
- mWalkabilityCoefficientC =
- data.get(LINKSET_WALKABILITY_C_FIELD).asInteger();
- if (mWalkabilityCoefficientC < MIN_WALKABILITY_VALUE)
- {
- llwarns << "Malformed pathfinding terrain data: Bad walkability C value (too low). Clamping to "
- << MIN_WALKABILITY_VALUE << llendl;
- mWalkabilityCoefficientC = MIN_WALKABILITY_VALUE;
- }
- if (mWalkabilityCoefficientC > MAX_WALKABILITY_VALUE)
- {
- llwarns << "Malformed pathfinding terrain data: Bad walkability C value (too high). Clamping to "
- << MAX_WALKABILITY_VALUE << llendl;
- mWalkabilityCoefficientC = MAX_WALKABILITY_VALUE;
- }
- }
- else
- {
- llwarns << "Malformed pathfinding terrain data: missing walkability C"
- << llendl;
- }
- if (data.has(LINKSET_WALKABILITY_D_FIELD) &&
- data.get(LINKSET_WALKABILITY_D_FIELD).isInteger())
- {
- mWalkabilityCoefficientD =
- data.get(LINKSET_WALKABILITY_D_FIELD).asInteger();
- if (mWalkabilityCoefficientD < MIN_WALKABILITY_VALUE)
- {
- llwarns << "Malformed pathfinding terrain data: Bad walkability D value (too low). Clamping to "
- << MIN_WALKABILITY_VALUE << llendl;
- mWalkabilityCoefficientD = MIN_WALKABILITY_VALUE;
- }
- if (mWalkabilityCoefficientD > MAX_WALKABILITY_VALUE)
- {
- llwarns << "Malformed pathfinding terrain data: Bad walkability D value (too high). Clamping to "
- << MAX_WALKABILITY_VALUE << llendl;
- mWalkabilityCoefficientD = MAX_WALKABILITY_VALUE;
- }
- }
- else
- {
- llwarns << "Malformed pathfinding terrain data: missing walkability D"
- << llendl;
- }
- }
- bool LLPathfindingLinkset::isPhantom(ELinksetUse use)
- {
- switch (use)
- {
- case kWalkable:
- case kStaticObstacle:
- case kDynamicObstacle:
- return false;
- case kMaterialVolume:
- case kExclusionVolume:
- case kDynamicPhantom:
- return true;
- default:
- llassert(false);
- return false;
- }
- }
- LLPathfindingLinkset::ELinksetUse LLPathfindingLinkset::getLinksetUse(bool phantom,
- ENavMeshGenerationCategory category)
- {
- if (phantom)
- {
- switch (category)
- {
- case kNavMeshGenerationIgnore:
- return kDynamicPhantom;
- case kNavMeshGenerationInclude:
- return kMaterialVolume;
- case kNavMeshGenerationExclude:
- return kExclusionVolume;
- default:
- llassert(false);
- return kUnknown;
- }
- }
- switch (category)
- {
- case kNavMeshGenerationIgnore:
- return kDynamicObstacle;
- case kNavMeshGenerationInclude:
- return kWalkable;
- case kNavMeshGenerationExclude:
- return kStaticObstacle;
- default:
- llassert(false);
- return kUnknown;
- }
- }
- LLPathfindingLinkset::ENavMeshGenerationCategory LLPathfindingLinkset::getNavMeshGenerationCategory(ELinksetUse use)
- {
- switch (use)
- {
- case kWalkable:
- case kMaterialVolume:
- return kNavMeshGenerationInclude;
- case kStaticObstacle:
- case kExclusionVolume:
- return kNavMeshGenerationExclude;
- case kDynamicObstacle:
- case kDynamicPhantom:
- return kNavMeshGenerationIgnore;
- default:
- llassert(false);
- return kNavMeshGenerationIgnore;
- }
- }
- LLSD LLPathfindingLinkset::convertCategoryToLLSD(ENavMeshGenerationCategory category)
- {
- switch (category)
- {
- case kNavMeshGenerationIgnore:
- return LLSD(LINKSET_CATEGORY_VALUE_IGNORE);
- case kNavMeshGenerationInclude:
- return LLSD(LINKSET_CATEGORY_VALUE_INCLUDE);
- case kNavMeshGenerationExclude:
- return LLSD(LINKSET_CATEGORY_VALUE_EXCLUDE);
- default:
- llassert(false);
- return LLSD(LINKSET_CATEGORY_VALUE_IGNORE);
- }
- }
- LLPathfindingLinkset::ENavMeshGenerationCategory LLPathfindingLinkset::convertCategoryFromLLSD(const LLSD& data)
- {
- if (!data.isInteger())
- {
- llassert(false);
- return kNavMeshGenerationIgnore;
- }
- switch (data.asInteger())
- {
- case LINKSET_CATEGORY_VALUE_IGNORE:
- return kNavMeshGenerationIgnore;
- case LINKSET_CATEGORY_VALUE_INCLUDE:
- return kNavMeshGenerationInclude;
- case LINKSET_CATEGORY_VALUE_EXCLUDE:
- return kNavMeshGenerationExclude;
- default:
- llassert(false);
- return kNavMeshGenerationIgnore;
- }
- }
|