187 lines
6.1 KiB
C++
187 lines
6.1 KiB
C++
#include "SceneManager.h"
|
|
#include "SelectionManager.h"
|
|
#include <algorithm>
|
|
|
|
namespace UI {
|
|
|
|
EntityID SceneManager::CreateEntity(const std::string& name, EntityID parent) {
|
|
EntityID id = m_nextEntityId++;
|
|
GameObject entity;
|
|
entity.id = id;
|
|
entity.name = name;
|
|
entity.parent = parent;
|
|
m_entities[id] = std::move(entity);
|
|
|
|
if (parent != INVALID_ENTITY_ID) {
|
|
m_entities[parent].children.push_back(id);
|
|
} else {
|
|
m_rootEntities.push_back(id);
|
|
}
|
|
|
|
OnEntityCreated.Invoke(id);
|
|
return id;
|
|
}
|
|
|
|
void SceneManager::DeleteEntity(EntityID id) {
|
|
auto it = m_entities.find(id);
|
|
if (it == m_entities.end()) return;
|
|
|
|
GameObject& entity = it->second;
|
|
|
|
std::vector<EntityID> childrenToDelete = entity.children;
|
|
for (EntityID childId : childrenToDelete) {
|
|
DeleteEntity(childId);
|
|
}
|
|
|
|
if (entity.parent != INVALID_ENTITY_ID) {
|
|
auto* parent = GetEntity(entity.parent);
|
|
if (parent) {
|
|
auto& siblings = parent->children;
|
|
siblings.erase(std::remove(siblings.begin(), siblings.end(), id), siblings.end());
|
|
}
|
|
} else {
|
|
m_rootEntities.erase(std::remove(m_rootEntities.begin(), m_rootEntities.end(), id), m_rootEntities.end());
|
|
}
|
|
|
|
if (SelectionManager::Get().GetSelectedEntity() == id) {
|
|
SelectionManager::Get().ClearSelection();
|
|
}
|
|
|
|
m_entities.erase(it);
|
|
OnEntityDeleted.Invoke(id);
|
|
}
|
|
|
|
ClipboardData SceneManager::CopyEntityRecursive(const GameObject* entity) {
|
|
ClipboardData data;
|
|
data.name = entity->name;
|
|
|
|
for (const auto& comp : entity->components) {
|
|
if (auto* transform = dynamic_cast<const TransformComponent*>(comp.get())) {
|
|
auto newComp = std::make_unique<TransformComponent>();
|
|
memcpy(newComp->position, transform->position, sizeof(transform->position));
|
|
memcpy(newComp->rotation, transform->rotation, sizeof(transform->rotation));
|
|
memcpy(newComp->scale, transform->scale, sizeof(transform->scale));
|
|
data.components.push_back(std::move(newComp));
|
|
}
|
|
else if (auto* meshRenderer = dynamic_cast<const MeshRendererComponent*>(comp.get())) {
|
|
auto newComp = std::make_unique<MeshRendererComponent>();
|
|
newComp->materialName = meshRenderer->materialName;
|
|
newComp->meshName = meshRenderer->meshName;
|
|
data.components.push_back(std::move(newComp));
|
|
}
|
|
}
|
|
|
|
for (EntityID childId : entity->children) {
|
|
const GameObject* child = GetEntity(childId);
|
|
if (child) {
|
|
data.children.push_back(CopyEntityRecursive(child));
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
void SceneManager::CopyEntity(EntityID id) {
|
|
const GameObject* entity = GetEntity(id);
|
|
if (!entity) return;
|
|
|
|
m_clipboard = CopyEntityRecursive(entity);
|
|
}
|
|
|
|
EntityID SceneManager::PasteEntityRecursive(const ClipboardData& data, EntityID parent) {
|
|
EntityID newId = CreateEntity(data.name, parent);
|
|
GameObject* newEntity = GetEntity(newId);
|
|
|
|
if (newEntity) {
|
|
newEntity->components.clear();
|
|
for (const auto& comp : data.components) {
|
|
if (auto* transform = dynamic_cast<const TransformComponent*>(comp.get())) {
|
|
auto newComp = std::make_unique<TransformComponent>();
|
|
memcpy(newComp->position, transform->position, sizeof(transform->position));
|
|
memcpy(newComp->rotation, transform->rotation, sizeof(transform->rotation));
|
|
memcpy(newComp->scale, transform->scale, sizeof(transform->scale));
|
|
newEntity->components.push_back(std::move(newComp));
|
|
}
|
|
else if (auto* meshRenderer = dynamic_cast<const MeshRendererComponent*>(comp.get())) {
|
|
auto newComp = std::make_unique<MeshRendererComponent>();
|
|
newComp->materialName = meshRenderer->materialName;
|
|
newComp->meshName = meshRenderer->meshName;
|
|
newEntity->components.push_back(std::move(newComp));
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const auto& childData : data.children) {
|
|
PasteEntityRecursive(childData, newId);
|
|
}
|
|
|
|
return newId;
|
|
}
|
|
|
|
EntityID SceneManager::PasteEntity(EntityID parent) {
|
|
if (!m_clipboard) return INVALID_ENTITY_ID;
|
|
return PasteEntityRecursive(*m_clipboard, parent);
|
|
}
|
|
|
|
EntityID SceneManager::DuplicateEntity(EntityID id) {
|
|
CopyEntity(id);
|
|
const GameObject* entity = GetEntity(id);
|
|
if (!entity) return INVALID_ENTITY_ID;
|
|
return PasteEntity(entity->parent);
|
|
}
|
|
|
|
void SceneManager::MoveEntity(EntityID id, EntityID newParent) {
|
|
GameObject* entity = GetEntity(id);
|
|
if (!entity || id == newParent) return;
|
|
|
|
if (entity->parent != INVALID_ENTITY_ID) {
|
|
GameObject* oldParent = GetEntity(entity->parent);
|
|
if (oldParent) {
|
|
auto& siblings = oldParent->children;
|
|
siblings.erase(std::remove(siblings.begin(), siblings.end(), id), siblings.end());
|
|
}
|
|
} else {
|
|
m_rootEntities.erase(std::remove(m_rootEntities.begin(), m_rootEntities.end(), id), m_rootEntities.end());
|
|
}
|
|
|
|
entity->parent = newParent;
|
|
|
|
if (newParent != INVALID_ENTITY_ID) {
|
|
GameObject* newParentEntity = GetEntity(newParent);
|
|
if (newParentEntity) {
|
|
newParentEntity->children.push_back(id);
|
|
}
|
|
} else {
|
|
m_rootEntities.push_back(id);
|
|
}
|
|
|
|
OnEntityChanged.Invoke(id);
|
|
}
|
|
|
|
void SceneManager::CreateDemoScene() {
|
|
m_entities.clear();
|
|
m_rootEntities.clear();
|
|
m_nextEntityId = 1;
|
|
m_clipboard.reset();
|
|
|
|
EntityID camera = CreateEntity("Main Camera");
|
|
GetEntity(camera)->AddComponent<TransformComponent>();
|
|
|
|
EntityID light = CreateEntity("Directional Light");
|
|
|
|
EntityID cube = CreateEntity("Cube");
|
|
GetEntity(cube)->AddComponent<TransformComponent>();
|
|
GetEntity(cube)->AddComponent<MeshRendererComponent>()->meshName = "Cube Mesh";
|
|
|
|
EntityID sphere = CreateEntity("Sphere");
|
|
GetEntity(sphere)->AddComponent<TransformComponent>();
|
|
GetEntity(sphere)->AddComponent<MeshRendererComponent>()->meshName = "Sphere Mesh";
|
|
|
|
EntityID player = CreateEntity("Player");
|
|
EntityID weapon = CreateEntity("Weapon", player);
|
|
|
|
OnSceneChanged.Invoke();
|
|
}
|
|
|
|
}
|