This commit is contained in:
antopilo
2024-09-19 21:11:07 -04:00
parent 7791cd9f29
commit 6ac1ff8386
10 changed files with 215 additions and 14 deletions

View File

@@ -110,7 +110,7 @@ Ref<Nuake::Texture> ThumbnailManager::GenerateThumbnail(const std::string& path,
camComponent.CameraInstance->AspectRatio = 1.0f;
m_ShadedFramebuffer->SetTexture(texture);
Ref<Prefab> prefab = Prefab::InstanceInScene(path, scene);
Ref<Prefab> prefab = Prefab::InstanceInScene(path, scene.get());
scene->Update(0.01f);
scene->Draw(*m_ShadedFramebuffer.get());

View File

@@ -35,7 +35,7 @@ namespace Nuake
return newPrefab;
}
Ref<Prefab> Prefab::InstanceInScene(const std::string& path, Ref<Scene> scene)
Ref<Prefab> Prefab::InstanceInScene(const std::string& path, Scene* scene)
{
Ref<Prefab> newPrefab = CreateRef<Prefab>();
newPrefab->Path = path;
@@ -53,6 +53,102 @@ namespace Nuake
return newPrefab;
}
Ref<Prefab> Prefab::InstanceOntoRoot(Entity entity, const std::string & path)
{
Ref<Prefab> newPrefab = CreateRef<Prefab>();
newPrefab->Path = path;
if (FileSystem::FileExists(path, false))
{
std::string prefabTextContent = FileSystem::ReadFile(path);
if (!prefabTextContent.empty())
{
json j = json::parse(prefabTextContent);
if (j == "")
return newPrefab;
newPrefab->Root = entity;
if (j.contains("Entities"))
{
std::map<uint32_t, uint32_t> newIdsLut;
newIdsLut[j["Root"]] = entity.GetID();
for (json e : j["Entities"])
{
if (e["NameComponent"]["ID"] == j["Root"])
{
continue; // skip root
}
Entity newEntity = { entity.GetScene()->m_Registry.create(), entity.GetScene() };
newEntity.Deserialize(e); // Id gets overriden by serialized id.
auto& nameComponent = newEntity.GetComponent<NameComponent>();
uint32_t oldId = nameComponent.ID;
uint32_t newId = OS::GetTime();
nameComponent.Name = nameComponent.Name;
nameComponent.ID = newId;
newIdsLut[oldId] = newId;
newPrefab->AddEntity(newEntity);
}
// Set reference to the parent entity to children
for (auto& e : newPrefab->Entities)
{
auto& parentC = e.GetComponent<ParentComponent>();
auto parent = entity.GetScene()->GetEntityByID(newIdsLut[parentC.ParentID]);
if (parentC.ParentID == j["Root"])
{
entity.AddChild(e);
}
else
{
parent.AddChild(e);
}
}
// Since the bones point to an entity, and we are instancing a prefab, the new skeleton is gonna be pointing to the wrong
// bones, we need to remap the skeleton to the new entities. We are simply reussing the same map we are using for the
// reparenting. Pretty neat.
std::function<void(SkeletonNode&)> recursiveBoneRemapping = [&recursiveBoneRemapping, &newIdsLut](SkeletonNode& currentBone)
{
currentBone.EntityHandle = newIdsLut[currentBone.EntityHandle];
for (SkeletonNode& bone : currentBone.Children)
{
recursiveBoneRemapping(bone);
}
};
// Do the remapping of the skeleton
for (auto& e : newPrefab->Entities)
{
if (!e.HasComponent<SkinnedModelComponent>())
{
continue;
}
auto& skinnedModelComponent = e.GetComponent<SkinnedModelComponent>();
if (!skinnedModelComponent.ModelResource)
{
continue;
}
SkeletonNode& currentBone = skinnedModelComponent.ModelResource->GetSkeletonRootNode();
recursiveBoneRemapping(currentBone);
}
}
}
}
return newPrefab;
}
void Prefab::ReInstance()
{
if (FileSystem::FileExists(Path, false))
@@ -159,7 +255,7 @@ namespace Nuake
parent.AddChild(e);
}
e.GetComponent<PrefabMember>().owner = Root;
e.GetComponent<PrefabMember>().owner = Root.GetID();
}
// Since the bones point to an entity, and we are instancing a prefab, the new skeleton is gonna be pointing to the wrong

View File

@@ -23,8 +23,8 @@ namespace Nuake {
static Ref<Prefab> CreatePrefabFromEntity(Entity entity);
static Ref<Prefab> New(const std::string& path);
static Ref<Prefab> InstanceInScene(const std::string& path, Ref<Scene> targetScene);
static Ref<Prefab> InstanceInScene(const std::string& path, Scene* targetScene);
static Ref<Prefab> InstanceOntoRoot(Entity entity, const std::string& path);
Prefab()
{
Path = "";
@@ -74,7 +74,7 @@ namespace Nuake {
END_SERIALIZE();
}
bool DeserializeIntoScene(const json& j, Ref<Scene> scene)
bool DeserializeIntoScene(const json& j, Scene* scene)
{
if (j == "")
return false;
@@ -96,7 +96,7 @@ namespace Nuake {
std::map<uint32_t, uint32_t> newIdsLut;
for (json e : j["Entities"])
{
Entity entity = { scene->m_Registry.create(), scene.get() };
Entity entity = { scene->m_Registry.create(), scene };
entity.Deserialize(e); // Id gets overriden by serialized id.
auto& nameComponent = entity.GetComponent<NameComponent>();

View File

@@ -7,16 +7,52 @@ namespace Nuake {
{
public:
Ref<Prefab> PrefabInstance;
std::string Path;
void SetPrefab(Ref<Prefab> prefab)
{
PrefabInstance = prefab;
Path = prefab->Path;
}
json Serialize()
{
BEGIN_SERIALIZE();
SERIALIZE_VAL(Path);
END_SERIALIZE();
}
bool Deserialize(const json& j)
{
DESERIALIZE_VAL(Path);
return true;
}
void PostDeserialize(Scene& scene)
{
//PrefabInstance->ReInstance();
//SetPrefab(Prefab::InstanceInScene(Path, &scene));
//PrefabInstance->Root.GetComponent<NameComponent>().IsPrefab = true;
//PrefabInstance->Root.AddComponent<PrefabComponent>();
}
};
class PrefabMember
{
public:
Entity owner;
uint32_t owner = 0;
json Serialize()
{
BEGIN_SERIALIZE();
SERIALIZE_VAL(owner);
END_SERIALIZE();
}
bool Deserialize(const json& j)
{
owner = j["owner"];
return true;
}
};
}

View File

@@ -85,7 +85,10 @@ namespace Nuake
SERIALIZE_OBJECT_REF_LBL("NavMeshVolumeComponent", GetComponent<NavMeshVolumeComponent>())
if (HasComponent<UIComponent>())
SERIALIZE_OBJECT_REF_LBL("UIComponent", GetComponent<UIComponent>())
if(HasComponent<PrefabComponent>())
SERIALIZE_OBJECT_REF_LBL("PrefabComponent", GetComponent<PrefabComponent>())
if (HasComponent<PrefabMember>())
SERIALIZE_OBJECT_REF_LBL("PrefabMember", GetComponent<PrefabMember>())
END_SERIALIZE();
}
@@ -99,6 +102,54 @@ namespace Nuake
}
DESERIALIZE_COMPONENT(NameComponent);
DESERIALIZE_COMPONENT(ParentComponent);
if (j.contains("PrefabComponent"))
{
GetComponent<NameComponent>().IsPrefab = true;
auto& prefabComp = AddComponent<PrefabComponent>();
const auto& prefabPath = j["PrefabComponent"]["Path"];
if (prefabPath.empty())
{
return true;
}
if (!FileSystem::FileExists(prefabPath, false))
{
return true;
}
// This will map serialized ID to new generated ones while
// keeping the parent/child relationship in the prefab file.
std::string prefabTextContent = FileSystem::ReadFile(prefabPath);
auto prefabJson = json::parse(prefabTextContent);
auto& rootId = prefabJson["Root"];
json rootJson = "";
for (const auto& entJson : prefabJson["Entities"])
{
bool isRoot = false;
if (entJson["NameComponent"]["ID"] == rootId)
{
rootJson = entJson;
isRoot = true;
continue;
}
}
Prefab::InstanceOntoRoot(Entity{(entt::entity)GetHandle(), m_Scene}, prefabPath);
DeserializeComponents(rootJson);
}
else
{
DeserializeComponents(j);
}
return true;
}
bool Entity::DeserializeComponents(const json& j)
{
DESERIALIZE_COMPONENT(ParticleEmitterComponent);
DESERIALIZE_COMPONENT(SpriteComponent);
DESERIALIZE_COMPONENT(CameraComponent);
@@ -119,12 +170,20 @@ namespace Nuake
DESERIALIZE_COMPONENT(NetScriptComponent);
DESERIALIZE_COMPONENT(NavMeshVolumeComponent);
DESERIALIZE_COMPONENT(UIComponent);
return true;
return false;
}
void Entity::PostDeserialize()
{
POSTDESERIALIZE_COMPONENT(QuakeMapComponent);
if (HasComponent<PrefabComponent>())
{
auto& prefabComp = GetComponent<PrefabComponent>();
const std::string& path = prefabComp.Path;
}
POSTDESERIALIZE_COMPONENT(PrefabComponent);
}
Entity::Entity(entt::entity handle, Scene* scene)

View File

@@ -130,6 +130,8 @@ namespace Nuake
json Serialize() override;
bool Deserialize(const json& str);
bool DeserializeComponents(const json& str);
void PostDeserialize();
Scene* GetScene() const

View File

@@ -306,7 +306,11 @@ namespace Nuake
for (const auto& e : prefabView)
{
auto& prefabComponent = prefabView.get<PrefabComponent>(e);
if (prefabComponent.PrefabInstance == nullptr)
{
continue;
}
const std::string& filePath = prefabComponent.PrefabInstance->Path;
if (!FileSystem::FileExists(filePath))
{
@@ -646,6 +650,11 @@ namespace Nuake
std::vector<json> entities = std::vector<json>();
for (Entity e : GetAllEntities())
{
if (e.HasComponent<PrefabMember>())
{
continue;
}
auto returnValue = std::async(std::launch::async, [&]() {
entities.push_back(e.Serialize());
});

View File

@@ -11,6 +11,7 @@ namespace Nuake
public:
Scene* m_Scene;
virtual bool Init() = 0;
virtual void Draw() = 0;

View File

@@ -147,7 +147,6 @@ namespace Nuake
for (auto& c : parentComponent.Children)
{
auto& childParentComponent = c.GetComponent<TransformComponent>();
childParentComponent.GlobalDirty = true;

View File

@@ -443,7 +443,6 @@ namespace Nuake {
bool IsOnGround(int entityId)
{
Entity entity = Entity((entt::entity)(entityId), Engine::GetCurrentScene().get());
if (entity.IsValid() && entity.HasComponent<CharacterControllerComponent>())
{
auto& characterController = entity.GetComponent<CharacterControllerComponent>();
@@ -500,7 +499,7 @@ namespace Nuake {
}
void Play(int entityId, Coral::String animation)
{
{
Entity entity = Entity((entt::entity)(entityId), Engine::GetCurrentScene().get());
if (entity.IsValid() && entity.HasComponent<SkinnedModelComponent>())