From f7fd56bda9a7114f6ba15b1d7f6cf31ac87c9b09 Mon Sep 17 00:00:00 2001 From: Stepan Date: Mon, 27 Oct 2025 01:37:44 +0300 Subject: [PATCH 01/24] homework 7 --- Engine/Editor/CMakeLists.txt | 2 + .../LevelEditor/ECS/ecsLevelEditor.cpp | 41 ++++-- .../private/LevelEditor/ECS/ecsLevelEditor.h | 20 +-- .../private/LevelEditor/LevelEditor.cpp | 119 ++++++++++++------ .../Editor/public/LevelEditor/LevelEditor.h | 3 + Engine/Source/World/CMakeLists.txt | 1 + Engine/Source/World/public/Level.h | 2 +- Samples/SimpleScene/Assets/Levels/main.xml | 4 +- 8 files changed, 134 insertions(+), 58 deletions(-) diff --git a/Engine/Editor/CMakeLists.txt b/Engine/Editor/CMakeLists.txt index b1e15e18f..f8bc6d29a 100644 --- a/Engine/Editor/CMakeLists.txt +++ b/Engine/Editor/CMakeLists.txt @@ -78,6 +78,8 @@ target_precompile_headers(Editor PRIVATE + + diff --git a/Engine/Editor/private/LevelEditor/ECS/ecsLevelEditor.cpp b/Engine/Editor/private/LevelEditor/ECS/ecsLevelEditor.cpp index b12ba322c..c4e682d76 100644 --- a/Engine/Editor/private/LevelEditor/ECS/ecsLevelEditor.cpp +++ b/Engine/Editor/private/LevelEditor/ECS/ecsLevelEditor.cpp @@ -1,28 +1,43 @@ #include -namespace -{ - void ParsePosition( - const GameEngine::EntitySystem::LevelEditorECS::PositionDesc& positionDesc, - GameEngine::EntitySystem::EditorECS::Position& position - ) - { - assert(positionDesc.value); - assert(std::ranges::count(*positionDesc.value, ',') == 2); - const char* compValue = positionDesc.value->c_str(); +namespace GameEngine { + Math::Vector3f ParseStringToFloat3(const World::LevelObject::ComponentDesc& componentDesc) { + + assert(std::ranges::count(componentDesc, ',') == 2); + + Math::Vector3f vec = Math::Vector3f::Zero(); + + const char* compValue = componentDesc.c_str(); char* end; float f = std::strtof(compValue, &end); - position.x = f; + vec.x = f; compValue = end + 1; f = std::strtof(compValue, &end); - position.y = f; + vec.y = f; compValue = end + 1; f = std::strtof(compValue, &end); - position.z = f; + vec.z = f; + + return vec; + } +} + +namespace +{ + void ParsePosition( + const GameEngine::EntitySystem::LevelEditorECS::PositionDesc& positionDesc, + GameEngine::EntitySystem::EditorECS::Position& position + ) + { + assert(positionDesc.value); + GameEngine::Math::Vector3f vecPos = GameEngine::ParseStringToFloat3(*positionDesc.value); + position.x = vecPos.x; + position.y = vecPos.y; + position.z = vecPos.z; } } diff --git a/Engine/Editor/private/LevelEditor/ECS/ecsLevelEditor.h b/Engine/Editor/private/LevelEditor/ECS/ecsLevelEditor.h index 85961e209..8be4e66c4 100644 --- a/Engine/Editor/private/LevelEditor/ECS/ecsLevelEditor.h +++ b/Engine/Editor/private/LevelEditor/ECS/ecsLevelEditor.h @@ -4,13 +4,19 @@ #include #include +#include -namespace GameEngine::EntitySystem::LevelEditorECS -{ - struct PositionDesc - { - const World::LevelObject::ComponentDesc* value; - }; +namespace GameEngine { + Math::Vector3f ParseStringToFloat3(const World::LevelObject::ComponentDesc& componentDesc); + + namespace EntitySystem::LevelEditorECS { + + struct PositionDesc + { + const World::LevelObject::ComponentDesc* value; + }; + + void RegisterLevelEditorEcsSystems(flecs::world& world); + } - void RegisterLevelEditorEcsSystems(flecs::world& world); } \ No newline at end of file diff --git a/Engine/Editor/private/LevelEditor/LevelEditor.cpp b/Engine/Editor/private/LevelEditor/LevelEditor.cpp index 08367b2c8..50d94c5b5 100644 --- a/Engine/Editor/private/LevelEditor/LevelEditor.cpp +++ b/Engine/Editor/private/LevelEditor/LevelEditor.cpp @@ -15,46 +15,15 @@ namespace GameEngine { LevelEditor::LevelEditor(flecs::world& world) { + m_World = world.get_world(); m_Level = LevelSerializer::Deserialize(Core::g_FileSystem->GetFilePath("Levels/Main.xml").generic_string()); for (World::LevelObject& levelObject : m_Level->GetLevelObjects()) { - flecs::entity entity = world.entity(levelObject.GetName().c_str()); - - World::LevelObject::ComponentList& componentList = levelObject.GetComponents(); - - World::LevelObject::ComponentList::iterator positionAttribute = std::ranges::find_if(componentList, - [](World::LevelObject::Component& component) - { - return !std::strcmp(component.first.c_str(), "Position"); - } - ); - - World::LevelObject::ComponentList::iterator geometryAttribute = std::ranges::find_if(componentList, - [](World::LevelObject::Component& component) - { - return !std::strcmp(component.first.c_str(), "GeometryPtr"); - } - ); - - if (positionAttribute != componentList.end() && - geometryAttribute != componentList.end()) - { - assert(World::WorldParser::GetCustomComponents().contains(geometryAttribute->second)); - - entity.set(EntitySystem::LevelEditorECS::PositionDesc{ &positionAttribute->second }); - - // Can be set to 0 since it doesn't matter now, will be updated by the system - entity.set(EntitySystem::EditorECS::Position{ 0.0f, 0.0f, 0.0f }); - entity.set(GeometryPtr{ - reinterpret_cast( - World::WorldParser::GetCustomComponents()[geometryAttribute->second] - ) - }); - } + AddLevelEditorEntity(levelObject); } - EntitySystem::LevelEditorECS::RegisterLevelEditorEcsSystems(world); + EntitySystem::LevelEditorECS::RegisterLevelEditorEcsSystems(m_World); } void LevelEditor::Draw() @@ -67,15 +36,34 @@ namespace GameEngine { if (ImGui::TreeNode(levelObject.GetName().c_str())) { + static const std::set VECTOR3_COMPONENTS = { + "Position", "Velocity", "Gravity", + }; for (World::LevelObject::Component& component : levelObject.GetComponents()) { - ImGui::InputText(component.first.c_str(), &component.second); + if (VECTOR3_COMPONENTS.contains(component.first)) { + Math::Vector3f vec = ParseStringToFloat3(component.second); + + float arrayPos[3] = { vec.x, vec.y, vec.z }; + ImGui::InputFloat3(component.first.c_str(), arrayPos); + component.second = + std::to_string(arrayPos[0]) + "," + + std::to_string(arrayPos[1]) + "," + + std::to_string(arrayPos[2]); + } + else { + ImGui::InputText(component.first.c_str(), &component.second); + } } ImGui::TreePop(); } } } + if (ImGui::Button("Add Default Object")) + { + AddDefaultObject(); + } if (ImGui::Button("Save")) { @@ -109,5 +97,66 @@ namespace GameEngine assert(m_Level.has_value()); LevelSerializer::Serialize(Core::g_FileSystem->GetFilePath("Levels/Main.xml").generic_string(), m_Level.value()); } + + void LevelEditor::AddDefaultObject() { + if (!m_Level.has_value()) return; + + std::string baseName = "NewObject1"; + std::string objectName = baseName; + int counter = 1; + + World::Level::LevelObjectList& objects = m_Level.value().GetLevelObjects(); + while ( std::ranges::find_if(objects, [&](const World::LevelObject& obj) { return obj.GetName() == objectName; }) != objects.end() ) { + objectName = baseName + std::to_string(++counter); + } + + World::LevelObject newLevelObject; + newLevelObject.SetName(objectName.c_str()); + newLevelObject.AddComponent("Position", "0.0,0.0,0.0"); + newLevelObject.AddComponent("Velocity", "0.0,0.0,0.0"); + newLevelObject.AddComponent("Gravity", "0.0,-9.8,0.0"); + newLevelObject.AddComponent("BouncePlane", "0.0,1.0,0.0,5.0"); + newLevelObject.AddComponent("Bounciness", "1.0"); + newLevelObject.AddComponent("GeometryPtr", "Cube"); + + m_Level.value().AddLevelObject(newLevelObject); + AddLevelEditorEntity(m_Level.value().GetLevelObjects().back()); + } + + void LevelEditor::AddLevelEditorEntity(World::LevelObject& levelObject) { + flecs::entity entity = m_World.entity(levelObject.GetName().c_str()); + + World::LevelObject::ComponentList& componentList = levelObject.GetComponents(); + + World::LevelObject::ComponentList::iterator positionAttribute = std::ranges::find_if(componentList, + [](World::LevelObject::Component& component) + { + return !std::strcmp(component.first.c_str(), "Position"); + } + ); + + World::LevelObject::ComponentList::iterator geometryAttribute = std::ranges::find_if(componentList, + [](World::LevelObject::Component& component) + { + return !std::strcmp(component.first.c_str(), "GeometryPtr"); + } + ); + + if (positionAttribute != componentList.end() && + geometryAttribute != componentList.end()) + { + assert(World::WorldParser::GetCustomComponents().contains(geometryAttribute->second)); + + entity.set(EntitySystem::LevelEditorECS::PositionDesc{ &positionAttribute->second }); + + // Can be set to 0 since it doesn't matter now, will be updated by the system + entity.set(EntitySystem::EditorECS::Position{ 0.0f, 0.0f, 0.0f }); + entity.set(GeometryPtr{ + reinterpret_cast( + World::WorldParser::GetCustomComponents()[geometryAttribute->second] + ) + }); + } + } } } \ No newline at end of file diff --git a/Engine/Editor/public/LevelEditor/LevelEditor.h b/Engine/Editor/public/LevelEditor/LevelEditor.h index 6607f8b8f..288332804 100644 --- a/Engine/Editor/public/LevelEditor/LevelEditor.h +++ b/Engine/Editor/public/LevelEditor/LevelEditor.h @@ -22,6 +22,8 @@ namespace GameEngine private: void Save(); + void AddDefaultObject(); + void AddLevelEditorEntity(World::LevelObject& levelObject); private: Core::Timer m_SaveButtonMessageTimer; @@ -29,6 +31,7 @@ namespace GameEngine float m_TimeToShowSaveButtonMessage = 3.f; std::optional m_Level = std::nullopt; + flecs::world m_World; }; } } \ No newline at end of file diff --git a/Engine/Source/World/CMakeLists.txt b/Engine/Source/World/CMakeLists.txt index 07f44f994..4a8bfe97d 100644 --- a/Engine/Source/World/CMakeLists.txt +++ b/Engine/Source/World/CMakeLists.txt @@ -62,6 +62,7 @@ target_precompile_headers(World PRIVATE + diff --git a/Engine/Source/World/public/Level.h b/Engine/Source/World/public/Level.h index f172aa868..a74f1b99d 100644 --- a/Engine/Source/World/public/Level.h +++ b/Engine/Source/World/public/Level.h @@ -9,7 +9,7 @@ namespace GameEngine::World class WORLD_API Level final { public: - using LevelObjectList = std::vector; + using LevelObjectList = std::list; public: Level() = delete; diff --git a/Samples/SimpleScene/Assets/Levels/main.xml b/Samples/SimpleScene/Assets/Levels/main.xml index 2df506c3d..3dba54c71 100644 --- a/Samples/SimpleScene/Assets/Levels/main.xml +++ b/Samples/SimpleScene/Assets/Levels/main.xml @@ -1,4 +1,4 @@ - - + + From 5390ddc44835fed73eecc9cab6ab91e88d6712b2 Mon Sep 17 00:00:00 2001 From: Stepan Date: Tue, 11 Nov 2025 17:38:14 +0300 Subject: [PATCH 02/24] added CameraManader with functions like createCamera and SwitchCamera in GameWorld --- Engine/Editor/private/EditorECS/ecsEditor.cpp | 25 +++--- Engine/Editor/private/GameEditor.cpp | 13 ++- Engine/Editor/public/EditorECS/ecsEditor.h | 6 +- Engine/Source/Core/private/Camera.cpp | 2 +- Engine/Source/Core/private/CameraManager.cpp | 81 +++++++++++++++++++ Engine/Source/Core/private/Input/Buttons.cpp | 3 + .../Input/Windows/WindowsKeyboardButtons.h | 6 ++ Engine/Source/Core/public/CameraManager.h | 38 +++++++++ Engine/Source/Core/public/Input/Buttons.h | 3 + Engine/Source/Game/private/Game.cpp | 7 +- .../RenderEngine/private/RenderEngine.cpp | 4 +- .../Assets/Configs/Input_default.ini | 5 +- .../private/GameFramework/GameFramework.cpp | 8 +- .../SimpleScene/Source/private/ecsControl.cpp | 41 +++++++--- .../SimpleScene/Source/public/ecsControl.h | 6 +- 15 files changed, 197 insertions(+), 51 deletions(-) create mode 100644 Engine/Source/Core/private/CameraManager.cpp create mode 100644 Engine/Source/Core/public/CameraManager.h diff --git a/Engine/Editor/private/EditorECS/ecsEditor.cpp b/Engine/Editor/private/EditorECS/ecsEditor.cpp index 2a6515ebc..2e8880eeb 100644 --- a/Engine/Editor/private/EditorECS/ecsEditor.cpp +++ b/Engine/Editor/private/EditorECS/ecsEditor.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -25,8 +25,8 @@ namespace GameEngine::EntitySystem::EditorECS } }); - world.system() - .each([&](flecs::entity e, Position& position, CameraPtr& camera, const Speed& speed) + world.system() + .each([&](flecs::entity e, CameraManagerPtr& cameraManager) { if (!Core::g_MainWindowsApplication->IsMouseCaptured() || !Core::g_MainWindowsApplication->IsFocused()) [[unlikely]] { @@ -38,29 +38,30 @@ namespace GameEngine::EntitySystem::EditorECS mouseMovement.dx *= 0.25 * (Math::Constants::PI / 180.f); mouseMovement.dy *= 0.25 * (Math::Constants::PI / 180.f); - camera.ptr->Rotate(mouseMovement.dx, mouseMovement.dy); + Core::Camera* camera = cameraManager.ptr->GetCamera(); + + cameraManager.ptr->GetCamera()->Rotate(mouseMovement.dx, mouseMovement.dy); Math::Vector3f currentMoveDir = Math::Vector3f::Zero(); if (Core::InputHandler::GetInstance()->IsKeyPressed(Core::KeyboardButton::A)) { - currentMoveDir = currentMoveDir - camera.ptr->GetRightDir(); + currentMoveDir = currentMoveDir - camera->GetRightDir(); } if (Core::InputHandler::GetInstance()->IsKeyPressed(Core::KeyboardButton::D)) { - currentMoveDir = currentMoveDir + camera.ptr->GetRightDir(); + currentMoveDir = currentMoveDir + camera->GetRightDir(); } if (Core::InputHandler::GetInstance()->IsKeyPressed(Core::KeyboardButton::S)) { - currentMoveDir = currentMoveDir - camera.ptr->GetViewDir(); + currentMoveDir = currentMoveDir - camera->GetViewDir(); } if (Core::InputHandler::GetInstance()->IsKeyPressed(Core::KeyboardButton::W)) { - currentMoveDir = currentMoveDir + camera.ptr->GetViewDir(); + currentMoveDir = currentMoveDir + camera->GetViewDir(); } - position.x = position.x + currentMoveDir.Normalized().x * speed.value * world.delta_time(); - position.y = position.y + currentMoveDir.Normalized().y * speed.value * world.delta_time(); - position.z = position.z + currentMoveDir.Normalized().z * speed.value * world.delta_time(); - camera.ptr->SetPosition(Math::Vector3f(position.x, position.y, position.z)); + float speed = 10.0f; + Math::Vector3f position = camera->GetPosition() + currentMoveDir.Normalized() * speed * world.delta_time(); + camera->SetPosition(position); }); } }; diff --git a/Engine/Editor/private/GameEditor.cpp b/Engine/Editor/private/GameEditor.cpp index b8f38aa9e..e52728aa2 100644 --- a/Engine/Editor/private/GameEditor.cpp +++ b/Engine/Editor/private/GameEditor.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -18,9 +18,8 @@ namespace GameEngine ) : PlatformLoop(PlatformLoopFunc) { - Core::g_MainCamera = new Core::Camera(); - Core::g_MainCamera->SetPosition(Math::Vector3f(0.0f, 12.0f, -10.0f)); - Core::g_MainCamera->SetViewDir(Math::Vector3f(0.0f, -6.0f, 12.0f)); + Core::g_CameraManager = new Core::CameraManager(); + Core::g_CameraManager->CreateCamera(); GUI::GUIContext::GetInstance()->PlatformInit(); m_renderThread = std::make_unique(); @@ -31,10 +30,8 @@ namespace GameEngine flecs::world world; world = m_EntityManager->GetWorld().get_world(); // huge refactoring requires or flecs custom fix because this api redundancy is just annoying - flecs::entity camera = m_EntityManager->GetWorld().entity() - .set(EntitySystem::EditorECS::Position{ 0.0f, 12.0f, -10.0f }) - .set(EntitySystem::EditorECS::Speed{ 10.f }) - .set(EntitySystem::EditorECS::CameraPtr{ Core::g_MainCamera }); + flecs::entity cameraManager = m_EntityManager->GetWorld().entity() + .set(EntitySystem::EditorECS::CameraManagerPtr{ Core::g_CameraManager }); EntitySystem::EditorECS::RegisterEditorEcsControlSystems(m_EntityManager->GetWorld()); diff --git a/Engine/Editor/public/EditorECS/ecsEditor.h b/Engine/Editor/public/EditorECS/ecsEditor.h index 82974e366..8255d3acf 100644 --- a/Engine/Editor/public/EditorECS/ecsEditor.h +++ b/Engine/Editor/public/EditorECS/ecsEditor.h @@ -4,14 +4,14 @@ namespace GameEngine::Core { - class Camera; + class CameraManager; } namespace GameEngine::EntitySystem::EditorECS { - struct CameraPtr + struct CameraManagerPtr { - Core::Camera* ptr; + Core::CameraManager* ptr; }; struct Position diff --git a/Engine/Source/Core/private/Camera.cpp b/Engine/Source/Core/private/Camera.cpp index f094e6e2b..a664c88d1 100644 --- a/Engine/Source/Core/private/Camera.cpp +++ b/Engine/Source/Core/private/Camera.cpp @@ -2,7 +2,7 @@ namespace GameEngine::Core { - Camera* g_MainCamera = nullptr; + //Camera* g_MainCamera = nullptr; Math::Matrix4x4f Camera::GetViewMatrix() { diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp new file mode 100644 index 000000000..29b477bd9 --- /dev/null +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -0,0 +1,81 @@ +#include +#include +#include + +namespace GameEngine::Core +{ + CameraManager* g_CameraManager = nullptr; + + void CameraManager::CreateCamera() + { + Camera* newCamera = new Core::Camera(); + newCamera->SetPosition(Math::Vector3f(0.0f, 12.0f, -10.0f)); + newCamera->SetViewDir(Math::Vector3f(0.0f, -6.0f, 12.0f)); + + AddCamera(newCamera); + } + + void CameraManager::AddCamera(Camera* camera) + { + if (m_CameraList.empty()) + { + m_CameraList.push_back(camera); + m_CurrCameraIt = m_CameraList.begin(); + return; + } + + if (m_CurrCameraIt == m_CameraList.end()) + { + m_CameraList.push_back(camera); + m_CurrCameraIt = std::prev(m_CameraList.end()); + return; + } + + m_CurrCameraIt = m_CameraList.insert(std::next(m_CurrCameraIt), camera); + } + + Camera* CameraManager::GetCamera() + { + assert(m_CurrCameraIt != m_CameraList.end()); + return *m_CurrCameraIt; + } + + void CameraManager::SwitchNextCamera() + { + if (m_CameraList.empty()) + return; + + if (m_CurrCameraIt == m_CameraList.end()) + { + m_CurrCameraIt = m_CameraList.begin(); + return; + } + + ++m_CurrCameraIt; + if (m_CurrCameraIt == m_CameraList.end()) + { + m_CurrCameraIt = m_CameraList.begin(); + } + } + + void CameraManager::SwitchPrevCamera() + { + if (m_CameraList.empty()) + return; + + if (m_CurrCameraIt == m_CameraList.end()) + { + m_CurrCameraIt = std::prev(m_CameraList.end()); + return; + } + + if (m_CurrCameraIt == m_CameraList.begin()) + { + m_CurrCameraIt = std::prev(m_CameraList.end()); + } + else + { + --m_CurrCameraIt; + } + } +} \ No newline at end of file diff --git a/Engine/Source/Core/private/Input/Buttons.cpp b/Engine/Source/Core/private/Input/Buttons.cpp index 5910a73eb..924d3386e 100644 --- a/Engine/Source/Core/private/Input/Buttons.cpp +++ b/Engine/Source/Core/private/Input/Buttons.cpp @@ -12,6 +12,9 @@ namespace GameEngine::Core {"w", KeyboardButton::W}, {"s", KeyboardButton::S}, {"d", KeyboardButton::D}, + {"q", KeyboardButton::Q}, + {"e", KeyboardButton::E}, + {"c", KeyboardButton::C}, {"spacebar", KeyboardButton::SPACEBAR}, {"f2", KeyboardButton::F2} }; diff --git a/Engine/Source/Core/private/Input/Windows/WindowsKeyboardButtons.h b/Engine/Source/Core/private/Input/Windows/WindowsKeyboardButtons.h index 369e8b91d..e9c4ec329 100644 --- a/Engine/Source/Core/private/Input/Windows/WindowsKeyboardButtons.h +++ b/Engine/Source/Core/private/Input/Windows/WindowsKeyboardButtons.h @@ -26,6 +26,12 @@ namespace GameEngine return KeyboardButton::W; case 'D': return KeyboardButton::D; + case 'Q': + return KeyboardButton::Q; + case 'E': + return KeyboardButton::E; + case 'C': + return KeyboardButton::C; case VK_SPACE: return KeyboardButton::SPACEBAR; case VK_F2: diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h new file mode 100644 index 000000000..8cc5617e1 --- /dev/null +++ b/Engine/Source/Core/public/CameraManager.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace GameEngine +{ + namespace Core + { + class CORE_API CameraManager final + { + public: + using CameraList = std::list; + + CameraManager() + : m_CurrCameraIt(m_CameraList.end()) + {} + + + void CreateCamera(); + Camera* GetCamera(); + void SwitchNextCamera(); + void SwitchPrevCamera(); + + private: + void AddCamera(Camera* camera); + + private: + CameraList m_CameraList; + CameraList::iterator m_CurrCameraIt; + }; + + extern CORE_API CameraManager* g_CameraManager; + } +} \ No newline at end of file diff --git a/Engine/Source/Core/public/Input/Buttons.h b/Engine/Source/Core/public/Input/Buttons.h index edb51e3b2..526742f1d 100644 --- a/Engine/Source/Core/public/Input/Buttons.h +++ b/Engine/Source/Core/public/Input/Buttons.h @@ -12,6 +12,9 @@ namespace GameEngine S, W, D, + Q, + E, + C, UP, DOWN, LEFT, diff --git a/Engine/Source/Game/private/Game.cpp b/Engine/Source/Game/private/Game.cpp index 030fcc352..5790932b5 100644 --- a/Engine/Source/Game/private/Game.cpp +++ b/Engine/Source/Game/private/Game.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -12,9 +12,8 @@ namespace GameEngine ) : PlatformLoop(PlatformLoopFunc) { - Core::g_MainCamera = new Core::Camera(); - Core::g_MainCamera->SetPosition(Math::Vector3f(0.0f, 12.0f, -10.0f)); - Core::g_MainCamera->SetViewDir(Math::Vector3f(0.0f, -6.0f, 12.0f)); + Core::g_CameraManager = new Core::CameraManager(); + Core::g_CameraManager->CreateCamera(); m_renderThread = std::make_unique(); diff --git a/Engine/Source/RenderEngine/private/RenderEngine.cpp b/Engine/Source/RenderEngine/private/RenderEngine.cpp index 1af3a97b3..301e5b8ef 100644 --- a/Engine/Source/RenderEngine/private/RenderEngine.cpp +++ b/Engine/Source/RenderEngine/private/RenderEngine.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -169,7 +169,7 @@ namespace GameEngine::Render assert(materialID != RenderObject::k_invalidMaterialID); // Projection and view matrices should be a part of Camera class - Math::Matrix4x4f view = Core::g_MainCamera->GetViewMatrix(); + Math::Matrix4x4f view = Core::g_CameraManager->GetCamera()->GetViewMatrix(); Math::Matrix4x4f proj = Math::ProjectionMatrixLH(0.25f * Math::Constants::PI, Core::g_MainWindowsApplication->GetAspectRatio(), 1.0f, 1000.0f); Math::Vector3f position = renderObject->GetPosition(frame); diff --git a/Samples/SimpleScene/Assets/Configs/Input_default.ini b/Samples/SimpleScene/Assets/Configs/Input_default.ini index af01be52c..20ef3506a 100644 --- a/Samples/SimpleScene/Assets/Configs/Input_default.ini +++ b/Samples/SimpleScene/Assets/Configs/Input_default.ini @@ -3,4 +3,7 @@ GoLeft=a GoRight=d GoForward=w GoBack=s -Jump=spacebar \ No newline at end of file +Jump=spacebar +CreateCamera=c +NextCamera=e +PrevCamera=q \ No newline at end of file diff --git a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp index df7fd8eca..019fc7a04 100644 --- a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp +++ b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -21,10 +21,8 @@ void GameFramework::Init() Core::g_FileSystem->GetFilePath("Levels/Main.xml").generic_string() ); - flecs::entity camera = m_World.entity() - .set(Position{ 0.0f, 12.0f, -10.0f }) - .set(Speed{ 10.f }) - .set(CameraPtr{ Core::g_MainCamera }) + flecs::entity cameraManager = m_World.entity() + .set(CameraManagerPtr{ Core::g_CameraManager }) .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); } diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index d6f278597..26c4002b4 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -12,37 +12,54 @@ using namespace GameEngine; void RegisterEcsControlSystems(flecs::world& world) { - world.system() - .each([&](flecs::entity e, Position& position, CameraPtr& camera, const Speed& speed, const ControllerPtr& controller) + world.system() + .each([&](flecs::entity e, CameraManagerPtr& cameraManager, const ControllerPtr& controller) { Core::InputHandler::MouseMovevement mouseMovement = Core::InputHandler::GetInstance()->GetMouseMovement(); mouseMovement.dx *= 0.25 * Math::Constants::PI / 180.f; mouseMovement.dy *= 0.25 * Math::Constants::PI / 180.f; - camera.ptr->Rotate(mouseMovement.dx, mouseMovement.dy); + Core::Camera* camera = cameraManager.ptr->GetCamera(); + + camera->Rotate(mouseMovement.dx, mouseMovement.dy); Math::Vector3f currentMoveDir = Math::Vector3f::Zero(); if (controller.ptr->IsPressed("GoLeft")) { - currentMoveDir = currentMoveDir - camera.ptr->GetRightDir(); + currentMoveDir = currentMoveDir - camera->GetRightDir(); } if (controller.ptr->IsPressed("GoRight")) { - currentMoveDir = currentMoveDir + camera.ptr->GetRightDir(); + currentMoveDir = currentMoveDir + camera->GetRightDir(); } if (controller.ptr->IsPressed("GoBack")) { - currentMoveDir = currentMoveDir - camera.ptr->GetViewDir(); + currentMoveDir = currentMoveDir - camera->GetViewDir(); } if (controller.ptr->IsPressed("GoForward")) { - currentMoveDir = currentMoveDir + camera.ptr->GetViewDir(); + currentMoveDir = currentMoveDir + camera->GetViewDir(); + } + float speed = 10.0f; + Math::Vector3f position = camera->GetPosition() + currentMoveDir.Normalized() * speed * world.delta_time(); + camera->SetPosition(position); + + if (controller.ptr->IsPressed("CreateCamera")) + { + cameraManager.ptr->CreateCamera(); + ecs_sleepf(1.0); + } + else if (controller.ptr->IsPressed("NextCamera")) + { + cameraManager.ptr->SwitchNextCamera(); + ecs_sleepf(1.0); + } + else if (controller.ptr->IsPressed("PrevCamera")) + { + cameraManager.ptr->SwitchPrevCamera(); + ecs_sleepf(1.0); } - position.x = position.x + currentMoveDir.Normalized().x * speed.value * world.delta_time(); - position.y = position.y + currentMoveDir.Normalized().y * speed.value * world.delta_time(); - position.z = position.z + currentMoveDir.Normalized().z * speed.value * world.delta_time(); - camera.ptr->SetPosition(Math::Vector3f(position.x, position.y, position.z)); }); world.system() diff --git a/Samples/SimpleScene/Source/public/ecsControl.h b/Samples/SimpleScene/Source/public/ecsControl.h index c322735f9..e6549bcb0 100644 --- a/Samples/SimpleScene/Source/public/ecsControl.h +++ b/Samples/SimpleScene/Source/public/ecsControl.h @@ -4,7 +4,7 @@ namespace GameEngine::Core { - class Camera; + class CameraManager; class Controller; } @@ -18,9 +18,9 @@ struct JumpSpeed float value; }; -struct CameraPtr +struct CameraManagerPtr { - GameEngine::Core::Camera* ptr; + GameEngine::Core::CameraManager* ptr; }; void RegisterEcsControlSystems(flecs::world& world); From 29308891cc52ad310432d6bd8a1d10f1b6c2a1b5 Mon Sep 17 00:00:00 2001 From: Stepan Date: Tue, 11 Nov 2025 18:56:49 +0300 Subject: [PATCH 03/24] added shared_ptr on Camera in CameraManager --- Engine/Editor/private/EditorECS/ecsEditor.cpp | 4 ++-- Engine/Source/Core/private/CameraManager.cpp | 9 +++++---- Engine/Source/Core/public/Camera.h | 2 ++ Engine/Source/Core/public/CameraManager.h | 10 +++++----- Engine/Source/RenderEngine/private/RenderEngine.cpp | 2 +- Samples/SimpleScene/Source/private/ecsControl.cpp | 2 +- 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Engine/Editor/private/EditorECS/ecsEditor.cpp b/Engine/Editor/private/EditorECS/ecsEditor.cpp index 2e8880eeb..4e2ad2cab 100644 --- a/Engine/Editor/private/EditorECS/ecsEditor.cpp +++ b/Engine/Editor/private/EditorECS/ecsEditor.cpp @@ -38,9 +38,9 @@ namespace GameEngine::EntitySystem::EditorECS mouseMovement.dx *= 0.25 * (Math::Constants::PI / 180.f); mouseMovement.dy *= 0.25 * (Math::Constants::PI / 180.f); - Core::Camera* camera = cameraManager.ptr->GetCamera(); + Core::Camera::Ptr camera = cameraManager.ptr->GetActiveCamera(); - cameraManager.ptr->GetCamera()->Rotate(mouseMovement.dx, mouseMovement.dy); + camera->Rotate(mouseMovement.dx, mouseMovement.dy); Math::Vector3f currentMoveDir = Math::Vector3f::Zero(); if (Core::InputHandler::GetInstance()->IsKeyPressed(Core::KeyboardButton::A)) diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index 29b477bd9..7fd0b6870 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -6,16 +6,17 @@ namespace GameEngine::Core { CameraManager* g_CameraManager = nullptr; - void CameraManager::CreateCamera() + Camera::Ptr CameraManager::CreateCamera() { - Camera* newCamera = new Core::Camera(); + auto newCamera = std::make_shared(); newCamera->SetPosition(Math::Vector3f(0.0f, 12.0f, -10.0f)); newCamera->SetViewDir(Math::Vector3f(0.0f, -6.0f, 12.0f)); AddCamera(newCamera); + return newCamera; } - void CameraManager::AddCamera(Camera* camera) + void CameraManager::AddCamera(Camera::Ptr camera) { if (m_CameraList.empty()) { @@ -34,7 +35,7 @@ namespace GameEngine::Core m_CurrCameraIt = m_CameraList.insert(std::next(m_CurrCameraIt), camera); } - Camera* CameraManager::GetCamera() + Camera::Ptr CameraManager::GetActiveCamera() { assert(m_CurrCameraIt != m_CameraList.end()); return *m_CurrCameraIt; diff --git a/Engine/Source/Core/public/Camera.h b/Engine/Source/Core/public/Camera.h index 78bc5a304..e0c37da88 100644 --- a/Engine/Source/Core/public/Camera.h +++ b/Engine/Source/Core/public/Camera.h @@ -11,6 +11,8 @@ namespace GameEngine class CORE_API Camera final { public: + using Ptr = std::shared_ptr; + Camera() = default; public: diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h index 8cc5617e1..e102d337b 100644 --- a/Engine/Source/Core/public/CameraManager.h +++ b/Engine/Source/Core/public/CameraManager.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace GameEngine { @@ -13,20 +14,19 @@ namespace GameEngine class CORE_API CameraManager final { public: - using CameraList = std::list; + using CameraList = std::list; CameraManager() : m_CurrCameraIt(m_CameraList.end()) {} - - void CreateCamera(); - Camera* GetCamera(); + Camera::Ptr CreateCamera(); + Camera::Ptr GetActiveCamera(); void SwitchNextCamera(); void SwitchPrevCamera(); private: - void AddCamera(Camera* camera); + void AddCamera(Camera::Ptr camera); private: CameraList m_CameraList; diff --git a/Engine/Source/RenderEngine/private/RenderEngine.cpp b/Engine/Source/RenderEngine/private/RenderEngine.cpp index 301e5b8ef..e80a1f32e 100644 --- a/Engine/Source/RenderEngine/private/RenderEngine.cpp +++ b/Engine/Source/RenderEngine/private/RenderEngine.cpp @@ -169,7 +169,7 @@ namespace GameEngine::Render assert(materialID != RenderObject::k_invalidMaterialID); // Projection and view matrices should be a part of Camera class - Math::Matrix4x4f view = Core::g_CameraManager->GetCamera()->GetViewMatrix(); + Math::Matrix4x4f view = Core::g_CameraManager->GetActiveCamera()->GetViewMatrix(); Math::Matrix4x4f proj = Math::ProjectionMatrixLH(0.25f * Math::Constants::PI, Core::g_MainWindowsApplication->GetAspectRatio(), 1.0f, 1000.0f); Math::Vector3f position = renderObject->GetPosition(frame); diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index 26c4002b4..fbfaa95ba 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -20,7 +20,7 @@ void RegisterEcsControlSystems(flecs::world& world) mouseMovement.dx *= 0.25 * Math::Constants::PI / 180.f; mouseMovement.dy *= 0.25 * Math::Constants::PI / 180.f; - Core::Camera* camera = cameraManager.ptr->GetCamera(); + Core::Camera::Ptr camera = cameraManager.ptr->GetActiveCamera(); camera->Rotate(mouseMovement.dx, mouseMovement.dy); From 8d9d6ccd652c36f97f440b99780ae319396ad464 Mon Sep 17 00:00:00 2001 From: Stepan Date: Tue, 11 Nov 2025 20:09:29 +0300 Subject: [PATCH 04/24] added currectly switch between buttons --- Engine/Source/Core/CMakeLists.txt | 2 + Engine/Source/Core/public/CameraManager.h | 2 - .../private/GameFramework/GameFramework.cpp | 1 + .../SimpleScene/Source/private/ecsControl.cpp | 54 +++++++++++++------ .../SimpleScene/Source/public/ecsControl.h | 7 +++ 5 files changed, 47 insertions(+), 19 deletions(-) diff --git a/Engine/Source/Core/CMakeLists.txt b/Engine/Source/Core/CMakeLists.txt index 140177e59..5f158dcaf 100644 --- a/Engine/Source/Core/CMakeLists.txt +++ b/Engine/Source/Core/CMakeLists.txt @@ -108,4 +108,6 @@ target_precompile_headers(Core + + ) \ No newline at end of file diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h index e102d337b..1e07b1447 100644 --- a/Engine/Source/Core/public/CameraManager.h +++ b/Engine/Source/Core/public/CameraManager.h @@ -4,8 +4,6 @@ #include #include #include -#include -#include namespace GameEngine { diff --git a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp index 019fc7a04..ceb69b657 100644 --- a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp +++ b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp @@ -23,6 +23,7 @@ void GameFramework::Init() flecs::entity cameraManager = m_World.entity() .set(CameraManagerPtr{ Core::g_CameraManager }) + .set(ButtonManager{ false, false, false }) .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); } diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index fbfaa95ba..213c45e8e 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -7,13 +7,34 @@ #include #include #include +#include using namespace GameEngine; + +static void ProcessButtonPress(const ControllerPtr& controller, + const char* actionName, + const std::function& action, + bool& wasPressedFlag) +{ + if (controller.ptr->IsPressed(actionName)) + { + if (!wasPressedFlag) + { + action(); + wasPressedFlag = true; + } + } + else + { + wasPressedFlag = false; + } +} + void RegisterEcsControlSystems(flecs::world& world) { - world.system() - .each([&](flecs::entity e, CameraManagerPtr& cameraManager, const ControllerPtr& controller) + world.system() + .each([&](flecs::entity e, CameraManagerPtr& cameraManager, ButtonManager& buttonManager, const ControllerPtr& controller) { Core::InputHandler::MouseMovevement mouseMovement = Core::InputHandler::GetInstance()->GetMouseMovement(); @@ -45,21 +66,20 @@ void RegisterEcsControlSystems(flecs::world& world) Math::Vector3f position = camera->GetPosition() + currentMoveDir.Normalized() * speed * world.delta_time(); camera->SetPosition(position); - if (controller.ptr->IsPressed("CreateCamera")) - { - cameraManager.ptr->CreateCamera(); - ecs_sleepf(1.0); - } - else if (controller.ptr->IsPressed("NextCamera")) - { - cameraManager.ptr->SwitchNextCamera(); - ecs_sleepf(1.0); - } - else if (controller.ptr->IsPressed("PrevCamera")) - { - cameraManager.ptr->SwitchPrevCamera(); - ecs_sleepf(1.0); - } + ProcessButtonPress(controller, "CreateCamera", + [&]() { cameraManager.ptr->CreateCamera(); }, + buttonManager.wasPressedCreateCameraButton + ); + + ProcessButtonPress(controller, "NextCamera", + [&]() { cameraManager.ptr->SwitchNextCamera(); }, + buttonManager.wasPressedNextCameraButton + ); + + ProcessButtonPress(controller, "PrevCamera", + [&]() { cameraManager.ptr->SwitchPrevCamera(); }, + buttonManager.wasPressedPrevCameraButton + ); }); world.system() diff --git a/Samples/SimpleScene/Source/public/ecsControl.h b/Samples/SimpleScene/Source/public/ecsControl.h index e6549bcb0..1af53476c 100644 --- a/Samples/SimpleScene/Source/public/ecsControl.h +++ b/Samples/SimpleScene/Source/public/ecsControl.h @@ -13,6 +13,13 @@ struct ControllerPtr GameEngine::Core::Controller* ptr; }; +struct ButtonManager +{ + bool wasPressedCreateCameraButton; + bool wasPressedNextCameraButton; + bool wasPressedPrevCameraButton; +}; + struct JumpSpeed { float value; From 34296906de5c173ec4695781c20a8b0689e4dcb8 Mon Sep 17 00:00:00 2001 From: Stepan Date: Tue, 11 Nov 2025 20:13:21 +0300 Subject: [PATCH 05/24] was already in the project --- Samples/SimpleScene/Source/private/ecsControl.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index 213c45e8e..2b87889a9 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -7,7 +7,6 @@ #include #include #include -#include using namespace GameEngine; From d61f76376c7e564b4996774de20ffa4817b37365 Mon Sep 17 00:00:00 2001 From: Stepan Date: Tue, 11 Nov 2025 20:15:28 +0300 Subject: [PATCH 06/24] added in CMakeList --- Engine/Source/Core/CMakeLists.txt | 1 + Engine/Source/Core/private/CameraManager.cpp | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Engine/Source/Core/CMakeLists.txt b/Engine/Source/Core/CMakeLists.txt index 5f158dcaf..72e6701ac 100644 --- a/Engine/Source/Core/CMakeLists.txt +++ b/Engine/Source/Core/CMakeLists.txt @@ -110,4 +110,5 @@ target_precompile_headers(Core + ) \ No newline at end of file diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index 7fd0b6870..908ebf12d 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -1,6 +1,4 @@ #include -#include -#include namespace GameEngine::Core { From 658a8d16c3c0ce8797f67cf3d3a62ddaa8a665f5 Mon Sep 17 00:00:00 2001 From: Stepan Date: Tue, 11 Nov 2025 20:19:22 +0300 Subject: [PATCH 07/24] added start value for a new camera --- Engine/Source/Core/private/CameraManager.cpp | 4 ++-- Engine/Source/Core/public/CameraManager.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index 908ebf12d..8e6b250b7 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -7,8 +7,8 @@ namespace GameEngine::Core Camera::Ptr CameraManager::CreateCamera() { auto newCamera = std::make_shared(); - newCamera->SetPosition(Math::Vector3f(0.0f, 12.0f, -10.0f)); - newCamera->SetViewDir(Math::Vector3f(0.0f, -6.0f, 12.0f)); + newCamera->SetPosition(startCameraPosition); + newCamera->SetViewDir(startCameraViewDir); AddCamera(newCamera); return newCamera; diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h index 1e07b1447..c86eff10e 100644 --- a/Engine/Source/Core/public/CameraManager.h +++ b/Engine/Source/Core/public/CameraManager.h @@ -29,6 +29,9 @@ namespace GameEngine private: CameraList m_CameraList; CameraList::iterator m_CurrCameraIt; + + inline static Math::Vector3f startCameraPosition = Math::Vector3f(0.0f, 12.0f, -10.0f); + inline static Math::Vector3f startCameraViewDir = Math::Vector3f(0.0f, -6.0f, 12.0f); }; extern CORE_API CameraManager* g_CameraManager; From c4f10c993a7e62db574c7227079d5ccb52cabb15 Mon Sep 17 00:00:00 2001 From: Stepan Date: Sun, 16 Nov 2025 14:38:20 +0300 Subject: [PATCH 08/24] code style --- .../private/LevelEditor/LevelEditor.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Engine/Editor/private/LevelEditor/LevelEditor.cpp b/Engine/Editor/private/LevelEditor/LevelEditor.cpp index 50d94c5b5..9cd8df795 100644 --- a/Engine/Editor/private/LevelEditor/LevelEditor.cpp +++ b/Engine/Editor/private/LevelEditor/LevelEditor.cpp @@ -41,7 +41,8 @@ namespace GameEngine }; for (World::LevelObject::Component& component : levelObject.GetComponents()) { - if (VECTOR3_COMPONENTS.contains(component.first)) { + if (VECTOR3_COMPONENTS.contains(component.first)) + { Math::Vector3f vec = ParseStringToFloat3(component.second); float arrayPos[3] = { vec.x, vec.y, vec.z }; @@ -51,7 +52,8 @@ namespace GameEngine std::to_string(arrayPos[1]) + "," + std::to_string(arrayPos[2]); } - else { + else + { ImGui::InputText(component.first.c_str(), &component.second); } } @@ -98,12 +100,16 @@ namespace GameEngine LevelSerializer::Serialize(Core::g_FileSystem->GetFilePath("Levels/Main.xml").generic_string(), m_Level.value()); } - void LevelEditor::AddDefaultObject() { - if (!m_Level.has_value()) return; + void LevelEditor::AddDefaultObject() + { + if (!m_Level.has_value()) + { + return; + } std::string baseName = "NewObject1"; std::string objectName = baseName; - int counter = 1; + uint16_t counter = 1; World::Level::LevelObjectList& objects = m_Level.value().GetLevelObjects(); while ( std::ranges::find_if(objects, [&](const World::LevelObject& obj) { return obj.GetName() == objectName; }) != objects.end() ) { @@ -123,7 +129,8 @@ namespace GameEngine AddLevelEditorEntity(m_Level.value().GetLevelObjects().back()); } - void LevelEditor::AddLevelEditorEntity(World::LevelObject& levelObject) { + void LevelEditor::AddLevelEditorEntity(World::LevelObject& levelObject) + { flecs::entity entity = m_World.entity(levelObject.GetName().c_str()); World::LevelObject::ComponentList& componentList = levelObject.GetComponents(); From 23b3063cca4d372ba2e1a5f0b1dae15daa1376bb Mon Sep 17 00:00:00 2001 From: Stepan Date: Sun, 16 Nov 2025 15:08:36 +0300 Subject: [PATCH 09/24] changed g_CameraManager to unique_ptr --- Engine/Source/Core/private/Camera.cpp | 2 - Engine/Source/Core/private/CameraManager.cpp | 4 +- Engine/Source/Core/public/CameraManager.h | 58 +++++++++---------- Engine/Source/Game/private/Game.cpp | 2 +- .../private/GameFramework/GameFramework.cpp | 2 +- 5 files changed, 33 insertions(+), 35 deletions(-) diff --git a/Engine/Source/Core/private/Camera.cpp b/Engine/Source/Core/private/Camera.cpp index a664c88d1..6a0fd5ae1 100644 --- a/Engine/Source/Core/private/Camera.cpp +++ b/Engine/Source/Core/private/Camera.cpp @@ -2,8 +2,6 @@ namespace GameEngine::Core { - //Camera* g_MainCamera = nullptr; - Math::Matrix4x4f Camera::GetViewMatrix() { return Math::ViewMatrixLH(m_Position, m_ViewDir, Math::Vector3f(0.0f, 1.0f, 0.0f)); diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index 8e6b250b7..59d7a160b 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -2,11 +2,11 @@ namespace GameEngine::Core { - CameraManager* g_CameraManager = nullptr; + std::unique_ptr g_CameraManager = nullptr; Camera::Ptr CameraManager::CreateCamera() { - auto newCamera = std::make_shared(); + Camera::Ptr newCamera = std::make_shared(); newCamera->SetPosition(startCameraPosition); newCamera->SetViewDir(startCameraViewDir); diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h index c86eff10e..9e3fb732e 100644 --- a/Engine/Source/Core/public/CameraManager.h +++ b/Engine/Source/Core/public/CameraManager.h @@ -7,33 +7,33 @@ namespace GameEngine { - namespace Core - { - class CORE_API CameraManager final - { - public: - using CameraList = std::list; - - CameraManager() - : m_CurrCameraIt(m_CameraList.end()) - {} - - Camera::Ptr CreateCamera(); - Camera::Ptr GetActiveCamera(); - void SwitchNextCamera(); - void SwitchPrevCamera(); - - private: - void AddCamera(Camera::Ptr camera); - - private: - CameraList m_CameraList; - CameraList::iterator m_CurrCameraIt; - - inline static Math::Vector3f startCameraPosition = Math::Vector3f(0.0f, 12.0f, -10.0f); - inline static Math::Vector3f startCameraViewDir = Math::Vector3f(0.0f, -6.0f, 12.0f); - }; - - extern CORE_API CameraManager* g_CameraManager; - } + namespace Core + { + class CORE_API CameraManager final + { + public: + using CameraList = std::list; + + CameraManager() + : m_CurrCameraIt(m_CameraList.end()) + {} + + Camera::Ptr CreateCamera(); + Camera::Ptr GetActiveCamera(); + void SwitchNextCamera(); + void SwitchPrevCamera(); + + private: + void AddCamera(Camera::Ptr camera); + + private: + CameraList m_CameraList; + CameraList::iterator m_CurrCameraIt; + + inline static Math::Vector3f startCameraPosition = Math::Vector3f(0.0f, 12.0f, -10.0f); + inline static Math::Vector3f startCameraViewDir = Math::Vector3f(0.0f, -6.0f, 12.0f); + }; + + extern CORE_API std::unique_ptr g_CameraManager; + } } \ No newline at end of file diff --git a/Engine/Source/Game/private/Game.cpp b/Engine/Source/Game/private/Game.cpp index 5790932b5..5b9cf0171 100644 --- a/Engine/Source/Game/private/Game.cpp +++ b/Engine/Source/Game/private/Game.cpp @@ -12,7 +12,7 @@ namespace GameEngine ) : PlatformLoop(PlatformLoopFunc) { - Core::g_CameraManager = new Core::CameraManager(); + Core::g_CameraManager = std::make_unique(); Core::g_CameraManager->CreateCamera(); m_renderThread = std::make_unique(); diff --git a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp index ceb69b657..19a2f3e92 100644 --- a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp +++ b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp @@ -22,7 +22,7 @@ void GameFramework::Init() ); flecs::entity cameraManager = m_World.entity() - .set(CameraManagerPtr{ Core::g_CameraManager }) + .set(CameraManagerPtr{ Core::g_CameraManager.get() }) .set(ButtonManager{ false, false, false }) .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); } From 94b0d100658641bcee40382453be09e651119685 Mon Sep 17 00:00:00 2001 From: Stepan Date: Sun, 16 Nov 2025 15:39:22 +0300 Subject: [PATCH 10/24] added new functional in CameraManager: SetActiveCamera(camera) --- Engine/Source/Core/CMakeLists.txt | 1 + Engine/Source/Core/private/CameraManager.cpp | 19 ++++++++++++++++++ Engine/Source/Core/private/Input/Buttons.cpp | 2 ++ .../Input/Windows/WindowsKeyboardButtons.h | 4 ++++ Engine/Source/Core/public/CameraManager.h | 3 +++ Engine/Source/Core/public/Input/Buttons.h | 2 ++ .../Assets/Configs/Input_default.ini | 4 +++- .../private/GameFramework/GameFramework.cpp | 1 + .../SimpleScene/Source/private/ecsControl.cpp | 20 ++++++++++++------- .../SimpleScene/Source/public/ecsControl.h | 7 +++++++ 10 files changed, 55 insertions(+), 8 deletions(-) diff --git a/Engine/Source/Core/CMakeLists.txt b/Engine/Source/Core/CMakeLists.txt index 72e6701ac..6f5593fad 100644 --- a/Engine/Source/Core/CMakeLists.txt +++ b/Engine/Source/Core/CMakeLists.txt @@ -111,4 +111,5 @@ target_precompile_headers(Core + ) \ No newline at end of file diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index 59d7a160b..a2d307a2a 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -39,6 +39,25 @@ namespace GameEngine::Core return *m_CurrCameraIt; } + void CameraManager::SetActiveCamera(Camera::Ptr camera) + { + if (!camera) + { + return; + } + + CameraList::iterator newCameraIt = std::find_if( + m_CameraList.begin(), + m_CameraList.end(), + [&](const Camera::Ptr& p) { return p == camera; } + ); + + if (newCameraIt != m_CameraList.end()) + { + m_CurrCameraIt = newCameraIt; + } + } + void CameraManager::SwitchNextCamera() { if (m_CameraList.empty()) diff --git a/Engine/Source/Core/private/Input/Buttons.cpp b/Engine/Source/Core/private/Input/Buttons.cpp index 924d3386e..9a1a2d951 100644 --- a/Engine/Source/Core/private/Input/Buttons.cpp +++ b/Engine/Source/Core/private/Input/Buttons.cpp @@ -15,6 +15,8 @@ namespace GameEngine::Core {"q", KeyboardButton::Q}, {"e", KeyboardButton::E}, {"c", KeyboardButton::C}, + {"t", KeyboardButton::T}, + {"r", KeyboardButton::R}, {"spacebar", KeyboardButton::SPACEBAR}, {"f2", KeyboardButton::F2} }; diff --git a/Engine/Source/Core/private/Input/Windows/WindowsKeyboardButtons.h b/Engine/Source/Core/private/Input/Windows/WindowsKeyboardButtons.h index e9c4ec329..dadbbdb2e 100644 --- a/Engine/Source/Core/private/Input/Windows/WindowsKeyboardButtons.h +++ b/Engine/Source/Core/private/Input/Windows/WindowsKeyboardButtons.h @@ -32,6 +32,10 @@ namespace GameEngine return KeyboardButton::E; case 'C': return KeyboardButton::C; + case 'T': + return KeyboardButton::T; + case 'R': + return KeyboardButton::R; case VK_SPACE: return KeyboardButton::SPACEBAR; case VK_F2: diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h index 9e3fb732e..f3e6d3d37 100644 --- a/Engine/Source/Core/public/CameraManager.h +++ b/Engine/Source/Core/public/CameraManager.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include namespace GameEngine { @@ -22,6 +24,7 @@ namespace GameEngine Camera::Ptr GetActiveCamera(); void SwitchNextCamera(); void SwitchPrevCamera(); + void SetActiveCamera(Camera::Ptr camera); private: void AddCamera(Camera::Ptr camera); diff --git a/Engine/Source/Core/public/Input/Buttons.h b/Engine/Source/Core/public/Input/Buttons.h index 526742f1d..cae2a27c9 100644 --- a/Engine/Source/Core/public/Input/Buttons.h +++ b/Engine/Source/Core/public/Input/Buttons.h @@ -15,6 +15,8 @@ namespace GameEngine Q, E, C, + T, + R, UP, DOWN, LEFT, diff --git a/Samples/SimpleScene/Assets/Configs/Input_default.ini b/Samples/SimpleScene/Assets/Configs/Input_default.ini index 20ef3506a..c0fdd199b 100644 --- a/Samples/SimpleScene/Assets/Configs/Input_default.ini +++ b/Samples/SimpleScene/Assets/Configs/Input_default.ini @@ -6,4 +6,6 @@ GoBack=s Jump=spacebar CreateCamera=c NextCamera=e -PrevCamera=q \ No newline at end of file +PrevCamera=q +SaveCamera=t +LoadCamera=r \ No newline at end of file diff --git a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp index 19a2f3e92..45aaaaf2a 100644 --- a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp +++ b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp @@ -23,6 +23,7 @@ void GameFramework::Init() flecs::entity cameraManager = m_World.entity() .set(CameraManagerPtr{ Core::g_CameraManager.get() }) + .set(SavedCameraPtr{ nullptr }) .set(ButtonManager{ false, false, false }) .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); } diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index 2b87889a9..48faa6b4d 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -32,8 +32,8 @@ static void ProcessButtonPress(const ControllerPtr& controller, void RegisterEcsControlSystems(flecs::world& world) { - world.system() - .each([&](flecs::entity e, CameraManagerPtr& cameraManager, ButtonManager& buttonManager, const ControllerPtr& controller) + world.system() + .each([&](flecs::entity e, CameraManagerPtr& cameraManager, SavedCameraPtr& savedCameraPtr, ButtonManager& buttonManager, const ControllerPtr& controller) { Core::InputHandler::MouseMovevement mouseMovement = Core::InputHandler::GetInstance()->GetMouseMovement(); @@ -66,19 +66,25 @@ void RegisterEcsControlSystems(flecs::world& world) camera->SetPosition(position); ProcessButtonPress(controller, "CreateCamera", - [&]() { cameraManager.ptr->CreateCamera(); }, - buttonManager.wasPressedCreateCameraButton - ); - + [&]() { cameraManager.ptr->CreateCamera(); }, + buttonManager.wasPressedCreateCameraButton + ); ProcessButtonPress(controller, "NextCamera", [&]() { cameraManager.ptr->SwitchNextCamera(); }, buttonManager.wasPressedNextCameraButton ); - ProcessButtonPress(controller, "PrevCamera", [&]() { cameraManager.ptr->SwitchPrevCamera(); }, buttonManager.wasPressedPrevCameraButton ); + ProcessButtonPress(controller, "SaveCamera", + [&]() { savedCameraPtr.ptr = cameraManager.ptr->GetActiveCamera(); }, + buttonManager.wasPressedSaveCameraButton + ); + ProcessButtonPress(controller, "LoadCamera", + [&]() { cameraManager.ptr->SetActiveCamera(savedCameraPtr.ptr); }, + buttonManager.wasPressedLoadCameraButton + ); }); world.system() diff --git a/Samples/SimpleScene/Source/public/ecsControl.h b/Samples/SimpleScene/Source/public/ecsControl.h index 1af53476c..489209976 100644 --- a/Samples/SimpleScene/Source/public/ecsControl.h +++ b/Samples/SimpleScene/Source/public/ecsControl.h @@ -18,6 +18,8 @@ struct ButtonManager bool wasPressedCreateCameraButton; bool wasPressedNextCameraButton; bool wasPressedPrevCameraButton; + bool wasPressedSaveCameraButton; + bool wasPressedLoadCameraButton; }; struct JumpSpeed @@ -30,5 +32,10 @@ struct CameraManagerPtr GameEngine::Core::CameraManager* ptr; }; +struct SavedCameraPtr +{ + GameEngine::Core::Camera::Ptr ptr; +}; + void RegisterEcsControlSystems(flecs::world& world); From 0754851a7b42f7f5c7eb53eacc2b757cf661fa96 Mon Sep 17 00:00:00 2001 From: Stepan Date: Sun, 16 Nov 2025 15:52:02 +0300 Subject: [PATCH 11/24] some fixes --- Engine/Editor/private/GameEditor.cpp | 4 ++-- Engine/Source/Core/public/CameraManager.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Engine/Editor/private/GameEditor.cpp b/Engine/Editor/private/GameEditor.cpp index e52728aa2..2a6a0d51f 100644 --- a/Engine/Editor/private/GameEditor.cpp +++ b/Engine/Editor/private/GameEditor.cpp @@ -18,7 +18,7 @@ namespace GameEngine ) : PlatformLoop(PlatformLoopFunc) { - Core::g_CameraManager = new Core::CameraManager(); + Core::g_CameraManager = std::make_unique(); Core::g_CameraManager->CreateCamera(); GUI::GUIContext::GetInstance()->PlatformInit(); @@ -31,7 +31,7 @@ namespace GameEngine // huge refactoring requires or flecs custom fix because this api redundancy is just annoying flecs::entity cameraManager = m_EntityManager->GetWorld().entity() - .set(EntitySystem::EditorECS::CameraManagerPtr{ Core::g_CameraManager }); + .set(EntitySystem::EditorECS::CameraManagerPtr{ Core::g_CameraManager.get()}); EntitySystem::EditorECS::RegisterEditorEcsControlSystems(m_EntityManager->GetWorld()); diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h index f3e6d3d37..b9b77e699 100644 --- a/Engine/Source/Core/public/CameraManager.h +++ b/Engine/Source/Core/public/CameraManager.h @@ -4,8 +4,6 @@ #include #include #include -#include -#include namespace GameEngine { From f51d00bd8dfbda61b2c2ca629c486a5f5efb048b Mon Sep 17 00:00:00 2001 From: Stepan Date: Sat, 22 Nov 2025 00:41:24 +0300 Subject: [PATCH 12/24] added common system (some new functional) which observer about was key pressed or not after some action. This system prevents keys from sticking --- .../Source/Core/private/Input/Controller.cpp | 26 +++++++++++ .../Core/private/Input/InputHandler.cpp | 46 ++++++++++++++++--- Engine/Source/Core/public/Input/Controller.h | 2 + .../Source/Core/public/Input/InputHandler.h | 10 +++- .../private/GameFramework/GameFramework.cpp | 1 - .../SimpleScene/Source/private/ecsControl.cpp | 42 +++++++---------- .../SimpleScene/Source/public/ecsControl.h | 9 ---- 7 files changed, 92 insertions(+), 44 deletions(-) diff --git a/Engine/Source/Core/private/Input/Controller.cpp b/Engine/Source/Core/private/Input/Controller.cpp index d58b9341c..7aa9a202f 100644 --- a/Engine/Source/Core/private/Input/Controller.cpp +++ b/Engine/Source/Core/private/Input/Controller.cpp @@ -45,4 +45,30 @@ namespace GameEngine::Core return false; } + + bool Controller::WasPressed(const std::string& event) + { + if (m_MouseEventMap.contains(event)) + { + return InputHandler::GetInstance()->WasKeyPressed(m_MouseEventMap[event]); + } + if (m_KeyboardEventMap.contains(event)) + { + return InputHandler::GetInstance()->WasKeyPressed(m_KeyboardEventMap[event]); + } + + return false; + } + + void Controller::SetWasPressed(const std::string& event) + { + if (m_MouseEventMap.contains(event)) + { + InputHandler::GetInstance()->SetWasKeyPressed(m_MouseEventMap[event]); + } + if (m_KeyboardEventMap.contains(event)) + { + InputHandler::GetInstance()->SetWasKeyPressed(m_KeyboardEventMap[event]); + } + } } \ No newline at end of file diff --git a/Engine/Source/Core/private/Input/InputHandler.cpp b/Engine/Source/Core/private/Input/InputHandler.cpp index 1395fbca0..08a10f741 100644 --- a/Engine/Source/Core/private/Input/InputHandler.cpp +++ b/Engine/Source/Core/private/Input/InputHandler.cpp @@ -30,7 +30,17 @@ namespace GameEngine::Core return; } - m_PressedButtons.set(static_cast(kb), true); + m_PressedButtons.set(2 * static_cast(kb), true); + } + + void InputHandler::SetWasKeyPressed(KeyboardButton kb) + { + if (kb == KeyboardButton::UNKNOWN) [[unlikely]] + { + return; + } + + m_PressedButtons.set(2 * static_cast(kb) + 1, true); } void InputHandler::KeyReleased(KeyboardButton kb) @@ -41,7 +51,8 @@ namespace GameEngine::Core return; } - m_PressedButtons.set(static_cast(kb), false); + m_PressedButtons.set(2 * static_cast(kb), false); + m_PressedButtons.set(2 * static_cast(kb) + 1, false); } void InputHandler::KeyPressed(MouseButton mb) @@ -52,7 +63,17 @@ namespace GameEngine::Core return; } - m_PressedButtons.set(KeyboardButtonCount + static_cast(mb), true); + m_PressedButtons.set(2 * KeyboardButtonCount + 2 * static_cast(mb), true); + } + + void InputHandler::SetWasKeyPressed(MouseButton mb) + { + if (mb == MouseButton::UNKNOWN) [[unlikely]] + { + return; + } + + m_PressedButtons.set(2 * KeyboardButtonCount + 2 * static_cast(mb) + 1, true); } void InputHandler::KeyReleased(MouseButton mb) @@ -63,19 +84,32 @@ namespace GameEngine::Core return; } - m_PressedButtons.set(KeyboardButtonCount + static_cast(mb), false); + m_PressedButtons.set(2 * KeyboardButtonCount + 2 * static_cast(mb), false); + m_PressedButtons.set(2 * KeyboardButtonCount + 2 * static_cast(mb) + 1, false); } bool InputHandler::IsKeyPressed(KeyboardButton kb) const { assert(kb != KeyboardButton::UNKNOWN); - return m_PressedButtons.test(static_cast(kb)); + return m_PressedButtons.test(2 * static_cast(kb)); } bool InputHandler::IsKeyPressed(MouseButton mb) const { assert(mb != MouseButton::UNKNOWN); - return m_PressedButtons.test(KeyboardButtonCount + static_cast(mb)); + return m_PressedButtons.test(2 * KeyboardButtonCount + 2 * static_cast(mb)); + } + + bool InputHandler::WasKeyPressed(KeyboardButton kb) const + { + assert(kb != KeyboardButton::UNKNOWN); + return m_PressedButtons.test(2 * static_cast(kb) + 1); + } + + bool InputHandler::WasKeyPressed(MouseButton mb) const + { + assert(mb != MouseButton::UNKNOWN); + return m_PressedButtons.test(2 * KeyboardButtonCount + 2 * static_cast(mb) + 1); } void InputHandler::OnMouseMove(float dx, float dy) diff --git a/Engine/Source/Core/public/Input/Controller.h b/Engine/Source/Core/public/Input/Controller.h index 399a317c6..d71cda3bb 100644 --- a/Engine/Source/Core/public/Input/Controller.h +++ b/Engine/Source/Core/public/Input/Controller.h @@ -17,6 +17,8 @@ namespace GameEngine public: bool IsPressed(const std::string& event); + bool WasPressed(const std::string& event); + void SetWasPressed(const std::string& event); private: std::unordered_map m_KeyboardEventMap; diff --git a/Engine/Source/Core/public/Input/InputHandler.h b/Engine/Source/Core/public/Input/InputHandler.h index fdd7fc759..5a2d7af09 100644 --- a/Engine/Source/Core/public/Input/InputHandler.h +++ b/Engine/Source/Core/public/Input/InputHandler.h @@ -30,11 +30,15 @@ namespace GameEngine::Core void Update(float dt); void KeyPressed(KeyboardButton kb); + void SetWasKeyPressed(KeyboardButton mb); void KeyReleased(KeyboardButton kb); void KeyPressed(MouseButton kb); + void SetWasKeyPressed(MouseButton mb); void KeyReleased(MouseButton mb); bool IsKeyPressed(KeyboardButton kb) const; bool IsKeyPressed(MouseButton mb) const; + bool WasKeyPressed(KeyboardButton kb) const; + bool WasKeyPressed(MouseButton mb) const; void OnMouseMove(float dx, float dy); const MouseMovevement& GetMouseMovement() const { return m_MouseMovevement; } @@ -42,9 +46,11 @@ namespace GameEngine::Core private: MouseMovevement m_MouseMovevement; + // First half of the bitset is for "is pressed" states, second half is for "was pressed" states + // [ KB_pressed[0] KB_was_pressed[0] KB_pressed[1] KB_was_pressed[1] ... MB_pressed[0] MB_was_pressed[0] MB_pressed[1] MB_was_pressed[1] ... ] std::bitset< - KeyboardButtonCount + - MouseButtonCount + 2 * KeyboardButtonCount + + 2 * MouseButtonCount > m_PressedButtons; static InputHandler* m_Instance; diff --git a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp index 45aaaaf2a..536fba373 100644 --- a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp +++ b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp @@ -24,7 +24,6 @@ void GameFramework::Init() flecs::entity cameraManager = m_World.entity() .set(CameraManagerPtr{ Core::g_CameraManager.get() }) .set(SavedCameraPtr{ nullptr }) - .set(ButtonManager{ false, false, false }) .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); } diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index 48faa6b4d..4a66fc02f 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -13,27 +13,22 @@ using namespace GameEngine; static void ProcessButtonPress(const ControllerPtr& controller, const char* actionName, - const std::function& action, - bool& wasPressedFlag) + const std::function& action) { - if (controller.ptr->IsPressed(actionName)) - { - if (!wasPressedFlag) - { - action(); - wasPressedFlag = true; - } - } - else - { - wasPressedFlag = false; - } + if (controller.ptr->IsPressed(actionName)) + { + if (!controller.ptr->WasPressed(actionName)) + { + action(); + controller.ptr->SetWasPressed(actionName); + } + } } void RegisterEcsControlSystems(flecs::world& world) { - world.system() - .each([&](flecs::entity e, CameraManagerPtr& cameraManager, SavedCameraPtr& savedCameraPtr, ButtonManager& buttonManager, const ControllerPtr& controller) + world.system() + .each([&](flecs::entity e, CameraManagerPtr& cameraManager, SavedCameraPtr& savedCameraPtr, const ControllerPtr& controller) { Core::InputHandler::MouseMovevement mouseMovement = Core::InputHandler::GetInstance()->GetMouseMovement(); @@ -66,24 +61,19 @@ void RegisterEcsControlSystems(flecs::world& world) camera->SetPosition(position); ProcessButtonPress(controller, "CreateCamera", - [&]() { cameraManager.ptr->CreateCamera(); }, - buttonManager.wasPressedCreateCameraButton + [&]() { cameraManager.ptr->CreateCamera(); } ); ProcessButtonPress(controller, "NextCamera", - [&]() { cameraManager.ptr->SwitchNextCamera(); }, - buttonManager.wasPressedNextCameraButton + [&]() { cameraManager.ptr->SwitchNextCamera(); } ); ProcessButtonPress(controller, "PrevCamera", - [&]() { cameraManager.ptr->SwitchPrevCamera(); }, - buttonManager.wasPressedPrevCameraButton + [&]() { cameraManager.ptr->SwitchPrevCamera(); } ); ProcessButtonPress(controller, "SaveCamera", - [&]() { savedCameraPtr.ptr = cameraManager.ptr->GetActiveCamera(); }, - buttonManager.wasPressedSaveCameraButton + [&]() { savedCameraPtr.ptr = cameraManager.ptr->GetActiveCamera(); } ); ProcessButtonPress(controller, "LoadCamera", - [&]() { cameraManager.ptr->SetActiveCamera(savedCameraPtr.ptr); }, - buttonManager.wasPressedLoadCameraButton + [&]() { cameraManager.ptr->SetActiveCamera(savedCameraPtr.ptr); } ); }); diff --git a/Samples/SimpleScene/Source/public/ecsControl.h b/Samples/SimpleScene/Source/public/ecsControl.h index 489209976..27fb5dfab 100644 --- a/Samples/SimpleScene/Source/public/ecsControl.h +++ b/Samples/SimpleScene/Source/public/ecsControl.h @@ -13,15 +13,6 @@ struct ControllerPtr GameEngine::Core::Controller* ptr; }; -struct ButtonManager -{ - bool wasPressedCreateCameraButton; - bool wasPressedNextCameraButton; - bool wasPressedPrevCameraButton; - bool wasPressedSaveCameraButton; - bool wasPressedLoadCameraButton; -}; - struct JumpSpeed { float value; From 940878266242ba0506989ce6cc2be6c53a819ba9 Mon Sep 17 00:00:00 2001 From: Stepan Date: Sat, 22 Nov 2025 02:03:27 +0300 Subject: [PATCH 13/24] added new level with two cudes which cameras are linked to --- .../Assets/Levels/FixedCamerasToObjects.xml | 4 ++++ .../private/GameFramework/GameFramework.cpp | 9 +++++++++ .../SimpleScene/Source/private/ecsControl.cpp | 19 +++++++++++++++++++ .../SimpleScene/Source/public/ecsControl.h | 8 ++++++++ 4 files changed, 40 insertions(+) create mode 100644 Samples/SimpleScene/Assets/Levels/FixedCamerasToObjects.xml diff --git a/Samples/SimpleScene/Assets/Levels/FixedCamerasToObjects.xml b/Samples/SimpleScene/Assets/Levels/FixedCamerasToObjects.xml new file mode 100644 index 000000000..16d1184a6 --- /dev/null +++ b/Samples/SimpleScene/Assets/Levels/FixedCamerasToObjects.xml @@ -0,0 +1,4 @@ + + + + diff --git a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp index 536fba373..d9c90192a 100644 --- a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp +++ b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp @@ -19,8 +19,11 @@ void GameFramework::Init() World::GameWorld::GetInstance()->LoadLevel( m_World, Core::g_FileSystem->GetFilePath("Levels/Main.xml").generic_string() + //Core::g_FileSystem->GetFilePath("Levels/FixedCamerasToObjects.xml").generic_string() ); + m_World.set(CameraManagerPtr{ Core::g_CameraManager.get() }); + flecs::entity cameraManager = m_World.entity() .set(CameraManagerPtr{ Core::g_CameraManager.get() }) .set(SavedCameraPtr{ nullptr }) @@ -70,6 +73,12 @@ void GameFramework::RegisterComponentsReflection() m_World.component() .member("value"); + + m_World.component() + .member("dx") + .member("dy") + .member("dz") + .member("ptr"); } void GameFramework::RegisterSystems() diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index 4a66fc02f..44ed76158 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -89,5 +89,24 @@ void RegisterEcsControlSystems(flecs::world& world) } } }); + + world.system() + .each([&](flecs::entity e, CameraPtr& cameraPtr) + { + if (!cameraPtr.ptr) + { + static const CameraManagerPtr* cameraManagerPtr = world.get(); + cameraPtr.ptr = cameraManagerPtr->ptr->CreateCamera(); + } + }); + + world.system() + .each([&](CameraPtr& cameraPtr, const Position& pos) + { + if (cameraPtr.ptr) + { + cameraPtr.ptr->SetPosition(Math::Vector3f(pos.x + cameraPtr.dx, pos.y + cameraPtr.dy, pos.z + cameraPtr.dz)); + } + }); } diff --git a/Samples/SimpleScene/Source/public/ecsControl.h b/Samples/SimpleScene/Source/public/ecsControl.h index 27fb5dfab..e6bd74388 100644 --- a/Samples/SimpleScene/Source/public/ecsControl.h +++ b/Samples/SimpleScene/Source/public/ecsControl.h @@ -23,6 +23,14 @@ struct CameraManagerPtr GameEngine::Core::CameraManager* ptr; }; +struct CameraPtr +{ + float dx; + float dy; + float dz; + GameEngine::Core::Camera::Ptr ptr = nullptr; +}; + struct SavedCameraPtr { GameEngine::Core::Camera::Ptr ptr; From ae9623590179103b3ac3f8f654bbe3799caa565f Mon Sep 17 00:00:00 2001 From: Stepan Date: Mon, 24 Nov 2025 22:09:03 +0300 Subject: [PATCH 14/24] code style --- Engine/Source/Core/private/CameraManager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index a2d307a2a..fb21b17ba 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -61,7 +61,9 @@ namespace GameEngine::Core void CameraManager::SwitchNextCamera() { if (m_CameraList.empty()) + { return; + } if (m_CurrCameraIt == m_CameraList.end()) { @@ -79,7 +81,9 @@ namespace GameEngine::Core void CameraManager::SwitchPrevCamera() { if (m_CameraList.empty()) + { return; + } if (m_CurrCameraIt == m_CameraList.end()) { From e5146cb662798d66b0d39bb70ae0673fa5414041 Mon Sep 17 00:00:00 2001 From: Stepan Date: Mon, 24 Nov 2025 23:43:30 +0300 Subject: [PATCH 15/24] added weak_ptr in CameraManager without checking if ptr is expired. --- Engine/Editor/private/GameEditor.cpp | 5 ++++- Engine/Editor/public/EditorECS/ecsEditor.h | 7 +++++++ Engine/Source/Core/private/CameraManager.cpp | 12 ++++++------ Engine/Source/Core/public/Camera.h | 1 + Engine/Source/Core/public/CameraManager.h | 5 +++-- Engine/Source/Game/private/Game.cpp | 2 +- .../Assets/Levels/FixedCamerasToObjects.xml | 4 ++-- .../Source/private/GameFramework/GameFramework.cpp | 7 +++++-- Samples/SimpleScene/Source/private/ecsControl.cpp | 10 +++++----- Samples/SimpleScene/Source/public/ecsControl.h | 8 +++++++- 10 files changed, 41 insertions(+), 20 deletions(-) diff --git a/Engine/Editor/private/GameEditor.cpp b/Engine/Editor/private/GameEditor.cpp index 2a6a0d51f..0e272320c 100644 --- a/Engine/Editor/private/GameEditor.cpp +++ b/Engine/Editor/private/GameEditor.cpp @@ -19,7 +19,7 @@ namespace GameEngine PlatformLoop(PlatformLoopFunc) { Core::g_CameraManager = std::make_unique(); - Core::g_CameraManager->CreateCamera(); + //Core::g_CameraManager->CreateCamera(); GUI::GUIContext::GetInstance()->PlatformInit(); m_renderThread = std::make_unique(); @@ -33,6 +33,9 @@ namespace GameEngine flecs::entity cameraManager = m_EntityManager->GetWorld().entity() .set(EntitySystem::EditorECS::CameraManagerPtr{ Core::g_CameraManager.get()}); + flecs::entity camera = m_EntityManager->GetWorld().entity() + .set(EntitySystem::EditorECS::CameraPtr{ Core::g_CameraManager->CreateCamera() }); + EntitySystem::EditorECS::RegisterEditorEcsControlSystems(m_EntityManager->GetWorld()); m_UIWindows.reserve(32); diff --git a/Engine/Editor/public/EditorECS/ecsEditor.h b/Engine/Editor/public/EditorECS/ecsEditor.h index 8255d3acf..c5e14c009 100644 --- a/Engine/Editor/public/EditorECS/ecsEditor.h +++ b/Engine/Editor/public/EditorECS/ecsEditor.h @@ -5,6 +5,8 @@ namespace GameEngine::Core { class CameraManager; + class Camera; + } namespace GameEngine::EntitySystem::EditorECS @@ -14,6 +16,11 @@ namespace GameEngine::EntitySystem::EditorECS Core::CameraManager* ptr; }; + struct CameraPtr + { + std::shared_ptr ptr; + }; + struct Position { float x; diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index fb21b17ba..d9d727ac1 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -25,23 +25,23 @@ namespace GameEngine::Core if (m_CurrCameraIt == m_CameraList.end()) { - m_CameraList.push_back(camera); + m_CameraList.push_back(static_cast(camera)); m_CurrCameraIt = std::prev(m_CameraList.end()); return; } - m_CurrCameraIt = m_CameraList.insert(std::next(m_CurrCameraIt), camera); + m_CurrCameraIt = m_CameraList.insert(std::next(m_CurrCameraIt), static_cast(camera)); } Camera::Ptr CameraManager::GetActiveCamera() { assert(m_CurrCameraIt != m_CameraList.end()); - return *m_CurrCameraIt; + return m_CurrCameraIt->lock(); } - void CameraManager::SetActiveCamera(Camera::Ptr camera) + void CameraManager::SetActiveCamera(Camera::WeakPtr camera) { - if (!camera) + if (camera.expired()) { return; } @@ -49,7 +49,7 @@ namespace GameEngine::Core CameraList::iterator newCameraIt = std::find_if( m_CameraList.begin(), m_CameraList.end(), - [&](const Camera::Ptr& p) { return p == camera; } + [&](const Camera::WeakPtr& p) { return p.lock() == camera.lock(); } ); if (newCameraIt != m_CameraList.end()) diff --git a/Engine/Source/Core/public/Camera.h b/Engine/Source/Core/public/Camera.h index e0c37da88..c16244552 100644 --- a/Engine/Source/Core/public/Camera.h +++ b/Engine/Source/Core/public/Camera.h @@ -12,6 +12,7 @@ namespace GameEngine { public: using Ptr = std::shared_ptr; + using WeakPtr = std::weak_ptr; Camera() = default; diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h index b9b77e699..68ece7b3e 100644 --- a/Engine/Source/Core/public/CameraManager.h +++ b/Engine/Source/Core/public/CameraManager.h @@ -12,7 +12,7 @@ namespace GameEngine class CORE_API CameraManager final { public: - using CameraList = std::list; + using CameraList = std::list; CameraManager() : m_CurrCameraIt(m_CameraList.end()) @@ -22,10 +22,11 @@ namespace GameEngine Camera::Ptr GetActiveCamera(); void SwitchNextCamera(); void SwitchPrevCamera(); - void SetActiveCamera(Camera::Ptr camera); + void SetActiveCamera(Camera::WeakPtr camera); private: void AddCamera(Camera::Ptr camera); + //CameraList::iterator FindValidFrom(CameraList::iterator startIt, int direction = 1); private: CameraList m_CameraList; diff --git a/Engine/Source/Game/private/Game.cpp b/Engine/Source/Game/private/Game.cpp index 5b9cf0171..c9d1c4412 100644 --- a/Engine/Source/Game/private/Game.cpp +++ b/Engine/Source/Game/private/Game.cpp @@ -13,7 +13,7 @@ namespace GameEngine PlatformLoop(PlatformLoopFunc) { Core::g_CameraManager = std::make_unique(); - Core::g_CameraManager->CreateCamera(); + //Core::g_CameraManager->CreateCamera(); m_renderThread = std::make_unique(); diff --git a/Samples/SimpleScene/Assets/Levels/FixedCamerasToObjects.xml b/Samples/SimpleScene/Assets/Levels/FixedCamerasToObjects.xml index 16d1184a6..15a9f31fe 100644 --- a/Samples/SimpleScene/Assets/Levels/FixedCamerasToObjects.xml +++ b/Samples/SimpleScene/Assets/Levels/FixedCamerasToObjects.xml @@ -1,4 +1,4 @@ - - + + diff --git a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp index d9c90192a..e29c6d6b9 100644 --- a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp +++ b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp @@ -26,8 +26,11 @@ void GameFramework::Init() flecs::entity cameraManager = m_World.entity() .set(CameraManagerPtr{ Core::g_CameraManager.get() }) - .set(SavedCameraPtr{ nullptr }) + .set(SavedCameraPtr{}) .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); + + flecs::entity camera = m_World.entity() + .set(CameraPtr{ Core::g_CameraManager->CreateCamera() }); } void GameFramework::RegisterComponentsReflection() @@ -74,7 +77,7 @@ void GameFramework::RegisterComponentsReflection() m_World.component() .member("value"); - m_World.component() + m_World.component() .member("dx") .member("dy") .member("dz") diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index 44ed76158..64d9e003d 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -61,7 +61,7 @@ void RegisterEcsControlSystems(flecs::world& world) camera->SetPosition(position); ProcessButtonPress(controller, "CreateCamera", - [&]() { cameraManager.ptr->CreateCamera(); } + [&]() { world.entity().set(CameraPtr{ cameraManager.ptr->CreateCamera() }); } ); ProcessButtonPress(controller, "NextCamera", [&]() { cameraManager.ptr->SwitchNextCamera(); } @@ -90,8 +90,8 @@ void RegisterEcsControlSystems(flecs::world& world) } }); - world.system() - .each([&](flecs::entity e, CameraPtr& cameraPtr) + world.system() + .each([&](flecs::entity e, FixedCameraPtr& cameraPtr) { if (!cameraPtr.ptr) { @@ -100,8 +100,8 @@ void RegisterEcsControlSystems(flecs::world& world) } }); - world.system() - .each([&](CameraPtr& cameraPtr, const Position& pos) + world.system() + .each([&](FixedCameraPtr& cameraPtr, const Position& pos) { if (cameraPtr.ptr) { diff --git a/Samples/SimpleScene/Source/public/ecsControl.h b/Samples/SimpleScene/Source/public/ecsControl.h index e6bd74388..1a480e6bb 100644 --- a/Samples/SimpleScene/Source/public/ecsControl.h +++ b/Samples/SimpleScene/Source/public/ecsControl.h @@ -24,6 +24,12 @@ struct CameraManagerPtr }; struct CameraPtr +{ + GameEngine::Core::Camera::Ptr ptr = nullptr; +}; + + +struct FixedCameraPtr { float dx; float dy; @@ -33,7 +39,7 @@ struct CameraPtr struct SavedCameraPtr { - GameEngine::Core::Camera::Ptr ptr; + GameEngine::Core::Camera::WeakPtr ptr; }; void RegisterEcsControlSystems(flecs::world& world); From d1dad350b2ce7aa4f34bf45bb25245f244186904 Mon Sep 17 00:00:00 2001 From: Stepan Date: Tue, 25 Nov 2025 00:41:32 +0300 Subject: [PATCH 16/24] added checking if weak_ptr is expired --- Engine/Source/Core/private/CameraManager.cpp | 32 +++++++++++++++++-- Engine/Source/Core/private/Input/Buttons.cpp | 1 + .../Input/Windows/WindowsKeyboardButtons.h | 2 ++ Engine/Source/Core/public/CameraManager.h | 3 +- Engine/Source/Core/public/Input/Buttons.h | 1 + .../Assets/Configs/Input_default.ini | 1 + .../private/GameFramework/GameFramework.cpp | 3 +- .../SimpleScene/Source/private/ecsControl.cpp | 18 ++++++++++- 8 files changed, 55 insertions(+), 6 deletions(-) diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index d9d727ac1..61746bce5 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -35,6 +35,7 @@ namespace GameEngine::Core Camera::Ptr CameraManager::GetActiveCamera() { + m_CurrCameraIt = FindValidCamera(m_CurrCameraIt); assert(m_CurrCameraIt != m_CameraList.end()); return m_CurrCameraIt->lock(); } @@ -47,9 +48,15 @@ namespace GameEngine::Core } CameraList::iterator newCameraIt = std::find_if( - m_CameraList.begin(), - m_CameraList.end(), - [&](const Camera::WeakPtr& p) { return p.lock() == camera.lock(); } + m_CameraList.begin(), + m_CameraList.end(), + [&](const Camera::WeakPtr& p) + { + if (!p.expired()) { + return p.lock() == camera.lock(); + } + return false; + } ); if (newCameraIt != m_CameraList.end()) @@ -100,4 +107,23 @@ namespace GameEngine::Core --m_CurrCameraIt; } } + + CameraManager::CameraList::iterator CameraManager::FindValidCamera(CameraList::iterator startIt) + { + for (CameraList::iterator it = startIt; !m_CameraList.empty(); ) + { + if (it == m_CameraList.end()) + { + it = m_CameraList.begin(); + } + + if (!(it->expired())) + { + return it; + } + it = m_CameraList.erase(it); + } + + return m_CameraList.end(); + } } \ No newline at end of file diff --git a/Engine/Source/Core/private/Input/Buttons.cpp b/Engine/Source/Core/private/Input/Buttons.cpp index 9a1a2d951..2e5440882 100644 --- a/Engine/Source/Core/private/Input/Buttons.cpp +++ b/Engine/Source/Core/private/Input/Buttons.cpp @@ -15,6 +15,7 @@ namespace GameEngine::Core {"q", KeyboardButton::Q}, {"e", KeyboardButton::E}, {"c", KeyboardButton::C}, + {"f", KeyboardButton::F}, {"t", KeyboardButton::T}, {"r", KeyboardButton::R}, {"spacebar", KeyboardButton::SPACEBAR}, diff --git a/Engine/Source/Core/private/Input/Windows/WindowsKeyboardButtons.h b/Engine/Source/Core/private/Input/Windows/WindowsKeyboardButtons.h index dadbbdb2e..e64f0f5b1 100644 --- a/Engine/Source/Core/private/Input/Windows/WindowsKeyboardButtons.h +++ b/Engine/Source/Core/private/Input/Windows/WindowsKeyboardButtons.h @@ -32,6 +32,8 @@ namespace GameEngine return KeyboardButton::E; case 'C': return KeyboardButton::C; + case 'F': + return KeyboardButton::F; case 'T': return KeyboardButton::T; case 'R': diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h index 68ece7b3e..823c5876f 100644 --- a/Engine/Source/Core/public/CameraManager.h +++ b/Engine/Source/Core/public/CameraManager.h @@ -23,10 +23,11 @@ namespace GameEngine void SwitchNextCamera(); void SwitchPrevCamera(); void SetActiveCamera(Camera::WeakPtr camera); + size_t GetCamerasCount() const { return m_CameraList.size(); } private: void AddCamera(Camera::Ptr camera); - //CameraList::iterator FindValidFrom(CameraList::iterator startIt, int direction = 1); + CameraList::iterator FindValidCamera(CameraList::iterator startIt); private: CameraList m_CameraList; diff --git a/Engine/Source/Core/public/Input/Buttons.h b/Engine/Source/Core/public/Input/Buttons.h index cae2a27c9..016d816f2 100644 --- a/Engine/Source/Core/public/Input/Buttons.h +++ b/Engine/Source/Core/public/Input/Buttons.h @@ -15,6 +15,7 @@ namespace GameEngine Q, E, C, + F, T, R, UP, diff --git a/Samples/SimpleScene/Assets/Configs/Input_default.ini b/Samples/SimpleScene/Assets/Configs/Input_default.ini index c0fdd199b..c32cf667f 100644 --- a/Samples/SimpleScene/Assets/Configs/Input_default.ini +++ b/Samples/SimpleScene/Assets/Configs/Input_default.ini @@ -5,6 +5,7 @@ GoForward=w GoBack=s Jump=spacebar CreateCamera=c +DeleteCamera=f NextCamera=e PrevCamera=q SaveCamera=t diff --git a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp index e29c6d6b9..c41a4a195 100644 --- a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp +++ b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp @@ -30,7 +30,8 @@ void GameFramework::Init() .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); flecs::entity camera = m_World.entity() - .set(CameraPtr{ Core::g_CameraManager->CreateCamera() }); + .set(CameraPtr{ Core::g_CameraManager->CreateCamera() }) + .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); } void GameFramework::RegisterComponentsReflection() diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index 64d9e003d..d9dc9d8e8 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -61,8 +61,10 @@ void RegisterEcsControlSystems(flecs::world& world) camera->SetPosition(position); ProcessButtonPress(controller, "CreateCamera", - [&]() { world.entity().set(CameraPtr{ cameraManager.ptr->CreateCamera() }); } + [&]() { world.entity().set(CameraPtr{ cameraManager.ptr->CreateCamera() }) + .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); } ); + ProcessButtonPress(controller, "NextCamera", [&]() { cameraManager.ptr->SwitchNextCamera(); } ); @@ -90,6 +92,20 @@ void RegisterEcsControlSystems(flecs::world& world) } }); + world.system() + .each([&](flecs::entity e, CameraPtr& cameraPtr, const ControllerPtr& controller) + { + static const CameraManagerPtr* cameraManagerPtr = world.get(); + + if (cameraManagerPtr->ptr->GetCamerasCount() > 1 && + cameraPtr.ptr == cameraManagerPtr->ptr->GetActiveCamera()) + { + ProcessButtonPress(controller, "DeleteCamera", + [&]() { e.destruct(); } + ); + } + }); + world.system() .each([&](flecs::entity e, FixedCameraPtr& cameraPtr) { From 2e86812d52d65700fb803288bea6fa30583cfb0e Mon Sep 17 00:00:00 2001 From: Stepan Date: Tue, 25 Nov 2025 20:27:37 +0300 Subject: [PATCH 17/24] added cameras as independent objects in a scene and CameraManader as a common system in a flecs world. --- Engine/Editor/private/EditorECS/ecsEditor.cpp | 12 +- Engine/Editor/private/GameEditor.cpp | 4 +- Engine/Source/Core/private/CameraManager.cpp | 33 +---- Engine/Source/Core/public/Camera.h | 11 +- Engine/Source/Core/public/CameraManager.h | 4 +- Engine/Source/Game/private/Game.cpp | 1 - .../Assets/Levels/FixedCamerasToObjects.xml | 5 +- .../private/GameFramework/GameFramework.cpp | 10 +- .../SimpleScene/Source/private/ecsControl.cpp | 140 +++++++++--------- .../SimpleScene/Source/public/ecsControl.h | 8 +- 10 files changed, 107 insertions(+), 121 deletions(-) diff --git a/Engine/Editor/private/EditorECS/ecsEditor.cpp b/Engine/Editor/private/EditorECS/ecsEditor.cpp index 4e2ad2cab..0c73c4904 100644 --- a/Engine/Editor/private/EditorECS/ecsEditor.cpp +++ b/Engine/Editor/private/EditorECS/ecsEditor.cpp @@ -25,10 +25,14 @@ namespace GameEngine::EntitySystem::EditorECS } }); - world.system() - .each([&](flecs::entity e, CameraManagerPtr& cameraManager) + world.system() + .each([&](flecs::entity e, CameraPtr& cameraPtr) { - if (!Core::g_MainWindowsApplication->IsMouseCaptured() || !Core::g_MainWindowsApplication->IsFocused()) [[unlikely]] + static const CameraManagerPtr* cameraManagerPtr = world.get(); + + if (cameraPtr.ptr != cameraManagerPtr->ptr->GetActiveCamera() || + !Core::g_MainWindowsApplication->IsMouseCaptured() || + !Core::g_MainWindowsApplication->IsFocused()) [[unlikely]] { return; } @@ -38,7 +42,7 @@ namespace GameEngine::EntitySystem::EditorECS mouseMovement.dx *= 0.25 * (Math::Constants::PI / 180.f); mouseMovement.dy *= 0.25 * (Math::Constants::PI / 180.f); - Core::Camera::Ptr camera = cameraManager.ptr->GetActiveCamera(); + Core::Camera::Ptr camera = cameraManagerPtr->ptr->GetActiveCamera(); camera->Rotate(mouseMovement.dx, mouseMovement.dy); diff --git a/Engine/Editor/private/GameEditor.cpp b/Engine/Editor/private/GameEditor.cpp index 0e272320c..9ef34b640 100644 --- a/Engine/Editor/private/GameEditor.cpp +++ b/Engine/Editor/private/GameEditor.cpp @@ -19,7 +19,6 @@ namespace GameEngine PlatformLoop(PlatformLoopFunc) { Core::g_CameraManager = std::make_unique(); - //Core::g_CameraManager->CreateCamera(); GUI::GUIContext::GetInstance()->PlatformInit(); m_renderThread = std::make_unique(); @@ -30,8 +29,7 @@ namespace GameEngine flecs::world world; world = m_EntityManager->GetWorld().get_world(); // huge refactoring requires or flecs custom fix because this api redundancy is just annoying - flecs::entity cameraManager = m_EntityManager->GetWorld().entity() - .set(EntitySystem::EditorECS::CameraManagerPtr{ Core::g_CameraManager.get()}); + m_EntityManager->GetWorld().set(EntitySystem::EditorECS::CameraManagerPtr{ Core::g_CameraManager.get() }); flecs::entity camera = m_EntityManager->GetWorld().entity() .set(EntitySystem::EditorECS::CameraPtr{ Core::g_CameraManager->CreateCamera() }); diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index 61746bce5..6f8f43f3d 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -10,27 +10,20 @@ namespace GameEngine::Core newCamera->SetPosition(startCameraPosition); newCamera->SetViewDir(startCameraViewDir); - AddCamera(newCamera); + AddCamera(Camera::WeakPtr(newCamera)); return newCamera; } - void CameraManager::AddCamera(Camera::Ptr camera) + void CameraManager::AddCamera(Camera::WeakPtr camera) { - if (m_CameraList.empty()) - { - m_CameraList.push_back(camera); - m_CurrCameraIt = m_CameraList.begin(); - return; - } - if (m_CurrCameraIt == m_CameraList.end()) { - m_CameraList.push_back(static_cast(camera)); + m_CameraList.push_back(camera); m_CurrCameraIt = std::prev(m_CameraList.end()); return; } - m_CurrCameraIt = m_CameraList.insert(std::next(m_CurrCameraIt), static_cast(camera)); + m_CurrCameraIt = m_CameraList.insert(std::next(m_CurrCameraIt), camera); } Camera::Ptr CameraManager::GetActiveCamera() @@ -59,10 +52,7 @@ namespace GameEngine::Core } ); - if (newCameraIt != m_CameraList.end()) - { - m_CurrCameraIt = newCameraIt; - } + m_CurrCameraIt = newCameraIt; } void CameraManager::SwitchNextCamera() @@ -72,13 +62,8 @@ namespace GameEngine::Core return; } - if (m_CurrCameraIt == m_CameraList.end()) - { - m_CurrCameraIt = m_CameraList.begin(); - return; - } - ++m_CurrCameraIt; + if (m_CurrCameraIt == m_CameraList.end()) { m_CurrCameraIt = m_CameraList.begin(); @@ -92,12 +77,6 @@ namespace GameEngine::Core return; } - if (m_CurrCameraIt == m_CameraList.end()) - { - m_CurrCameraIt = std::prev(m_CameraList.end()); - return; - } - if (m_CurrCameraIt == m_CameraList.begin()) { m_CurrCameraIt = std::prev(m_CameraList.end()); diff --git a/Engine/Source/Core/public/Camera.h b/Engine/Source/Core/public/Camera.h index c16244552..2cd572d9a 100644 --- a/Engine/Source/Core/public/Camera.h +++ b/Engine/Source/Core/public/Camera.h @@ -8,14 +8,16 @@ namespace GameEngine { namespace Core { + class CameraManager; + class CORE_API Camera final { + friend class CameraManager; + public: using Ptr = std::shared_ptr; using WeakPtr = std::weak_ptr; - Camera() = default; - public: Math::Matrix4x4f GetViewMatrix(); Math::Vector3f GetPosition() const { return m_Position; } @@ -26,11 +28,12 @@ namespace GameEngine void Rotate(float yaw, float pitch); + public: // wants private + Camera() = default; + private: Math::Vector3f m_Position; Math::Vector3f m_ViewDir; }; - - extern CORE_API Camera* g_MainCamera; } } \ No newline at end of file diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h index 823c5876f..7fc98ce8a 100644 --- a/Engine/Source/Core/public/CameraManager.h +++ b/Engine/Source/Core/public/CameraManager.h @@ -1,8 +1,6 @@ #pragma once #include -#include -#include #include namespace GameEngine @@ -26,7 +24,7 @@ namespace GameEngine size_t GetCamerasCount() const { return m_CameraList.size(); } private: - void AddCamera(Camera::Ptr camera); + void AddCamera(Camera::WeakPtr camera); CameraList::iterator FindValidCamera(CameraList::iterator startIt); private: diff --git a/Engine/Source/Game/private/Game.cpp b/Engine/Source/Game/private/Game.cpp index c9d1c4412..f5ee6b72e 100644 --- a/Engine/Source/Game/private/Game.cpp +++ b/Engine/Source/Game/private/Game.cpp @@ -13,7 +13,6 @@ namespace GameEngine PlatformLoop(PlatformLoopFunc) { Core::g_CameraManager = std::make_unique(); - //Core::g_CameraManager->CreateCamera(); m_renderThread = std::make_unique(); diff --git a/Samples/SimpleScene/Assets/Levels/FixedCamerasToObjects.xml b/Samples/SimpleScene/Assets/Levels/FixedCamerasToObjects.xml index 15a9f31fe..1b3314543 100644 --- a/Samples/SimpleScene/Assets/Levels/FixedCamerasToObjects.xml +++ b/Samples/SimpleScene/Assets/Levels/FixedCamerasToObjects.xml @@ -1,4 +1,5 @@ - - + + + diff --git a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp index c41a4a195..88f58e3c5 100644 --- a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp +++ b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -8,6 +7,7 @@ #include #include #include +#include using namespace GameEngine; @@ -24,8 +24,7 @@ void GameFramework::Init() m_World.set(CameraManagerPtr{ Core::g_CameraManager.get() }); - flecs::entity cameraManager = m_World.entity() - .set(CameraManagerPtr{ Core::g_CameraManager.get() }) + flecs::entity cameraSavingSystem = m_World.entity() .set(SavedCameraPtr{}) .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); @@ -78,11 +77,10 @@ void GameFramework::RegisterComponentsReflection() m_World.component() .member("value"); - m_World.component() + m_World.component() .member("dx") .member("dy") - .member("dz") - .member("ptr"); + .member("dz"); } void GameFramework::RegisterSystems() diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index d9dc9d8e8..4966b83e6 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -27,56 +27,62 @@ static void ProcessButtonPress(const ControllerPtr& controller, void RegisterEcsControlSystems(flecs::world& world) { - world.system() - .each([&](flecs::entity e, CameraManagerPtr& cameraManager, SavedCameraPtr& savedCameraPtr, const ControllerPtr& controller) + world.system() + .each([&](flecs::entity e, CameraPtr& cameraPtr, const ControllerPtr& controller) { - Core::InputHandler::MouseMovevement mouseMovement = Core::InputHandler::GetInstance()->GetMouseMovement(); + static const CameraManagerPtr* cameraManagerPtr = world.get(); - mouseMovement.dx *= 0.25 * Math::Constants::PI / 180.f; - mouseMovement.dy *= 0.25 * Math::Constants::PI / 180.f; + if (cameraPtr.ptr == cameraManagerPtr->ptr->GetActiveCamera()) + { + Core::InputHandler::MouseMovevement mouseMovement = Core::InputHandler::GetInstance()->GetMouseMovement(); - Core::Camera::Ptr camera = cameraManager.ptr->GetActiveCamera(); + mouseMovement.dx *= 0.25 * Math::Constants::PI / 180.f; + mouseMovement.dy *= 0.25 * Math::Constants::PI / 180.f; - camera->Rotate(mouseMovement.dx, mouseMovement.dy); + Core::Camera::Ptr camera = cameraPtr.ptr; - Math::Vector3f currentMoveDir = Math::Vector3f::Zero(); - if (controller.ptr->IsPressed("GoLeft")) - { - currentMoveDir = currentMoveDir - camera->GetRightDir(); - } - if (controller.ptr->IsPressed("GoRight")) - { - currentMoveDir = currentMoveDir + camera->GetRightDir(); - } - if (controller.ptr->IsPressed("GoBack")) - { - currentMoveDir = currentMoveDir - camera->GetViewDir(); - } - if (controller.ptr->IsPressed("GoForward")) - { - currentMoveDir = currentMoveDir + camera->GetViewDir(); + camera->Rotate(mouseMovement.dx, mouseMovement.dy); + + Math::Vector3f currentMoveDir = Math::Vector3f::Zero(); + if (controller.ptr->IsPressed("GoLeft")) + { + currentMoveDir = currentMoveDir - camera->GetRightDir(); + } + if (controller.ptr->IsPressed("GoRight")) + { + currentMoveDir = currentMoveDir + camera->GetRightDir(); + } + if (controller.ptr->IsPressed("GoBack")) + { + currentMoveDir = currentMoveDir - camera->GetViewDir(); + } + if (controller.ptr->IsPressed("GoForward")) + { + currentMoveDir = currentMoveDir + camera->GetViewDir(); + } + float speed = 10.0f; + Math::Vector3f position = camera->GetPosition() + currentMoveDir.Normalized() * speed * world.delta_time(); + camera->SetPosition(position); + + ProcessButtonPress(controller, "CreateCamera", + [&]() { world.entity().set(CameraPtr{ cameraManagerPtr->ptr->CreateCamera() }) + .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); } + ); + + ProcessButtonPress(controller, "NextCamera", + [&]() { cameraManagerPtr->ptr->SwitchNextCamera(); } + ); + ProcessButtonPress(controller, "PrevCamera", + [&]() { cameraManagerPtr->ptr->SwitchPrevCamera(); } + ); + + if (cameraManagerPtr->ptr->GetCamerasCount() > 1) + { + ProcessButtonPress(controller, "DeleteCamera", + [&]() { e.destruct(); } + ); + } } - float speed = 10.0f; - Math::Vector3f position = camera->GetPosition() + currentMoveDir.Normalized() * speed * world.delta_time(); - camera->SetPosition(position); - - ProcessButtonPress(controller, "CreateCamera", - [&]() { world.entity().set(CameraPtr{ cameraManager.ptr->CreateCamera() }) - .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); } - ); - - ProcessButtonPress(controller, "NextCamera", - [&]() { cameraManager.ptr->SwitchNextCamera(); } - ); - ProcessButtonPress(controller, "PrevCamera", - [&]() { cameraManager.ptr->SwitchPrevCamera(); } - ); - ProcessButtonPress(controller, "SaveCamera", - [&]() { savedCameraPtr.ptr = cameraManager.ptr->GetActiveCamera(); } - ); - ProcessButtonPress(controller, "LoadCamera", - [&]() { cameraManager.ptr->SetActiveCamera(savedCameraPtr.ptr); } - ); }); world.system() @@ -92,37 +98,37 @@ void RegisterEcsControlSystems(flecs::world& world) } }); - world.system() - .each([&](flecs::entity e, CameraPtr& cameraPtr, const ControllerPtr& controller) + world.system() + .each([&](flecs::entity e, SavedCameraPtr& savedCameraPtr, const ControllerPtr& controller) + { + static const CameraManagerPtr* cameraManagerPtr = world.get(); + + ProcessButtonPress(controller, "SaveCamera", + [&]() { savedCameraPtr.ptr = cameraManagerPtr->ptr->GetActiveCamera(); } + ); + ProcessButtonPress(controller, "LoadCamera", + [&]() { cameraManagerPtr->ptr->SetActiveCamera(savedCameraPtr.ptr); } + ); + }); + + world.system() + .each([&](flecs::entity e, DeltaFixedCamera& delta) { static const CameraManagerPtr* cameraManagerPtr = world.get(); - if (cameraManagerPtr->ptr->GetCamerasCount() > 1 && - cameraPtr.ptr == cameraManagerPtr->ptr->GetActiveCamera()) + if (!e.has(world.lookup("CameraPtr").id())) { - ProcessButtonPress(controller, "DeleteCamera", - [&]() { e.destruct(); } - ); + e.set(CameraPtr{ cameraManagerPtr->ptr->CreateCamera() }); } }); - world.system() - .each([&](flecs::entity e, FixedCameraPtr& cameraPtr) + world.system() + .each([&](DeltaFixedCamera& delta, CameraPtr& cameraPtr, const Position& pos) { - if (!cameraPtr.ptr) - { - static const CameraManagerPtr* cameraManagerPtr = world.get(); - cameraPtr.ptr = cameraManagerPtr->ptr->CreateCamera(); - } + if (cameraPtr.ptr) + { + cameraPtr.ptr->SetPosition(Math::Vector3f(pos.x + delta.dx, pos.y + delta.dy, pos.z + delta.dz)); + } }); - - world.system() - .each([&](FixedCameraPtr& cameraPtr, const Position& pos) - { - if (cameraPtr.ptr) - { - cameraPtr.ptr->SetPosition(Math::Vector3f(pos.x + cameraPtr.dx, pos.y + cameraPtr.dy, pos.z + cameraPtr.dz)); - } - }); } diff --git a/Samples/SimpleScene/Source/public/ecsControl.h b/Samples/SimpleScene/Source/public/ecsControl.h index 1a480e6bb..47206cfc9 100644 --- a/Samples/SimpleScene/Source/public/ecsControl.h +++ b/Samples/SimpleScene/Source/public/ecsControl.h @@ -5,6 +5,7 @@ namespace GameEngine::Core { class CameraManager; + class Camera; class Controller; } @@ -25,21 +26,20 @@ struct CameraManagerPtr struct CameraPtr { - GameEngine::Core::Camera::Ptr ptr = nullptr; + std::shared_ptr ptr = nullptr; }; -struct FixedCameraPtr +struct DeltaFixedCamera { float dx; float dy; float dz; - GameEngine::Core::Camera::Ptr ptr = nullptr; }; struct SavedCameraPtr { - GameEngine::Core::Camera::WeakPtr ptr; + std::weak_ptr ptr; }; void RegisterEcsControlSystems(flecs::world& world); From 890d192869ad9f80e5392e2b4fad18bcd78daad1 Mon Sep 17 00:00:00 2001 From: Stepan Date: Wed, 3 Dec 2025 22:31:45 +0300 Subject: [PATCH 18/24] delete friend CameraManader from Camera --- Engine/Source/Core/public/Camera.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Engine/Source/Core/public/Camera.h b/Engine/Source/Core/public/Camera.h index 2cd572d9a..f6d1ca176 100644 --- a/Engine/Source/Core/public/Camera.h +++ b/Engine/Source/Core/public/Camera.h @@ -8,16 +8,14 @@ namespace GameEngine { namespace Core { - class CameraManager; - class CORE_API Camera final { - friend class CameraManager; - public: using Ptr = std::shared_ptr; using WeakPtr = std::weak_ptr; + Camera() = default; + public: Math::Matrix4x4f GetViewMatrix(); Math::Vector3f GetPosition() const { return m_Position; } @@ -28,9 +26,6 @@ namespace GameEngine void Rotate(float yaw, float pitch); - public: // wants private - Camera() = default; - private: Math::Vector3f m_Position; Math::Vector3f m_ViewDir; From bde1845d0a2d825000ec31640351ab699aff0800 Mon Sep 17 00:00:00 2001 From: Stepan Date: Wed, 3 Dec 2025 23:10:03 +0300 Subject: [PATCH 19/24] changed CameraManader from observer to owner --- Engine/Editor/public/EditorECS/ecsEditor.h | 2 +- Engine/Source/Core/private/CameraManager.cpp | 46 +++++-------------- Engine/Source/Core/public/Camera.h | 3 +- Engine/Source/Core/public/CameraManager.h | 20 +++++--- .../SimpleScene/Source/private/ecsControl.cpp | 2 +- .../SimpleScene/Source/public/ecsControl.h | 4 +- 6 files changed, 30 insertions(+), 47 deletions(-) diff --git a/Engine/Editor/public/EditorECS/ecsEditor.h b/Engine/Editor/public/EditorECS/ecsEditor.h index c5e14c009..023a48dd5 100644 --- a/Engine/Editor/public/EditorECS/ecsEditor.h +++ b/Engine/Editor/public/EditorECS/ecsEditor.h @@ -18,7 +18,7 @@ namespace GameEngine::EntitySystem::EditorECS struct CameraPtr { - std::shared_ptr ptr; + Core::Camera* ptr; }; struct Position diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index 6f8f43f3d..866970e64 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -4,38 +4,37 @@ namespace GameEngine::Core { std::unique_ptr g_CameraManager = nullptr; - Camera::Ptr CameraManager::CreateCamera() + Camera* CameraManager::CreateCamera() { - Camera::Ptr newCamera = std::make_shared(); + Camera* newCamera = new Camera(); newCamera->SetPosition(startCameraPosition); newCamera->SetViewDir(startCameraViewDir); - AddCamera(Camera::WeakPtr(newCamera)); + AddCamera(newCamera); return newCamera; } - void CameraManager::AddCamera(Camera::WeakPtr camera) + void CameraManager::AddCamera(Camera* camera) { if (m_CurrCameraIt == m_CameraList.end()) { - m_CameraList.push_back(camera); + m_CameraList.push_back(std::unique_ptr(camera)); m_CurrCameraIt = std::prev(m_CameraList.end()); return; } - m_CurrCameraIt = m_CameraList.insert(std::next(m_CurrCameraIt), camera); + m_CurrCameraIt = m_CameraList.insert(std::next(m_CurrCameraIt), std::unique_ptr(camera)); } - Camera::Ptr CameraManager::GetActiveCamera() + Camera* CameraManager::GetActiveCamera() { - m_CurrCameraIt = FindValidCamera(m_CurrCameraIt); assert(m_CurrCameraIt != m_CameraList.end()); - return m_CurrCameraIt->lock(); + return m_CurrCameraIt->get(); } - void CameraManager::SetActiveCamera(Camera::WeakPtr camera) + void CameraManager::SetActiveCamera(Camera* camera) { - if (camera.expired()) + if (!camera) { return; } @@ -43,12 +42,9 @@ namespace GameEngine::Core CameraList::iterator newCameraIt = std::find_if( m_CameraList.begin(), m_CameraList.end(), - [&](const Camera::WeakPtr& p) + [&](const Camera::Ptr& p) { - if (!p.expired()) { - return p.lock() == camera.lock(); - } - return false; + return p.get() == camera; } ); @@ -87,22 +83,4 @@ namespace GameEngine::Core } } - CameraManager::CameraList::iterator CameraManager::FindValidCamera(CameraList::iterator startIt) - { - for (CameraList::iterator it = startIt; !m_CameraList.empty(); ) - { - if (it == m_CameraList.end()) - { - it = m_CameraList.begin(); - } - - if (!(it->expired())) - { - return it; - } - it = m_CameraList.erase(it); - } - - return m_CameraList.end(); - } } \ No newline at end of file diff --git a/Engine/Source/Core/public/Camera.h b/Engine/Source/Core/public/Camera.h index f6d1ca176..d7225bf6a 100644 --- a/Engine/Source/Core/public/Camera.h +++ b/Engine/Source/Core/public/Camera.h @@ -11,8 +11,7 @@ namespace GameEngine class CORE_API Camera final { public: - using Ptr = std::shared_ptr; - using WeakPtr = std::weak_ptr; + using Ptr = std::unique_ptr; Camera() = default; diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h index 7fc98ce8a..2905b8b22 100644 --- a/Engine/Source/Core/public/CameraManager.h +++ b/Engine/Source/Core/public/CameraManager.h @@ -10,21 +10,27 @@ namespace GameEngine class CORE_API CameraManager final { public: - using CameraList = std::list; + using CameraList = std::list; CameraManager() - : m_CurrCameraIt(m_CameraList.end()) - {} + : m_CurrCameraIt(m_CameraList.end()) {} - Camera::Ptr CreateCamera(); - Camera::Ptr GetActiveCamera(); + CameraManager(const CameraManager&) = delete; + CameraManager& operator=(const CameraManager&) = delete; + + CameraManager(CameraManager&&) = default; + CameraManager& operator=(CameraManager&&) = default; + + public: + Camera* CreateCamera(); + Camera* GetActiveCamera(); void SwitchNextCamera(); void SwitchPrevCamera(); - void SetActiveCamera(Camera::WeakPtr camera); + void SetActiveCamera(Camera* camera); size_t GetCamerasCount() const { return m_CameraList.size(); } private: - void AddCamera(Camera::WeakPtr camera); + void AddCamera(Camera* camera); CameraList::iterator FindValidCamera(CameraList::iterator startIt); private: diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index 4966b83e6..023625e18 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -39,7 +39,7 @@ void RegisterEcsControlSystems(flecs::world& world) mouseMovement.dx *= 0.25 * Math::Constants::PI / 180.f; mouseMovement.dy *= 0.25 * Math::Constants::PI / 180.f; - Core::Camera::Ptr camera = cameraPtr.ptr; + Core::Camera* camera = cameraPtr.ptr; camera->Rotate(mouseMovement.dx, mouseMovement.dy); diff --git a/Samples/SimpleScene/Source/public/ecsControl.h b/Samples/SimpleScene/Source/public/ecsControl.h index 47206cfc9..cac6a75e7 100644 --- a/Samples/SimpleScene/Source/public/ecsControl.h +++ b/Samples/SimpleScene/Source/public/ecsControl.h @@ -26,7 +26,7 @@ struct CameraManagerPtr struct CameraPtr { - std::shared_ptr ptr = nullptr; + GameEngine::Core::Camera* ptr = nullptr; }; @@ -39,7 +39,7 @@ struct DeltaFixedCamera struct SavedCameraPtr { - std::weak_ptr ptr; + GameEngine::Core::Camera* ptr; }; void RegisterEcsControlSystems(flecs::world& world); From 1ba71cee7022b5fded89c7de3e37a7bc8db4fce4 Mon Sep 17 00:00:00 2001 From: Stepan Date: Wed, 3 Dec 2025 23:16:09 +0300 Subject: [PATCH 20/24] added function for delete camera --- Engine/Source/Core/private/CameraManager.cpp | 18 ++++++++++++++++++ Engine/Source/Core/public/CameraManager.h | 1 + .../SimpleScene/Source/private/ecsControl.cpp | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index 866970e64..2984af99e 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -83,4 +83,22 @@ namespace GameEngine::Core } } + void CameraManager::DeleteCamera(Camera* camera) + { + CameraList::iterator forDelCameraIt = std::find_if( + m_CameraList.begin(), + m_CameraList.end(), + [&](const Camera::Ptr& p) + { + return p.get() == camera; + } + ); + + if (m_CurrCameraIt == forDelCameraIt) + { + SwitchNextCamera(); + } + m_CameraList.erase(forDelCameraIt); + } + } \ No newline at end of file diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h index 2905b8b22..1e087b354 100644 --- a/Engine/Source/Core/public/CameraManager.h +++ b/Engine/Source/Core/public/CameraManager.h @@ -23,6 +23,7 @@ namespace GameEngine public: Camera* CreateCamera(); + void DeleteCamera(Camera* camera); Camera* GetActiveCamera(); void SwitchNextCamera(); void SwitchPrevCamera(); diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index 023625e18..b0d0797be 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -79,7 +79,7 @@ void RegisterEcsControlSystems(flecs::world& world) if (cameraManagerPtr->ptr->GetCamerasCount() > 1) { ProcessButtonPress(controller, "DeleteCamera", - [&]() { e.destruct(); } + [&]() { cameraManagerPtr->ptr->DeleteCamera(camera); e.destruct(); } ); } } From 3de60ee710a4c5e204495908ae466cdbf1671c29 Mon Sep 17 00:00:00 2001 From: Stepan Date: Wed, 3 Dec 2025 23:26:18 +0300 Subject: [PATCH 21/24] some clear code --- Engine/Source/Core/private/CameraManager.cpp | 30 +++++++++----------- Engine/Source/Core/public/CameraManager.h | 5 ++-- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index 2984af99e..d33949b58 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -39,14 +39,7 @@ namespace GameEngine::Core return; } - CameraList::iterator newCameraIt = std::find_if( - m_CameraList.begin(), - m_CameraList.end(), - [&](const Camera::Ptr& p) - { - return p.get() == camera; - } - ); + It newCameraIt = FindIterator(camera); m_CurrCameraIt = newCameraIt; } @@ -85,14 +78,7 @@ namespace GameEngine::Core void CameraManager::DeleteCamera(Camera* camera) { - CameraList::iterator forDelCameraIt = std::find_if( - m_CameraList.begin(), - m_CameraList.end(), - [&](const Camera::Ptr& p) - { - return p.get() == camera; - } - ); + It forDelCameraIt = FindIterator(camera); if (m_CurrCameraIt == forDelCameraIt) { @@ -101,4 +87,16 @@ namespace GameEngine::Core m_CameraList.erase(forDelCameraIt); } + CameraManager::It CameraManager::FindIterator(Camera* camera) + { + It it = std::find_if( + m_CameraList.begin(), + m_CameraList.end(), + [&](const Camera::Ptr& p) + { + return p.get() == camera; + } + ); + return it; + } } \ No newline at end of file diff --git a/Engine/Source/Core/public/CameraManager.h b/Engine/Source/Core/public/CameraManager.h index 1e087b354..c05868344 100644 --- a/Engine/Source/Core/public/CameraManager.h +++ b/Engine/Source/Core/public/CameraManager.h @@ -11,6 +11,7 @@ namespace GameEngine { public: using CameraList = std::list; + using It = CameraList::iterator; CameraManager() : m_CurrCameraIt(m_CameraList.end()) {} @@ -32,11 +33,11 @@ namespace GameEngine private: void AddCamera(Camera* camera); - CameraList::iterator FindValidCamera(CameraList::iterator startIt); + It FindIterator(Camera* camera); private: CameraList m_CameraList; - CameraList::iterator m_CurrCameraIt; + It m_CurrCameraIt; inline static Math::Vector3f startCameraPosition = Math::Vector3f(0.0f, 12.0f, -10.0f); inline static Math::Vector3f startCameraViewDir = Math::Vector3f(0.0f, -6.0f, 12.0f); From d1bbe617c0a0683854e203f0334a1a73f9e2cb37 Mon Sep 17 00:00:00 2001 From: Stepan Date: Wed, 3 Dec 2025 23:41:18 +0300 Subject: [PATCH 22/24] fixed camera ptr in editor --- Engine/Editor/private/EditorECS/ecsEditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/Editor/private/EditorECS/ecsEditor.cpp b/Engine/Editor/private/EditorECS/ecsEditor.cpp index 0c73c4904..d9909e49f 100644 --- a/Engine/Editor/private/EditorECS/ecsEditor.cpp +++ b/Engine/Editor/private/EditorECS/ecsEditor.cpp @@ -42,7 +42,7 @@ namespace GameEngine::EntitySystem::EditorECS mouseMovement.dx *= 0.25 * (Math::Constants::PI / 180.f); mouseMovement.dy *= 0.25 * (Math::Constants::PI / 180.f); - Core::Camera::Ptr camera = cameraManagerPtr->ptr->GetActiveCamera(); + Core::Camera* camera = cameraManagerPtr->ptr->GetActiveCamera(); camera->Rotate(mouseMovement.dx, mouseMovement.dy); From 945c9f0dfaff8bd547f6e69fd9d0f4302614f5d2 Mon Sep 17 00:00:00 2001 From: Stepan Date: Thu, 4 Dec 2025 02:24:45 +0300 Subject: [PATCH 23/24] processed extreme cases --- Engine/Source/Core/private/CameraManager.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/Engine/Source/Core/private/CameraManager.cpp b/Engine/Source/Core/private/CameraManager.cpp index d33949b58..fbc094b51 100644 --- a/Engine/Source/Core/private/CameraManager.cpp +++ b/Engine/Source/Core/private/CameraManager.cpp @@ -34,13 +34,13 @@ namespace GameEngine::Core void CameraManager::SetActiveCamera(Camera* camera) { - if (!camera) + It newCameraIt = FindIterator(camera); + + if (newCameraIt == m_CameraList.end()) { return; } - It newCameraIt = FindIterator(camera); - m_CurrCameraIt = newCameraIt; } @@ -80,9 +80,21 @@ namespace GameEngine::Core { It forDelCameraIt = FindIterator(camera); + if (forDelCameraIt == m_CameraList.end()) + { + return; + } + if (m_CurrCameraIt == forDelCameraIt) { - SwitchNextCamera(); + if (GetCamerasCount() == 1) + { + m_CurrCameraIt = m_CameraList.end(); + } + else + { + SwitchNextCamera(); + } } m_CameraList.erase(forDelCameraIt); } From 207d45071db156f03dff5c00a49f9586e0d49667 Mon Sep 17 00:00:00 2001 From: Stepan Date: Sat, 6 Dec 2025 16:06:21 +0300 Subject: [PATCH 24/24] returned the speed to the camera as a component --- Engine/Editor/private/EditorECS/ecsEditor.cpp | 8 ++++---- Engine/Editor/private/GameEditor.cpp | 3 ++- .../Source/private/GameFramework/GameFramework.cpp | 1 + Samples/SimpleScene/Source/private/ecsControl.cpp | 9 +++++---- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Engine/Editor/private/EditorECS/ecsEditor.cpp b/Engine/Editor/private/EditorECS/ecsEditor.cpp index d9909e49f..095502725 100644 --- a/Engine/Editor/private/EditorECS/ecsEditor.cpp +++ b/Engine/Editor/private/EditorECS/ecsEditor.cpp @@ -25,8 +25,8 @@ namespace GameEngine::EntitySystem::EditorECS } }); - world.system() - .each([&](flecs::entity e, CameraPtr& cameraPtr) + world.system() + .each([&](flecs::entity e, CameraPtr& cameraPtr, const Speed& speed) { static const CameraManagerPtr* cameraManagerPtr = world.get(); @@ -63,8 +63,8 @@ namespace GameEngine::EntitySystem::EditorECS { currentMoveDir = currentMoveDir + camera->GetViewDir(); } - float speed = 10.0f; - Math::Vector3f position = camera->GetPosition() + currentMoveDir.Normalized() * speed * world.delta_time(); + + Math::Vector3f position = camera->GetPosition() + currentMoveDir.Normalized() * speed.value * world.delta_time(); camera->SetPosition(position); }); } diff --git a/Engine/Editor/private/GameEditor.cpp b/Engine/Editor/private/GameEditor.cpp index 9ef34b640..e00438915 100644 --- a/Engine/Editor/private/GameEditor.cpp +++ b/Engine/Editor/private/GameEditor.cpp @@ -32,7 +32,8 @@ namespace GameEngine m_EntityManager->GetWorld().set(EntitySystem::EditorECS::CameraManagerPtr{ Core::g_CameraManager.get() }); flecs::entity camera = m_EntityManager->GetWorld().entity() - .set(EntitySystem::EditorECS::CameraPtr{ Core::g_CameraManager->CreateCamera() }); + .set(EntitySystem::EditorECS::CameraPtr{ Core::g_CameraManager->CreateCamera() }) + .set(EntitySystem::EditorECS::Speed{ 10.f }); EntitySystem::EditorECS::RegisterEditorEcsControlSystems(m_EntityManager->GetWorld()); diff --git a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp index 88f58e3c5..34d4ca35c 100644 --- a/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp +++ b/Samples/SimpleScene/Source/private/GameFramework/GameFramework.cpp @@ -30,6 +30,7 @@ void GameFramework::Init() flecs::entity camera = m_World.entity() .set(CameraPtr{ Core::g_CameraManager->CreateCamera() }) + .set(Speed{ 10.f }) .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); } diff --git a/Samples/SimpleScene/Source/private/ecsControl.cpp b/Samples/SimpleScene/Source/private/ecsControl.cpp index b0d0797be..a9c9c1566 100644 --- a/Samples/SimpleScene/Source/private/ecsControl.cpp +++ b/Samples/SimpleScene/Source/private/ecsControl.cpp @@ -27,8 +27,8 @@ static void ProcessButtonPress(const ControllerPtr& controller, void RegisterEcsControlSystems(flecs::world& world) { - world.system() - .each([&](flecs::entity e, CameraPtr& cameraPtr, const ControllerPtr& controller) + world.system() + .each([&](flecs::entity e, CameraPtr& cameraPtr, const Speed& speed, const ControllerPtr& controller) { static const CameraManagerPtr* cameraManagerPtr = world.get(); @@ -60,12 +60,13 @@ void RegisterEcsControlSystems(flecs::world& world) { currentMoveDir = currentMoveDir + camera->GetViewDir(); } - float speed = 10.0f; - Math::Vector3f position = camera->GetPosition() + currentMoveDir.Normalized() * speed * world.delta_time(); + + Math::Vector3f position = camera->GetPosition() + currentMoveDir.Normalized() * speed.value * world.delta_time(); camera->SetPosition(position); ProcessButtonPress(controller, "CreateCamera", [&]() { world.entity().set(CameraPtr{ cameraManagerPtr->ptr->CreateCamera() }) + .set(Speed{ speed.value }) .set(ControllerPtr{ new Core::Controller(Core::g_FileSystem->GetConfigPath("Input_default.ini")) }); } );