Skip to content

Commit 10f80d5

Browse files
committed
Add basic Nameplate widget
1 parent 17a2c61 commit 10f80d5

File tree

16 files changed

+380
-48
lines changed

16 files changed

+380
-48
lines changed

Source/Game-Lib/Game-Lib/ECS/Components/UI/Widget.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace ECS::Components::UI
3737
public:
3838
WidgetType type;
3939
WidgetFlags flags = WidgetFlags::Default;
40-
i32 worldTransformIndex = -1;
40+
u32 worldTransformIndex = std::numeric_limits<u32>().max();
4141

4242
Scripting::UI::Widget* scriptWidget = nullptr;
4343

Source/Game-Lib/Game-Lib/Rendering/Canvas/CanvasRenderer.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,6 @@ void CanvasRenderer::Update(f32 deltaTime)
138138
{
139139
auto& panel = uiRegistry->get<Panel>(entity);
140140
auto& panelTemplate = uiRegistry->get<PanelTemplate>(entity);
141-
if (widget.worldTransformIndex != -1)
142-
{
143-
volatile int asd = 123;
144-
}
145141

146142
// In pixel units
147143
vec2 panelPos = transform.GetWorldPosition();
@@ -150,7 +146,7 @@ void CanvasRenderer::Update(f32 deltaTime)
150146
// Convert to clip space units
151147
panelSize = PixelSizeToNDC(panelSize, size);
152148

153-
if (widget.worldTransformIndex != -1)
149+
if (widget.worldTransformIndex != std::numeric_limits<u32>().max())
154150
{
155151
panelPos = (panelPos / refSize) * 2.0f;
156152
}
@@ -239,6 +235,22 @@ void CanvasRenderer::Update(f32 deltaTime)
239235
uiRegistry->clear<DirtyClipper>();
240236
}
241237

238+
u32 CanvasRenderer::ReserveWorldTransform()
239+
{
240+
return _widgetWorldPositions.Add();
241+
}
242+
243+
void CanvasRenderer::ReleaseWorldTransform(u32 index)
244+
{
245+
_widgetWorldPositions.Remove(index);
246+
}
247+
248+
void CanvasRenderer::UpdateWorldTransform(u32 index, const vec3& position)
249+
{
250+
_widgetWorldPositions[index] = vec4(position, 1.0);
251+
_widgetWorldPositions.SetDirtyElement(index);
252+
}
253+
242254
void CanvasRenderer::AddCanvasPass(Renderer::RenderGraph* renderGraph, RenderResources& resources, u8 frameIndex)
243255
{
244256
struct Data
@@ -471,7 +483,7 @@ void CanvasRenderer::CreatePermanentResources()
471483
_widgetWorldPositions.SetUsage(Renderer::BufferUsage::STORAGE_BUFFER);
472484

473485
// Push a debug position
474-
_widgetWorldPositions.Add(vec3(0, 0, 0));
486+
_widgetWorldPositions.Add(vec4(0, 0, 0, 1));
475487

476488
// Create pipelines
477489
Renderer::ImageFormat renderTargetFormat = _renderer->GetSwapChainImageFormat();
@@ -698,7 +710,7 @@ void CanvasRenderer::UpdateTextVertices(ECS::Components::UI::Widget& widget, ECS
698710

699711
vec2 planeMin;
700712
vec2 planeMax;
701-
if (widget.worldTransformIndex != -1)
713+
if (widget.worldTransformIndex != std::numeric_limits<u32>().max())
702714
{
703715
planeMin = (vec2(planeLeft, planeBottom) / refSize) * 2.0f;
704716
planeMax = (vec2(planeRight, planeTop) / refSize) * 2.0f;
@@ -791,8 +803,8 @@ void CanvasRenderer::UpdatePanelData(entt::entity entity, ECS::Components::Trans
791803
BoundingRect* boundingRect = &registry->get<BoundingRect>(entity);
792804

793805
vec2 referenceSize = vec2(Renderer::Settings::UI_REFERENCE_WIDTH, Renderer::Settings::UI_REFERENCE_HEIGHT);
794-
vec2 clipRegionMin = vec2(0.0f, 0.0f);
795-
vec2 clipRegionMax = vec2(1.0f, 1.0f);
806+
vec2 clipRegionMin = clipper->clipRegionMin;
807+
vec2 clipRegionMax = clipper->clipRegionMax;
796808

797809
if (clipper->clipRegionOverrideEntity != entt::null)
798810
{

Source/Game-Lib/Game-Lib/Rendering/Canvas/CanvasRenderer.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ class CanvasRenderer
4747

4848
//CanvasTextureID AddTexture(Renderer::TextureID textureID);
4949

50+
u32 ReserveWorldTransform();
51+
void ReleaseWorldTransform(u32 index);
52+
void UpdateWorldTransform(u32 index, const vec3& position);
53+
5054
void AddCanvasPass(Renderer::RenderGraph* renderGraph, RenderResources& resources, u8 frameIndex);
5155

5256
private:
@@ -105,7 +109,7 @@ class CanvasRenderer
105109

106110
Renderer::GPUVector<CharDrawData> _charDrawDatas;
107111

108-
Renderer::GPUVector<vec3> _widgetWorldPositions;
112+
Renderer::GPUVector<vec4> _widgetWorldPositions;
109113

110114
Renderer::Font* _font;
111115
Renderer::SamplerID _sampler;
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include "UnitHandler.h"
2+
#include "Game-Lib/ECS/Components/AttachmentData.h"
3+
#include "Game-Lib/ECS/Components/Model.h"
4+
#include "Game-Lib/ECS/Singletons/CharacterSingleton.h"
5+
#include "Game-Lib/ECS/Util/Transforms.h"
6+
#include "Game-Lib/Scripting/LuaState.h"
7+
#include "Game-Lib/Scripting/LuaManager.h"
8+
#include "Game-Lib/Scripting/Systems/LuaSystemBase.h"
9+
#include "Game-Lib/Util/AttachmentUtil.h"
10+
#include "Game-Lib/Util/ServiceLocator.h"
11+
12+
#include <lualib.h>
13+
#include <entt/entt.hpp>
14+
15+
namespace Scripting
16+
{
17+
static LuaMethod unitMethods[] =
18+
{
19+
{ "GetLocal", UnitHandler::GetLocal },
20+
{ "GetNamePosition", UnitHandler::GetNamePosition }
21+
};
22+
23+
void UnitHandler::Register(lua_State* state)
24+
{
25+
LuaMethodTable::Set(state, unitMethods, "Unit");
26+
}
27+
28+
void UnitHandler::Clear()
29+
{
30+
31+
}
32+
33+
i32 UnitHandler::GetLocal(lua_State* state)
34+
{
35+
LuaState ctx(state);
36+
37+
entt::registry* registry = ServiceLocator::GetEnttRegistries()->gameRegistry;
38+
auto& characterSingleton = registry->ctx().get<ECS::Singletons::CharacterSingleton>();
39+
40+
if (!registry->valid(characterSingleton.moverEntity))
41+
{
42+
ctx.Push();
43+
}
44+
else
45+
{
46+
ctx.Push(entt::to_integral(characterSingleton.moverEntity));
47+
}
48+
49+
return 1;
50+
}
51+
52+
i32 UnitHandler::GetNamePosition(lua_State* state)
53+
{
54+
LuaState ctx(state);
55+
56+
u32 unitID = ctx.Get(std::numeric_limits<u32>().max(), 1);
57+
if (unitID == std::numeric_limits<u32>().max())
58+
{
59+
luaL_error(state, "Expected unitID as parameter 1");
60+
}
61+
entt::entity entityID = entt::entity(unitID);
62+
63+
entt::registry* registry = ServiceLocator::GetEnttRegistries()->gameRegistry;
64+
if (!registry->valid(entityID))
65+
{
66+
luaL_error(state, "Invalid unitID");
67+
}
68+
69+
if (!registry->all_of<ECS::Components::Model, ECS::Components::AttachmentData>(entityID))
70+
{
71+
luaL_error(state, "Unit does not have a model or attachment data");
72+
}
73+
74+
ECS::Components::Model& model = registry->get<ECS::Components::Model>(entityID);
75+
ECS::Components::AttachmentData& attachmentData = registry->get<ECS::Components::AttachmentData>(entityID);
76+
77+
if (!Util::Attachment::EnableAttachment(entityID, model, attachmentData, Attachment::Defines::Type::PlayerName))
78+
{
79+
luaL_error(state, "Failed to enable attachment");
80+
}
81+
82+
const mat4x4* mat = Util::Attachment::GetAttachmentMatrix(attachmentData, Attachment::Defines::Type::PlayerName);
83+
vec3 position = (*mat)[3];
84+
85+
const auto& transform = registry->get<ECS::Components::Transform>(entityID);
86+
position += transform.GetWorldPosition();
87+
88+
ctx.Push(position);
89+
return 1;
90+
}
91+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
#include "LuaEventHandlerBase.h"
3+
#include "Game-Lib/Scripting/LuaDefines.h"
4+
#include "Game-Lib/Scripting/LuaMethodTable.h"
5+
6+
#include <Base/Types.h>
7+
8+
namespace Scripting
9+
{
10+
class UnitHandler : public LuaHandlerBase
11+
{
12+
public:
13+
void Register(lua_State* state) override;
14+
void Clear() override;
15+
16+
public:
17+
18+
19+
public: // Registered Functions
20+
static i32 GetLocal(lua_State* state);
21+
static i32 GetNamePosition(lua_State* state);
22+
};
23+
}

Source/Game-Lib/Game-Lib/Scripting/LuaDefines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ namespace Scripting
1717
GameEvent,
1818
PlayerEvent,
1919
UI,
20+
Unit,
2021
Database,
2122
Game,
2223
Count

Source/Game-Lib/Game-Lib/Scripting/LuaManager.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "Handlers/GlobalHandler.h"
88
#include "Handlers/PlayerEventHandler.h"
99
#include "Handlers/UIHandler.h"
10+
#include "Handlers/UnitHandler.h"
1011
#include "Systems/GenericSystem.h"
1112
#include "Systems/LuaSystemBase.h"
1213
#include "Game-Lib/Util/ServiceLocator.h"
@@ -47,6 +48,7 @@ namespace Scripting
4748
SetLuaHandler(LuaHandlerType::GameEvent, new GameEventHandler());
4849
SetLuaHandler(LuaHandlerType::PlayerEvent, new PlayerEventHandler());
4950
SetLuaHandler(LuaHandlerType::UI, new UI::UIHandler());
51+
SetLuaHandler(LuaHandlerType::Unit, new UnitHandler());
5052
SetLuaHandler(LuaHandlerType::Database, new Database::DatabaseHandler());
5153
SetLuaHandler(LuaHandlerType::Game, new Game::GameHandler());
5254

Source/Game-Lib/Game-Lib/Scripting/UI/Panel.cpp

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ namespace Scripting::UI
3030
{ "SetTexCoords", PanelMethods::SetTexCoords },
3131

3232
{ "SetColor", PanelMethods::SetColor },
33-
{ "SetAlpha", PanelMethods::SetAlpha },
34-
35-
{ "DebugSetWorldTransformIndex", PanelMethods::DebugSetWorldTransformIndex }
33+
{ "SetAlpha", PanelMethods::SetAlpha }
3634
};
3735

3836
void Panel::Register(lua_State* state)
@@ -348,31 +346,5 @@ namespace Scripting::UI
348346

349347
return 0;
350348
}
351-
352-
i32 DebugSetWorldTransformIndex(lua_State* state)
353-
{
354-
LuaState ctx(state);
355-
356-
Widget* widget = ctx.GetUserData<Widget>(nullptr, 1);
357-
if (widget == nullptr)
358-
{
359-
luaL_error(state, "Widget is null");
360-
}
361-
362-
i32 index = ctx.Get(-1, 2);
363-
364-
entt::registry* registry = ServiceLocator::GetEnttRegistries()->uiRegistry;
365-
auto& widgetComp = registry->get<ECS::Components::UI::Widget>(widget->entity);
366-
widgetComp.worldTransformIndex = index;
367-
368-
auto& transform = registry->get<ECS::Components::Transform2D>(widget->entity);
369-
transform.SetIgnoreParent(index != -1);
370-
371-
registry->get_or_emplace<ECS::Components::UI::DirtyWidgetData>(widget->entity);
372-
registry->get_or_emplace<ECS::Components::UI::DirtyWidgetTransform>(widget->entity);
373-
registry->get_or_emplace<ECS::Components::UI::DirtyWidgetWorldTransformIndex>(widget->entity);
374-
375-
return 0;
376-
}
377349
}
378350
}

Source/Game-Lib/Game-Lib/Scripting/UI/Panel.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,5 @@ namespace Scripting::UI
2424
i32 SetTexCoords(lua_State* state);
2525
i32 SetColor(lua_State* state);
2626
i32 SetAlpha(lua_State* state);
27-
28-
i32 DebugSetWorldTransformIndex(lua_State* state);
2927
};
3028
}

Source/Game-Lib/Game-Lib/Scripting/UI/Widget.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "Game-Lib/ECS/Singletons/UISingleton.h"
88
#include "Game-Lib/ECS/Util/Transform2D.h"
99
#include "Game-Lib/ECS/Util/UIUtil.h"
10+
#include "Game-Lib/Rendering/Canvas/CanvasRenderer.h"
11+
#include "Game-Lib/Rendering/GameRenderer.h"
1012
#include "Game-Lib/Scripting/LuaState.h"
1113
#include "Game-Lib/Scripting/UI/Panel.h"
1214
#include "Game-Lib/Scripting/UI/Text.h"
@@ -540,6 +542,7 @@ i32 Scripting::UI::WidgetMethods::SetClipRect(lua_State* state)
540542
else
541543
{
542544
registry->emplace_or_replace<ECS::Components::UI::DirtyClipper>(widget->entity);
545+
registry->emplace_or_replace<ECS::Components::UI::DirtyWidgetData>(widget->entity);
543546
}
544547

545548
registry->emplace_or_replace<ECS::Components::UI::DirtyCanvasTag>(widget->canvasEntity);
@@ -863,6 +866,53 @@ i32 Scripting::UI::WidgetMethods::SetWorldPosY(lua_State* state)
863866
return 0;
864867
}
865868

869+
i32 Scripting::UI::WidgetMethods::SetPos3D(lua_State* state)
870+
{
871+
LuaState ctx(state);
872+
873+
Widget* widget = ctx.GetUserData<Widget>(nullptr, 1);
874+
if (widget == nullptr)
875+
{
876+
luaL_error(state, "Widget is null");
877+
}
878+
879+
entt::registry* registry = ServiceLocator::GetEnttRegistries()->uiRegistry;
880+
auto& widgetComp = registry->get<ECS::Components::UI::Widget>(widget->entity);
881+
auto& transform = registry->get<ECS::Components::Transform2D>(widget->entity);
882+
883+
auto* canvasRenderer = ServiceLocator::GetGameRenderer()->GetCanvasRenderer();
884+
885+
if (lua_isnil(state, 2))
886+
{
887+
transform.SetIgnoreParent(false);
888+
889+
if (widgetComp.worldTransformIndex != std::numeric_limits<u32>().max())
890+
{
891+
canvasRenderer->ReleaseWorldTransform(widgetComp.worldTransformIndex);
892+
}
893+
894+
widgetComp.worldTransformIndex = std::numeric_limits<u32>().max();
895+
}
896+
else
897+
{
898+
transform.SetIgnoreParent(true);
899+
900+
if (widgetComp.worldTransformIndex == std::numeric_limits<u32>().max())
901+
{
902+
widgetComp.worldTransformIndex = canvasRenderer->ReserveWorldTransform();
903+
}
904+
905+
vec3 pos = ctx.Get(vec3(0, 0, 0), 2);
906+
canvasRenderer->UpdateWorldTransform(widgetComp.worldTransformIndex, pos);
907+
}
908+
909+
registry->get_or_emplace<ECS::Components::UI::DirtyWidgetData>(widget->entity);
910+
registry->get_or_emplace<ECS::Components::UI::DirtyWidgetTransform>(widget->entity);
911+
registry->get_or_emplace<ECS::Components::UI::DirtyWidgetWorldTransformIndex>(widget->entity);
912+
913+
return 0;
914+
}
915+
866916
i32 Scripting::UI::WidgetInputMethods::SetOnMouseDown(lua_State* state)
867917
{
868918
LuaState ctx(state);

0 commit comments

Comments
 (0)