Entity parent/child hierarchies implemented

master
Joey Pollack 3 years ago
parent d893849dc3
commit 2279b3ff45

@ -1,5 +1,6 @@
High Importance:
☐ Colors are not saved accurately
✔ Add Component button on properties view no longer works @critical @done(22-09-07 13:44)
✔ AssetBrowser back button does not stop at the asset root directory @high @done(22-07-05 13:53)
✔ Editor does not get absolute paths from the file browser - replace with NFD dialogs @critical @done(22-05-20 18:36)

@ -52,15 +52,15 @@ int main(int argc, char** argv)
}
//std::cout << "\nEngine core successfully initialized!\n";
try
{
core.RunGameLoop();
}
catch(const std::exception& e)
{
lunarium::Logger::Fatal(lunarium::LogCategory::CORE, "Unhandled exception: %s", e.what());
}
core.RunGameLoop();
// try
// {
// core.RunGameLoop();
// }
// catch(const std::exception& e)
// {
// lunarium::Logger::Fatal(lunarium::LogCategory::CORE, "Unhandled exception: %s", e.what());
// }
core.Shutdown();

@ -120,13 +120,17 @@ namespace lunarium { namespace editor
was_clicked = ImGui::IsItemClicked(ImGuiMouseButton_Left);
was_right_clicked = ImGui::IsItemClicked(ImGuiMouseButton_Right);
const std::vector<LUUID>& children = pEnt->GetChildren();
for (auto iter = children.begin(); iter != children.end(); iter++)
if (pEnt->HasChildren())
{
Entity* pe = mpWorld->GetEntity((*iter));
ShowEntity(pe);
const std::vector<LUUID>& children = pEnt->GetChildren();
for (auto iter = children.begin(); iter != children.end(); iter++)
{
Entity* pe = mpWorld->GetEntity((*iter));
ShowEntity(pe);
}
}
ImGui::TreePop();
}
else

@ -19,6 +19,7 @@
#include <renderer/orthographic_camera.h>
#include <string>
#include <vector>
namespace lunarium
{
@ -86,13 +87,30 @@ namespace lunarium
// UTILITY COMPONENTS
/////////////////////////////////////////////////////////////////////
// These components are for internal use only. They do not show up in the editor.
struct UUIDComponent
{
LUUID UUID;
UUIDComponent() = default;
UUIDComponent(const UUIDComponent&) = default;
};
struct ParentEntityComponent
{
LUUID parent;
LUUID Parent;
ParentEntityComponent() = default;
ParentEntityComponent(const ParentEntityComponent&) = default;
};
struct ChildrenComponent
{
std::vector<LUUID> Children;
ChildrenComponent() = default;
ChildrenComponent(const ChildrenComponent&) = default;
};
}
#endif // LUNARIUM_COMPONENTS_H_

@ -42,6 +42,11 @@ namespace lunarium
return mUUID;
}
entt::entity Entity::GetEnttHandle() const
{
return mHandle;
}
std::string Entity::GetName() const
{
return mName;
@ -53,9 +58,10 @@ namespace lunarium
}
bool Entity::HasChildren() const
bool Entity::HasChildren()
{
return mChildren.size() > 0;
return HasComponent<ChildrenComponent>();
//return mChildren.size() > 0;
}
@ -63,7 +69,16 @@ namespace lunarium
{
Entity* e = mWorld.GetEntity(child);
e->AddComponent<ParentEntityComponent>(mUUID);
mChildren.push_back(child);
if (!HasComponent<ChildrenComponent>())
{
AddComponent<ChildrenComponent>();
}
ChildrenComponent& ccomp = GetComponent<ChildrenComponent>();
ccomp.Children.push_back(child);
//mChildren.push_back(child);
}
@ -71,40 +86,61 @@ namespace lunarium
{
Entity* e = mWorld.GetEntity(child);
e->ClearParent();
for (auto iter = mChildren.begin(); iter != mChildren.end(); iter++)
if (!HasChildren())
{
Logger::Error(LogCategory::GAME_SYSTEM, "RemoveChild called on entity that does not have children");
return;
}
ChildrenComponent& ccomp = GetComponent<ChildrenComponent>();
for (auto iter = ccomp.Children.begin(); iter != ccomp.Children.end(); iter++)
{
if ((*iter) == child)
{
mChildren.erase(iter);
ccomp.Children.erase(iter);
break;
}
}
if (ccomp.Children.size() < 1)
{
RemoveComponent<ChildrenComponent>();
}
}
const std::vector<LUUID>& Entity::GetChildren() const
std::vector<LUUID>& Entity::GetChildren()
{
return mChildren;
}
if (!HasChildren())
{
Logger::Error(LogCategory::GAME_SYSTEM, "GetChildren called on entity that does not have children");
return std::move(std::vector<LUUID>());
}
bool Entity::HasParent() const
{
return mParentSet;
ChildrenComponent& ccomp = GetComponent<ChildrenComponent>();
return ccomp.Children;
}
LUUID Entity::GetParent() const
{
return mParent;
}
// bool Entity::HasParent() const
// {
// return mParentSet;
// }
void Entity::SetParent(LUUID parent)
{
mParent = parent;
}
// LUUID Entity::GetParent() const
// {
// return mParent;
// }
// void Entity::SetParent(LUUID parent)
// {
// mParent = parent;
// }
void Entity::ClearParent()
{
mParentSet = false;
RemoveComponent<ParentEntityComponent>();
}
@ -119,6 +155,15 @@ namespace lunarium
node["name"] = mName;
auto& components = node["components"];
if (HasComponent<UUIDComponent>())
{
nlohmann::ordered_json uuid;
uuid["type_name"] = "UUIDComponent";
uuid["UUID"] = (u64)GetComponent<UUIDComponent>().UUID;
components.emplace_back(uuid);
}
if (HasComponent<TagComponent>())
{
nlohmann::ordered_json tag;
@ -210,22 +255,39 @@ namespace lunarium
nlohmann::ordered_json parent;
ParentEntityComponent& comp = GetComponent<ParentEntityComponent>();
parent["type_name"] = "ParentEntityComponent";
parent["UUID"] = (u64)comp.parent;
parent["UUID"] = (u64)comp.Parent;
components.emplace_back(parent);
}
if (HasComponent<ChildrenComponent>())
{
nlohmann::ordered_json children_node;
ChildrenComponent& comp = GetComponent<ChildrenComponent>();
children_node["type_name"] = "ChildrenComponent";
auto& children = children_node["children"];
for (int i = 0; i < comp.Children.size(); i++)
{
nlohmann::ordered_json child;
child["UUID"] = comp.Children[i];
children.emplace_back(child);
}
components.emplace_back(children_node);
}
// TODO: ADD CODE TO SERIALIZE ANY NEW COMPONENTS
// Children
auto& children = node["children"];
for (int i = 0; i < mChildren.size(); i++)
{
nlohmann::ordered_json child;
child["UUID"] = mChildren[i];
children.emplace_back(child);
}
// auto& children = node["children"];
// for (int i = 0; i < mChildren.size(); i++)
// {
// nlohmann::ordered_json child;
// child["UUID"] = mChildren[i];
// children.emplace_back(child);
// }
#endif
return OpRes::OK();
@ -246,6 +308,12 @@ namespace lunarium
std::string comp_type_name = comp["type_name"].get<std::string>();
if ("UUIDComponent" == comp_type_name)
{
LUUID uuid = comp["UUID"].get<u64>();
AddComponent<UUIDComponent>(uuid);
}
if ("TagComponent" == comp_type_name)
{
std::string info = comp["info"].get<std::string>();
@ -325,20 +393,35 @@ namespace lunarium
AddComponent<ParentEntityComponent>(parent);
}
if ("ChildrenComponent" == comp_type_name)
{
auto& children = comp["children"];
std::vector<LUUID> children_vec;
for (auto iter = children.begin(); iter != children.end(); iter++)
{
auto& child = *iter;
LUUID ne = child["UUID"].get<u64>();
children_vec.push_back(ne);
}
AddComponent<ChildrenComponent>(children_vec);
}
// TODO: ADD CODE TO DESERIALIZE ANY NEW COMPONENTS
}
// TODO: Load children
auto& children = node["children"];
for (auto iter = children.begin(); iter != children.end(); iter++)
{
auto& child = *iter;
LUUID ne = child["UUID"].get<u64>();
mChildren.push_back(ne);
}
// auto& children = node["children"];
// for (auto iter = children.begin(); iter != children.end(); iter++)
// {
// auto& child = *iter;
// LUUID ne = child["UUID"].get<u64>();
// mChildren.push_back(ne);
// }
#endif
return OpRes::OK();

@ -65,17 +65,18 @@ namespace lunarium // TODO: : public JSONSerializable
}
LUUID GetUUID() const;
entt::entity GetEnttHandle() const;
std::string GetName() const;
void SetName(std::string name);
bool HasChildren() const;
bool HasChildren();
void AddChild(LUUID child);
void RemoveChild(LUUID child);
const std::vector<LUUID>& GetChildren() const;
std::vector<LUUID>& GetChildren();
bool HasParent() const;
LUUID GetParent() const;
void SetParent(LUUID parent);
// bool HasParent() const;
// LUUID GetParent() const;
// void SetParent(LUUID parent);
void ClearParent();
// Serializing
@ -91,7 +92,7 @@ namespace lunarium // TODO: : public JSONSerializable
std::string mName;
entt::entity mHandle;
World& mWorld; // The world the entity is contained within
std::vector<LUUID> mChildren;
//std::vector<LUUID> mChildren;
private:
void Init();

@ -16,7 +16,6 @@
#include <renderer/renderer2D.h>
#include <renderer/orthographic_camera.h>
#include "entity.h"
#include "components.h"
namespace lunarium
{
@ -58,24 +57,37 @@ namespace lunarium
}
void World::Render(lunarium::Renderer2D* pGraphics) const
void World::Render(lunarium::Renderer2D* pGraphics)
{
// switch (mMode)
// Draw the Renderables that also have a transform
// Code from:
// https://github.com/skypjack/entt/wiki/Crash-Course:-entity-component-system#views-and-groups
// mECSRegistry.view<TransformComponent, BlockOutComponent>().each([&](auto entity, auto &transform, auto &blockout)
// {
// case RunMode::EDITOR: RenderEditor(pGraphics); break;
// }
// Rectangle rect(transform.Position.x, transform.Position.y, blockout.Size.x, blockout.Size.y);
// Color color(blockout.Color.x, blockout.Color.y, blockout.Color.z, blockout.Color.w);
// TODO: Modify to handle parent/child rendering
// glm::mat4 parent_transform(1.0f);
// if (mECSRegistry.all_of<ParentEntityComponent>(entity))
// {
// // UUIDComponent uuid = mECSRegistry.get<UUIDComponent>(entity);
// // LUUID uid = uuid.UUID;
// ParentEntityComponent& parent = mECSRegistry.get<ParentEntityComponent>(entity);
// parent_transform = GetParentTransform(parent.Parent);
// }
// pGraphics->DrawQuad(rect, color, nullptr, 0.0f, Rectangle(-1, -1, -1, -1), parent_transform);
// });
// Draw the Renderables that also have a transform
// Code from:
// https://github.com/skypjack/entt/wiki/Crash-Course:-entity-component-system#views-and-groups
mECSRegistry.view<TransformComponent, BlockOutComponent>().each([&](auto entity, auto &transform, auto &blockout)
{
Rectangle rect(transform.Position.x, transform.Position.y, blockout.Size.x, blockout.Size.y);
Color color(blockout.Color.x, blockout.Color.y, blockout.Color.z, blockout.Color.w);
pGraphics->DrawQuad(rect, color);
if (!mECSRegistry.all_of<ParentEntityComponent>(entity))
{
DrawHeirarchy(pGraphics, entity, transform, blockout, glm::mat4(1.0f));
}
});
}
@ -135,6 +147,59 @@ namespace lunarium
// RUN MODE HELPERS
/////////////////////////////////////////////////////////////////////
void World::DrawHeirarchy(lunarium::Renderer2D* g, entt::entity& entity, TransformComponent& my_trans, BlockOutComponent& bo_comp, glm::mat4 current_transform)
{
// Draw current entity
Rectangle rect(my_trans.Position.x, my_trans.Position.y, bo_comp.Size.x, bo_comp.Size.y);
Color color(bo_comp.Color.x, bo_comp.Color.y, bo_comp.Color.z, bo_comp.Color.w);
g->DrawQuad(rect, color, nullptr, -my_trans.Rotation.z, Rectangle(-1, -1, -1, -1), current_transform);
// Apply transform to children's transforms
current_transform *= my_trans.GetTransform();
// Iterate and draw children
if (mECSRegistry.all_of<ChildrenComponent>(entity))
{
ChildrenComponent& children_comp = mECSRegistry.get<ChildrenComponent>(entity);
for (int i = 0; i < children_comp.Children.size(); i++)
{
Entity* pEnt = GetEntity(children_comp.Children[i]);
entt::entity handle = pEnt->GetEnttHandle();
if (pEnt->HasComponent<TransformComponent>() && pEnt->HasComponent<BlockOutComponent>())
{
TransformComponent& trans_comp = pEnt->GetComponent<TransformComponent>();
BlockOutComponent& bo_comp = pEnt->GetComponent<BlockOutComponent>();
DrawHeirarchy(g, handle, trans_comp, bo_comp, current_transform);
}
}
}
}
glm::mat4 World::GetParentTransform(LUUID parent)
{
glm::mat4 transform(1.0f);
Entity* p = GetEntity(parent);
if (p->HasComponent<TransformComponent>())
{
TransformComponent t = p->GetComponent<TransformComponent>();
transform = t.GetTransform();
if (p->HasComponent<ParentEntityComponent>())
{
transform *= GetParentTransform(p->GetComponent<ParentEntityComponent>().Parent);
}
}
return transform;
}
void World::RenderEditor(lunarium::Renderer2D* pGraphics) const
{
// NOTE: MAY BE REMOVED

@ -17,6 +17,7 @@
#include <assets/serializing/json_serializable.h>
#include <utils/op_res.h>
#include <entt/entt.hpp>
#include "components.h"
#include <vector>
#include <map>
@ -68,7 +69,7 @@ namespace lunarium
void OnLoad();
void OnUnload();
void Update(float dt);
void Render(lunarium::Renderer2D* pGraphics) const;
void Render(lunarium::Renderer2D* pGraphics);
void SetActiveCamera(OrthographicCamera* pCam);
void SetRunMode(RunMode mode);
@ -109,6 +110,8 @@ namespace lunarium
private: // HELPERS
void RenderEditor(lunarium::Renderer2D* pGraphics) const;
glm::mat4 GetParentTransform(LUUID parent);
void DrawHeirarchy(lunarium::Renderer2D* g, entt::entity& entity, TransformComponent& my_trans, BlockOutComponent& bo_comp, glm::mat4 current_transform);
};
}

Loading…
Cancel
Save