diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp
index efc73dc63..2f77600b8 100644
--- a/Source/Engine/Level/Level.cpp
+++ b/Source/Engine/Level/Level.cpp
@@ -588,9 +588,9 @@ public:
{
LOG(Info, "Prepare scene objects");
SceneBeginData beginData;
- for (int32 i = 0; i < Level::Scenes.Count(); i++)
+ for (auto scene : Level::Scenes)
{
- Level::Scenes[i]->BeginPlay(&beginData);
+ scene->BeginPlay(&beginData);
}
beginData.OnDone();
}
diff --git a/Source/Engine/Level/Scene/Scene.cpp b/Source/Engine/Level/Scene/Scene.cpp
index 9304b679a..b9b5444ab 100644
--- a/Source/Engine/Level/Scene/Scene.cpp
+++ b/Source/Engine/Level/Scene/Scene.cpp
@@ -30,13 +30,37 @@ bool SceneAsset::IsInternalType() const
return true;
}
+BoundingBox SceneNavigation::GetNavigationBounds()
+{
+ if (Volumes.IsEmpty())
+ return BoundingBox::Empty;
+ PROFILE_CPU_NAMED("GetNavigationBounds");
+ auto box = Volumes[0]->GetBox();
+ for (int32 i = 1; i < Volumes.Count(); i++)
+ BoundingBox::Merge(box, Volumes[i]->GetBox(), box);
+ return box;
+}
+
+NavMeshBoundsVolume* SceneNavigation::FindNavigationBoundsOverlap(const BoundingBox& bounds)
+{
+ NavMeshBoundsVolume* result = nullptr;
+ for (int32 i = 0; i < Volumes.Count(); i++)
+ {
+ if (Volumes[i]->GetBox().Intersects(bounds))
+ {
+ result = Volumes[i];
+ break;
+ }
+ }
+ return result;
+}
+
#define CSG_COLLIDER_NAME TEXT("CSG.Collider")
#define CSG_MODEL_NAME TEXT("CSG.Model")
Scene::Scene(const SpawnParams& params)
: Actor(params)
, Rendering(this)
- , Ticking(this)
, LightmapsData(this)
, CSGData(this)
{
@@ -65,31 +89,6 @@ void Scene::SetLightmapSettings(const LightmapSettings& value)
Info.LightmapSettings = value;
}
-BoundingBox Scene::GetNavigationBounds()
-{
- if (NavigationVolumes.IsEmpty())
- return BoundingBox::Empty;
- PROFILE_CPU_NAMED("GetNavigationBounds");
- auto box = NavigationVolumes[0]->GetBox();
- for (int32 i = 1; i < NavigationVolumes.Count(); i++)
- BoundingBox::Merge(box, NavigationVolumes[i]->GetBox(), box);
- return box;
-}
-
-NavMeshBoundsVolume* Scene::FindNavigationBoundsOverlap(const BoundingBox& bounds)
-{
- NavMeshBoundsVolume* result = nullptr;
- for (int32 i = 0; i < NavigationVolumes.Count(); i++)
- {
- if (NavigationVolumes[i]->GetBox().Intersects(bounds))
- {
- result = NavigationVolumes[i];
- break;
- }
- }
- return result;
-}
-
void Scene::ClearLightmaps()
{
LightmapsData.ClearLightmaps();
@@ -283,7 +282,7 @@ void Scene::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
CSGData.DeserializeIfExists(stream, "CSG", modifier);
// [Deprecated on 13.01.2021, expires on 13.01.2023]
- if (modifier->EngineBuild <= 6215 && NavigationMeshes.IsEmpty())
+ if (modifier->EngineBuild <= 6215 && Navigation.Meshes.IsEmpty())
{
const auto e = SERIALIZE_FIND_MEMBER(stream, "NavMesh");
if (e != stream.MemberEnd())
diff --git a/Source/Engine/Level/Scene/Scene.h b/Source/Engine/Level/Scene/Scene.h
index 305a31ca6..474e0907f 100644
--- a/Source/Engine/Level/Scene/Scene.h
+++ b/Source/Engine/Level/Scene/Scene.h
@@ -8,22 +8,18 @@
#include "SceneCSGData.h"
#include "SceneRendering.h"
#include "SceneTicking.h"
+#include "SceneNavigation.h"
class MeshCollider;
-class Level;
-class ReloadScriptsAction;
-class NavMeshBoundsVolume;
-class NavMesh;
///
/// The scene root object that contains a hierarchy of actors.
///
API_CLASS() class FLAXENGINE_API Scene : public Actor
{
+ friend class Level;
+ friend class ReloadScriptsAction;
DECLARE_SCENE_OBJECT(Scene);
- friend Level;
- friend ReloadScriptsAction;
-public:
///
/// Finalizes an instance of the class.
@@ -47,8 +43,6 @@ public:
///
DateTime SaveTime;
-public:
-
///
/// The scene rendering manager.
///
@@ -59,6 +53,11 @@ public:
///
SceneTicking Ticking;
+ ///
+ /// The navigation data.
+ ///
+ SceneNavigation Navigation;
+
///
/// The static light manager for this scene.
///
@@ -80,31 +79,6 @@ public:
///
API_PROPERTY() void SetLightmapSettings(const LightmapSettings& value);
-public:
-
- ///
- /// The list of registered navigation bounds volumes (in the scene).
- ///
- Array NavigationVolumes;
-
- ///
- /// The list of registered navigation meshes (in the scene).
- ///
- Array NavigationMeshes;
-
- ///
- /// Gets the total navigation volumes bounds.
- ///
- /// The navmesh bounds.
- BoundingBox GetNavigationBounds();
-
- ///
- /// Finds the navigation volume bounds that have intersection with the given world-space bounding box.
- ///
- /// The bounds.
- /// The intersecting volume or null if none found.
- NavMeshBoundsVolume* FindNavigationBoundsOverlap(const BoundingBox& bounds);
-
public:
///
@@ -119,8 +93,6 @@ public:
/// The timeout to wait before building CSG (in milliseconds).
API_FUNCTION() void BuildCSG(float timeoutMs = 50);
-public:
-
#if USE_EDITOR
///
diff --git a/Source/Engine/Level/Scene/SceneCSGData.h b/Source/Engine/Level/Scene/SceneCSGData.h
index 0f85e75af..373ebd06c 100644
--- a/Source/Engine/Level/Scene/SceneCSGData.h
+++ b/Source/Engine/Level/Scene/SceneCSGData.h
@@ -2,13 +2,13 @@
#pragma once
-#include "Engine/Content/AssetReference.h"
-#include "Engine/Content/Assets/RawDataAsset.h"
-#include "Engine/Content/Assets/Model.h"
-#include "Engine/Serialization/ISerializable.h"
#include "Engine/Core/Math/Triangle.h"
#include "Engine/Core/Collections/Dictionary.h"
#include "Engine/Physics/CollisionData.h"
+#include "Engine/Serialization/ISerializable.h"
+#include "Engine/Content/AssetReference.h"
+#include "Engine/Content/Assets/RawDataAsset.h"
+#include "Engine/Content/Assets/Model.h"
class Scene;
@@ -74,7 +74,6 @@ namespace CSG
///
/// Determines whether this container has CSG data linked.
///
- /// true if this CSG data container is valid; otherwise, false.
bool HasData() const;
public:
diff --git a/Source/Engine/Level/Scene/SceneNavigation.h b/Source/Engine/Level/Scene/SceneNavigation.h
new file mode 100644
index 000000000..31ccb63b9
--- /dev/null
+++ b/Source/Engine/Level/Scene/SceneNavigation.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+
+#pragma once
+
+#include "Engine/Core/Collections/Array.h"
+
+class NavMesh;
+class NavMeshBoundsVolume;
+
+///
+/// Scene navigation subsystem.
+///
+class FLAXENGINE_API SceneNavigation
+{
+public:
+
+ ///
+ /// The list of registered navigation bounds volumes (on the scene).
+ ///
+ Array Volumes;
+
+ ///
+ /// The list of registered navigation meshes (on the scene).
+ ///
+ Array Meshes;
+
+ ///
+ /// Gets the total navigation volumes bounds.
+ ///
+ BoundingBox GetNavigationBounds();
+
+ ///
+ /// Finds the navigation volume bounds that have intersection with the given world-space bounding box.
+ ///
+ /// The bounds.
+ /// The intersecting volume or null if none found.
+ NavMeshBoundsVolume* FindNavigationBoundsOverlap(const BoundingBox& bounds);
+};
diff --git a/Source/Engine/Level/Scene/SceneTicking.cpp b/Source/Engine/Level/Scene/SceneTicking.cpp
index 862e3a352..b3a6c1cdc 100644
--- a/Source/Engine/Level/Scene/SceneTicking.cpp
+++ b/Source/Engine/Level/Scene/SceneTicking.cpp
@@ -4,6 +4,12 @@
#include "Scene.h"
#include "Engine/Scripting/Script.h"
+SceneTicking::TickData::TickData(int32 capacity)
+ : Scripts(capacity)
+ , Ticks(capacity)
+{
+}
+
void SceneTicking::TickData::AddScript(Script* script)
{
Scripts.Add(script);
@@ -22,6 +28,65 @@ void SceneTicking::TickData::RemoveScript(Script* script)
#endif
}
+void SceneTicking::TickData::RemoveTick(void* callee)
+{
+ for (int32 i = 0; i < Ticks.Count(); i++)
+ {
+ if (Ticks[i].Callee == callee)
+ {
+ Ticks.RemoveAt(i);
+ break;
+ }
+ }
+}
+
+void SceneTicking::TickData::Tick()
+{
+ TickScripts(Scripts);
+
+ for (int32 i = 0; i < Ticks.Count(); i++)
+ Ticks[i].Call();
+}
+
+#if USE_EDITOR
+
+void SceneTicking::TickData::RemoveTickExecuteInEditor(void* callee)
+{
+ for (int32 i = 0; i < TicksExecuteInEditor.Count(); i++)
+ {
+ if (TicksExecuteInEditor[i].Callee == callee)
+ {
+ TicksExecuteInEditor.RemoveAt(i);
+ break;
+ }
+ }
+}
+
+void SceneTicking::TickData::TickExecuteInEditor()
+{
+ TickScripts(ScriptsExecuteInEditor);
+
+ for (int32 i = 0; i < TicksExecuteInEditor.Count(); i++)
+ TicksExecuteInEditor[i].Call();
+}
+
+#endif
+
+void SceneTicking::TickData::Clear()
+{
+ Scripts.Clear();
+ Ticks.Clear();
+#if USE_EDITOR
+ ScriptsExecuteInEditor.Clear();
+ TicksExecuteInEditor.Clear();
+#endif
+}
+
+SceneTicking::FixedUpdateTickData::FixedUpdateTickData()
+ : TickData(512)
+{
+}
+
void SceneTicking::FixedUpdateTickData::TickScripts(const Array