1624 lines
73 KiB
C++
1624 lines
73 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_4
|
|
#include "CoreMinimal.h"
|
|
#endif
|
|
#include "UObject/ObjectMacros.h"
|
|
#include "Templates/SubclassOf.h"
|
|
#include "EngineDefines.h"
|
|
#include "LinkGenerationConfig.h"
|
|
#include "AI/Navigation/NavigationTypes.h"
|
|
#include "AI/Navigation/NavigationDataResolution.h"
|
|
#include "NavigationSystemTypes.h"
|
|
#include "NavigationData.h"
|
|
#include "NavMesh/NavMeshPath.h"
|
|
#include "RecastNavMesh.generated.h"
|
|
|
|
#define RECAST_MAX_SEARCH_NODES 2048
|
|
|
|
#define RECAST_MIN_TILE_SIZE 300.f
|
|
|
|
#define RECAST_MAX_AREAS 64
|
|
#define RECAST_DEFAULT_AREA (RECAST_MAX_AREAS - 1)
|
|
#define RECAST_LOW_AREA (RECAST_MAX_AREAS - 2)
|
|
#define RECAST_NULL_AREA 0
|
|
// Note poly costs are still floats in UE so we are using FLT_MAX as unwalkable still.
|
|
// Path CostLimit and Distance are based on FVector::FReal.
|
|
#define RECAST_UNWALKABLE_POLY_COST FLT_MAX
|
|
|
|
// If set, recast will use async workers for rebuilding tiles in runtime
|
|
// All access to tile data must be guarded with critical sections
|
|
#ifndef RECAST_ASYNC_REBUILDING
|
|
#define RECAST_ASYNC_REBUILDING 1
|
|
#endif
|
|
|
|
//If set we will time slice the nav regen if RECAST_ASYNC_REBUILDING is 0
|
|
#ifndef ALLOW_TIME_SLICE_NAV_REGEN
|
|
#define ALLOW_TIME_SLICE_NAV_REGEN 0
|
|
#endif
|
|
|
|
//TIME_SLICE_NAV_REGEN must be 0 if we are async rebuilding recast
|
|
#define TIME_SLICE_NAV_REGEN (ALLOW_TIME_SLICE_NAV_REGEN && !RECAST_ASYNC_REBUILDING)
|
|
|
|
// LWC_TODO_AI Note we are using int32 here for X and Y which does mean that we could overflow the limit of an int for LWCoords
|
|
// unless fairly large tile sizes are used.As WORLD_MAX is currently in flux until we have a better idea of what we are
|
|
// going to be able to support its probably not worth investing time in this potential issue right now.
|
|
|
|
class FPImplRecastNavMesh;
|
|
class FRecastQueryFilter;
|
|
class INavLinkCustomInterface;
|
|
class UCanvas;
|
|
class UNavArea;
|
|
class UNavigationDataChunk;
|
|
class UPrimitiveComponent;
|
|
class URecastNavMeshDataChunk;
|
|
class ARecastNavMesh;
|
|
struct FRecastAreaNavModifierElement;
|
|
class dtNavMesh;
|
|
class dtQueryFilter;
|
|
class FRecastNavMeshGenerator;
|
|
struct dtMeshTile;
|
|
class UNavigationSystemV1;
|
|
class UNavigationSystemBase;
|
|
|
|
UENUM()
|
|
namespace ERecastPartitioning
|
|
{
|
|
// keep in sync with rcRegionPartitioning enum!
|
|
|
|
enum Type : int
|
|
{
|
|
Monotone,
|
|
Watershed,
|
|
ChunkyMonotone,
|
|
};
|
|
}
|
|
|
|
UENUM()
|
|
enum class ENavigationLedgeSlopeFilterMode : uint8
|
|
{
|
|
Recast, // Use walkableClimb value to filter
|
|
None, // Skip slope filtering
|
|
UseStepHeightFromAgentMaxSlope // Use maximum step height computed from AgentMaxSlope
|
|
};
|
|
|
|
struct FDetourTileSizeInfo
|
|
{
|
|
unsigned short VertCount = 0;
|
|
unsigned short PolyCount = 0;
|
|
unsigned short MaxLinkCount = 0;
|
|
unsigned short DetailMeshCount = 0;
|
|
unsigned short DetailVertCount = 0;
|
|
unsigned short DetailTriCount = 0;
|
|
unsigned short BvNodeCount = 0;
|
|
unsigned short OffMeshConCount = 0;
|
|
unsigned short OffMeshSegConCount = 0;
|
|
unsigned short ClusterCount = 0;
|
|
unsigned short OffMeshBase = 0;
|
|
};
|
|
|
|
struct FDetourTileLayout
|
|
{
|
|
NAVIGATIONSYSTEM_API FDetourTileLayout(const dtMeshTile& tile);
|
|
NAVIGATIONSYSTEM_API FDetourTileLayout(const FDetourTileSizeInfo& SizeInfo);
|
|
|
|
private:
|
|
void InitFromSizeInfo(const FDetourTileSizeInfo& SizeInfo);
|
|
|
|
public:
|
|
int32 HeaderSize = 0;
|
|
int32 VertsSize = 0;
|
|
int32 PolysSize = 0;
|
|
int32 LinksSize = 0;
|
|
int32 DetailMeshesSize = 0;
|
|
int32 DetailVertsSize = 0;
|
|
int32 DetailTrisSize = 0;
|
|
int32 BvTreeSize = 0;
|
|
int32 OffMeshConsSize = 0;
|
|
int32 OffMeshSegsSize = 0;
|
|
int32 ClustersSize = 0;
|
|
int32 PolyClustersSize = 0;
|
|
int32 TileSize = 0;
|
|
};
|
|
|
|
namespace ERecastPathFlags
|
|
{
|
|
/** If set, path won't be post processed. */
|
|
inline const int32 SkipStringPulling = (1 << 0);
|
|
|
|
/** If set, path will contain navigation corridor. */
|
|
inline const int32 GenerateCorridor = (1 << 1);
|
|
|
|
/** Make your game-specific flags start at this index */
|
|
inline const uint8 FirstAvailableFlag = 2;
|
|
}
|
|
|
|
#if WITH_RECAST
|
|
struct FRecastDebugPathfindingNode
|
|
{
|
|
NavNodeRef PolyRef;
|
|
NavNodeRef ParentRef;
|
|
FVector::FReal Cost = 0.;
|
|
FVector::FReal TotalCost = 0.;
|
|
FVector::FReal Length = 0.;
|
|
|
|
FVector NodePos;
|
|
TArray<FVector3f, TInlineAllocator<6> > Verts; // LWC_TODO: Precision loss. Issue here is regarding debug rendering needing to work with FVector3f.
|
|
uint8 NumVerts;
|
|
|
|
uint8 bOpenSet : 1;
|
|
uint8 bOffMeshLink : 1;
|
|
uint8 bModified : 1;
|
|
|
|
FRecastDebugPathfindingNode() : PolyRef(0), ParentRef(0), NumVerts(0), bOpenSet(0), bOffMeshLink(0), bModified(0) {}
|
|
FRecastDebugPathfindingNode(NavNodeRef InPolyRef) : PolyRef(InPolyRef), ParentRef(0), NumVerts(0), bOpenSet(0), bOffMeshLink(0), bModified(0) {}
|
|
|
|
FORCEINLINE bool operator==(const NavNodeRef& OtherPolyRef) const { return PolyRef == OtherPolyRef; }
|
|
FORCEINLINE bool operator==(const FRecastDebugPathfindingNode& Other) const { return PolyRef == Other.PolyRef; }
|
|
FORCEINLINE friend uint32 GetTypeHash(const FRecastDebugPathfindingNode& Other) { return GetTypeHash(Other.PolyRef); }
|
|
|
|
FORCEINLINE FVector::FReal GetHeuristicCost() const { return TotalCost - Cost; }
|
|
};
|
|
|
|
namespace ERecastDebugPathfindingFlags
|
|
{
|
|
enum Type : uint8
|
|
{
|
|
Basic = 0x0,
|
|
BestNode = 0x1,
|
|
Vertices = 0x2,
|
|
PathLength = 0x4
|
|
};
|
|
}
|
|
|
|
struct FRecastDebugPathfindingData
|
|
{
|
|
TSet<FRecastDebugPathfindingNode> Nodes;
|
|
FSetElementId BestNode;
|
|
uint8 Flags;
|
|
|
|
FRecastDebugPathfindingData() : Flags(ERecastDebugPathfindingFlags::Basic) {}
|
|
FRecastDebugPathfindingData(ERecastDebugPathfindingFlags::Type InFlags) : Flags(InFlags) {}
|
|
};
|
|
|
|
struct FRecastDebugGeometry
|
|
{
|
|
enum EOffMeshLinkEnd
|
|
{
|
|
OMLE_None = 0x0,
|
|
OMLE_Left = 0x1,
|
|
OMLE_Right = 0x2,
|
|
OMLE_Both = OMLE_Left | OMLE_Right
|
|
};
|
|
|
|
struct FOffMeshLink
|
|
{
|
|
FVector Left;
|
|
FVector Right;
|
|
uint8 AreaID;
|
|
uint8 Direction;
|
|
uint8 ValidEnds;
|
|
bool bIsGenerated;
|
|
float Radius;
|
|
float Height;
|
|
FColor Color;
|
|
};
|
|
|
|
#if WITH_NAVMESH_CLUSTER_LINKS
|
|
struct FCluster
|
|
{
|
|
TArray<int32> MeshIndices;
|
|
};
|
|
|
|
struct FClusterLink
|
|
{
|
|
FVector FromCluster;
|
|
FVector ToCluster;
|
|
};
|
|
#endif // WITH_NAVMESH_CLUSTER_LINKS
|
|
|
|
// This is an unsupported feature and has not been finished to production quality.
|
|
#if WITH_NAVMESH_SEGMENT_LINKS
|
|
struct FOffMeshSegment
|
|
{
|
|
FVector LeftStart, LeftEnd;
|
|
FVector RightStart, RightEnd;
|
|
uint8 AreaID;
|
|
uint8 Direction;
|
|
uint8 ValidEnds;
|
|
};
|
|
#endif // WITH_NAVMESH_SEGMENT_LINKS
|
|
|
|
static constexpr int32 BuildTimeBucketsCount = 5;
|
|
|
|
TArray<FVector> MeshVerts;
|
|
|
|
TArray<int32> AreaIndices[RECAST_MAX_AREAS];
|
|
TArray<int32> ForbiddenIndices;
|
|
TArray<int32> BuiltMeshIndices;
|
|
TArray<int32> TileBuildTimesIndices[BuildTimeBucketsCount];
|
|
|
|
TArray<FVector> PolyEdges;
|
|
TArray<FVector> NavMeshEdges;
|
|
TArray<FOffMeshLink> OffMeshLinks;
|
|
TArray<FOffMeshLink> ForbiddenLinks;
|
|
|
|
#if WITH_NAVMESH_CLUSTER_LINKS
|
|
TArray<FCluster> Clusters;
|
|
TArray<FClusterLink> ClusterLinks;
|
|
#endif // WITH_NAVMESH_CLUSTER_LINKS
|
|
|
|
#if WITH_NAVMESH_SEGMENT_LINKS
|
|
TArray<FOffMeshSegment> OffMeshSegments;
|
|
TArray<int32> OffMeshSegmentAreas[RECAST_MAX_AREAS];
|
|
#endif // WITH_NAVMESH_SEGMENT_LINKS
|
|
|
|
#if RECAST_INTERNAL_DEBUG_DATA
|
|
TArray<FIntPoint> TilesToDisplayInternalData;
|
|
#endif
|
|
|
|
uint32 bGatherPolyEdges : 1;
|
|
uint32 bGatherNavMeshEdges : 1;
|
|
uint32 bMarkForbiddenPolys : 1;
|
|
uint32 bGatherTileBuildTimesHeatMap : 1;
|
|
|
|
double MinTileBuildTime = DBL_MAX;
|
|
double MaxTileBuildTime = 0.;
|
|
|
|
FRecastDebugGeometry() : bGatherPolyEdges(false), bGatherNavMeshEdges(false), bMarkForbiddenPolys(false), bGatherTileBuildTimesHeatMap(false)
|
|
{}
|
|
|
|
uint32 NAVIGATIONSYSTEM_API GetAllocatedSize() const;
|
|
};
|
|
|
|
struct FNavTileRef
|
|
{
|
|
FNavTileRef() {}
|
|
explicit FNavTileRef(const uint64 InTileRef) : TileRef(InTileRef) {}
|
|
|
|
explicit operator uint64() const { return TileRef; }
|
|
|
|
bool operator==(const FNavTileRef InRef) const { return TileRef == (uint64)InRef; }
|
|
bool operator!=(const FNavTileRef InRef) const { return TileRef != (uint64)InRef; }
|
|
|
|
bool IsValid() const { return TileRef != (uint64)FNavTileRef(); }
|
|
|
|
FORCEINLINE friend uint32 GetTypeHash(const FNavTileRef& NavTileRef) { return GetTypeHash(NavTileRef.TileRef); }
|
|
|
|
/** Those 2 functions are used for backward compatibility of the following deprecated functions in FRecastNavMeshGenerator and ARecastNavMesh:
|
|
* RemoveTileLayers
|
|
* AddGeneratedTilesTimeSliced
|
|
* AddGeneratedTiles
|
|
* RemoveLayers
|
|
* ProcessTileTasksAsync
|
|
* ProcessTileTasks
|
|
* AttachTiles
|
|
* DetachTiles
|
|
* OnNavMeshTilesUpdated
|
|
* InvalidateAffectedPaths
|
|
* They will be removed with the deprecated methods */
|
|
static void NAVIGATIONSYSTEM_API DeprecatedGetTileIdsFromNavTileRefs(const FPImplRecastNavMesh* RecastNavMeshImpl, const TArray<FNavTileRef>& InTileRefs, TArray<uint32>& OutTileIds);
|
|
static void NAVIGATIONSYSTEM_API DeprecatedMakeTileRefsFromTileIds(const FPImplRecastNavMesh* RecastNavMeshImpl, const TArray<uint32>& InTileIds, TArray<FNavTileRef>& OutTileRefs);
|
|
|
|
private:
|
|
uint64 TileRef = 0;
|
|
};
|
|
|
|
struct FNavPoly
|
|
{
|
|
NavNodeRef Ref;
|
|
FVector Center;
|
|
};
|
|
|
|
namespace ERecastNamedFilter
|
|
{
|
|
enum Type
|
|
{
|
|
FilterOutNavLinks = 0, // filters out all off-mesh connections
|
|
FilterOutAreas, // filters out all navigation areas except the default one (RECAST_DEFAULT_AREA)
|
|
FilterOutNavLinksAndAreas, // combines FilterOutNavLinks and FilterOutAreas
|
|
|
|
NamedFiltersCount,
|
|
};
|
|
}
|
|
|
|
struct FNavigationWallEdge
|
|
{
|
|
FNavigationWallEdge() = default;
|
|
FNavigationWallEdge(const FVector& InStart, const FVector& InEnd)
|
|
: Start(InStart)
|
|
, End(InEnd)
|
|
{
|
|
}
|
|
FVector Start = FVector::ZeroVector;
|
|
FVector End = FVector::ZeroVector;
|
|
};
|
|
#endif //WITH_RECAST
|
|
|
|
UENUM()
|
|
enum class EHeightFieldRenderMode : uint8
|
|
{
|
|
Solid = 0,
|
|
Walkable
|
|
};
|
|
|
|
USTRUCT()
|
|
struct FRecastNavMeshTileGenerationDebug
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
NAVIGATIONSYSTEM_API FRecastNavMeshTileGenerationDebug();
|
|
|
|
/** If set, the selected internal debug data will be kept during tile generation to be displayed with the navmesh. */
|
|
UPROPERTY(Transient, EditAnywhere, Category = Debug)
|
|
uint32 bEnabled : 1;
|
|
|
|
/** Selected tile coordinate, only this tile will have it's internal data kept.
|
|
* When MaxTileCoordinate is enabled, this defines the lower bound of a rectangle.
|
|
* Tip: displaying the navmesh using 'Draw Tile Labels' show tile coordinates. */
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
FIntVector TileCoordinate = FIntVector::ZeroValue;
|
|
|
|
/** Optional: Highest bound included tile to define a rectangle with TileCoordinate for which the internal data is kept.
|
|
* Tip: displaying the navmesh using 'Draw Tile Labels' show tile coordinates. */
|
|
UPROPERTY(EditAnywhere, Category = Debug, meta=(EditCondition="bUseMaxTileCoordinate"))
|
|
FIntVector MaxTileCoordinate = FIntVector::ZeroValue;
|
|
|
|
/** If set, the generator will only generate the tile selected to debug (set in TileCoordinate).*/
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bGenerateDebugTileOnly : 1;
|
|
|
|
/** Display the collision used for the navmesh rasterization.
|
|
* Note: The visualization is affected by the DrawOffset of the RecastNavmesh owner*/
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bCollisionGeometry : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
EHeightFieldRenderMode HeightFieldRenderMode;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bHeightfieldFromRasterization : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bHeightfieldPostInclusionBoundsFiltering : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bHeightfieldPostHeightFiltering : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bHeightfieldBounds : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bCompactHeightfield : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bCompactHeightfieldEroded : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bHeightFieldLayers : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bCompactHeightfieldRegions : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bCompactHeightfieldDistances : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bTileCacheLayerAreas : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bTileCacheLayerRegions : 1;
|
|
|
|
/** If set, the contour simplification step will be skipped. Beware that enabling this changes the way navmesh will generate when Tile Generation Debug is enabled. */
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bSkipContourSimplification : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bTileCacheContours : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bTileCachePolyMesh : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug)
|
|
uint32 bTileCacheDetailMesh : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug, meta=(InlineEditConditionToggle))
|
|
uint32 bUseMaxTileCoordinate : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Debug, meta = (Bitmask, BitmaskEnum = "/Script/NavigationSystem.ELinkGenerationDebugFlags"))
|
|
uint16 LinkGenerationDebugFlags;
|
|
|
|
/** Using -1 as no selected edge. */
|
|
UPROPERTY(EditAnywhere, Category = Debug, meta=(UIMin=-1, ClampMin=-1))
|
|
int32 LinkGenerationSelectedEdge;
|
|
|
|
/** Indicates if the tile coordinate in parameter is within the tile coordinate selected to debug.
|
|
* Either equal to TileCoordinate or inside the rectangle formed by TileCoordinate and MaxTileCoordinate. */
|
|
NAVIGATIONSYSTEM_API bool IsWithinTileCoordinates(const int32 TileX, const int32 TileY) const;
|
|
};
|
|
|
|
/**
|
|
* Used to list tiles that needs rebuilding.
|
|
*/
|
|
struct FNavMeshDirtyTileElement
|
|
{
|
|
FIntPoint Coordinates;
|
|
FVector::FReal InvokerDistanceSquared;
|
|
ENavigationInvokerPriority InvokerPriority;
|
|
};
|
|
|
|
/**
|
|
* Structure to handle nav mesh tile's raw data persistence and releasing
|
|
*/
|
|
struct FNavMeshTileData
|
|
{
|
|
// helper function so that we release NavData via dtFree not regular delete (for navigation mem stats)
|
|
struct FNavData
|
|
{
|
|
// Temporary test to help reproduce a crash.
|
|
void TestPtr() const;
|
|
|
|
FNavData(uint8* InNavData, const int32 InDataSize) : RawNavData(InNavData)
|
|
{
|
|
if (RawNavData != nullptr)
|
|
{
|
|
// Temporary test to help reproduce a crash.
|
|
static uint8 Temp = 0;
|
|
Temp = *RawNavData;
|
|
|
|
AllocatedSize = FMemory::GetAllocSize((void*)RawNavData);
|
|
check(AllocatedSize == 0 || AllocatedSize >= InDataSize);
|
|
}
|
|
else
|
|
{
|
|
AllocatedSize = 0;
|
|
}
|
|
}
|
|
~FNavData();
|
|
|
|
const uint8* GetRawNavData() const { return RawNavData; }
|
|
uint8* GetMutableRawNavData() { return RawNavData; }
|
|
|
|
void Reset()
|
|
{
|
|
RawNavData = nullptr;
|
|
AllocatedSize = 0;
|
|
}
|
|
|
|
protected:
|
|
uint8* RawNavData;
|
|
SIZE_T AllocatedSize; // != DataSize
|
|
};
|
|
|
|
// layer index
|
|
int32 LayerIndex;
|
|
FBox LayerBBox;
|
|
// size of allocated data
|
|
int32 DataSize;
|
|
// actual tile data
|
|
TSharedPtr<FNavData, ESPMode::ThreadSafe> NavData;
|
|
|
|
FNavMeshTileData() : LayerIndex(0), DataSize(0) { }
|
|
~FNavMeshTileData();
|
|
|
|
explicit FNavMeshTileData(uint8* RawData, int32 RawDataSize, int32 LayerIdx = 0, FBox LayerBounds = FBox(ForceInit));
|
|
|
|
FORCEINLINE uint8* GetData()
|
|
{
|
|
check(NavData.IsValid());
|
|
return NavData->GetMutableRawNavData();
|
|
}
|
|
|
|
FORCEINLINE const uint8* GetData() const
|
|
{
|
|
check(NavData.IsValid());
|
|
return NavData->GetRawNavData();
|
|
}
|
|
|
|
FORCEINLINE uint8* GetDataSafe()
|
|
{
|
|
return NavData.IsValid() ? NavData->GetMutableRawNavData() : NULL;
|
|
}
|
|
|
|
FORCEINLINE bool operator==(const uint8* RawData) const
|
|
{
|
|
return GetData() == RawData;
|
|
}
|
|
|
|
FORCEINLINE bool IsValid() const { return NavData.IsValid() && GetData() != nullptr && DataSize > 0; }
|
|
|
|
uint8* Release();
|
|
|
|
// Duplicate shared state so we will have own copy of the data
|
|
void MakeUnique();
|
|
};
|
|
|
|
DECLARE_MULTICAST_DELEGATE(FOnNavMeshUpdate);
|
|
|
|
namespace FNavMeshConfig
|
|
{
|
|
struct FRecastNamedFiltersCreator
|
|
{
|
|
FRecastNamedFiltersCreator(bool bVirtualFilters);
|
|
};
|
|
}
|
|
|
|
USTRUCT()
|
|
struct FNavMeshResolutionParam
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
bool IsValid() const { return CellSize > 0.f && CellHeight > 0.f && AgentMaxStepHeight > 0.f; }
|
|
|
|
/** Horizontal size of voxelization cell */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "1.0", ClampMax = "1024.0"))
|
|
float CellSize = 25.f;
|
|
|
|
/** Vertical size of voxelization cell */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "1.0", ClampMax = "1024.0"))
|
|
float CellHeight = 10.f;
|
|
|
|
/** Largest vertical step the agent can perform */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "0.0"))
|
|
float AgentMaxStepHeight = 35.f;
|
|
};
|
|
|
|
UCLASS(config=Engine, defaultconfig, hidecategories=(Input,Rendering,Tags,Transformation,Actor,Layers,Replication), notplaceable, MinimalAPI)
|
|
class ARecastNavMesh : public ANavigationData
|
|
{
|
|
GENERATED_UCLASS_BODY()
|
|
|
|
typedef uint16 FNavPolyFlags;
|
|
|
|
NAVIGATIONSYSTEM_API virtual void Serialize( FArchive& Ar ) override;
|
|
|
|
#if WITH_EDITOR
|
|
NAVIGATIONSYSTEM_API virtual bool CanEditChange(const FProperty* InProperty) const override;
|
|
#endif
|
|
|
|
/** Draw edges of every navmesh's triangle */
|
|
UPROPERTY(EditAnywhere, Category=Display)
|
|
uint32 bDrawTriangleEdges:1;
|
|
|
|
/** Draw edges of every poly (i.e. not only border-edges) */
|
|
UPROPERTY(EditAnywhere, Category=Display, config)
|
|
uint32 bDrawPolyEdges:1;
|
|
|
|
/** if disabled skips filling drawn navmesh polygons */
|
|
UPROPERTY(EditAnywhere, Category = Display)
|
|
uint32 bDrawFilledPolys:1;
|
|
|
|
/** Draw border-edges */
|
|
UPROPERTY(EditAnywhere, Category=Display)
|
|
uint32 bDrawNavMeshEdges:1;
|
|
|
|
/** Draw the tile boundaries */
|
|
UPROPERTY(EditAnywhere, Category=Display)
|
|
uint32 bDrawTileBounds:1;
|
|
|
|
/** Draw the tile resolutions */
|
|
UPROPERTY(EditAnywhere, Category=Display)
|
|
uint32 bDrawTileResolutions:1;
|
|
|
|
/** Draw input geometry passed to the navmesh generator. Recommend disabling other geometry rendering via viewport showflags in editor. */
|
|
UPROPERTY(EditAnywhere, Category=Display)
|
|
uint32 bDrawPathCollidingGeometry:1;
|
|
|
|
UPROPERTY(EditAnywhere, Category=Display)
|
|
uint32 bDrawTileLabels:1;
|
|
|
|
UPROPERTY(EditAnywhere, Category=Display)
|
|
uint32 bDrawTileBuildTimes:1;
|
|
|
|
UPROPERTY(EditAnywhere, Category=Display)
|
|
uint32 bDrawTileBuildTimesHeatMap:1;
|
|
|
|
/** Draw a label for every poly that indicates its poly and tile indices */
|
|
UPROPERTY(EditAnywhere, Category=Display, meta = (DisplayName = "Draw Polygon Indices"))
|
|
uint32 bDrawPolygonLabels:1;
|
|
|
|
/** Draw a label for every poly that indicates its default and fixed costs */
|
|
UPROPERTY(EditAnywhere, Category=Display, meta=(DisplayName="Draw Polygon Costs"))
|
|
uint32 bDrawDefaultPolygonCost:1;
|
|
|
|
/** Draw a label for every poly that indicates its poly and area flags */
|
|
UPROPERTY(EditAnywhere, Category=Display)
|
|
uint32 bDrawPolygonFlags:1;
|
|
|
|
UPROPERTY(EditAnywhere, Category=Display)
|
|
uint32 bDrawLabelsOnPathNodes:1;
|
|
|
|
/** Draw valid links (both ends are valid). */
|
|
UPROPERTY(EditAnywhere, Category=Display)
|
|
uint32 bDrawNavLinks:1;
|
|
|
|
/** Draw failed links and valid links. */
|
|
UPROPERTY(EditAnywhere, Category=Display, Meta = (DisplayName = "Draw Failed and Valid NavLinks"))
|
|
uint32 bDrawFailedNavLinks:1;
|
|
|
|
/** Draw navmesh's clusters and cluster links. (Requires WITH_NAVMESH_CLUSTER_LINKS=1) */
|
|
UPROPERTY(EditAnywhere, Category=Display)
|
|
uint32 bDrawClusters:1;
|
|
|
|
/** Draw octree used to store navigation relevant actors */
|
|
UPROPERTY(EditAnywhere, Category = Display)
|
|
uint32 bDrawOctree : 1;
|
|
|
|
/** Draw octree used to store navigation relevant actors with the elements bounds */
|
|
UPROPERTY(EditAnywhere, Category = Display, meta=(editcondition = "bDrawOctree"))
|
|
uint32 bDrawOctreeDetails : 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Display)
|
|
uint32 bDrawMarkedForbiddenPolys : 1;
|
|
|
|
/** if true, show currently rebuilding tiles differently when visualizing */
|
|
UPROPERTY(config)
|
|
uint32 bDistinctlyDrawTilesBeingBuilt:1;
|
|
|
|
/** vertical offset added to navmesh's debug representation for better readability */
|
|
UPROPERTY(EditAnywhere, Category=Display, config)
|
|
float DrawOffset;
|
|
|
|
UPROPERTY(EditAnywhere, Category = Display)
|
|
FRecastNavMeshTileGenerationDebug TileGenerationDebug;
|
|
|
|
//----------------------------------------------------------------------//
|
|
// NavMesh generation parameters
|
|
//----------------------------------------------------------------------//
|
|
|
|
/** if true, the NavMesh will allocate fixed size pool for tiles, should be enabled to support streaming */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config)
|
|
uint32 bFixedTilePoolSize:1;
|
|
|
|
/** maximum number of tiles NavMesh can hold */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config, meta=(editcondition = "bFixedTilePoolSize"))
|
|
int32 TilePoolSize;
|
|
|
|
/** size of single tile, expressed in uu */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config, meta=(ClampMin = "300.0"))
|
|
float TileSizeUU;
|
|
|
|
/**
|
|
* Note that we are not using _DEPRECATED on the following deprecated properties
|
|
* since it prevents the property from being serialized back which can break the
|
|
* process of duplicating the navmesh for PIE
|
|
*/
|
|
|
|
UE_DEPRECATED(all, "Use NavMeshResolutionParams to set CellSize for the different resolutions instead")
|
|
UPROPERTY(config, meta = (DeprecatedProperty, DeprecationMessage = "Use NavMeshResolutionParams to set CellSize for the different resolutions instead"))
|
|
float CellSize;
|
|
|
|
UE_DEPRECATED(all, "Use NavMeshResolutionParams to set CellHeight for the different resolutions instead")
|
|
UPROPERTY(config, meta = (DeprecatedProperty, DeprecationMessage = "Use NavMeshResolutionParams to set CellHeight for the different resolutions instead"))
|
|
float CellHeight;
|
|
|
|
UE_DEPRECATED(all, "Use NavMeshResolutionParams to set AgentMaxStepHeight for the different resolutions instead")
|
|
UPROPERTY(config, meta = (DeprecatedProperty, DeprecationMessage = "Use NavMeshResolutionParams to set AgentMaxStepHeight for the different resolutions instead"))
|
|
float AgentMaxStepHeight;
|
|
|
|
/** Resolution params
|
|
* If using multiple resolutions, it's recommended to chose the highest resolution first and
|
|
* set it according to the highest desired precision and then the other resolutions. */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config)
|
|
FNavMeshResolutionParam NavMeshResolutionParams[(uint8)ENavigationDataResolution::MAX];
|
|
|
|
/** Radius of smallest agent to traverse this navmesh */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "0.0"))
|
|
float AgentRadius;
|
|
|
|
/** Size of the tallest agent that will path with this navmesh. */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "0.0"))
|
|
float AgentHeight;
|
|
|
|
/* The maximum slope (angle) that the agent can move on. */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config, meta=(ClampMin = "0.0", ClampMax = "89.0", UIMin = "0.0", UIMax = "89.0" ))
|
|
float AgentMaxSlope;
|
|
|
|
/* The minimum dimension of area. Areas smaller than this will be discarded */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config, meta=(ClampMin = "0.0"))
|
|
float MinRegionArea;
|
|
|
|
/* The size limit of regions to be merged with bigger regions (watershed partitioning only) */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config, meta=(ClampMin = "0.0"))
|
|
float MergeRegionSize;
|
|
|
|
/** Maximum vertical deviation between raw contour points to allowing merging (in voxel).
|
|
* Use a low value (2-5) depending on CellHeight, AgentMaxStepHeight and AgentMaxSlope, to allow more precise contours (also see SimplificationElevationRatio).
|
|
* Use very high value to deactivate (Recast behavior). */
|
|
UE_DEPRECATED(5.5, "Not used anymore, the behavior is now binded to SimplificationElevationRatio.")
|
|
UPROPERTY(config)
|
|
int MaxVerticalMergeError;
|
|
|
|
/** How much navigable shapes can get simplified - the higher the value the more freedom */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "0.0"))
|
|
float MaxSimplificationError;
|
|
|
|
/** When simplifying contours, how much is the vertical error taken into account when comparing with MaxSimplificationError.
|
|
* Use 0 to deactivate (Recast behavior), use 1 as a typical value. */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "0.0"))
|
|
float SimplificationElevationRatio;
|
|
|
|
/** Sets the limit for number of asynchronous tile generators running at one time, also used for some synchronous tasks */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "0", UIMin = "0"), AdvancedDisplay)
|
|
int32 MaxSimultaneousTileGenerationJobsCount;
|
|
|
|
/** Absolute hard limit to number of navmesh tiles. Be very, very careful while modifying it while
|
|
* having big maps with navmesh. A single, empty tile takes 176 bytes and empty tiles are
|
|
* allocated up front (subject to change, but that's where it's at now)
|
|
* @note TileNumberHardLimit is always rounded up to the closest power of 2 */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "1", UIMin = "1"), AdvancedDisplay)
|
|
int32 TileNumberHardLimit;
|
|
|
|
/** Used when connecting segment links across layers to determine how much memory to allocate to hold skipped layers */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, meta = (ClampMin = "1", UIMin = "1"), AdvancedDisplay)
|
|
int32 ExpectedMaxLayersPerTile;
|
|
|
|
UPROPERTY(VisibleAnywhere, Category = Generation, AdvancedDisplay)
|
|
int32 PolyRefTileBits;
|
|
|
|
UPROPERTY(VisibleAnywhere, Category = Generation, AdvancedDisplay)
|
|
int32 PolyRefNavPolyBits;
|
|
|
|
UPROPERTY(VisibleAnywhere, Category = Generation, AdvancedDisplay)
|
|
int32 PolyRefSaltBits;
|
|
|
|
/** Use this if you don't want your tiles to start at (0,0,0) */
|
|
UPROPERTY(EditAnywhere, Category = Generation, AdvancedDisplay)
|
|
FVector NavMeshOriginOffset;
|
|
|
|
/** navmesh draw distance in game (always visible in editor) */
|
|
UPROPERTY(config)
|
|
float DefaultDrawDistance;
|
|
|
|
/** specifies default limit to A* nodes used when performing navigation queries.
|
|
* Can be overridden by passing custom FNavigationQueryFilter */
|
|
UPROPERTY(config)
|
|
float DefaultMaxSearchNodes;
|
|
|
|
/** specifies default limit to A* nodes used when performing hierarchical navigation queries. */
|
|
UPROPERTY(config)
|
|
float DefaultMaxHierarchicalSearchNodes;
|
|
|
|
/** filtering methode used for filtering ledge slopes */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config, AdvancedDisplay)
|
|
ENavigationLedgeSlopeFilterMode LedgeSlopeFilterMode;
|
|
|
|
/** partitioning method for creating navmesh polys */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config, AdvancedDisplay)
|
|
TEnumAsByte<ERecastPartitioning::Type> RegionPartitioning;
|
|
|
|
/** partitioning method for creating tile layers */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config, AdvancedDisplay)
|
|
TEnumAsByte<ERecastPartitioning::Type> LayerPartitioning;
|
|
|
|
/** number of chunk splits (along single axis) used for region's partitioning: ChunkyMonotone */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config, AdvancedDisplay)
|
|
int32 RegionChunkSplits;
|
|
|
|
/** number of chunk splits (along single axis) used for layer's partitioning: ChunkyMonotone */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config, AdvancedDisplay)
|
|
int32 LayerChunkSplits;
|
|
|
|
/** Controls whether Navigation Areas will be sorted by cost before application
|
|
* to navmesh during navmesh generation. This is relevant when there are
|
|
* areas overlapping and we want to have area cost express area relevancy
|
|
* as well. Setting it to true will result in having area sorted by cost,
|
|
* but it will also increase navmesh generation cost a bit */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config)
|
|
uint32 bSortNavigationAreasByCost:1;
|
|
|
|
/* In a world partitioned map, is this navmesh using world partitioning */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config, meta = (EditCondition = "bAllowWorldPartitionedNavMesh", HideEditConditionToggle, DisplayName = "IsWorldPartitionedNavMesh"))
|
|
uint32 bIsWorldPartitioned : 1;
|
|
|
|
/** Experimental: if set, navlinks will be automatically generated.
|
|
* @see FNavLinkGenerationJumpDownConfig */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config)
|
|
uint32 bGenerateNavLinks : 1;
|
|
|
|
/** controls whether voxel filtering will be applied (via FRecastTileGenerator::ApplyVoxelFilter).
|
|
* Results in generated navmesh better fitting navigation bounds, but hits (a bit) generation performance */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config, AdvancedDisplay)
|
|
uint32 bPerformVoxelFiltering:1;
|
|
|
|
/** mark areas with insufficient free height above instead of cutting them out (accessible only for area modifiers using replace mode) */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, AdvancedDisplay)
|
|
uint32 bMarkLowHeightAreas : 1;
|
|
|
|
/** Expand the top of the area nav modifier's bounds by one cell height when applying to the navmesh.
|
|
If unset, navmesh on top of surfaces might not be marked by marking bounds flush with top surfaces (since navmesh is generated slightly above collision, depending on cell height). */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, AdvancedDisplay)
|
|
uint32 bUseExtraTopCellWhenMarkingAreas : 1;
|
|
|
|
/** if set, only single low height span will be allowed under valid one */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, AdvancedDisplay)
|
|
uint32 bFilterLowSpanSequences : 1;
|
|
|
|
/** if set, only low height spans with corresponding area modifier will be stored in tile cache (reduces memory, can't modify without full tile rebuild) */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, AdvancedDisplay)
|
|
uint32 bFilterLowSpanFromTileCache : 1;
|
|
|
|
/** if set, navmesh data gathering will never happen on the game thread and will only be done on background threads */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, AdvancedDisplay)
|
|
uint32 bDoFullyAsyncNavDataGathering : 1;
|
|
|
|
/** TODO: switch to disable new code from OffsetFromCorners if necessary - remove it later */
|
|
UPROPERTY(config)
|
|
uint32 bUseBetterOffsetsFromCorners : 1;
|
|
|
|
/** If set, tiles generated without any navmesh data will be marked to distinguish them from not generated / streamed out ones. Defaults to false. */
|
|
UPROPERTY(config)
|
|
uint32 bStoreEmptyTileLayers : 1;
|
|
|
|
/** Indicates whether default navigation filters will use virtual functions. Defaults to true. */
|
|
UPROPERTY(config)
|
|
uint32 bUseVirtualFilters : 1;
|
|
|
|
/** Indicates whether to use the virtual methods to check if an object should generate geometry or
|
|
* if we should call the normal method directly (i.e. FNavigationOctreeElement::ShouldUseGeometry).
|
|
* If enabled, will also check if an object requesting an update on the navmesh is excluded to avoid dirtying the areas unnecessarily.
|
|
* Defaults to false. */
|
|
UPROPERTY(config)
|
|
uint32 bUseVirtualGeometryFilteringAndDirtying : 1;
|
|
|
|
/** If set, paths can end at navlink poly (not the ground one!) */
|
|
UPROPERTY(config)
|
|
uint32 bAllowNavLinkAsPathEnd : 1;
|
|
|
|
/** The maximum number of y coords to process when time slicing filter ledge spans during navmesh regeneration. */
|
|
UPROPERTY(EditAnywhere, Category = TimeSlicing, config, AdvancedDisplay, meta = (ClampMin = "1", UIMin = "1"))
|
|
int32 TimeSliceFilterLedgeSpansMaxYProcess = 13;
|
|
|
|
/** If a single time sliced section of navmesh regen code exceeds this duration then it will trigger debug logging */
|
|
UPROPERTY(EditAnywhere, Category = TimeSlicing, config, AdvancedDisplay)
|
|
double TimeSliceLongDurationDebug = 0.002;
|
|
|
|
/** If >= 1, when sorting pending tiles by priority, tiles near invokers (within the distance threshold) will have their priority increased. */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, AdvancedDisplay)
|
|
uint32 InvokerTilePriorityBumpDistanceThresholdInTileUnits = 1;
|
|
|
|
/** Priority increase steps for tiles that are withing near distance. */
|
|
UPROPERTY(EditAnywhere, Category = Generation, config, AdvancedDisplay)
|
|
uint8 InvokerTilePriorityBumpIncrease = 1;
|
|
|
|
protected:
|
|
#if WITH_EDITORONLY_DATA
|
|
/** World partitioned navmesh are only allowed in partitioned worlds. */
|
|
UPROPERTY()
|
|
uint32 bAllowWorldPartitionedNavMesh : 1;
|
|
#endif // WITH_EDITORONLY_DATA
|
|
|
|
/** Experimental configuration to generate vertical links. */
|
|
UPROPERTY(EditAnywhere, Category=Generation, config)
|
|
FNavLinkGenerationJumpDownConfig NavLinkJumpDownConfig;
|
|
|
|
private:
|
|
/** @returns true if there were no tiles when the navmesh was loaded. */
|
|
bool bHasNoTileData : 1 = false;
|
|
|
|
/** Cache rasterized voxels instead of just collision vertices/indices in navigation octree */
|
|
UPROPERTY(config)
|
|
uint32 bUseVoxelCache : 1;
|
|
|
|
/** indicates how often we will sort navigation tiles to mach players position */
|
|
UPROPERTY(config)
|
|
float TileSetUpdateInterval;
|
|
|
|
/** contains last available dtPoly's flag bit set (8th bit at the moment of writing) */
|
|
static NAVIGATIONSYSTEM_API FNavPolyFlags NavLinkFlag;
|
|
|
|
/** Squared draw distance */
|
|
static NAVIGATIONSYSTEM_API FVector::FReal DrawDistanceSq;
|
|
|
|
/** MinimumSizeForChaosNavMeshInfluence*/
|
|
static NAVIGATIONSYSTEM_API float MinimumSizeForChaosNavMeshInfluenceSq;
|
|
|
|
public:
|
|
|
|
struct FRaycastResult
|
|
{
|
|
enum
|
|
{
|
|
MAX_PATH_CORRIDOR_POLYS = 128
|
|
};
|
|
|
|
NavNodeRef CorridorPolys[MAX_PATH_CORRIDOR_POLYS];
|
|
float CorridorCost[MAX_PATH_CORRIDOR_POLYS];
|
|
int32 CorridorPolysCount;
|
|
FVector::FReal HitTime;
|
|
FVector HitNormal;
|
|
uint32 bIsRaycastEndInCorridor : 1;
|
|
|
|
FRaycastResult()
|
|
: CorridorPolysCount(0)
|
|
, HitTime(TNumericLimits<FVector::FReal>::Max())
|
|
, HitNormal(0.f)
|
|
, bIsRaycastEndInCorridor(false)
|
|
{
|
|
FMemory::Memzero(CorridorPolys);
|
|
FMemory::Memzero(CorridorCost);
|
|
}
|
|
|
|
FORCEINLINE int32 GetMaxCorridorSize() const { return MAX_PATH_CORRIDOR_POLYS; }
|
|
FORCEINLINE bool HasHit() const { return HitTime != TNumericLimits<FVector::FReal>::Max(); }
|
|
FORCEINLINE NavNodeRef GetLastNodeRef() const { return CorridorPolysCount > 0 ? CorridorPolys[CorridorPolysCount - 1] : INVALID_NAVNODEREF; }
|
|
};
|
|
|
|
//----------------------------------------------------------------------//
|
|
// Recast runtime params
|
|
//----------------------------------------------------------------------//
|
|
/** Euclidean distance heuristic scale used while pathfinding */
|
|
UPROPERTY(EditAnywhere, Category = Query, config, meta = (ClampMin = "0.1"))
|
|
float HeuristicScale;
|
|
|
|
/** Value added to each search height to compensate for error between navmesh polys and walkable geometry */
|
|
UPROPERTY(EditAnywhere, Category = Query, config, meta = (ClampMin = "0.0"))
|
|
float VerticalDeviationFromGroundCompensation;
|
|
|
|
/** broadcast for navmesh updates */
|
|
FOnNavMeshUpdate OnNavMeshUpdate;
|
|
|
|
FORCEINLINE static void SetDrawDistance(FVector::FReal NewDistance) { DrawDistanceSq = NewDistance * NewDistance; }
|
|
FORCEINLINE static FVector::FReal GetDrawDistanceSq() { return DrawDistanceSq; }
|
|
|
|
FORCEINLINE static void SetMinimumSizeForChaosNavMeshInfluence(float NewSize) { MinimumSizeForChaosNavMeshInfluenceSq = NewSize * NewSize; }
|
|
FORCEINLINE static float GetMinimumSizeForChaosNavMeshInfluenceSq() { return MinimumSizeForChaosNavMeshInfluenceSq; }
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
NAVIGATIONSYSTEM_API bool HasValidNavmesh() const;
|
|
|
|
/** Dtor */
|
|
NAVIGATIONSYSTEM_API virtual ~ARecastNavMesh();
|
|
|
|
#if WITH_RECAST
|
|
//----------------------------------------------------------------------//
|
|
// Life cycle & serialization
|
|
//----------------------------------------------------------------------//
|
|
public:
|
|
|
|
//~ Begin UObject Interface
|
|
NAVIGATIONSYSTEM_API virtual void PostInitProperties() override;
|
|
NAVIGATIONSYSTEM_API virtual void PostLoad() override;
|
|
NAVIGATIONSYSTEM_API virtual void PostRegisterAllComponents() override;
|
|
NAVIGATIONSYSTEM_API virtual void PostUnregisterAllComponents() override;
|
|
NAVIGATIONSYSTEM_API virtual void BeginDestroy() override;
|
|
|
|
#if WITH_EDITOR
|
|
NAVIGATIONSYSTEM_API virtual void PostEditChangeChainProperty( struct FPropertyChangedChainEvent& PropertyChangedChainEvent) override;
|
|
NAVIGATIONSYSTEM_API virtual void PostEditChangeProperty( struct FPropertyChangedEvent& PropertyChangedEvent) override;
|
|
NAVIGATIONSYSTEM_API virtual void PostEditUndo() override;
|
|
#endif // WITH_EDITOR
|
|
//~ End UObject Interface
|
|
|
|
#if WITH_EDITOR
|
|
/** RecastNavMesh instances are dynamically spawned and should not be coppied */
|
|
virtual bool ShouldExport() override { return false; }
|
|
#endif
|
|
|
|
NAVIGATIONSYSTEM_API virtual void LoadBeforeGeneratorRebuild() override;
|
|
|
|
NAVIGATIONSYSTEM_API virtual void CleanUp() override;
|
|
|
|
//~ Begin ANavigationData Interface
|
|
NAVIGATIONSYSTEM_API virtual FNavLocation GetRandomPoint(FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const override;
|
|
/** finds a random location in Radius, reachable from Origin.
|
|
* @param Radius needs to be non-negative. The function fails for Radius < 0. Radius being 0 is still rasults in a valid request. */
|
|
NAVIGATIONSYSTEM_API virtual bool GetRandomReachablePointInRadius(const FVector& Origin, float Radius, FNavLocation& OutResult, FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const override;
|
|
NAVIGATIONSYSTEM_API virtual bool GetRandomPointInNavigableRadius(const FVector& Origin, float Radius, FNavLocation& OutResult, FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const override;
|
|
|
|
NAVIGATIONSYSTEM_API virtual bool FindMoveAlongSurface(const FNavLocation& StartLocation, const FVector& TargetPosition, FNavLocation& OutLocation, FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const override;
|
|
NAVIGATIONSYSTEM_API virtual bool FindOverlappingEdges(const FNavLocation& StartLocation, TConstArrayView<FVector> ConvexPolygon, TArray<FVector>& OutEdges, FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const override;
|
|
NAVIGATIONSYSTEM_API virtual bool GetPathSegmentBoundaryEdges(const FNavigationPath& Path, const FNavPathPoint& StartPoint, const FNavPathPoint& EndPoint, const TConstArrayView<FVector> SearchArea, TArray<FVector>& OutEdges, const float MaxAreaEnterCost, FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const override;
|
|
NAVIGATIONSYSTEM_API virtual bool ProjectPoint(const FVector& Point, FNavLocation& OutLocation, const FVector& Extent, FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const override;
|
|
NAVIGATIONSYSTEM_API virtual bool IsNodeRefValid(NavNodeRef NodeRef) const override;
|
|
|
|
/** Project batch of points using shared search extent and filter */
|
|
NAVIGATIONSYSTEM_API virtual void BatchProjectPoints(TArray<FNavigationProjectionWork>& Workload, const FVector& Extent, FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const override;
|
|
|
|
/** Project batch of points using shared search filter. This version is not requiring user to pass in Extent,
|
|
* and is instead relying on FNavigationProjectionWork.ProjectionLimit.
|
|
* @note function will assert if item's FNavigationProjectionWork.ProjectionLimit is invalid */
|
|
NAVIGATIONSYSTEM_API virtual void BatchProjectPoints(TArray<FNavigationProjectionWork>& Workload, FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const override;
|
|
|
|
NAVIGATIONSYSTEM_API virtual ENavigationQueryResult::Type CalcPathCost(const FVector& PathStart, const FVector& PathEnd, FVector::FReal& OutPathCost, FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const override;
|
|
NAVIGATIONSYSTEM_API virtual ENavigationQueryResult::Type CalcPathLength(const FVector& PathStart, const FVector& PathEnd, FVector::FReal& OutPathLength, FSharedConstNavQueryFilter QueryFilter = NULL, const UObject* Querier = NULL) const override;
|
|
NAVIGATIONSYSTEM_API virtual ENavigationQueryResult::Type CalcPathLengthAndCost(const FVector& PathStart, const FVector& PathEnd, FVector::FReal& OutPathLength, FVector::FReal& OutPathCost, FSharedConstNavQueryFilter QueryFilter = NULL, const UObject* Querier = NULL) const override;
|
|
NAVIGATIONSYSTEM_API virtual bool DoesNodeContainLocation(NavNodeRef NodeRef, const FVector& WorldSpaceLocation) const override;
|
|
|
|
NAVIGATIONSYSTEM_API virtual UPrimitiveComponent* ConstructRenderingComponent() override;
|
|
/** Returns bounding box for the navmesh. */
|
|
virtual FBox GetBounds() const override { return GetNavMeshBounds(); }
|
|
/** Called on world origin changes **/
|
|
NAVIGATIONSYSTEM_API virtual void ApplyWorldOffset(const FVector& InOffset, bool bWorldShift) override;
|
|
|
|
NAVIGATIONSYSTEM_API virtual void FillNavigationDataChunkActor(const FBox& InQueryBounds, class ANavigationDataChunkActor& DataChunkActor, FBox& OutTilesBounds) const override;
|
|
|
|
NAVIGATIONSYSTEM_API virtual void OnStreamingNavDataAdded(class ANavigationDataChunkActor& InActor) override;
|
|
NAVIGATIONSYSTEM_API virtual void OnStreamingNavDataRemoved(class ANavigationDataChunkActor& InActor) override;
|
|
|
|
NAVIGATIONSYSTEM_API virtual void OnStreamingLevelAdded(ULevel* InLevel, UWorld* InWorld) override;
|
|
NAVIGATIONSYSTEM_API virtual void OnStreamingLevelRemoved(ULevel* InLevel, UWorld* InWorld) override;
|
|
|
|
#if WITH_EDITOR
|
|
NAVIGATIONSYSTEM_API virtual double GetWorldPartitionNavigationDataBuilderOverlap() const override;
|
|
#endif
|
|
//~ End ANavigationData Interface
|
|
|
|
NAVIGATIONSYSTEM_API virtual void AttachNavMeshDataChunk(URecastNavMeshDataChunk& NavDataChunk);
|
|
NAVIGATIONSYSTEM_API virtual void DetachNavMeshDataChunk(URecastNavMeshDataChunk& NavDataChunk);
|
|
|
|
UE_DEPRECATED(5.4, "Use GetActiveTileSet instead.")
|
|
NAVIGATIONSYSTEM_API const TArray<FIntPoint>& GetActiveTiles() const;
|
|
UE_DEPRECATED(5.4, "Use GetActiveTileSet instead.")
|
|
NAVIGATIONSYSTEM_API TArray<FIntPoint>& GetActiveTiles();
|
|
|
|
NAVIGATIONSYSTEM_API const TSet<FIntPoint>& GetActiveTileSet() const;
|
|
NAVIGATIONSYSTEM_API TSet<FIntPoint>& GetActiveTileSet();
|
|
|
|
NAVIGATIONSYSTEM_API void LogRecastTile(const TCHAR* Caller, const FName& Prefix, const FName& OperationName, const dtNavMesh& DetourMesh, const int32 TileX, const int32 TileY, const int32 LayerIndex, const uint64 TileRef) const;
|
|
|
|
protected:
|
|
/** Serialization helper. */
|
|
NAVIGATIONSYSTEM_API void SerializeRecastNavMesh(FArchive& Ar, FPImplRecastNavMesh*& NavMesh, int32 NavMeshVersion);
|
|
|
|
NAVIGATIONSYSTEM_API virtual void RestrictBuildingToActiveTiles(bool InRestrictBuildingToActiveTiles) override;
|
|
|
|
NAVIGATIONSYSTEM_API virtual void OnRegistered() override;
|
|
|
|
public:
|
|
/** Get the CellSize for the given resolution. */
|
|
float GetCellSize(const ENavigationDataResolution Resolution) const { return NavMeshResolutionParams[(uint8)Resolution].CellSize; }
|
|
|
|
/** Set the CellSize for the given resolution. */
|
|
void SetCellSize(const ENavigationDataResolution Resolution, const float Size) { NavMeshResolutionParams[(uint8)Resolution].CellSize = Size; }
|
|
|
|
/** Get the CellHeight for the given resolution. */
|
|
float GetCellHeight(const ENavigationDataResolution Resolution) const { return NavMeshResolutionParams[(uint8)Resolution].CellHeight; }
|
|
|
|
/** Set the CellHeight for the given resolution. */
|
|
void SetCellHeight(const ENavigationDataResolution Resolution, const float Height) { NavMeshResolutionParams[(uint8)Resolution].CellHeight = Height; }
|
|
|
|
/** Get the AgentMaxStepHeight for the given resolution. */
|
|
float GetAgentMaxStepHeight(const ENavigationDataResolution Resolution) const { return NavMeshResolutionParams[(uint8)Resolution].AgentMaxStepHeight; }
|
|
|
|
/** Set the AgentMaxStepHeight for the given resolution. */
|
|
void SetAgentMaxStepHeight(const ENavigationDataResolution Resolution, const float MaxStepHeight) { NavMeshResolutionParams[(uint8)Resolution].AgentMaxStepHeight = MaxStepHeight; }
|
|
|
|
/** Returns the tile size in world units. */
|
|
NAVIGATIONSYSTEM_API float GetTileSizeUU() const;
|
|
|
|
/** Whether NavMesh should adjust its tile pool size when NavBounds are changed */
|
|
NAVIGATIONSYSTEM_API bool IsResizable() const;
|
|
|
|
/** Returns bounding box for the whole navmesh. */
|
|
NAVIGATIONSYSTEM_API FBox GetNavMeshBounds() const;
|
|
|
|
/** Returns bounding box for a given navmesh tile. */
|
|
UE_DEPRECATED(5.5, "Use the version of this function that takes a FNavTileRef instead.")
|
|
NAVIGATIONSYSTEM_API FBox GetNavMeshTileBounds(int32 TileIndex) const;
|
|
|
|
/** Returns bounding box for a given navmesh tile. */
|
|
NAVIGATIONSYSTEM_API FBox GetNavMeshTileBounds(FNavTileRef TileRef) const;
|
|
|
|
/** Retrieves XY coordinates of tile specified by index */
|
|
UE_DEPRECATED(5.5, "Use the version of this function that takes a FNavTileRef instead.")
|
|
NAVIGATIONSYSTEM_API bool GetNavMeshTileXY(int32 TileIndex, int32& OutX, int32& OutY, int32& Layer) const;
|
|
|
|
/** Retrieves XY coordinates of tile */
|
|
NAVIGATIONSYSTEM_API bool GetNavMeshTileXY(FNavTileRef TileRef, int32& OutX, int32& OutY, int32& Layer) const;
|
|
|
|
/** Retrieves XY coordinates of tile specified by position */
|
|
NAVIGATIONSYSTEM_API bool GetNavMeshTileXY(const FVector& Point, int32& OutX, int32& OutY) const;
|
|
|
|
/** Retrieves the tile resolution */
|
|
UE_DEPRECATED(5.5, "Use the version of this function that takes a FNavTileRef instead.")
|
|
NAVIGATIONSYSTEM_API bool GetNavmeshTileResolution(int32 TileIndex, ENavigationDataResolution& OutResolution) const;
|
|
|
|
/** Retrieves the tile resolution */
|
|
NAVIGATIONSYSTEM_API bool GetNavmeshTileResolution(FNavTileRef TileRef, ENavigationDataResolution& OutResolution) const;
|
|
|
|
/** Checks the supplied Points tile indicies can fit in the range of an int32 */
|
|
NAVIGATIONSYSTEM_API bool CheckTileIndicesInValidRange(const FVector& Point, bool& bOutInRange) const;
|
|
|
|
/** Retrieves all tile indices at matching XY coordinates */
|
|
UE_DEPRECATED(5.5, "Use the version of this function that takes an array of FNavTileRefs instead.")
|
|
NAVIGATIONSYSTEM_API void GetNavMeshTilesAt(int32 TileX, int32 TileY, TArray<int32>& Indices) const;
|
|
|
|
/** Retrieves all tiles at matching XY coordinates */
|
|
NAVIGATIONSYSTEM_API void GetNavMeshTilesAt(int32 TileX, int32 TileY, TArray<FNavTileRef>& OutRefs) const;
|
|
|
|
/** Retrieves number of tiles in this navmesh */
|
|
NAVIGATIONSYSTEM_API int32 GetNavMeshTilesCount() const;
|
|
|
|
/** Retrieves all tiles in this navmesh */
|
|
NAVIGATIONSYSTEM_API void GetAllNavMeshTiles(TArray<FNavTileRef>& OutRefs) const;
|
|
|
|
/** Removes compressed tile data at given tile coord */
|
|
NAVIGATIONSYSTEM_API void RemoveTileCacheLayers(int32 TileX, int32 TileY);
|
|
|
|
/** Stores compressed tile data for given tile coord */
|
|
NAVIGATIONSYSTEM_API void AddTileCacheLayers(int32 TileX, int32 TileY, const TArray<FNavMeshTileData>& InLayers);
|
|
|
|
#if RECAST_INTERNAL_DEBUG_DATA
|
|
NAVIGATIONSYSTEM_API void RemoveTileDebugData(int32 TileX, int32 TileY);
|
|
NAVIGATIONSYSTEM_API void AddTileDebugData(int32 TileX, int32 TileY, const struct FRecastInternalDebugData& InTileDebugData);
|
|
#endif
|
|
|
|
/** Marks tile coord as rebuild and empty */
|
|
NAVIGATIONSYSTEM_API void MarkEmptyTileCacheLayers(int32 TileX, int32 TileY);
|
|
|
|
/** Returns compressed tile data at given tile coord */
|
|
NAVIGATIONSYSTEM_API TArray<FNavMeshTileData> GetTileCacheLayers(int32 TileX, int32 TileY) const;
|
|
|
|
/** Gets the size of the compressed tile cache, this is slow */
|
|
#if !UE_BUILD_SHIPPING
|
|
NAVIGATIONSYSTEM_API int32 GetCompressedTileCacheSize();
|
|
#endif
|
|
|
|
NAVIGATIONSYSTEM_API void GetEdgesForPathCorridor(const TArray<NavNodeRef>* PathCorridor, TArray<struct FNavigationPortalEdge>* PathCorridorEdges) const;
|
|
|
|
NAVIGATIONSYSTEM_API void UpdateDrawing();
|
|
|
|
/** Creates a task to be executed on GameThread calling UpdateDrawing */
|
|
NAVIGATIONSYSTEM_API void RequestDrawingUpdate(bool bForce = false);
|
|
|
|
/** called after regenerating tiles */
|
|
NAVIGATIONSYSTEM_API virtual void OnNavMeshTilesUpdated(const TArray<FNavTileRef>& ChangedTiles);
|
|
|
|
#if WITH_NAVMESH_SEGMENT_LINKS
|
|
/** Creates segment link connections for the given tiles. Called after navigation tiles are finished generating. */
|
|
NAVIGATIONSYSTEM_API virtual void CreateSegmentLinkConnections(TSet<FNavTileRef>& TilesPendingSegmentLinks);
|
|
#endif
|
|
|
|
/** Event from generator that navmesh build has finished */
|
|
NAVIGATIONSYSTEM_API virtual void OnNavMeshGenerationFinished();
|
|
|
|
NAVIGATIONSYSTEM_API virtual void EnsureBuildCompletion() override;
|
|
|
|
NAVIGATIONSYSTEM_API virtual void SetConfig(const FNavDataConfig& Src) override;
|
|
protected:
|
|
NAVIGATIONSYSTEM_API virtual void FillConfig(FNavDataConfig& Dest) override;
|
|
|
|
FORCEINLINE const FNavigationQueryFilter& GetRightFilterRef(FSharedConstNavQueryFilter Filter) const
|
|
{
|
|
return *(Filter.IsValid() ? Filter.Get() : GetDefaultQueryFilter().Get());
|
|
}
|
|
|
|
public:
|
|
|
|
static NAVIGATIONSYSTEM_API bool IsVoxelCacheEnabled();
|
|
|
|
//----------------------------------------------------------------------//
|
|
// Debug
|
|
//----------------------------------------------------------------------//
|
|
|
|
/* Gather debug geometry.
|
|
* @params OutGeometry Output geometry.
|
|
* @params TileIndex Used to collect geometry for a specific tile, INDEX_NONE will gather all tiles
|
|
* @return True if done collecting.
|
|
*/
|
|
UE_DEPRECATED(5.5, "Use the version of the function that takes a FNavTileRef instead.")
|
|
NAVIGATIONSYSTEM_API bool GetDebugGeometryForTile(FRecastDebugGeometry& OutGeometry, int32 TileIndex) const;
|
|
|
|
/* Gather debug geometry.
|
|
* @params OutGeometry Output geometry.
|
|
* @params TileRef Used to collect geometry for a specific tile, an invalid FNavTileRef will gather all tiles
|
|
* @return True if done collecting.
|
|
*/
|
|
NAVIGATIONSYSTEM_API bool GetDebugGeometryForTile(FRecastDebugGeometry& OutGeometry, FNavTileRef TileRef) const;
|
|
|
|
// @todo docuement
|
|
NAVIGATIONSYSTEM_API void DrawDebugPathCorridor(NavNodeRef const* PathPolys, int32 NumPathPolys, bool bPersistent=true) const;
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
NAVIGATIONSYSTEM_API virtual uint32 LogMemUsed() const override;
|
|
#endif // !UE_BUILD_SHIPPING
|
|
|
|
NAVIGATIONSYSTEM_API void UpdateNavMeshDrawing();
|
|
|
|
//----------------------------------------------------------------------//
|
|
// Utilities
|
|
//----------------------------------------------------------------------//
|
|
NAVIGATIONSYSTEM_API virtual void OnNavAreaChanged() override;
|
|
NAVIGATIONSYSTEM_API virtual void OnNavAreaAdded(const UClass* NavAreaClass, int32 AgentIndex) override;
|
|
NAVIGATIONSYSTEM_API virtual void OnNavAreaRemoved(const UClass* NavAreaClass) override;
|
|
NAVIGATIONSYSTEM_API virtual int32 GetNewAreaID(const UClass* AreaClass) const override;
|
|
virtual int32 GetMaxSupportedAreas() const override { return RECAST_MAX_AREAS; }
|
|
|
|
/** Get forbidden area flags from default query filter */
|
|
NAVIGATIONSYSTEM_API uint16 GetDefaultForbiddenFlags() const;
|
|
/** Change forbidden area flags in default query filter */
|
|
NAVIGATIONSYSTEM_API void SetDefaultForbiddenFlags(uint16 ForbiddenAreaFlags);
|
|
|
|
/** Area sort function */
|
|
NAVIGATIONSYSTEM_API virtual void SortAreasForGenerator(TArray<FRecastAreaNavModifierElement>& Areas) const;
|
|
|
|
NAVIGATIONSYSTEM_API virtual void RecreateDefaultFilter();
|
|
|
|
int32 GetMaxSimultaneousTileGenerationJobsCount() const { return MaxSimultaneousTileGenerationJobsCount; }
|
|
NAVIGATIONSYSTEM_API void SetMaxSimultaneousTileGenerationJobsCount(int32 NewJobsCountLimit);
|
|
|
|
/** Returns query extent including adjustments for voxelization error compensation */
|
|
FVector GetModifiedQueryExtent(const FVector& QueryExtent) const
|
|
{
|
|
// Using HALF_WORLD_MAX instead of BIG_NUMBER, else using the extent for a box will result in NaN.
|
|
return FVector(QueryExtent.X, QueryExtent.Y, QueryExtent.Z >= HALF_WORLD_MAX ? HALF_WORLD_MAX : (QueryExtent.Z + FMath::Max(0., VerticalDeviationFromGroundCompensation)));
|
|
}
|
|
|
|
//----------------------------------------------------------------------//
|
|
// Custom navigation links
|
|
//----------------------------------------------------------------------//
|
|
|
|
NAVIGATIONSYSTEM_API virtual void UpdateCustomLink(const INavLinkCustomInterface* CustomLink) override;
|
|
|
|
UE_DEPRECATED(5.3, "Use version of this function that takes a FNavLinkId. This function now has no effect.")
|
|
void UpdateNavigationLinkArea(int32 UserId, TSubclassOf<UNavArea> AreaClass) const {}
|
|
|
|
/** update area class and poly flags for all offmesh links with given UserId */
|
|
NAVIGATIONSYSTEM_API void UpdateNavigationLinkArea(FNavLinkId UserId, TSubclassOf<UNavArea> AreaClass) const;
|
|
|
|
#if WITH_NAVMESH_SEGMENT_LINKS
|
|
/** update area class and poly flags for all offmesh segment links with given UserId */
|
|
NAVIGATIONSYSTEM_API void UpdateSegmentLinkArea(int32 UserId, TSubclassOf<UNavArea> AreaClass) const;
|
|
#endif // WITH_NAVMESH_SEGMENT_LINKS
|
|
|
|
//----------------------------------------------------------------------//
|
|
// Batch processing (important with async rebuilding)
|
|
//----------------------------------------------------------------------//
|
|
|
|
/** Starts batch processing and locks access to navmesh from other threads */
|
|
NAVIGATIONSYSTEM_API virtual void BeginBatchQuery() const override;
|
|
|
|
/** Finishes batch processing and release locks */
|
|
NAVIGATIONSYSTEM_API virtual void FinishBatchQuery() const override;
|
|
|
|
//----------------------------------------------------------------------//
|
|
// Querying
|
|
//----------------------------------------------------------------------//
|
|
|
|
/** dtNavMesh getter */
|
|
NAVIGATIONSYSTEM_API dtNavMesh* GetRecastMesh();
|
|
|
|
/** dtNavMesh getter */
|
|
NAVIGATIONSYSTEM_API const dtNavMesh* GetRecastMesh() const;
|
|
|
|
UE_DEPRECATED(5.3, "Please use GetNavLinkUserId() instead. This function only returns Invalid.")
|
|
int32 GetLinkUserId(NavNodeRef LinkPolyID) const
|
|
{
|
|
return static_cast<int32>(FNavLinkId::Invalid.GetId());
|
|
}
|
|
|
|
/** Retrieves LinkUserID associated with indicated PolyID */
|
|
NAVIGATIONSYSTEM_API FNavLinkId GetNavLinkUserId(NavNodeRef LinkPolyID) const;
|
|
|
|
NAVIGATIONSYSTEM_API FColor GetAreaIDColor(uint8 AreaID) const;
|
|
|
|
/** Finds the polygons along the navigation graph that touch the specified circle. */
|
|
NAVIGATIONSYSTEM_API bool FindPolysAroundCircle(const FVector& CenterPos, const NavNodeRef CenterNodeRef, const FVector::FReal Radius, const FSharedConstNavQueryFilter& Filter, const UObject* QueryOwner, TArray<NavNodeRef>* OutPolys = nullptr, TArray<NavNodeRef>* OutPolysParent = nullptr, TArray<float>* OutPolysCost = nullptr, int32* OutPolysCount = nullptr) const;
|
|
|
|
/** Returns nearest navmesh polygon to Loc, or INVALID_NAVNODEREF if Loc is not on the navmesh. */
|
|
NAVIGATIONSYSTEM_API NavNodeRef FindNearestPoly(FVector const& Loc, FVector const& Extent, FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const;
|
|
|
|
/** Finds the distance to the closest wall, limited to MaxDistance
|
|
* [out] OutClosestPointOnWall, if supplied, will be set to closest point on closest wall. Will not be set if no wall in the area (return value 0.f) */
|
|
NAVIGATIONSYSTEM_API FVector::FReal FindDistanceToWall(const FVector& StartLoc, FSharedConstNavQueryFilter Filter = nullptr, FVector::FReal MaxDistance = TNumericLimits<FVector::FReal>::Max(), FVector* OutClosestPointOnWall = nullptr) const;
|
|
|
|
/** Retrieves center of the specified polygon. Returns false on error. */
|
|
NAVIGATIONSYSTEM_API bool GetPolyCenter(NavNodeRef PolyID, FVector& OutCenter) const;
|
|
|
|
/** Retrieves the vertices for the specified polygon. Returns false on error. */
|
|
NAVIGATIONSYSTEM_API bool GetPolyVerts(NavNodeRef PolyID, TArray<FVector>& OutVerts) const;
|
|
|
|
/** Retrieves a random point inside the specified polygon. Returns false on error. */
|
|
NAVIGATIONSYSTEM_API bool GetRandomPointInPoly(NavNodeRef PolyID, FVector& OutPoint) const;
|
|
|
|
/** Retrieves the surface area of the specified polygon. Returns 0 on error. */
|
|
NAVIGATIONSYSTEM_API FVector::FReal GetPolySurfaceArea(NavNodeRef PolyID) const;
|
|
|
|
/** Retrieves area ID for the specified polygon. */
|
|
NAVIGATIONSYSTEM_API uint32 GetPolyAreaID(NavNodeRef PolyID) const;
|
|
|
|
/** Sets area ID for the specified polygon. */
|
|
NAVIGATIONSYSTEM_API bool SetPolyArea(NavNodeRef PolyID, TSubclassOf<UNavArea> AreaClass);
|
|
|
|
/** Sets area ID for the specified polygons */
|
|
NAVIGATIONSYSTEM_API void SetPolyArrayArea(const TArray<FNavPoly>& Polys, TSubclassOf<UNavArea> AreaClass);
|
|
|
|
/** In given Bounds find all areas of class OldArea and replace them with NewArea
|
|
* @return number of polys touched */
|
|
NAVIGATIONSYSTEM_API int32 ReplaceAreaInTileBounds(const FBox& Bounds, TSubclassOf<UNavArea> OldArea, TSubclassOf<UNavArea> NewArea, bool ReplaceLinks = true, TArray<NavNodeRef>* OutTouchedNodes = nullptr);
|
|
|
|
/** Retrieves poly and area flags for specified polygon */
|
|
NAVIGATIONSYSTEM_API bool GetPolyFlags(NavNodeRef PolyID, uint16& PolyFlags, uint16& AreaFlags) const;
|
|
NAVIGATIONSYSTEM_API bool GetPolyFlags(NavNodeRef PolyID, FNavMeshNodeFlags& Flags) const;
|
|
|
|
/** Finds all polys connected with specified one */
|
|
NAVIGATIONSYSTEM_API bool GetPolyNeighbors(NavNodeRef PolyID, TArray<FNavigationPortalEdge>& Neighbors) const;
|
|
|
|
/** Finds all polys connected with specified one, results expressed as array of NavNodeRefs */
|
|
NAVIGATIONSYSTEM_API bool GetPolyNeighbors(NavNodeRef PolyID, TArray<NavNodeRef>& Neighbors) const;
|
|
|
|
/** Finds edges of specified poly */
|
|
NAVIGATIONSYSTEM_API bool GetPolyEdges(NavNodeRef PolyID, TArray<FNavigationPortalEdge>& Neighbors) const;
|
|
|
|
/** Finds all wall segments for the specified polygon (walls or area borders) */
|
|
NAVIGATIONSYSTEM_API bool GetPolyWallSegments(NavNodeRef PolyID, FSharedConstNavQueryFilter Filter, const UObject* QueryOwner, TArray<FNavigationPortalEdge>& OutNeighbors) const;
|
|
|
|
/** Finds closest point constrained to given poly */
|
|
NAVIGATIONSYSTEM_API bool GetClosestPointOnPoly(NavNodeRef PolyID, const FVector& TestPt, FVector& PointOnPoly) const;
|
|
|
|
/** Decode poly ID into tile index and poly index */
|
|
NAVIGATIONSYSTEM_API bool GetPolyTileIndex(NavNodeRef PolyID, uint32& PolyIndex, uint32& TileIndex) const;
|
|
|
|
/** Retrieves start and end point of offmesh link */
|
|
NAVIGATIONSYSTEM_API bool GetLinkEndPoints(NavNodeRef LinkPolyID, FVector& PointA, FVector& PointB) const;
|
|
|
|
/** Retrieves bounds of cluster. Returns false on error. */
|
|
NAVIGATIONSYSTEM_API bool GetClusterBounds(NavNodeRef ClusterRef, FBox& OutBounds) const;
|
|
|
|
/** Get random point in given cluster */
|
|
NAVIGATIONSYSTEM_API bool GetRandomPointInCluster(NavNodeRef ClusterRef, FNavLocation& OutLocation) const;
|
|
|
|
/** Get cluster ref containing given poly ref */
|
|
NAVIGATIONSYSTEM_API NavNodeRef GetClusterRef(NavNodeRef PolyRef) const;
|
|
|
|
/** Retrieves all polys within given pathing distance from StartLocation.
|
|
* @NOTE query is not using string-pulled path distance (for performance reasons),
|
|
* it measured distance between middles of portal edges, do you might want to
|
|
* add an extra margin to PathingDistance */
|
|
NAVIGATIONSYSTEM_API bool GetPolysWithinPathingDistance(FVector const& StartLoc, const FVector::FReal PathingDistance, TArray<NavNodeRef>& FoundPolys,
|
|
FSharedConstNavQueryFilter Filter = nullptr, const UObject* Querier = nullptr, FRecastDebugPathfindingData* DebugData = nullptr) const;
|
|
|
|
/** Filters nav polys in PolyRefs with Filter */
|
|
NAVIGATIONSYSTEM_API bool FilterPolys(TArray<NavNodeRef>& PolyRefs, const FRecastQueryFilter* Filter, const UObject* Querier = NULL) const;
|
|
|
|
/** Get all polys from tile */
|
|
UE_DEPRECATED(5.5, "Use the version of this function that takes a FNavTileRef instead.")
|
|
NAVIGATIONSYSTEM_API bool GetPolysInTile(int32 TileIndex, TArray<FNavPoly>& Polys) const;
|
|
|
|
/** Get all polys from tile */
|
|
NAVIGATIONSYSTEM_API bool GetPolysInTile(FNavTileRef TileRef, TArray<FNavPoly>& Polys) const;
|
|
|
|
/** Get up to 256 polys that overlap the specified box */
|
|
NAVIGATIONSYSTEM_API bool GetPolysInBox(const FBox& Box, TArray<FNavPoly>& Polys, FSharedConstNavQueryFilter Filter = nullptr, const UObject* Owner = nullptr) const;
|
|
|
|
/** Find up to 64 navmesh eges in up to 64 polys around the center */
|
|
NAVIGATIONSYSTEM_API bool FindEdges(const NavNodeRef CenterNodeRef, const FVector Center, const FVector::FReal Radius, const FSharedConstNavQueryFilter Filter, TArray<FNavigationWallEdge>& OutEdges) const;
|
|
|
|
/** Get all navmesh edges from tile that form the border of the passed in Filter */
|
|
NAVIGATIONSYSTEM_API void GetTilePolyEdgesForFilter(FNavTileRef TileRef, FSharedConstNavQueryFilter Filter, TArray<FNavigationWallEdge>& OutEdges) const;
|
|
|
|
/** Get all exterior nav mesh edges from tile */
|
|
NAVIGATIONSYSTEM_API bool GetEdgesInTile(FNavTileRef TileRef, TArray<FNavigationWallEdge>& OutEdges) const;
|
|
|
|
/** Get all polys from tile */
|
|
NAVIGATIONSYSTEM_API bool GetNavLinksInTile(const int32 TileIndex, TArray<FNavPoly>& Polys, const bool bIncludeLinksFromNeighborTiles) const;
|
|
|
|
/** Projects point on navmesh, returning all hits along vertical line defined by min-max Z params */
|
|
NAVIGATIONSYSTEM_API bool ProjectPointMulti(const FVector& Point, TArray<FNavLocation>& OutLocations, const FVector& Extent,
|
|
FVector::FReal MinZ, FVector::FReal MaxZ, FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const;
|
|
|
|
// @todo document
|
|
static NAVIGATIONSYSTEM_API FPathFindingResult FindPath(const FNavAgentProperties& AgentProperties, const FPathFindingQuery& Query);
|
|
static NAVIGATIONSYSTEM_API bool TestPath(const FNavAgentProperties& AgentProperties, const FPathFindingQuery& Query, int32* NumVisitedNodes);
|
|
static NAVIGATIONSYSTEM_API bool TestHierarchicalPath(const FNavAgentProperties& AgentProperties, const FPathFindingQuery& Query, int32* NumVisitedNodes);
|
|
static NAVIGATIONSYSTEM_API bool NavMeshRaycast(const ANavigationData* Self, const FVector& RayStart, const FVector& RayEnd, FVector& HitLocation, FSharedConstNavQueryFilter QueryFilter, const UObject* Querier, FRaycastResult& Result);
|
|
static bool NavMeshRaycast(const ANavigationData* Self, const FVector& RayStart, const FVector& RayEnd, FVector& HitLocation, FSharedConstNavQueryFilter QueryFilter, const UObject* Querier = NULL);
|
|
static bool NavMeshRaycast(const ANavigationData* Self, const FVector& RayStart, const FVector& RayEnd, FVector& HitLocation, FNavigationRaycastAdditionalResults* AdditionalResults, FSharedConstNavQueryFilter QueryFilter, const UObject* Querier = NULL);
|
|
static NAVIGATIONSYSTEM_API bool NavMeshRaycast(const ANavigationData* Self, NavNodeRef RayStartNode, const FVector& RayStart, const FVector& RayEnd, FVector& HitLocation, FSharedConstNavQueryFilter QueryFilter, const UObject* Querier = NULL);
|
|
static NAVIGATIONSYSTEM_API bool NavMeshRaycast(const ANavigationData* Self, NavNodeRef RayStartNode, const FVector& RayStart, const FVector& RayEnd, FVector& HitLocation, FNavigationRaycastAdditionalResults* AdditionalResults, FSharedConstNavQueryFilter QueryFilter, const UObject* Querier = NULL);
|
|
|
|
NAVIGATIONSYSTEM_API virtual void BatchRaycast(TArray<FNavigationRaycastWork>& Workload, FSharedConstNavQueryFilter QueryFilter, const UObject* Querier = NULL) const override;
|
|
|
|
/** finds a Filter-passing navmesh location closest to specified StartLoc
|
|
* @return true if adjusting was required, false otherwise */
|
|
NAVIGATIONSYSTEM_API bool AdjustLocationWithFilter(const FVector& StartLoc, FVector& OutAdjustedLocation, const FNavigationQueryFilter& Filter, const UObject* Querier = NULL) const;
|
|
|
|
/** Check if navmesh is defined (either built/streamed or recognized as empty tile by generator) in given radius.
|
|
* @returns true if ALL tiles inside are ready
|
|
*/
|
|
NAVIGATIONSYSTEM_API bool HasCompleteDataInRadius(const FVector& TestLocation, FVector::FReal TestRadius) const;
|
|
|
|
/** Check if navmesh is defined (either built/streamed or recognized as empty tile by generator) within given radius around the given segment.
|
|
* @returns true if ALL tiles inside are ready
|
|
*/
|
|
NAVIGATIONSYSTEM_API bool HasCompleteDataAroundSegment(const FVector& StartLocation, const FVector& EndLocation, FVector::FReal TestRadius) const;
|
|
|
|
/** @return true is specified segment is fully on navmesh (respecting the optional filter) */
|
|
NAVIGATIONSYSTEM_API bool IsSegmentOnNavmesh(const FVector& SegmentStart, const FVector& SegmentEnd, FSharedConstNavQueryFilter Filter = NULL, const UObject* Querier = NULL) const;
|
|
|
|
/** Check if poly is a custom link */
|
|
NAVIGATIONSYSTEM_API bool IsCustomLink(NavNodeRef PolyRef) const;
|
|
|
|
/** finds stringpulled path from given corridor */
|
|
NAVIGATIONSYSTEM_API bool FindStraightPath(const FVector& StartLoc, const FVector& EndLoc, const TArray<NavNodeRef>& PathCorridor, TArray<FNavPathPoint>& PathPoints, TArray<FNavLinkId>* CustomLinks = NULL) const;
|
|
|
|
/** Runs A* pathfinding on navmesh and collect data for every step */
|
|
NAVIGATIONSYSTEM_API int32 DebugPathfinding(const FPathFindingQuery& Query, TArray<FRecastDebugPathfindingData>& Steps);
|
|
|
|
static NAVIGATIONSYSTEM_API const FRecastQueryFilter* GetNamedFilter(ERecastNamedFilter::Type FilterType);
|
|
FORCEINLINE static FNavPolyFlags GetNavLinkFlag() { return NavLinkFlag; }
|
|
|
|
NAVIGATIONSYSTEM_API virtual bool NeedsRebuild() const override;
|
|
NAVIGATIONSYSTEM_API virtual bool SupportsRuntimeGeneration() const override;
|
|
NAVIGATIONSYSTEM_API virtual bool SupportsStreaming() const override;
|
|
|
|
NAVIGATIONSYSTEM_API bool IsWorldPartitionedDynamicNavmesh() const;
|
|
|
|
/** When using active tiles generation, navigation is only allowed to be runtime generated on a subset of tiles.
|
|
* The subset is be defined by navinvokers or loaded world partitioned cells. */
|
|
NAVIGATIONSYSTEM_API bool IsUsingActiveTilesGeneration(const UNavigationSystemV1& NavSys) const;
|
|
|
|
/** Runs after LoadBeforeGeneratorRebuild but before the rebuild. */
|
|
NAVIGATIONSYSTEM_API virtual void PostLoadPreRebuild() override;
|
|
|
|
NAVIGATIONSYSTEM_API virtual void ConditionalConstructGenerator() override;
|
|
|
|
bool ShouldGatherDataOnGameThread() const { return bDoFullyAsyncNavDataGathering == false; }
|
|
int32 GetTileNumberHardLimit() const { return TileNumberHardLimit; }
|
|
|
|
NAVIGATIONSYSTEM_API virtual void UpdateActiveTiles(const TArray<FNavigationInvokerRaw>& InvokerLocations);
|
|
NAVIGATIONSYSTEM_API virtual void RemoveTiles(const TArray<FIntPoint>& Tiles);
|
|
|
|
NAVIGATIONSYSTEM_API void RebuildTile(const TArray<FNavMeshDirtyTileElement>& Tiles);
|
|
|
|
NAVIGATIONSYSTEM_API void DirtyTilesInBounds(const FBox& Bounds);
|
|
|
|
#if RECAST_INTERNAL_DEBUG_DATA
|
|
NAVIGATIONSYSTEM_API const TMap<FIntPoint, struct FRecastInternalDebugData>* GetDebugDataMap() const;
|
|
#endif
|
|
|
|
const FNavLinkGenerationJumpDownConfig& GetNavLinkJumpDownConfig() const { return NavLinkJumpDownConfig; }
|
|
|
|
protected:
|
|
|
|
NAVIGATIONSYSTEM_API void UpdatePolyRefBitsPreview();
|
|
|
|
/** Invalidates active paths that go through changed tiles */
|
|
NAVIGATIONSYSTEM_API void InvalidateAffectedPaths(const TArray<FNavTileRef>& ChangedTiles);
|
|
|
|
/** created a new FRecastNavMeshGenerator instance. Overrider to supply your
|
|
* own extentions. Note: needs to derive from FRecastNavMeshGenerator */
|
|
NAVIGATIONSYSTEM_API virtual FRecastNavMeshGenerator* CreateGeneratorInstance();
|
|
|
|
NAVIGATIONSYSTEM_API void CheckToDiscardSubLevelNavData(const UNavigationSystemBase& NavSys);
|
|
|
|
void RegisterGeneratedLinksProxy();
|
|
void UnregisterGeneratedLinksProxy();
|
|
|
|
/* Create and register links proxy. It's expected to be called on load or when the navmesh is rebuilt. */
|
|
void CreateAndRegisterJumpDownLinksProxy(const FNavLinkId LinkProxyId = FNavLinkId::GenerateUniqueId());
|
|
|
|
private:
|
|
friend struct FRecastGraphWrapper;
|
|
friend FRecastNavMeshGenerator;
|
|
friend class FPImplRecastNavMesh;
|
|
friend class URecastNavMeshDataChunk;
|
|
// destroys FPImplRecastNavMesh instance if it has been created
|
|
NAVIGATIONSYSTEM_API void DestroyRecastPImpl();
|
|
// @todo docuement
|
|
NAVIGATIONSYSTEM_API void UpdateNavVersion();
|
|
NAVIGATIONSYSTEM_API void UpdateNavObject();
|
|
|
|
/** @return Navmesh data chunk that belongs to this actor */
|
|
NAVIGATIONSYSTEM_API URecastNavMeshDataChunk* GetNavigationDataChunk(ULevel* InLevel) const;
|
|
|
|
/** @return Navmesh data chunk that belongs to this actor */
|
|
NAVIGATIONSYSTEM_API URecastNavMeshDataChunk* GetNavigationDataChunk(const ANavigationDataChunkActor& InActor) const;
|
|
|
|
/** Check if navmesh is defined (either built/streamed or recognized as empty tile by generator) in given tile */
|
|
bool HasCompleteDataInTile(const int32 TileX, const int32 TileY) const;
|
|
|
|
protected:
|
|
// retrieves RecastNavMeshImpl
|
|
FPImplRecastNavMesh* GetRecastNavMeshImpl() { return RecastNavMeshImpl; }
|
|
const FPImplRecastNavMesh* GetRecastNavMeshImpl() const { return RecastNavMeshImpl; }
|
|
|
|
struct FUpdateActiveTilesWorkingMem
|
|
{
|
|
TSet<FIntPoint> OldActiveSet;
|
|
|
|
#if WITH_EDITORONLY_DATA
|
|
UE_DEPRECATED(5.5, "TilesInMinDistance not used anymore, use TilesInMinDistanceMap instead.")
|
|
TArray<FNavMeshDirtyTileElement> TilesInMinDistance;
|
|
#endif
|
|
TMap<FIntPoint, FNavMeshDirtyTileElement> TilesInMinDistanceMap;
|
|
|
|
TSet<FIntPoint> TilesInMaxDistance;
|
|
TArray<FIntPoint> TileToAppend;
|
|
};
|
|
FUpdateActiveTilesWorkingMem UpdateActiveTilesWorkingMem;
|
|
|
|
private:
|
|
/** @return Navmesh data chunk that belongs to this actor */
|
|
NAVIGATIONSYSTEM_API URecastNavMeshDataChunk* GetNavigationDataChunk(const TArray<UNavigationDataChunk*>& InChunks) const;
|
|
|
|
/** NavMesh versioning. */
|
|
uint32 NavMeshVersion;
|
|
|
|
/**
|
|
* This is a pimpl-style arrangement used to tightly hide the Recast internals from the rest of the engine.
|
|
* Using this class should *not* require the inclusion of the private RecastNavMesh.h
|
|
* @NOTE: if we switch over to C++11 this should be unique_ptr
|
|
* @TODO since it's no secret we're using recast there's no point in having separate implementation class. FPImplRecastNavMesh should be merged into ARecastNavMesh
|
|
*/
|
|
FPImplRecastNavMesh* RecastNavMeshImpl;
|
|
|
|
#if RECAST_ASYNC_REBUILDING
|
|
/** batch query counter */
|
|
mutable int32 BatchQueryCounter;
|
|
|
|
#endif // RECAST_ASYNC_REBUILDING
|
|
|
|
private:
|
|
static NAVIGATIONSYSTEM_API const FRecastQueryFilter* NamedFilters[ERecastNamedFilter::NamedFiltersCount];
|
|
#else
|
|
virtual bool IsNodeRefValid(NavNodeRef NodeRef) const override { return true; }
|
|
virtual FBox GetBounds() const override { return FBox(); }
|
|
virtual void BatchRaycast(TArray<FNavigationRaycastWork>& Workload, FSharedConstNavQueryFilter QueryFilter, const UObject* Querier = nullptr) const override {}
|
|
virtual bool FindMoveAlongSurface(const FNavLocation& StartLocation, const FVector& TargetPosition, FNavLocation& OutLocation, FSharedConstNavQueryFilter Filter = nullptr, const UObject* Querier = nullptr) const override { return false; }
|
|
virtual bool FindOverlappingEdges(const FNavLocation& StartLocation, TConstArrayView<FVector> ConvexPolygon, TArray<FVector>& OutEdges, FSharedConstNavQueryFilter Filter = nullptr, const UObject* Querier = nullptr) const override { return false; }
|
|
virtual bool GetPathSegmentBoundaryEdges(const FNavigationPath& Path, const FNavPathPoint& StartPoint, const FNavPathPoint& EndPoint, const TConstArrayView<FVector> SearchArea, TArray<FVector>& OutEdges, const float MaxAreaEnterCost, FSharedConstNavQueryFilter Filter = nullptr, const UObject* Querier = nullptr) const override { return false; }
|
|
virtual FNavLocation GetRandomPoint(FSharedConstNavQueryFilter Filter = nullptr, const UObject* Querier = nullptr) const override { return FNavLocation(); }
|
|
virtual bool GetRandomReachablePointInRadius(const FVector& Origin, float Radius, FNavLocation& OutResult, FSharedConstNavQueryFilter Filter = nullptr, const UObject* Querier = nullptr) const override { return false; }
|
|
virtual bool GetRandomPointInNavigableRadius(const FVector& Origin, float Radius, FNavLocation& OutResult, FSharedConstNavQueryFilter Filter = nullptr, const UObject* Querier = nullptr) const override { return false; }
|
|
virtual bool ProjectPoint(const FVector& Point, FNavLocation& OutLocation, const FVector& Extent, FSharedConstNavQueryFilter Filter = nullptr, const UObject* Querier = nullptr) const override { return false; }
|
|
virtual void BatchProjectPoints(TArray<FNavigationProjectionWork>& Workload, const FVector& Extent, FSharedConstNavQueryFilter Filter = nullptr, const UObject* Querier = nullptr) const override {}
|
|
virtual void BatchProjectPoints(TArray<FNavigationProjectionWork>& Workload, FSharedConstNavQueryFilter Filter = nullptr, const UObject* Querier = nullptr) const override {}
|
|
virtual ENavigationQueryResult::Type CalcPathCost(const FVector& PathStart, const FVector& PathEnd, FVector::FReal& OutPathCost, FSharedConstNavQueryFilter QueryFilter = nullptr, const UObject* Querier = nullptr) const override { return ENavigationQueryResult::Invalid; }
|
|
virtual ENavigationQueryResult::Type CalcPathLength(const FVector& PathStart, const FVector& PathEnd, FVector::FReal& OutPathLength, FSharedConstNavQueryFilter QueryFilter = nullptr, const UObject* Querier = nullptr) const override { return ENavigationQueryResult::Invalid; }
|
|
virtual ENavigationQueryResult::Type CalcPathLengthAndCost(const FVector& PathStart, const FVector& PathEnd, FVector::FReal& OutPathLength, FVector::FReal& OutPathCost, FSharedConstNavQueryFilter QueryFilter = nullptr, const UObject* Querier = nullptr) const override { return ENavigationQueryResult::Invalid; }
|
|
virtual bool DoesNodeContainLocation(NavNodeRef NodeRef, const FVector& WorldSpaceLocation) const override { return false; }
|
|
#endif // WITH_RECAST
|
|
|
|
public:
|
|
//----------------------------------------------------------------------//
|
|
// Blueprint functions
|
|
//----------------------------------------------------------------------//
|
|
|
|
/** @return true if any polygon/link has been touched */
|
|
UFUNCTION(BlueprintCallable, Category = NavMesh, meta = (DisplayName = "ReplaceAreaInTileBounds"))
|
|
NAVIGATIONSYSTEM_API bool K2_ReplaceAreaInTileBounds(FBox Bounds, TSubclassOf<UNavArea> OldArea, TSubclassOf<UNavArea> NewArea, bool ReplaceLinks = true);
|
|
};
|
|
|
|
#if WITH_RECAST
|
|
FORCEINLINE
|
|
bool ARecastNavMesh::NavMeshRaycast(const ANavigationData* Self, const FVector& RayStart, const FVector& RayEnd, FVector& HitLocation, FSharedConstNavQueryFilter QueryFilter, const UObject* Querier)
|
|
{
|
|
return NavMeshRaycast(Self, RayStart, RayEnd, HitLocation, nullptr, QueryFilter, Querier);
|
|
}
|
|
|
|
FORCEINLINE
|
|
bool ARecastNavMesh::NavMeshRaycast(const ANavigationData* Self, const FVector& RayStart, const FVector& RayEnd, FVector& HitLocation, FNavigationRaycastAdditionalResults* AdditionalResults, FSharedConstNavQueryFilter QueryFilter, const UObject* Querier)
|
|
{
|
|
FRaycastResult Result;
|
|
const bool bDidHit = NavMeshRaycast(Self, RayStart, RayEnd, HitLocation, QueryFilter, Querier, Result);
|
|
if (AdditionalResults)
|
|
{
|
|
AdditionalResults->bIsRayEndInCorridor = Result.bIsRaycastEndInCorridor;
|
|
}
|
|
return bDidHit;
|
|
}
|
|
|
|
|
|
/** structure to cache owning RecastNavMesh data so that it doesn't have to be polled
|
|
* directly from RecastNavMesh while asyncronously generating navmesh */
|
|
struct FRecastNavMeshCachedData
|
|
{
|
|
ARecastNavMesh::FNavPolyFlags FlagsPerArea[RECAST_MAX_AREAS];
|
|
ARecastNavMesh::FNavPolyFlags FlagsPerOffMeshLinkArea[RECAST_MAX_AREAS];
|
|
TMap<const UClass*, int32> AreaClassToIdMap;
|
|
TWeakObjectPtr<const ARecastNavMesh> ActorOwner;
|
|
uint32 bUseSortFunction : 1;
|
|
|
|
static FRecastNavMeshCachedData Construct(const ARecastNavMesh* RecastNavMeshActor);
|
|
void OnAreaAdded(const UClass* AreaClass, int32 AreaID);
|
|
void OnAreaRemoved(const UClass* AreaClass);
|
|
};
|
|
|
|
#endif // WITH_RECAST
|