diff --git a/Source/Game/Game/Application/Application.cpp b/Source/Game/Game/Application/Application.cpp
index be77db85..7c6505fc 100644
--- a/Source/Game/Game/Application/Application.cpp
+++ b/Source/Game/Game/Application/Application.cpp
@@ -227,6 +227,8 @@ bool Application::Init()
ServiceLocator::SetTaskScheduler(_taskScheduler);
_registries.gameRegistry = new entt::registry();
+ _registries.eventIncomingRegistry = new entt::registry();
+ _registries.eventOutgoingRegistry = new entt::registry();
ServiceLocator::SetEnttRegistries(&_registries);
_inputManager = new InputManager();
@@ -451,6 +453,16 @@ bool Application::Tick(f32 deltaTime)
}
_ecsScheduler->Update(*_registries.gameRegistry, deltaTime);
+
+ // Handle Double Buffered Event Swap
+ {
+ _registries.eventIncomingRegistry->clear();
+
+ entt::registry* temp = _registries.eventIncomingRegistry;
+ _registries.eventIncomingRegistry = _registries.eventOutgoingRegistry;
+ _registries.eventOutgoingRegistry = temp;
+ }
+
_animationSystem->Update(deltaTime);
_editorHandler->Update(deltaTime);
diff --git a/Source/Game/Game/Application/EnttRegistries.h b/Source/Game/Game/Application/EnttRegistries.h
index 97860406..8351e88e 100644
--- a/Source/Game/Game/Application/EnttRegistries.h
+++ b/Source/Game/Game/Application/EnttRegistries.h
@@ -4,4 +4,6 @@
struct EnttRegistries
{
entt::registry* gameRegistry;
+ entt::registry* eventIncomingRegistry;
+ entt::registry* eventOutgoingRegistry;
};
\ No newline at end of file
diff --git a/Source/Game/Game/ECS/Components/Events.h b/Source/Game/Game/ECS/Components/Events.h
new file mode 100644
index 00000000..2398931f
--- /dev/null
+++ b/Source/Game/Game/ECS/Components/Events.h
@@ -0,0 +1,10 @@
+#pragma once
+#include
+
+namespace ECS::Components
+{
+ struct MapLoadedEvent
+ {
+ u32 mapId;
+ };
+}
\ No newline at end of file
diff --git a/Source/Game/Game/ECS/Scheduler.h b/Source/Game/Game/ECS/Scheduler.h
index 08354664..b51cce46 100644
--- a/Source/Game/Game/ECS/Scheduler.h
+++ b/Source/Game/Game/ECS/Scheduler.h
@@ -5,14 +5,14 @@
namespace ECS
{
- class Scheduler
- {
- public:
- Scheduler();
+ class Scheduler
+ {
+ public:
+ Scheduler();
- void Init(entt::registry & registry);
- void Update(entt::registry& registry, f32 deltaTime);
+ void Init(entt::registry & registry);
+ void Update(entt::registry& registry, f32 deltaTime);
- private:
- };
+ private:
+ };
}
\ No newline at end of file
diff --git a/Source/Game/Game/ECS/Systems/CharacterController.cpp b/Source/Game/Game/ECS/Systems/CharacterController.cpp
index e3c6caf0..d7e85701 100644
--- a/Source/Game/Game/ECS/Systems/CharacterController.cpp
+++ b/Source/Game/Game/ECS/Systems/CharacterController.cpp
@@ -1,9 +1,9 @@
#include "CharacterController.h"
#include "Game/Animation/AnimationSystem.h"
-
#include "Game/ECS/Components/AABB.h"
#include "Game/ECS/Components/Camera.h"
+#include "Game/ECS/Components/Events.h"
#include "Game/ECS/Components/Model.h"
#include "Game/ECS/Components/Name.h"
#include "Game/ECS/Singletons/ActiveCamera.h"
@@ -11,8 +11,9 @@
#include "Game/ECS/Singletons/FreeflyingCameraSettings.h"
#include "Game/ECS/Singletons/JoltState.h"
#include "Game/ECS/Singletons/OrbitalCameraSettings.h"
+#include "Game/ECS/Util/EventUtil.h"
#include "Game/ECS/Util/Transforms.h"
-
+#include "Game/Gameplay/MapLoader.h"
#include "Game/Rendering/GameRenderer.h"
#include "Game/Rendering/Debug/JoltDebugRenderer.h"
#include "Game/Rendering/Model/ModelLoader.h"
@@ -57,21 +58,7 @@ namespace ECS::Systems
transformSystem.SetWorldPosition(characterSingleton.modelEntity, vec3(0.0f, 0.0f, 0.0f));
transformSystem.ParentEntityTo(characterSingleton.entity, characterSingleton.modelEntity);
- ModelLoader* modelLoader = ServiceLocator::GetGameRenderer()->GetModelLoader();
- u32 modelHash = modelLoader->GetModelHashFromModelPath("character/human/female/humanfemale.complexmodel");
- modelLoader->LoadModelForEntity(characterSingleton.modelEntity, modelHash);
-
- JPH::BodyInterface& bodyInterface = joltState.physicsSystem.GetBodyInterface();
-
- JPH::CapsuleShapeSettings shapeSetting(0.8f, 0.25f);
- JPH::ShapeSettings::ShapeResult shapeResult = shapeSetting.Create();
-
- JPH::CharacterVirtualSettings characterSettings;
- characterSettings.mShape = shapeResult.Get();
- characterSettings.mBackFaceMode = JPH::EBackFaceMode::IgnoreBackFaces;
-
- characterSingleton.character = new JPH::CharacterVirtual(&characterSettings, JPH::RVec3(0.0f, 0.0f, 0.0f), JPH::Quat::sIdentity(), &joltState.physicsSystem);
- characterSingleton.character->SetShapeOffset(JPH::Vec3(0.0f, 0.8f, 0.0f));
+ InitCharacterController(registry);
InputManager* inputManager = ServiceLocator::GetInputManager();
characterSingleton.keybindGroup = inputManager->CreateKeybindGroup("CharacterController", 100);
@@ -188,6 +175,11 @@ namespace ECS::Systems
entt::registry::context& ctx = registry.ctx();
auto& characterSingleton = ctx.get();
+ Util::EventUtil::OnEvent([&](const Components::MapLoadedEvent& event)
+ {
+ InitCharacterController(registry);
+ });
+
#ifdef JPH_DEBUG_RENDERER
// TODO: Fix Jolt Primitives being erased in JoltDebugRenderer causing crash when changing map
//Components::Transform& transform = registry.get(characterSingleton.modelEntity);
@@ -525,18 +517,47 @@ namespace ECS::Systems
}
}
- void CharacterController::ReInitCharacterModel(entt::registry& registry)
+ void CharacterController::InitCharacterController(entt::registry& registry)
{
entt::registry::context& ctx = registry.ctx();
auto& joltState = ctx.get();
auto& transformSystem = ctx.get();
+ auto& activeCamera = ctx.get();
+ auto& orbitalCameraSettings = ctx.get();
auto& characterSingleton = ctx.emplace();
ModelLoader* modelLoader = ServiceLocator::GetGameRenderer()->GetModelLoader();
u32 modelHash = modelLoader->GetModelHashFromModelPath("character/human/female/humanfemale.complexmodel");
modelLoader->LoadModelForEntity(characterSingleton.modelEntity, modelHash);
- characterSingleton.character->SetPosition(JPH::Vec3(-1500.0f, 310.0f, 1250.0f));
+ JPH::BodyInterface& bodyInterface = joltState.physicsSystem.GetBodyInterface();
+
+ JPH::CapsuleShapeSettings shapeSetting(0.8f, 0.25f);
+ JPH::ShapeSettings::ShapeResult shapeResult = shapeSetting.Create();
+
+ JPH::CharacterVirtualSettings characterSettings;
+ characterSettings.mShape = shapeResult.Get();
+ characterSettings.mBackFaceMode = JPH::EBackFaceMode::IgnoreBackFaces;
+
+ characterSingleton.character = new JPH::CharacterVirtual(&characterSettings, JPH::RVec3(0.0f, 0.0f, 0.0f), JPH::Quat::sIdentity(), &joltState.physicsSystem);
+ characterSingleton.character->SetShapeOffset(JPH::Vec3(0.0f, 0.8f, 0.0f));
+
+ MapLoader* mapLoader = ServiceLocator::GetGameRenderer()->GetMapLoader();
+
+ JPH::Vec3 newPosition = JPH::Vec3(-1500.0f, 310.0f, 1250.0f);
+
+ if (mapLoader->GetCurrentMapID() == std::numeric_limits().max())
+ {
+ newPosition = JPH::Vec3(0.0f, 0.0f, 0.0f);
+ }
+
+ characterSingleton.character->SetPosition(newPosition);
+ transformSystem.SetWorldPosition(characterSingleton.entity, vec3(newPosition.GetX(), newPosition.GetY(), newPosition.GetZ()));
+
+ if (activeCamera.entity == orbitalCameraSettings.entity)
+ {
+ transformSystem.ParentEntityTo(characterSingleton.entity, orbitalCameraSettings.entity);
+ }
}
}
\ No newline at end of file
diff --git a/Source/Game/Game/ECS/Systems/CharacterController.h b/Source/Game/Game/ECS/Systems/CharacterController.h
index 8ecd65e5..7cc3655d 100644
--- a/Source/Game/Game/ECS/Systems/CharacterController.h
+++ b/Source/Game/Game/ECS/Systems/CharacterController.h
@@ -10,6 +10,6 @@ namespace ECS::Systems
static void Init(entt::registry& registry);
static void Update(entt::registry& registry, f32 deltaTime);
- static void ReInitCharacterModel(entt::registry& registry);
+ static void InitCharacterController(entt::registry& registry);
};
}
\ No newline at end of file
diff --git a/Source/Game/Game/ECS/Util/EventUtil.h b/Source/Game/Game/ECS/Util/EventUtil.h
new file mode 100644
index 00000000..4c2b4481
--- /dev/null
+++ b/Source/Game/Game/ECS/Util/EventUtil.h
@@ -0,0 +1,38 @@
+#pragma once
+#include "Game/Application/EnttRegistries.h"
+#include "Game/Util/ServiceLocator.h"
+
+#include
+
+#include
+
+namespace ECS::Util
+{
+ namespace EventUtil
+ {
+ template
+ inline void PushEventTo(entt::registry& registry, Events&&... events)
+ {
+ entt::entity eventEntity = registry.create();
+ (registry.emplace>(eventEntity, std::forward(events)), ...);
+ }
+
+ template
+ inline void PushEvent(Events&&... events)
+ {
+ EnttRegistries* registries = ServiceLocator::GetEnttRegistries();
+ entt::registry* eventRegistry = registries->eventOutgoingRegistry;
+
+ PushEventTo(*eventRegistry, std::forward(events)...);
+ }
+
+ template
+ inline void OnEvent(Handler&& handler)
+ {
+ EnttRegistries* registries = ServiceLocator::GetEnttRegistries();
+ entt::registry* eventRegistry = registries->eventIncomingRegistry;
+
+ eventRegistry->view().each(std::forward(handler));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Game/Game/Gameplay/MapLoader.cpp b/Source/Game/Game/Gameplay/MapLoader.cpp
index 5add9e36..5ba422ff 100644
--- a/Source/Game/Game/Gameplay/MapLoader.cpp
+++ b/Source/Game/Game/Gameplay/MapLoader.cpp
@@ -2,8 +2,10 @@
#include "Game/Application/EnttRegistries.h"
#include "Game/Editor/EditorHandler.h"
#include "Game/Editor/Inspector.h"
+#include "Game/ECS/Components/Events.h"
#include "Game/ECS/Singletons/ClientDBCollection.h"
#include "Game/ECS/Singletons/MapDB.h"
+#include "Game/ECS/Util/EventUtil.h"
#include "Game/Rendering/GameRenderer.h"
#include "Game/Rendering/Debug/JoltDebugRenderer.h"
#include "Game/Rendering/Terrain/TerrainLoader.h"
@@ -39,6 +41,7 @@ void MapLoader::Update(f32 deltaTime)
// Clear Map
if (request.internalMapNameHash == std::numeric_limits().max())
{
+ _currentMapID = std::numeric_limits().max();
ClearRenderersForMap();
}
else
@@ -88,12 +91,16 @@ void MapLoader::Update(f32 deltaTime)
{
if (!_modelLoader->ContainsDiscoveredModel(mapHeader.placement.nameHash))
return;
+
+ _currentMapID = mapID;
ClearRenderersForMap();
_modelLoader->LoadPlacement(mapHeader.placement);
}
else
{
+ _currentMapID = mapID;
+
TerrainLoader::LoadDesc loadDesc;
loadDesc.loadType = TerrainLoader::LoadType::Full;
loadDesc.mapName = internalMapName;
@@ -129,4 +136,6 @@ void MapLoader::ClearRenderersForMap()
Editor::EditorHandler* editorHandler = ServiceLocator::GetEditorHandler();
editorHandler->GetInspector()->ClearSelection();
+
+ ECS::Util::EventUtil::PushEvent(ECS::Components::MapLoadedEvent{ _currentMapID });
}
diff --git a/Source/Game/Game/Gameplay/MapLoader.h b/Source/Game/Game/Gameplay/MapLoader.h
index 471859bf..93498116 100644
--- a/Source/Game/Game/Gameplay/MapLoader.h
+++ b/Source/Game/Game/Gameplay/MapLoader.h
@@ -26,7 +26,7 @@ class MapLoader
void UnloadMap();
void LoadMap(u32 mapHash);
- const u32 GetCurrentMapIndex() { return _currentMapIndex; }
+ const u32 GetCurrentMapID() { return _currentMapID; }
private:
void ClearRenderersForMap();
@@ -36,6 +36,6 @@ class MapLoader
ModelLoader* _modelLoader = nullptr;
LiquidLoader* _liquidLoader = nullptr;
- u32 _currentMapIndex = std::numeric_limits().max();
+ u32 _currentMapID = std::numeric_limits().max();
moodycamel::ConcurrentQueue _requests;
};
\ No newline at end of file
diff --git a/Source/Game/Game/Rendering/Model/ModelLoader.cpp b/Source/Game/Game/Rendering/Model/ModelLoader.cpp
index 2f29f7ee..6cea73f5 100644
--- a/Source/Game/Game/Rendering/Model/ModelLoader.cpp
+++ b/Source/Game/Game/Rendering/Model/ModelLoader.cpp
@@ -180,6 +180,8 @@ void ModelLoader::Clear()
bodyInterface.RemoveBody(id);
bodyInterface.DestroyBody(id);
}
+
+ _instanceIDToBodyID.clear();
}
for (auto& pair : _nameHashToJoltShape)
@@ -756,10 +758,12 @@ void ModelLoader::AddStaticInstance(entt::entity entityID, const LoadRequestInte
// Create the actual rigid body
JPH::Body* body = bodyInterface.CreateBody(bodySettings); // Note that if we run out of bodies this can return nullptr
-
- JPH::BodyID bodyID = body->GetID();
- bodyInterface.AddBody(bodyID, JPH::EActivation::Activate);
- _instanceIDToBodyID[instanceID] = bodyID.GetIndexAndSequenceNumber();
+ if (body)
+ {
+ JPH::BodyID bodyID = body->GetID();
+ bodyInterface.AddBody(bodyID, JPH::EActivation::Activate);
+ _instanceIDToBodyID[instanceID] = bodyID.GetIndexAndSequenceNumber();
+ }
}
}
diff --git a/Source/Game/Game/Rendering/Terrain/TerrainLoader.cpp b/Source/Game/Game/Rendering/Terrain/TerrainLoader.cpp
index 6dedb5a8..394e6554 100644
--- a/Source/Game/Game/Rendering/Terrain/TerrainLoader.cpp
+++ b/Source/Game/Game/Rendering/Terrain/TerrainLoader.cpp
@@ -2,8 +2,10 @@
#include "TerrainRenderer.h"
#include "Game/Application/EnttRegistries.h"
+#include "Game/ECS/Components/Events.h"
#include "Game/ECS/Singletons/JoltState.h"
#include "Game/ECS/Systems/CharacterController.h"
+#include "Game/ECS/Util/EventUtil.h"
#include "Game/Editor/EditorHandler.h"
#include "Game/Editor/Inspector.h"
#include "Game/Rendering/Debug/DebugRenderer.h"
@@ -11,6 +13,7 @@
#include "Game/Rendering/GameRenderer.h"
#include "Game/Rendering/Model/ModelLoader.h"
#include "Game/Rendering/Liquid/LiquidLoader.h"
+#include "Game/Gameplay/MapLoader.h"
#include "Game/Util/JoltStream.h"
#include "Game/Util/MapUtil.h"
#include "Game/Util/ServiceLocator.h"
@@ -402,7 +405,8 @@ void TerrainLoader::LoadFullMapRequest(const LoadRequestInternal& request)
taskScheduler->AddTaskSetToPipe(&loadChunksTask);
taskScheduler->WaitforTask(&loadChunksTask);
- ECS::Systems::CharacterController::ReInitCharacterModel(*registry);
+ u32 mapID = ServiceLocator::GetGameRenderer()->GetMapLoader()->GetCurrentMapID();
+ ECS::Util::EventUtil::PushEvent(ECS::Components::MapLoadedEvent{ mapID });
i32 physicsOptimizeBP = *CVarSystem::Get()->GetIntCVar(CVarCategory::Client | CVarCategory::Physics, "optimizeBP"_h);
if (physicsEnabled && physicsOptimizeBP)
diff --git a/Source/Game/Game/Scripting/LuaManager.h b/Source/Game/Game/Scripting/LuaManager.h
index 2d28f2b8..3edf3706 100644
--- a/Source/Game/Game/Scripting/LuaManager.h
+++ b/Source/Game/Game/Scripting/LuaManager.h
@@ -36,7 +36,7 @@ namespace Scripting
template
bool SetGlobal(const std::string& name, T& value, bool canOverride)
{
- if (_globalTable.data.contains(name) && canOverride)
+ if (_globalTable.data.contains(name) && !canOverride)
return false;
_globalTable.data[name] = value;