Add support for masking navmesh agents in NavMeshBoundsVolume

This commit is contained in:
Wojtek Figat
2021-01-15 11:59:21 +01:00
parent 2c2c1af97f
commit 65d3883f03
3 changed files with 38 additions and 2 deletions

View File

@@ -2,6 +2,7 @@
#include "NavMeshBoundsVolume.h"
#include "Engine/Level/Scene/Scene.h"
#include "Engine/Serialization/Serialization.h"
#if USE_EDITOR
#include "Editor/Editor.h"
#include "Editor/Managed/ManagedEditor.h"
@@ -13,6 +14,24 @@ NavMeshBoundsVolume::NavMeshBoundsVolume(const SpawnParams& params)
{
}
void NavMeshBoundsVolume::Serialize(SerializeStream& stream, const void* otherObj)
{
// Base
BoxVolume::Serialize(stream, otherObj);
SERIALIZE_GET_OTHER_OBJ(NavMeshBoundsVolume);
SERIALIZE_MEMBER(AgentsMask, AgentsMask.Mask);
}
void NavMeshBoundsVolume::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
{
// Base
BoxVolume::Deserialize(stream, modifier);
DESERIALIZE_MEMBER(AgentsMask, AgentsMask.Mask);
}
void NavMeshBoundsVolume::OnEnable()
{
// Base

View File

@@ -3,6 +3,7 @@
#pragma once
#include "Engine/Level/Actors/BoxVolume.h"
#include "NavigationTypes.h"
/// <summary>
/// A special type of volume that defines the areas of the scene in which navigation meshes are generated.
@@ -10,6 +11,20 @@
API_CLASS() class FLAXENGINE_API NavMeshBoundsVolume : public BoxVolume
{
DECLARE_SCENE_OBJECT(NavMeshBoundsVolume);
public:
/// <summary>
/// The agent types used by this navmesh bounds volume (from navigation settings). Can be used to generate navmesh for a certain set of agents.
/// </summary>
API_FIELD(Attributes="EditorDisplay(\"Box Volume\"), EditorOrder(10)")
NavAgentMask AgentsMask;
public:
// [BoxVolume]
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
protected:
// [BoxVolume]

View File

@@ -296,7 +296,7 @@ void RasterizeGeometry(const BoundingBox& tileBoundsNavMesh, const Matrix& world
// Builds navmesh tile bounds and check if there are any valid navmesh volumes at that tile location
// Returns true if tile is intersecting with any navmesh bounds volume actor - which means tile is in use
bool GetNavMeshTileBounds(Scene* scene, int32 x, int32 y, float tileSize, BoundingBox& tileBoundsNavMesh, const Matrix& worldToNavMesh)
bool GetNavMeshTileBounds(Scene* scene, NavMesh* navMesh, int32 x, int32 y, float tileSize, BoundingBox& tileBoundsNavMesh, const Matrix& worldToNavMesh)
{
// Build initial tile bounds (with infinite extent)
tileBoundsNavMesh.Minimum.X = (float)x * tileSize;
@@ -312,6 +312,8 @@ bool GetNavMeshTileBounds(Scene* scene, int32 x, int32 y, float tileSize, Boundi
for (int32 i = 0; i < scene->NavigationVolumes.Count(); i++)
{
const auto volume = scene->NavigationVolumes[i];
if (!volume->AgentsMask.IsNavMeshSupported(navMesh->Properties))
continue;
const auto& volumeBounds = volume->GetBox();
BoundingBox volumeBoundsNavMesh;
BoundingBox::Transform(volumeBounds, worldToNavMesh, volumeBoundsNavMesh);
@@ -821,7 +823,7 @@ void BuildDirtyBounds(Scene* scene, NavMesh* navMesh, const BoundingBox& dirtyBo
for (int32 x = tilesMin.X; x < tilesMax.X; x++)
{
BoundingBox tileBoundsNavMesh;
if (GetNavMeshTileBounds(scene, x, y, tileSize, tileBoundsNavMesh, worldToNavMesh))
if (GetNavMeshTileBounds(scene, navMesh, x, y, tileSize, tileBoundsNavMesh, worldToNavMesh))
{
BuildTileAsync(navMesh, x, y, config, tileBoundsNavMesh, worldToNavMesh, tileSize);
}