Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f7fd56b
homework 7
Stepazavr Oct 26, 2025
5390ddc
added CameraManader with functions like createCamera and SwitchCamera…
Stepazavr Nov 11, 2025
2930889
added shared_ptr on Camera in CameraManager
Stepazavr Nov 11, 2025
8d9d6cc
added currectly switch between buttons
Stepazavr Nov 11, 2025
3429690
<functional> was already in the project
Stepazavr Nov 11, 2025
d61f763
added <iterator> in CMakeList
Stepazavr Nov 11, 2025
658a8d1
added start value for a new camera
Stepazavr Nov 11, 2025
c4f10c9
code style
Stepazavr Nov 16, 2025
23b3063
changed g_CameraManager to unique_ptr
Stepazavr Nov 16, 2025
94b0d10
added new functional in CameraManager: SetActiveCamera(camera)
Stepazavr Nov 16, 2025
0754851
some fixes
Stepazavr Nov 16, 2025
f51d00b
added common system (some new functional) which observer about was ke…
Stepazavr Nov 21, 2025
9408782
added new level with two cudes which cameras are linked to
Stepazavr Nov 21, 2025
ae96235
code style
Stepazavr Nov 24, 2025
e5146cb
added weak_ptr in CameraManager without checking if ptr is expired.
Stepazavr Nov 24, 2025
d1dad35
added checking if weak_ptr is expired
Stepazavr Nov 24, 2025
2e86812
added cameras as independent objects in a scene and CameraManader as …
Stepazavr Nov 25, 2025
890d192
delete friend CameraManader from Camera
Stepazavr Dec 3, 2025
bde1845
changed CameraManader from observer to owner
Stepazavr Dec 3, 2025
1ba71ce
added function for delete camera
Stepazavr Dec 3, 2025
3de60ee
some clear code
Stepazavr Dec 3, 2025
d1bbe61
fixed camera ptr in editor
Stepazavr Dec 3, 2025
945c9f0
processed extreme cases
Stepazavr Dec 3, 2025
207d450
returned the speed to the camera as a component
Stepazavr Dec 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Engine/Editor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ target_precompile_headers(Editor
PRIVATE
<algorithm>
<unordered_map>
<set>
<list>
<vector>
<string>
<cassert>
Expand Down
31 changes: 18 additions & 13 deletions Engine/Editor/private/EditorECS/ecsEditor.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include <Camera.h>
#include <CameraManager.h>
#include <Constants.h>
#include <EditorECS/ecsEditor.h>
#include <ECS/ecsSystems.h>
Expand All @@ -25,10 +25,14 @@ namespace GameEngine::EntitySystem::EditorECS
}
});

world.system<Position, CameraPtr, const Speed>()
.each([&](flecs::entity e, Position& position, CameraPtr& camera, const Speed& speed)
world.system<CameraPtr, const Speed>()
.each([&](flecs::entity e, CameraPtr& cameraPtr, const Speed& speed)
{
if (!Core::g_MainWindowsApplication->IsMouseCaptured() || !Core::g_MainWindowsApplication->IsFocused()) [[unlikely]]
static const CameraManagerPtr* cameraManagerPtr = world.get<CameraManagerPtr>();

if (cameraPtr.ptr != cameraManagerPtr->ptr->GetActiveCamera() ||
!Core::g_MainWindowsApplication->IsMouseCaptured() ||
!Core::g_MainWindowsApplication->IsFocused()) [[unlikely]]
{
return;
}
Expand All @@ -38,29 +42,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 = cameraManagerPtr->ptr->GetActiveCamera();

camera->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));

Math::Vector3f position = camera->GetPosition() + currentMoveDir.Normalized() * speed.value * world.delta_time();
camera->SetPosition(position);
});
}
};
13 changes: 6 additions & 7 deletions Engine/Editor/private/GameEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include <Debug/Console.h>
#include <EditorECS/ecsEditor.h>
#include <Camera.h>
#include <CameraManager.h>
#include <DefaultGeometry.h>
#include <Window/IWindow.h>
#include <GUIContext.h>
Expand All @@ -18,9 +18,7 @@ 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 = std::make_unique<Core::CameraManager>();

GUI::GUIContext::GetInstance()->PlatformInit();
m_renderThread = std::make_unique<Render::RenderThread>();
Expand All @@ -31,10 +29,11 @@ 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

m_EntityManager->GetWorld().set(EntitySystem::EditorECS::CameraManagerPtr{ Core::g_CameraManager.get() });

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 });
.set(EntitySystem::EditorECS::CameraPtr{ Core::g_CameraManager->CreateCamera() })
.set(EntitySystem::EditorECS::Speed{ 10.f });

EntitySystem::EditorECS::RegisterEditorEcsControlSystems(m_EntityManager->GetWorld());

Expand Down
41 changes: 28 additions & 13 deletions Engine/Editor/private/LevelEditor/ECS/ecsLevelEditor.cpp
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@
#include <LevelEditor/ECS/ecsLevelEditor.h>

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;
}
}

Expand Down
20 changes: 13 additions & 7 deletions Engine/Editor/private/LevelEditor/ECS/ecsLevelEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
#include <flecs.h>

#include <EditorECS/ecsEditor.h>
#include <Vector.h>

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);
}
126 changes: 91 additions & 35 deletions Engine/Editor/private/LevelEditor/LevelEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<RenderCore::Geometry*>(
World::WorldParser::GetCustomComponents()[geometryAttribute->second]
)
});
}
AddLevelEditorEntity(levelObject);
}

EntitySystem::LevelEditorECS::RegisterLevelEditorEcsSystems(world);
EntitySystem::LevelEditorECS::RegisterLevelEditorEcsSystems(m_World);
}

void LevelEditor::Draw()
Expand All @@ -67,15 +36,36 @@ namespace GameEngine
{
if (ImGui::TreeNode(levelObject.GetName().c_str()))
{
static const std::set<std::string> 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"))
{
Expand Down Expand Up @@ -109,5 +99,71 @@ 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;
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() ) {
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<RenderCore::Geometry*>(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не static_cast?

World::WorldParser::GetCustomComponents()[geometryAttribute->second]
)
});
}
}
}
}
7 changes: 7 additions & 0 deletions Engine/Editor/public/EditorECS/ecsEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@

namespace GameEngine::Core
{
class CameraManager;
class Camera;

}

namespace GameEngine::EntitySystem::EditorECS
{
struct CameraManagerPtr
{
Core::CameraManager* ptr;
};

struct CameraPtr
{
Core::Camera* ptr;
Expand Down
3 changes: 3 additions & 0 deletions Engine/Editor/public/LevelEditor/LevelEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ namespace GameEngine

private:
void Save();
void AddDefaultObject();
void AddLevelEditorEntity(World::LevelObject& levelObject);

private:
Core::Timer m_SaveButtonMessageTimer;
bool m_SaveButtonPressed = false;
float m_TimeToShowSaveButtonMessage = 3.f;

std::optional<World::Level> m_Level = std::nullopt;
flecs::world m_World;
};
}
}
Loading