|
|
|
|
/******************************************************************************
|
|
|
|
|
* File - entity.cpp
|
|
|
|
|
* Author - Joey Pollack
|
|
|
|
|
* Date - 2022/05/23 (y/m/d)
|
|
|
|
|
* Mod Date - 2022/05/23 (y/m/d)
|
|
|
|
|
* Description - Provides functionality to work with world entities
|
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "entity.h"
|
|
|
|
|
#include "world.h"
|
|
|
|
|
#include "components.h"
|
|
|
|
|
#include <utils/logger.h>
|
|
|
|
|
|
|
|
|
|
namespace lunarium
|
|
|
|
|
{
|
|
|
|
|
Entity::Entity(World& w)
|
|
|
|
|
: mHandle(entt::null), mWorld(w), mParent(0), mParentSet(false)
|
|
|
|
|
{
|
|
|
|
|
mUUID = UUID::GetNewID();
|
|
|
|
|
Init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Entity::Entity(World& w, LUUID uuid, entt::entity handle)
|
|
|
|
|
: mHandle(handle), mWorld(w), mUUID(uuid)
|
|
|
|
|
{
|
|
|
|
|
Init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Entity::Init()
|
|
|
|
|
{
|
|
|
|
|
auto prev = mHandle;
|
|
|
|
|
mHandle = mWorld.GetEntityRegistry()->create(mHandle);
|
|
|
|
|
|
|
|
|
|
if (prev != mHandle && prev != entt::null)
|
|
|
|
|
{
|
|
|
|
|
Logger::Warn(LogCategory::GAME_SYSTEM, "Requested entity handle was not used");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LUUID Entity::GetUUID() const
|
|
|
|
|
{
|
|
|
|
|
return mUUID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
entt::entity Entity::GetEnttHandle() const
|
|
|
|
|
{
|
|
|
|
|
return mHandle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string Entity::GetName() const
|
|
|
|
|
{
|
|
|
|
|
return mName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Entity::SetName(std::string name)
|
|
|
|
|
{
|
|
|
|
|
mName = name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Entity::HasChildren()
|
|
|
|
|
{
|
|
|
|
|
return HasComponent<ChildrenComponent>();
|
|
|
|
|
//return mChildren.size() > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Entity::AddChild(LUUID child)
|
|
|
|
|
{
|
|
|
|
|
Entity* e = mWorld.GetEntity(child);
|
|
|
|
|
e->AddComponent<ParentEntityComponent>(mUUID);
|
|
|
|
|
|
|
|
|
|
if (!HasComponent<ChildrenComponent>())
|
|
|
|
|
{
|
|
|
|
|
AddComponent<ChildrenComponent>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ChildrenComponent& ccomp = GetComponent<ChildrenComponent>();
|
|
|
|
|
ccomp.Children.push_back(child);
|
|
|
|
|
|
|
|
|
|
//mChildren.push_back(child);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Entity::RemoveChild(LUUID child)
|
|
|
|
|
{
|
|
|
|
|
Entity* e = mWorld.GetEntity(child);
|
|
|
|
|
e->ClearParent();
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
ccomp.Children.erase(iter);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ccomp.Children.size() < 1)
|
|
|
|
|
{
|
|
|
|
|
RemoveComponent<ChildrenComponent>();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<LUUID>& Entity::GetChildren()
|
|
|
|
|
{
|
|
|
|
|
if (!HasChildren())
|
|
|
|
|
{
|
|
|
|
|
Logger::Error(LogCategory::GAME_SYSTEM, "GetChildren called on entity that does not have children");
|
|
|
|
|
return std::move(std::vector<LUUID>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ChildrenComponent& ccomp = GetComponent<ChildrenComponent>();
|
|
|
|
|
return ccomp.Children;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bool Entity::HasParent() const
|
|
|
|
|
// {
|
|
|
|
|
// return mParentSet;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// LUUID Entity::GetParent() const
|
|
|
|
|
// {
|
|
|
|
|
// return mParent;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// void Entity::SetParent(LUUID parent)
|
|
|
|
|
// {
|
|
|
|
|
// mParent = parent;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
void Entity::ClearParent()
|
|
|
|
|
{
|
|
|
|
|
mParentSet = false;
|
|
|
|
|
RemoveComponent<ParentEntityComponent>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
// SERIALIZING
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
OpRes Entity::Serialize(nlohmann::ordered_json& node)
|
|
|
|
|
{
|
|
|
|
|
#if !BUILD_NO_EDITOR // Only does this when this is an editor build
|
|
|
|
|
|
|
|
|
|
node["UUID"] = mUUID;
|
|
|
|
|
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;
|
|
|
|
|
tag["type_name"] = "TagComponent";
|
|
|
|
|
tag["info"] = GetComponent<TagComponent>().Info;
|
|
|
|
|
components.emplace_back(tag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (HasComponent<TransformComponent>())
|
|
|
|
|
{
|
|
|
|
|
nlohmann::ordered_json transform;
|
|
|
|
|
TransformComponent& comp = GetComponent<TransformComponent>();
|
|
|
|
|
transform["type_name"] = "TransformComponent";
|
|
|
|
|
|
|
|
|
|
auto& pos = transform["position"];
|
|
|
|
|
pos["x"] = comp.Position.x;
|
|
|
|
|
pos["y"] = comp.Position.y;
|
|
|
|
|
pos["z"] = comp.Position.z;
|
|
|
|
|
|
|
|
|
|
auto& rot = transform["rotation"];
|
|
|
|
|
rot["x"] = comp.Rotation.x;
|
|
|
|
|
rot["y"] = comp.Rotation.y;
|
|
|
|
|
rot["z"] = comp.Rotation.z;
|
|
|
|
|
|
|
|
|
|
auto& scale = transform["scale"];
|
|
|
|
|
scale["x"] = comp.Scale.x;
|
|
|
|
|
scale["y"] = comp.Scale.y;
|
|
|
|
|
scale["z"] = comp.Scale.z;
|
|
|
|
|
|
|
|
|
|
components.emplace_back(transform);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (HasComponent<VelocityComponent>())
|
|
|
|
|
{
|
|
|
|
|
nlohmann::ordered_json velocity;
|
|
|
|
|
VelocityComponent& comp = GetComponent<VelocityComponent>();
|
|
|
|
|
velocity["type_name"] = "VelocityComponent";
|
|
|
|
|
|
|
|
|
|
auto& pos = velocity["velocity"];
|
|
|
|
|
pos["x"] = comp.Velocity.x;
|
|
|
|
|
pos["y"] = comp.Velocity.y;
|
|
|
|
|
pos["z"] = comp.Velocity.z;
|
|
|
|
|
|
|
|
|
|
components.emplace_back(velocity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (HasComponent<CameraComponent>())
|
|
|
|
|
{
|
|
|
|
|
nlohmann::ordered_json camera;
|
|
|
|
|
CameraComponent& comp = GetComponent<CameraComponent>();
|
|
|
|
|
camera["type_name"] = "CameraComponent";
|
|
|
|
|
|
|
|
|
|
auto& pos = camera["position"];
|
|
|
|
|
pos["x"] = comp.Camera.GetPosition().X;
|
|
|
|
|
pos["y"] = comp.Camera.GetPosition().Y;
|
|
|
|
|
pos["z"] = 0.0f;
|
|
|
|
|
|
|
|
|
|
auto& rot = camera["rotation"];
|
|
|
|
|
rot["degrees"] = comp.Camera.GetRotation();
|
|
|
|
|
|
|
|
|
|
auto& vpsize = camera["viewport_size"];
|
|
|
|
|
vpsize["width"] = comp.Camera.GetViewportSize().Width;
|
|
|
|
|
vpsize["height"] = comp.Camera.GetViewportSize().Height;
|
|
|
|
|
|
|
|
|
|
components.emplace_back(camera);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (HasComponent<BlockOutComponent>())
|
|
|
|
|
{
|
|
|
|
|
nlohmann::ordered_json blockout;
|
|
|
|
|
BlockOutComponent& comp = GetComponent<BlockOutComponent>();
|
|
|
|
|
blockout["type_name"] = "BlockOutComponent";
|
|
|
|
|
|
|
|
|
|
auto& color = blockout["color"];
|
|
|
|
|
color["r"] = comp.Color.x;
|
|
|
|
|
color["g"] = comp.Color.y;
|
|
|
|
|
color["b"] = comp.Color.a;
|
|
|
|
|
color["a"] = comp.Color.w;
|
|
|
|
|
|
|
|
|
|
auto& size = blockout["size"];
|
|
|
|
|
size["width"] = comp.Size.x;
|
|
|
|
|
size["height"] = comp.Size.y;
|
|
|
|
|
|
|
|
|
|
blockout["render_layer"] = comp.RenderLayer;
|
|
|
|
|
|
|
|
|
|
components.emplace_back(blockout);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (HasComponent<ParentEntityComponent>())
|
|
|
|
|
{
|
|
|
|
|
nlohmann::ordered_json parent;
|
|
|
|
|
ParentEntityComponent& comp = GetComponent<ParentEntityComponent>();
|
|
|
|
|
parent["type_name"] = "ParentEntityComponent";
|
|
|
|
|
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);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
return OpRes::OK();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OpRes Entity::Deserialize(nlohmann::ordered_json& node)
|
|
|
|
|
{
|
|
|
|
|
#if !BUILD_NO_EDITOR // Only does this when this is an editor build
|
|
|
|
|
|
|
|
|
|
mUUID = node["UUID"].get<u64>();
|
|
|
|
|
mName = node["name"].get<std::string>();
|
|
|
|
|
|
|
|
|
|
// TODO: Load components
|
|
|
|
|
auto& components = node["components"];
|
|
|
|
|
for (auto iter = components.begin(); iter != components.end(); iter++)
|
|
|
|
|
{
|
|
|
|
|
auto& comp = *iter;
|
|
|
|
|
|
|
|
|
|
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>();
|
|
|
|
|
AddComponent<TagComponent>(info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ("TransformComponent" == comp_type_name)
|
|
|
|
|
{
|
|
|
|
|
auto& pos = comp["position"];
|
|
|
|
|
float x = pos["x"].get<f32>();
|
|
|
|
|
float y = pos["y"].get<f32>();
|
|
|
|
|
float z = pos["z"].get<f32>();
|
|
|
|
|
glm::vec3 position(x, y, z);
|
|
|
|
|
|
|
|
|
|
auto& rot = comp["rotation"];
|
|
|
|
|
x = rot["x"].get<f32>();
|
|
|
|
|
y = rot["y"].get<f32>();
|
|
|
|
|
z = rot["z"].get<f32>();
|
|
|
|
|
glm::vec3 rotation(x, y, z);
|
|
|
|
|
|
|
|
|
|
auto& sc = comp["scale"];
|
|
|
|
|
x = sc["x"].get<f32>();
|
|
|
|
|
y = sc["y"].get<f32>();
|
|
|
|
|
z = sc["z"].get<f32>();
|
|
|
|
|
glm::vec3 scale(x, y, z);
|
|
|
|
|
|
|
|
|
|
AddComponent<TransformComponent>(position, rotation, scale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ("VelocityComponent" == comp_type_name)
|
|
|
|
|
{
|
|
|
|
|
auto& vel = comp["velocity"];
|
|
|
|
|
float x = vel["x"].get<f32>();
|
|
|
|
|
float y = vel["y"].get<f32>();
|
|
|
|
|
float z = vel["z"].get<f32>();
|
|
|
|
|
glm::vec3 velocity(x, y, z);
|
|
|
|
|
|
|
|
|
|
AddComponent<VelocityComponent>(velocity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ("CameraComponent" == comp_type_name)
|
|
|
|
|
{
|
|
|
|
|
auto& pos = comp["position"];
|
|
|
|
|
float x = pos["x"].get<f32>();
|
|
|
|
|
float y = pos["y"].get<f32>();
|
|
|
|
|
float z = pos["z"].get<f32>();
|
|
|
|
|
glm::vec3 position(x, y, z);
|
|
|
|
|
|
|
|
|
|
auto& rot = comp["rotation"];
|
|
|
|
|
float deg = rot["degrees"];
|
|
|
|
|
|
|
|
|
|
auto& vps = comp["viewport_size"];
|
|
|
|
|
float width = vps["width"].get<f32>();
|
|
|
|
|
float height = vps["height"].get<f32>();
|
|
|
|
|
|
|
|
|
|
OrthographicCamera cam({x, y}, {width, height});
|
|
|
|
|
cam.SetRotation(deg);
|
|
|
|
|
|
|
|
|
|
AddComponent<CameraComponent>(cam);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ("BlockOutComponent" == comp_type_name)
|
|
|
|
|
{
|
|
|
|
|
auto& color = comp["color"];
|
|
|
|
|
glm::vec4 Color(color["r"].get<f32>(), color["g"].get<f32>(), color["b"].get<f32>(), color["a"].get<f32>());
|
|
|
|
|
|
|
|
|
|
auto& size = comp["size"];
|
|
|
|
|
glm::vec2 Size(size["width"].get<f32>(), size["height"].get<f32>());
|
|
|
|
|
|
|
|
|
|
int layer = comp["render_layer"].get<int>();
|
|
|
|
|
|
|
|
|
|
AddComponent<BlockOutComponent>(Color, Size, layer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ("ParentEntityComponent" == comp_type_name)
|
|
|
|
|
{
|
|
|
|
|
LUUID parent = comp["UUID"].get<u64>();
|
|
|
|
|
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);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
return OpRes::OK();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Entity::IsValidNode(nlohmann::ordered_json& node)
|
|
|
|
|
{
|
|
|
|
|
if (node["UUID"].is_null()) { return false; }
|
|
|
|
|
if (!node["UUID"].is_number()) { return false; }
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nlohmann::ordered_json Entity::AsJSON()
|
|
|
|
|
{
|
|
|
|
|
#if !BUILD_NO_EDITOR // Only does this when this is an editor build
|
|
|
|
|
nlohmann::ordered_json node;
|
|
|
|
|
|
|
|
|
|
Serialize(node).LogIfFailed(LogCategory::GAME_SYSTEM);
|
|
|
|
|
|
|
|
|
|
return node;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return nlohmann::ordered_json();
|
|
|
|
|
}
|
|
|
|
|
}
|