From 2c2c1af97f7e0538ea30415e345b50ea348ccddf Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 15 Jan 2021 11:59:04 +0100 Subject: [PATCH] Add NavAgentMask --- .../Dedicated/NavAgentMaskEditor.cs | 92 +++++++++++++++++++ Source/Engine/Navigation/Navigation.cpp | 36 ++++++++ .../Engine/Navigation/NavigationSettings.cs | 12 +++ Source/Engine/Navigation/NavigationTypes.h | 24 +++++ Source/Engine/Serialization/JsonSerializer.cs | 1 + 5 files changed, 165 insertions(+) create mode 100644 Source/Editor/CustomEditors/Dedicated/NavAgentMaskEditor.cs diff --git a/Source/Editor/CustomEditors/Dedicated/NavAgentMaskEditor.cs b/Source/Editor/CustomEditors/Dedicated/NavAgentMaskEditor.cs new file mode 100644 index 000000000..ab0151bb9 --- /dev/null +++ b/Source/Editor/CustomEditors/Dedicated/NavAgentMaskEditor.cs @@ -0,0 +1,92 @@ +// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. + +using System.Linq; +using FlaxEditor.Content.Settings; +using FlaxEngine; +using FlaxEngine.GUI; + +namespace FlaxEditor.CustomEditors.Dedicated +{ + /// + /// Custom editor for . + /// + /// + [CustomEditor(typeof(NavAgentMask)), DefaultEditor] + internal class NavAgentMaskEditor : CustomEditor + { + private CheckBox[] _checkBoxes; + + /// + public override void Initialize(LayoutElementsContainer layout) + { + var settings = GameSettings.Load(); + if (settings.NavMeshes == null || settings.NavMeshes.Length == 0) + { + layout.Label("Missing navmesh settings"); + return; + } + + _checkBoxes = new CheckBox[settings.NavMeshes.Length]; + for (int i = 0; i < settings.NavMeshes.Length; i++) + { + ref var navmesh = ref settings.NavMeshes[i]; + var property = layout.AddPropertyItem(navmesh.Name, navmesh.Agent.ToString()); + property.Labels.Last().TextColorHighlighted = navmesh.Color; + var checkbox = property.Checkbox().CheckBox; + UpdateCheckbox(checkbox, i); + checkbox.Tag = i; + checkbox.StateChanged += OnCheckboxStateChanged; + _checkBoxes[i] = checkbox; + } + } + + /// + protected override void Deinitialize() + { + _checkBoxes = null; + + base.Deinitialize(); + } + + /// + public override void Refresh() + { + if (_checkBoxes != null) + { + for (int i = 0; i < _checkBoxes.Length; i++) + { + UpdateCheckbox(_checkBoxes[i], i); + } + } + + base.Refresh(); + } + + private void OnCheckboxStateChanged(CheckBox checkBox) + { + var i = (int)checkBox.Tag; + var value = (NavAgentMask)Values[0]; + var mask = 1u << i; + value.Mask &= ~mask; + value.Mask |= checkBox.Checked ? mask : 0; + SetValue(value); + } + + private void UpdateCheckbox(CheckBox checkbox, int i) + { + for (var j = 0; j < Values.Count; j++) + { + var value = (((NavAgentMask)Values[j]).Mask & (1 << i)) != 0; + if (j == 0) + { + checkbox.Checked = value; + } + else if (checkbox.State != CheckBoxState.Intermediate) + { + if (checkbox.Checked != value) + checkbox.State = CheckBoxState.Intermediate; + } + } + } + } +} diff --git a/Source/Engine/Navigation/Navigation.cpp b/Source/Engine/Navigation/Navigation.cpp index 29b081150..5e73f40c7 100644 --- a/Source/Engine/Navigation/Navigation.cpp +++ b/Source/Engine/Navigation/Navigation.cpp @@ -97,6 +97,42 @@ bool NavAgentProperties::operator==(const NavAgentProperties& other) const return Math::NearEqual(Radius, other.Radius) && Math::NearEqual(Height, other.Height) && Math::NearEqual(StepHeight, other.StepHeight) && Math::NearEqual(MaxSlopeAngle, other.MaxSlopeAngle); } +bool NavAgentMask::IsAgentSupported(int32 agentIndex) const +{ + return (Mask & (1 << agentIndex)) != 0; +} + +bool NavAgentMask::IsAgentSupported(const NavAgentProperties& agentProperties) const +{ + auto settings = NavigationSettings::Get(); + for (int32 agentIndex = 0; agentIndex < settings->NavMeshes.Count(); agentIndex++) + { + if (settings->NavMeshes[agentIndex].Agent == agentProperties) + { + return (Mask & (1 << agentIndex)) != 0; + } + } + return false; +} + +bool NavAgentMask::IsNavMeshSupported(const NavMeshProperties& navMeshProperties) const +{ + auto settings = NavigationSettings::Get(); + for (int32 agentIndex = 0; agentIndex < settings->NavMeshes.Count(); agentIndex++) + { + if (settings->NavMeshes[agentIndex] == navMeshProperties) + { + return (Mask & (1 << agentIndex)) != 0; + } + } + return false; +} + +bool NavAgentMask::operator==(const NavAgentMask& other) const +{ + return Mask == other.Mask; +} + bool NavMeshProperties::operator==(const NavMeshProperties& other) const { return Name == other.Name && Quaternion::NearEqual(Rotation, other.Rotation, 0.001f) && Agent == other.Agent; diff --git a/Source/Engine/Navigation/NavigationSettings.cs b/Source/Engine/Navigation/NavigationSettings.cs index da300b3f1..4127ebe6b 100644 --- a/Source/Engine/Navigation/NavigationSettings.cs +++ b/Source/Engine/Navigation/NavigationSettings.cs @@ -72,3 +72,15 @@ namespace FlaxEditor.Content.Settings } } } + +namespace FlaxEngine +{ + partial struct NavAgentProperties + { + /// + public override string ToString() + { + return $"Radius: {Radius}, Height: {Height}, StepHeight: {StepHeight}, MaxSlopeAngle: {MaxSlopeAngle}"; + } + } +} diff --git a/Source/Engine/Navigation/NavigationTypes.h b/Source/Engine/Navigation/NavigationTypes.h index f00c1683e..d02b2acc4 100644 --- a/Source/Engine/Navigation/NavigationTypes.h +++ b/Source/Engine/Navigation/NavigationTypes.h @@ -91,6 +91,30 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(NavMeshProperties); } }; +/// +/// The navigation system agents selection mask (from navigation system settings). Uses 1 bit per agent type (up to 32 agents). +/// +API_STRUCT() struct FLAXENGINE_API NavAgentMask +{ +DECLARE_SCRIPTING_TYPE_MINIMAL(NavAgentMask); + + /// + /// The agents selection mask. + /// + API_FIELD() uint32 Mask = MAX_uint32; + + bool IsAgentSupported(int32 agentIndex) const; + bool IsAgentSupported(const NavAgentProperties& agentProperties) const; + bool IsNavMeshSupported(const NavMeshProperties& navMeshProperties) const; + + bool operator==(const NavAgentMask& other) const; + + bool operator!=(const NavAgentMask& other) const + { + return !operator==(other); + } +}; + /// /// The result information for navigation mesh queries. /// diff --git a/Source/Engine/Serialization/JsonSerializer.cs b/Source/Engine/Serialization/JsonSerializer.cs index 231831442..535499442 100644 --- a/Source/Engine/Serialization/JsonSerializer.cs +++ b/Source/Engine/Serialization/JsonSerializer.cs @@ -120,6 +120,7 @@ namespace FlaxEngine.Json } } */ + /// /// Objects serialization tool (json format). ///