Skip to content

Commit 9f4a6f2

Browse files
Mapping Asset node hierarchy and Scene node hierarchy (JeanPhilippeKernel#452)
* refactored arena splitting * support drag n drop scene opening * implemented scene asset node mapping
1 parent 0c3c6d7 commit 9f4a6f2

File tree

17 files changed

+304
-41
lines changed

17 files changed

+304
-41
lines changed

Tetragrama/Components/DockspaceUIComponent.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,22 @@ namespace Tetragrama::Components
600600
co_return;
601601
}
602602

603+
std::future<void> DockspaceUIComponent::OnOpenMeshRequestAsync(const char* filename)
604+
{
605+
Importers::AssetMeshFileHeader header;
606+
if (Importers::IAssetImporter::ReadAssetMeshFileHeader(filename, header))
607+
{
608+
auto asset_mesh = Managers::AssetManager::GetAsset<Importers::AssetMesh>(header.Id);
609+
if (asset_mesh)
610+
{
611+
auto ctx = reinterpret_cast<EditorContext*>(ParentLayer->ParentContext);
612+
auto handle_ref = ctx->AssetManagerPtr->GetMeshNodeHierarchyHandle(asset_mesh->MeshUUID);
613+
ctx->PendingOnLoadHierarchies->Enqueue(handle_ref);
614+
}
615+
}
616+
co_return;
617+
}
618+
603619
std::future<void> DockspaceUIComponent::OnImportAssetAsync(const char* filename)
604620
{
605621
if ((ZEngine::Helpers::secure_strlen(filename) == 0) || m_asset_importer->IsImporting())

Tetragrama/Components/DockspaceUIComponent.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ namespace Tetragrama::Components
4949
std::future<void> OnNewSceneAsync();
5050
std::future<void> OnOpenSceneAsync();
5151
std::future<void> OnOpenSceneRequestAsync(const char* filename);
52+
std::future<void> OnOpenMeshRequestAsync(const char* filename);
5253
std::future<void> OnImportAssetAsync(const char* filename);
5354
std::future<void> OnExitAsync();
5455

Tetragrama/Components/HierarchyViewUIComponent.cpp

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,12 @@ namespace Tetragrama::Components
3636

3737
void HierarchyViewUIComponent::Update(ZEngine::Core::TimeStep dt)
3838
{
39+
if (!ParentLayer)
40+
{
41+
return;
42+
}
3943

40-
if (ParentLayer && ParentLayer->ParentWindow)
44+
if (ParentLayer->ParentWindow)
4145
{
4246
auto window = ParentLayer->ParentWindow;
4347
if (IDevice::As<Keyboard>()->IsKeyPressed(ZENGINE_KEY_T, window))
@@ -55,6 +59,84 @@ namespace Tetragrama::Components
5559
m_gizmo_operation = ImGuizmo::OPERATION::SCALE;
5660
}
5761
}
62+
63+
if (ParentLayer->ParentContext)
64+
{
65+
auto ctx = reinterpret_cast<EditorContext*>(ParentLayer->ParentContext);
66+
auto current_scene = ctx->CurrentScenePtr;
67+
68+
Managers::AssetManager::AssetHandle handle = {};
69+
if (ctx->PendingOnLoadHierarchies->Pop(handle))
70+
{
71+
Importers::AssetNodeHierarchy* mesh_node_hierarchy = Managers::AssetManager::GetAsset<Importers::AssetNodeHierarchy>(handle);
72+
if (!mesh_node_hierarchy)
73+
{
74+
return;
75+
}
76+
77+
struct StackEntry
78+
{
79+
int Parent = -1;
80+
int Depth = -1;
81+
int node_id = -1;
82+
};
83+
84+
for (int i = 0; i < mesh_node_hierarchy->Hierarchies.size(); ++i)
85+
{
86+
if (mesh_node_hierarchy->Hierarchies[i].Parent == -1)
87+
{
88+
std::stack<StackEntry> stack;
89+
stack.push({0, 1, i});
90+
91+
while (!stack.empty())
92+
{
93+
auto entry = stack.top();
94+
stack.pop();
95+
96+
if (entry.node_id == -1)
97+
{
98+
continue;
99+
}
100+
101+
auto node_ref = Importers::AssetNodeRef{.AssetNodeHandle = handle, .NodeHierarchyIndex = entry.node_id};
102+
if (mesh_node_hierarchy->NodeNames.contains(entry.node_id))
103+
{
104+
auto name_idx = mesh_node_hierarchy->NodeNames[entry.node_id];
105+
node_ref.Name = mesh_node_hierarchy->Names[name_idx].c_str();
106+
}
107+
108+
int scene_node_id = current_scene->CreateSceneNode(entry.Parent, entry.Depth, node_ref);
109+
110+
const auto& node = mesh_node_hierarchy->Hierarchies[entry.node_id];
111+
bool has_children = (node.FirstChild != -1);
112+
113+
if (has_children)
114+
{
115+
// Push TreePop manually
116+
stack.push({-1}); // Marker for TreePop
117+
118+
// Push children in reverse order
119+
auto scratch = ZGetScratch(&ParentLayer->LocalArena);
120+
ZEngine::Core::Containers::Array<int> children;
121+
children.init(scratch.Arena, 5);
122+
123+
for (int child = node.FirstChild; child != -1; child = mesh_node_hierarchy->Hierarchies[child].RightSibling)
124+
{
125+
children.push(child);
126+
}
127+
128+
for (int i = static_cast<int>(children.size()) - 1; i >= 0; --i)
129+
{
130+
stack.push({scene_node_id, (entry.Depth + 1), children[i]});
131+
}
132+
133+
ZReleaseScratch(scratch);
134+
}
135+
}
136+
}
137+
}
138+
}
139+
}
58140
}
59141

60142
void HierarchyViewUIComponent::Render(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, ZEngine::Hardwares::CommandBuffer* const command_buffer)

Tetragrama/Components/SceneViewportUIComponent.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ namespace Tetragrama::Components
127127
{
128128
Messengers::IMessenger::SendAsync<Windows::Layers::Layer, Messengers::GenericMessage<std::string>>(EDITOR_COMPONENT_DOCKSPACE_REQUEST_OPENSCENE, Messengers::GenericMessage<std::string>(buf));
129129
}
130+
else if (file_ext == ".zemesh")
131+
{
132+
Messengers::IMessenger::SendAsync<Windows::Layers::Layer, Messengers::GenericMessage<std::string>>(EDITOR_COMPONENT_DOCKSPACE_REQUEST_OPENMESH, Messengers::GenericMessage<std::string>(buf));
133+
}
130134
}
131135
}
132136
ImGui::EndDragDropTarget();

Tetragrama/Editor.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@ namespace Tetragrama
2020
{
2121
AssetManager::Initialize(arena);
2222

23-
Context = ZPushStruct(arena, EditorContext);
24-
Context->Arena = arena;
23+
Context = ZPushStruct(arena, EditorContext);
24+
Context->Arena = arena;
2525

26-
Context->AssetManagerPtr = AssetManager::Instance();
27-
Context->ConfigurationPtr = ZPushStructCtor(Context->Arena, EditorConfiguration);
28-
Context->CameraControllerPtr = ZPushStructCtor(Context->Arena, EditorCameraController);
29-
UILayer = ZPushStructCtor(Context->Arena, ImguiLayer);
30-
CanvasLayer = ZPushStructCtor(Context->Arena, RenderLayer);
26+
Context->AssetManagerPtr = AssetManager::Instance();
27+
Context->ConfigurationPtr = ZPushStructCtor(Context->Arena, EditorConfiguration);
28+
Context->CameraControllerPtr = ZPushStructCtor(Context->Arena, EditorCameraController);
29+
Context->PendingOnLoadHierarchies = CreateRef<ZEngine::Helpers::ThreadSafeQueue<Managers::AssetManager::AssetHandle>>();
30+
UILayer = ZPushStructCtor(Context->Arena, ImguiLayer);
31+
CanvasLayer = ZPushStructCtor(Context->Arena, RenderLayer);
3132

32-
Context->CurrentScenePtr = ZPushStructCtor(Context->Arena, EditorScene);
33+
Context->CurrentScenePtr = ZPushStructCtor(Context->Arena, EditorScene);
3334

3435
if (ZEngine::Helpers::secure_strlen(file))
3536
{

Tetragrama/Editor.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ namespace Tetragrama
3535

3636
struct EditorContext
3737
{
38-
ZEngine::Core::Memory::ArenaAllocator* Arena = nullptr;
39-
std::atomic_int SelectedSceneNode = -1;
40-
ZRawPtr(EditorConfiguration) ConfigurationPtr = nullptr;
41-
ZRawPtr(EditorScene) CurrentScenePtr = nullptr;
42-
ZRawPtr(Controllers::EditorCameraController) CameraControllerPtr = nullptr;
43-
ZRawPtr(Managers::AssetManager) AssetManagerPtr = nullptr;
38+
ZEngine::Core::Memory::ArenaAllocator* Arena = nullptr;
39+
std::atomic_int SelectedSceneNode = -1;
40+
ZRawPtr(EditorConfiguration) ConfigurationPtr = nullptr;
41+
ZRawPtr(EditorScene) CurrentScenePtr = nullptr;
42+
ZRawPtr(Controllers::EditorCameraController) CameraControllerPtr = nullptr;
43+
ZRawPtr(Managers::AssetManager) AssetManagerPtr = nullptr;
44+
ZEngine::Helpers::Ref<ZEngine::Helpers::ThreadSafeQueue<Managers::AssetManager::AssetHandle>> PendingOnLoadHierarchies = nullptr;
4445
};
4546

4647
struct Editor

Tetragrama/EditorScene.cpp

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,56 @@ namespace Tetragrama
7878
return node_id;
7979
}
8080

81-
void EditorScene::CreateSceneNode(int parent, int depth)
81+
// void EditorScene::CreateSceneNode(int parent, int depth)
82+
//{
83+
// int node_id = AddHierarchyNode(parent, depth);
84+
// if (node_id < 0)
85+
// {
86+
// ZENGINE_CORE_ERROR("EditorScene::CreateSceneNode, failed to create scene node")
87+
// return;
88+
// }
89+
90+
// NodeNames[node_id] = Names.size();
91+
// auto& name = Names.push_use({});
92+
// name.init(&LocalArena, "Empty entity");
93+
94+
// NodeMeshes.insert(node_id, uuids::uuid{});
95+
96+
// HasPendingChanges.store(true, std::memory_order_release);
97+
//}
98+
99+
int EditorScene::CreateSceneNode(int parent, int depth, const Importers::AssetNodeRef& metadata)
82100
{
83101
int node_id = AddHierarchyNode(parent, depth);
84102
if (node_id < 0)
85103
{
86104
ZENGINE_CORE_ERROR("EditorScene::CreateSceneNode, failed to create scene node")
87-
return;
105+
return node_id;
88106
}
89107

90108
NodeNames[node_id] = Names.size();
91109
auto& name = Names.push_use({});
92-
name.init(&LocalArena, "Empty entity");
93110

94111
NodeMeshes.insert(node_id, uuids::uuid{});
112+
if (metadata.IsValid())
113+
{
114+
Hierarchies[node_id].NodeRef = metadata;
115+
if (ZEngine::Helpers::secure_strlen(metadata.Name) > 0)
116+
{
117+
name.init(&LocalArena, metadata.Name);
118+
}
119+
else
120+
{
121+
name.init(&LocalArena, "Empty entity");
122+
}
123+
}
124+
else
125+
{
126+
name.init(&LocalArena, "Empty entity");
127+
}
95128

96129
HasPendingChanges.store(true, std::memory_order_release);
130+
return node_id;
97131
}
98132

99133
void EditorScene::RemoveSceneNode(int node_id)

Tetragrama/EditorScene.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ namespace Tetragrama
6060

6161
int AddHierarchyNode(int parent, int depth);
6262

63-
void CreateSceneNode(int parent = 0, int depth = 1);
63+
// void CreateSceneNode(int parent = 0, int depth = 1) = delete;
64+
int CreateSceneNode(int parent = 0, int depth = 1, const Importers::AssetNodeRef& = {});
6465
void RemoveSceneNode(int node_id);
6566
void ReparentNode(int node_id, int new_parent);
6667
bool IsSceneNodeDeleted(int node_id);

Tetragrama/Importers/AssetTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ namespace Tetragrama::Importers
7777

7878
struct AssetNodeRef
7979
{
80+
cstring Name = nullptr;
8081
uint32_t AssetNodeHandle = 0xFFFFFFFF;
8182
int NodeHierarchyIndex = -1;
8283

Tetragrama/Importers/IAssetImporter.cpp

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,12 @@ namespace Tetragrama::Importers
250250

251251
in.seekg(std::ios::beg);
252252

253-
uint32_t scene_magic;
254-
uint32_t scene_version;
255-
ReadBinary(in, scene_magic);
256-
ReadBinary(in, scene_version);
253+
uint32_t meshf_magic;
254+
uint32_t meshf_version;
255+
ReadBinary(in, meshf_magic);
256+
ReadBinary(in, meshf_version);
257257

258-
if (scene_magic != ZEMESH_MAGIC && scene_version != ASSET_FILE_VERSION)
258+
if (meshf_magic != ZEMESH_MAGIC && meshf_version != ASSET_FILE_VERSION)
259259
{
260260
in.close();
261261
return;
@@ -393,4 +393,41 @@ namespace Tetragrama::Importers
393393

394394
in.close();
395395
}
396+
397+
bool IAssetImporter::ReadAssetMeshFileHeader(cstring asset_file, AssetMeshFileHeader& header)
398+
{
399+
bool output = false;
400+
if (!ZEngine::Helpers::secure_strlen(asset_file))
401+
{
402+
return output;
403+
}
404+
405+
std::ifstream in(asset_file, std::ios::binary);
406+
407+
if (!in.is_open())
408+
{
409+
in.close();
410+
return output;
411+
}
412+
413+
in.seekg(std::ios::beg);
414+
415+
ReadBinary(in, header.MagicNumber);
416+
ReadBinary(in, header.Version);
417+
418+
if (header.MagicNumber != ZEMESH_MAGIC && header.Version != ASSET_FILE_VERSION)
419+
{
420+
in.close();
421+
return output;
422+
}
423+
424+
/*
425+
* Asset Mesh Header
426+
*/
427+
ReadBinary(in, header.Id);
428+
output = true;
429+
430+
in.close();
431+
return output;
432+
}
396433
} // namespace Tetragrama::Importers

0 commit comments

Comments
 (0)