Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Win32, path tracer fixes #108

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
7a1b5f2
UI Fixes
ajmd17 Oct 21, 2024
69d5ae4
Fixes for C# components
ajmd17 Oct 27, 2024
aa490b6
Fixes for entity management from c#
ajmd17 Oct 28, 2024
96720d4
Refactor HyperionEditor to EditorSubsystem
ajmd17 Oct 28, 2024
aa48118
Fix scroll
ajmd17 Oct 31, 2024
1cef86c
Allow HypMethod to be used with C# structs
ajmd17 Nov 3, 2024
1e2fcf3
Renderproxy version
ajmd17 Nov 4, 2024
79ca0e5
Change usage of ID<Entity> to Handle<Entity> to ensure entities objec…
ajmd17 Nov 7, 2024
0cca7cf
Allow bitwise serialization of HypStructs
ajmd17 Nov 9, 2024
5a076a8
Fix debug drawer shader, add `GetDescriptorSet` overload that uses se…
ajmd17 Nov 10, 2024
0eeac44
Remove framebuffer from renderable attributes
ajmd17 Nov 12, 2024
cd3f5ce
Sky fixes
ajmd17 Nov 13, 2024
f358794
Update
ajmd17 Nov 14, 2024
462aff6
Text instancing WIP
ajmd17 Nov 14, 2024
559cd2e
Add shader reflection to provide additional metadata for CompiledShaders
ajmd17 Nov 15, 2024
0841265
Serialization fixes
ajmd17 Nov 16, 2024
693db8a
Instancing works for rendering text
ajmd17 Nov 17, 2024
3b5b47b
Remove excess text rendering code
ajmd17 Nov 18, 2024
0d48e9e
Change uses of Extent3D, Extent2D to Vec3u and Vec2u
ajmd17 Nov 19, 2024
902e9f2
Fix for Forest container `Remove` method, add `HypEnum`
ajmd17 Nov 20, 2024
fc6541b
Update
ajmd17 Nov 20, 2024
4cf0ffb
Adding Undo/Redo
ajmd17 Nov 22, 2024
76b44a4
Win32 fixes p1
Nov 23, 2024
eaf7829
WIP - New EntityInstanceBatch allocation method (dynamic)
Nov 24, 2024
a3a65d6
Windows fixes
Nov 24, 2024
21a803c
RT fixes (WIP)
Nov 24, 2024
f8372f1
Debugging lightmapper crashes
Nov 25, 2024
9e35e0e
Using material buffer AcquireIndex() rather than material ID
ajmd17 Nov 26, 2024
780fa41
Area light fixes
ajmd17 Nov 27, 2024
0461954
Light RenderResources
ajmd17 Nov 27, 2024
bfcd5c3
Renderresources doc
ajmd17 Nov 27, 2024
04f47dc
Mesh RenderResources
ajmd17 Nov 27, 2024
74afffc
Refactoring
ajmd17 Nov 28, 2024
073a934
UI update
ajmd17 Dec 3, 2024
1abe5e9
Undo fixes
ajmd17 Dec 4, 2024
f99bb84
TEMP
ajmd17 Dec 4, 2024
a2f3bda
Abstract RenderResources into IResource
ajmd17 Dec 4, 2024
5b77ee9
TEMP
ajmd17 Dec 4, 2024
311c99c
update
ajmd17 Dec 6, 2024
d33cc4f
Custom task thread pools
ajmd17 Dec 6, 2024
2eb48f4
Lightmapper thread pool
ajmd17 Dec 7, 2024
ef480cf
Refactoring
ajmd17 Dec 8, 2024
125e81a
Debugging UI objects having wrong textures (only shows with bindless …
Dec 20, 2024
a5e2a75
Fix crash, work on path tracer (still not accurate)
Jan 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 2 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[submodule "submodules/glslang"]
path = submodules/glslang
url = https://github.com/KhronosGroup/glslang
url = https://github.com/notomorrow/glslang
branch = hyp-modifications
[submodule "submodules/libdatachannel"]
path = submodules/libdatachannel
url = https://github.com/paullouisageneau/libdatachannel
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ if (${NATIVE})
# if glslang folder exists, link with it.
if(EXISTS "${CMAKE_SOURCE_DIR}/submodules/glslang/glslang/CMakeLists.txt")
add_definitions(-DHYP_GLSLANG=1)
add_definitions(-DHYP_GLSLANG_MODIFICATIONS=1)

include_directories(BEFORE submodules/glslang)
add_subdirectory(submodules/glslang)
Expand Down
42 changes: 22 additions & 20 deletions containers.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

<ArrayItems Condition="use_inline_storage == false || m_storage.m_is_dynamic == true">
<Size>(m_size - m_start_offset)</Size>
<ValuePointer>($T1 *)(m_storage.m_buffer + m_start_offset)</ValuePointer>
<ValuePointer>(($T1 *)m_storage.m_buffer + m_start_offset)</ValuePointer>
</ArrayItems>
<ArrayItems Condition="use_inline_storage == true &amp;&amp; m_storage.m_is_dynamic == false">
<Size>(m_size - m_start_offset)</Size>
Expand All @@ -31,27 +31,27 @@
</Type>

<Type Name="hyperion::containers::detail::String&lt;*&gt;">
<DisplayString Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; $T1 == 2">{{ {(m_storage.m_buffer + m_start_offset), s8} }}</DisplayString>
<DisplayString Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; $T1 == 2">{{ {((CharType *)m_storage.m_buffer + m_start_offset), s8} }}</DisplayString>
<DisplayString Condition="use_inline_storage == true &amp;&amp; m_storage.m_is_dynamic == false &amp;&amp; $T1 == 2">{{ {(((CharType *)&amp;m_storage.m_inline_storage.data[0]) + m_start_offset), s8} }}</DisplayString>
<DisplayString Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; $T1 == 1 &amp;&amp; is_ansi">{{ {(m_storage.m_buffer + m_start_offset), s} }}</DisplayString>
<DisplayString Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; $T1 == 1 &amp;&amp; is_ansi">{{ {((CharType *)m_storage.m_buffer + m_start_offset), s} }}</DisplayString>
<DisplayString Condition="use_inline_storage == true &amp;&amp; m_storage.m_is_dynamic == false &amp;&amp; $T1 == 1 &amp;&amp; is_ansi">{{ {(((CharType *)&amp;m_storage.m_inline_storage.data[0]) + m_start_offset), s} }}</DisplayString>
<DisplayString Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; $T1 == 3 &amp;&amp; is_utf16">{{ {(m_storage.m_buffer + m_start_offset), su} }}</DisplayString>
<DisplayString Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; $T1 == 3 &amp;&amp; is_utf16">{{ {((CharType *)m_storage.m_buffer + m_start_offset), su} }}</DisplayString>
<DisplayString Condition="use_inline_storage == true &amp;&amp; m_storage.m_is_dynamic == false &amp;&amp; $T1 == 3 &amp;&amp; is_utf16">{{ {(((CharType *)&amp;m_storage.m_inline_storage.data[0]) + m_start_offset), su} }}</DisplayString>
<DisplayString Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; $T1 == 4 &amp;&amp; is_utf32">{{ {(m_storage.m_buffer + m_start_offset), s32} }}</DisplayString>
<DisplayString Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; $T1 == 4 &amp;&amp; is_utf32">{{ {((CharType *)m_storage.m_buffer + m_start_offset), s32} }}</DisplayString>
<DisplayString Condition="use_inline_storage == true &amp;&amp; m_storage.m_is_dynamic == false &amp;&amp; $T1 == 4 &amp;&amp; is_utf32">{{ {(((CharType *)&amp;m_storage.m_inline_storage.data[0]) + m_start_offset), s32} }}</DisplayString>
<DisplayString Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; $T1 == 5 &amp;&amp; is_wide">{{ {(m_storage.m_buffer + m_start_offset), su} }}</DisplayString>
<DisplayString Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; $T1 == 5 &amp;&amp; is_wide">{{ {((CharType *)m_storage.m_buffer + m_start_offset), su} }}</DisplayString>
<DisplayString Condition="use_inline_storage == true &amp;&amp; m_storage.m_is_dynamic == false &amp;&amp; $T1 == 5 &amp;&amp; is_wide">{{ {(((CharType *)&amp;m_storage.m_inline_storage.data[0]) + m_start_offset), su} }}</DisplayString>

<Expand>
<Item Name="[Text]" Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; is_utf8">(m_storage.m_buffer + m_start_offset), s8</Item>
<Item Name="[Text]" Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; is_utf8">((CharType *)m_storage.m_buffer + m_start_offset), s8</Item>
<Item Name="[Text]" Condition="use_inline_storage == true &amp;&amp; m_storage.m_is_dynamic == false &amp;&amp; is_utf8">(((CharType *)&amp;m_storage.m_inline_storage.data[0]) + m_start_offset), s8</Item>
<Item Name="[Text]" Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; is_ansi">(m_storage.m_buffer + m_start_offset), s</Item>
<Item Name="[Text]" Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; is_ansi">((CharType *)m_storage.m_buffer + m_start_offset), s</Item>
<Item Name="[Text]" Condition="use_inline_storage == true &amp;&amp; m_storage.m_is_dynamic == false &amp;&amp; is_ansi">(((CharType *)&amp;m_storage.m_inline_storage.data[0]) + m_start_offset), s</Item>
<Item Name="[Text]" Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; is_utf16">(m_storage.m_buffer + m_start_offset), su</Item>
<Item Name="[Text]" Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; is_utf16">((CharType *)m_storage.m_buffer + m_start_offset), su</Item>
<Item Name="[Text]" Condition="use_inline_storage == true &amp;&amp; m_storage.m_is_dynamic == false &amp;&amp; is_utf16">(((CharType *)&amp;m_storage.m_inline_storage.data[0]) + m_start_offset), su</Item>
<Item Name="[Text]" Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; is_utf32">(m_storage.m_buffer + m_start_offset), s32</Item>
<Item Name="[Text]" Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; is_utf32">((CharType *)m_storage.m_buffer + m_start_offset), s32</Item>
<Item Name="[Text]" Condition="use_inline_storage == true &amp;&amp; m_storage.m_is_dynamic == false &amp;&amp; is_utf32">(((CharType *)&amp;m_storage.m_inline_storage.data[0]) + m_start_offset), s32</Item>
<Item Name="[Text]" Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; is_wide">(m_storage.m_buffer + m_start_offset), su</Item>
<Item Name="[Text]" Condition="use_inline_storage == false || m_storage.m_is_dynamic == true &amp;&amp; is_wide">((CharType *)m_storage.m_buffer + m_start_offset), su</Item>
<Item Name="[Text]" Condition="use_inline_storage == true &amp;&amp; m_storage.m_is_dynamic == false &amp;&amp; is_wide">(((CharType *)&amp;m_storage.m_inline_storage.data[0]) + m_start_offset), su</Item>

<Item Name="[Type]">string_type</Item>
Expand All @@ -78,7 +78,7 @@
<Exec Condition="m_buckets.use_inline_storage == false">bucket_ptr = ((hyperion::containers::detail::HashBucket&lt;$T1,$T2&gt; *) m_buckets.m_storage.m_buffer)</Exec>

<Exec Condition="m_buckets.use_inline_storage == true &amp;&amp; m_buckets.m_storage.m_is_dynamic == false">bucket_ptr = ((hyperion::containers::detail::HashBucket&lt;$T1,$T2&gt; *)&amp;m_buckets.m_storage.m_inline_storage.data[0] + m_buckets.m_start_offset)</Exec>
<Exec Condition="m_buckets.use_inline_storage == false || m_buckets.m_storage.m_is_dynamic == true">bucket_ptr = (hyperion::containers::detail::HashBucket&lt;$T1,$T2&gt; *)(m_buckets.m_storage.m_buffer + m_buckets.m_start_offset)</Exec>
<Exec Condition="m_buckets.use_inline_storage == false || m_buckets.m_storage.m_is_dynamic == true">bucket_ptr = ((hyperion::containers::detail::HashBucket&lt;$T1,$T2&gt; *)m_buckets.m_storage.m_buffer + m_buckets.m_start_offset)</Exec>

<Loop>
<Break Condition="bucket_index == (m_buckets.m_size - m_buckets.m_start_offset)" />
Expand Down Expand Up @@ -128,7 +128,7 @@
</Type>

<Type Name="hyperion::utilities::detail::VariantBase&lt;*,*&gt;">
<DisplayString>{{ TypeID={m_current_type_id} }}</DisplayString>
<DisplayString>{{ Index={m_current_index} }}</DisplayString>
<Expand>
<Item Name="[Data]">m_storage.data_buffer</Item>
</Expand>
Expand Down Expand Up @@ -167,7 +167,9 @@

<Expand>
<!--<Item Name="[Data]">(0)</Item>-->
<ExpandedItem Condition="index != 0">($T1 *)(&amp;(s_container-&gt;m_data.m_values[index - 1]))</ExpandedItem>

<!-- FIXME objectcontainer now uses linkedlist internally -->
<ExpandedItem Condition="index != 0">($T1 *)(&amp;(((hyperion::ObjectContainer&lt;$T1&gt; *)s_container)-&gt;m_data.m_values[index - 1]))</ExpandedItem>
<ExpandedItem Condition="index == 0">($T1 *)0</ExpandedItem>
</Expand>
</Type>
Expand All @@ -189,7 +191,7 @@
<Exec Condition="g_name_registry-&gt;m_name_map.m_buckets.use_inline_storage == false">bucket_ptr = ((hyperion::containers::detail::HashBucket&lt;unsigned __int64,hyperion::containers::detail::String&lt;1&gt; &gt; *) &amp;(g_name_registry-&gt;m_name_map.m_buckets.m_storage.m_buffer))</Exec>

<Exec Condition="g_name_registry-&gt;m_name_map.m_buckets.use_inline_storage == true &amp;&amp; g_name_registry-&gt;m_name_map.m_buckets.m_storage.m_is_dynamic == false">bucket_ptr = ((hyperion::containers::detail::HashBucket&lt;unsigned __int64,hyperion::containers::detail::String&lt;1&gt; &gt; *)&amp;g_name_registry-&gt;m_name_map.m_buckets.m_storage.m_inline_storage.data[0] + g_name_registry-&gt;m_name_map.m_buckets.m_start_offset)</Exec>
<Exec Condition="g_name_registry-&gt;m_name_map.m_buckets.use_inline_storage == false || g_name_registry-&gt;m_name_map.m_buckets.m_storage.m_is_dynamic == true">bucket_ptr = (hyperion::containers::detail::HashBucket&lt;unsigned __int64,hyperion::containers::detail::String&lt;1&gt; &gt; *)(g_name_registry-&gt;m_name_map.m_buckets.m_storage.m_buffer + g_name_registry-&gt;m_name_map.m_buckets.m_start_offset)</Exec>
<Exec Condition="g_name_registry-&gt;m_name_map.m_buckets.use_inline_storage == false || g_name_registry-&gt;m_name_map.m_buckets.m_storage.m_is_dynamic == true">bucket_ptr = ((hyperion::containers::detail::HashBucket&lt;unsigned __int64,hyperion::containers::detail::String&lt;1&gt; &gt; *)g_name_registry-&gt;m_name_map.m_buckets.m_storage.m_buffer + g_name_registry-&gt;m_name_map.m_buckets.m_start_offset)</Exec>

<Loop>
<Break Condition="found == true || bucket_index == (g_name_registry-&gt;m_name_map.m_buckets.m_size - g_name_registry-&gt;m_name_map.m_buckets.m_start_offset)" />
Expand All @@ -204,7 +206,7 @@
<Item Name="StringValue">(char*)&amp;(current_head-&gt;pair.second.m_storage.m_inline_storage.data + current_head-&gt;pair.second.m_start_offset)[0],sb</Item>
</If>
<If Condition="current_head-&gt;pair.second.use_inline_storage == false || current_head-&gt;pair.second.m_storage.m_is_dynamic == true">
<Item Name="StringValue">(char*)&amp;(current_head-&gt;pair.second.m_storage.m_buffer + current_head-&gt;pair.second.m_start_offset)[0],sb</Item>
<Item Name="StringValue">&amp;((char*)current_head-&gt;pair.second.m_storage.m_buffer + current_head-&gt;pair.second.m_start_offset)[0],sb</Item>
</If>
<Exec>found = true</Exec>
</If>
Expand All @@ -224,14 +226,14 @@
</Type>

<Type Name="hyperion::renderer::RenderObjectHandle_Strong&lt;*,*&gt;">
<DisplayString>{{ ID={index} Strong={_container->m_data.m_values[index - 1].ref_count_strong.m_value} Weak={_container->m_data.m_values[index - 1].ref_count_weak.m_value} }}</DisplayString>
<DisplayString>{{ ID={index} Strong={s_container->m_data.m_values[index - 1].ref_count_strong.m_value} Weak={s_container->m_data.m_values[index - 1].ref_count_weak.m_value} }}</DisplayString>

<Expand>
<Item Name="[Strong]">(_container->m_data.m_values[index - 1].ref_count_strong.m_value)</Item>
<Item Name="[Weak]">_container->m_data.m_values[index - 1].ref_count_weak.m_value</Item>
<Item Name="[Strong]">(s_container->m_data.m_values[index - 1].ref_count_strong.m_value)</Item>
<Item Name="[Weak]">s_container->m_data.m_values[index - 1].ref_count_weak.m_value</Item>
<!--<Item Name="[Name]">_container->m_debug_names.m_values[index]</Item>-->

<ExpandedItem>($T1 *)(&amp;(_container->m_data.m_values[index - 1].storage))</ExpandedItem>
<ExpandedItem>($T1 *)(&amp;(s_container->m_data.m_values[index - 1].storage))</ExpandedItem>
</Expand>
</Type>

Expand Down
2 changes: 1 addition & 1 deletion res/Shaders.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ frag = DeferredIndirect.frag
vert = Deferred.vert

[DeferredDirect]
permute = LIGHT_TYPE(DIRECTIONAL POINT SPOT AREA_RECT), SSR_ENABLED, REFLECTION_PROBE_ENABLED, ENV_GRID_ENABLED, RT_REFLECTIONS_ENABLED, RT_GI_ENABLED, HBIL_ENABLED, HBAO_EABLED, LIGHT_RAYS_ENABLED
permute = LIGHT_TYPE(DIRECTIONAL POINT SPOT AREA_RECT)
frag = DeferredDirect.frag
vert = Deferred.vert

Expand Down
11 changes: 8 additions & 3 deletions res/data/config/app.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
{
"rendering": {
"ssr": {
"enabled": false,
"quality": "low",
"roughness_scattering": true,
"enabled": false,
"cone_tracing": true
},
"rt": {
"reflections": {
"enabled": false
},
"path_tracer": {
"enabled": false
"enabled": true
},
"gi": {
"enabled": false
},
"enabled": false
"enabled": true
},
"taa": {
"enabled": true
Expand Down Expand Up @@ -45,5 +45,10 @@
"app": {
"name": "HyperionEditor",
"args": "-ResX=1920 -ResY=1080"
},
"lightmapper": {
"ideal_triangles_per_job": 4096,
"gpu": true,
"threads": 16
}
}
2 changes: 1 addition & 1 deletion res/data/dotnet/runtimeconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"runtimeOptions": {
"additionalProbingPaths": ["../res/data/dotnet/lib", "."],
"additionalProbingPaths": ["..\\..\\..\\res\\data\\dotnet\\lib", "."],
"tfm": "net8.0",
"framework": {
"name": "Microsoft.NETCore.App",
Expand Down
163 changes: 163 additions & 0 deletions res/scripts/src/Hyperion/Editor/UI/EditorMain.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@

using System;
using System.IO;
using Hyperion;

namespace FooBar
{
// temp
class TestDataSource : UIDataSource
{

}

public class TestEditorTask : LongRunningEditorTask
{
public TestEditorTask()
{
}

public override void Cancel()
{
Logger.Log(LogType.Info, "Cancel task");
}

public override bool IsCompleted()
{
return false;
}

public override void Process()
{
Logger.Log(LogType.Info, "Process task! testing");
}
}

public class EditorMain : UIEventHandler
{
public override void Init(Entity entity)
{
base.Init(entity);
}

public UIEventHandlerResult SimulateClicked()
{
// Test: Force GC
GC.Collect();

World world = Scene.GetWorld();

if (world.GetGameState().Mode == GameStateMode.Simulating)
{
Logger.Log(LogType.Info, "Stop simulation");

world.StopSimulating();
return UIEventHandlerResult.Ok;
}

Logger.Log(LogType.Info, "Start simulation");

world.StartSimulating();

var editorSubsystem = World.GetSubsystem<EditorSubsystem>();

if (editorSubsystem == null)
{
Logger.Log(LogType.Error, "EditorSubsystem not found");

return UIEventHandlerResult.Error;
}

editorSubsystem.AddTask(new TestEditorTask());

return UIEventHandlerResult.Ok;
}

public UIEventHandlerResult UndoClicked()
{
Logger.Log(LogType.Info, "Undo clicked");

var editorSubsystem = World.GetSubsystem<EditorSubsystem>();

if (editorSubsystem == null)
{
Logger.Log(LogType.Error, "EditorSubsystem not found");

return UIEventHandlerResult.Error;
}

if (!editorSubsystem.GetActionStack().CanUndo())
{
Logger.Log(LogType.Info, "Cannot undo, stack is empty");

return UIEventHandlerResult.Ok;
}

editorSubsystem.GetActionStack().Undo();

return UIEventHandlerResult.Ok;
}

public UIEventHandlerResult RedoClicked()
{
Logger.Log(LogType.Info, "Redo clicked");

var editorSubsystem = World.GetSubsystem<EditorSubsystem>();

if (editorSubsystem == null)
{
Logger.Log(LogType.Error, "EditorSubsystem not found");

return UIEventHandlerResult.Error;
}

if (!editorSubsystem.GetActionStack().CanRedo())
{
Logger.Log(LogType.Info, "Cannot redo, stack is empty");

return UIEventHandlerResult.Ok;
}

editorSubsystem.GetActionStack().Redo();

return UIEventHandlerResult.Ok;
}

public UIEventHandlerResult AddNodeClicked()
{
var editorSubsystem = World.GetSubsystem<EditorSubsystem>();

if (editorSubsystem == null)
{
Logger.Log(LogType.Error, "EditorSubsystem not found");

return UIEventHandlerResult.Ok;
}

var node = new Node();
node.SetName("New Node");

editorSubsystem.GetActionStack().Push(new EditorAction(
new Name("AddNewNode"),
() =>
{
editorSubsystem.GetScene().GetRoot().AddChild(node);
editorSubsystem.SetFocusedNode(node);
},
() =>
{
node.Remove();

if (editorSubsystem.GetFocusedNode() == node)
{
editorSubsystem.SetFocusedNode(null);
}
}
));

// @TODO Focus on node in scene view

return UIEventHandlerResult.Ok;
}
}
}
Loading