Optimsed OBJ Loader from ~60 seconds to ~3
This commit is contained in:
parent
9d653be08c
commit
20635140fe
@ -12,9 +12,9 @@ local rotationSpeed = 25 -- Degrees per second for spinning
|
|||||||
local new_rotation = 0
|
local new_rotation = 0
|
||||||
|
|
||||||
-- Variables for bobbing effect
|
-- Variables for bobbing effect
|
||||||
local initial_position = {x = 0, y = 0, z = 0} -- To store the gun's initial position
|
local initial_position = { x = 0, y = 0, z = 0 } -- To store the gun's initial position
|
||||||
local bobAmplitude = 5 -- Amplitude of the bobbing (units)
|
local bobAmplitude = 5 -- Amplitude of the bobbing (units)
|
||||||
local bobFrequency = 0.5 -- Frequency of the bobbing (oscillations per second)
|
local bobFrequency = 0.5 -- Frequency of the bobbing (oscillations per second)
|
||||||
|
|
||||||
-- Reference to the Gun GameObject and its Transform component
|
-- Reference to the Gun GameObject and its Transform component
|
||||||
local gun = nil
|
local gun = nil
|
||||||
@ -22,9 +22,21 @@ local transform = nil
|
|||||||
|
|
||||||
local TAU = Math.constants.TAU
|
local TAU = Math.constants.TAU
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function OnInit()
|
function OnInit()
|
||||||
local startTime = os.clock()
|
local startTime = os.clock()
|
||||||
Engine.Log("Init START", {1.0,1.0,1.0,1.0})
|
|
||||||
|
Engine.Expose("GameObjectName", GameObjectName)
|
||||||
|
Engine.Expose("new_rotation", new_rotation)
|
||||||
|
Engine.Expose("elapsedTime", elapsedTime)
|
||||||
|
Engine.Expose("bobAmplitude", bobAmplitude)
|
||||||
|
Engine.Expose("bobFrequency", bobFrequency)
|
||||||
|
|
||||||
|
|
||||||
|
Engine.Log("Init START", { 1.0, 1.0, 1.0, 1.0 })
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -34,41 +46,43 @@ function OnInit()
|
|||||||
transform = gun:GetComponent("Transform")
|
transform = gun:GetComponent("Transform")
|
||||||
if transform then
|
if transform then
|
||||||
local pos = transform:GetPosition()
|
local pos = transform:GetPosition()
|
||||||
initial_position = {x = pos.x, y = pos.y, z = pos.z}
|
initial_position = { x = pos.x, y = pos.y, z = pos.z }
|
||||||
Engine.Log("Gun found and initial position updated.", {1, 1, 1, 1})
|
Engine.Log("Gun found and initial position updated.", { 1, 1, 1, 1 })
|
||||||
else
|
else
|
||||||
Engine.Log("Transform component not found on Gun.", {1, 1, 0, 1})
|
Engine.Log("Transform component not found on Gun.", { 1, 1, 0, 1 })
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Engine.Log("Gun GameObject still not found.", {1, 1, 0, 1})
|
Engine.Log("Gun GameObject still not found.", { 1, 1, 0, 1 })
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
elseif not transform then
|
elseif not transform then
|
||||||
transform = gun:GetComponent("Transform")
|
transform = gun:GetComponent("Transform")
|
||||||
if transform then
|
if transform then
|
||||||
local pos = transform:GetPosition()
|
local pos = transform:GetPosition()
|
||||||
initial_position = {x = pos.x, y = pos.y, z = pos.z}
|
initial_position = { x = pos.x, y = pos.y, z = pos.z }
|
||||||
Engine.Log("Transform component found and initial position updated.", {1, 1, 1, 1})
|
Engine.Log("Transform component found and initial position updated.", { 1, 1, 1, 1 })
|
||||||
else
|
else
|
||||||
Engine.Log("Transform component still not found on Gun.", {1, 1, 0, 1})
|
Engine.Log("Transform component still not found on Gun.", { 1, 1, 0, 1 })
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Engine.Log("Init OK", {0.0,1.0,0.0,1.0})
|
Engine.Log("Init OK", { 0.0, 1.0, 0.0, 1.0 })
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local endTime = os.clock()
|
local endTime = os.clock()
|
||||||
|
|
||||||
|
|
||||||
Engine.Log(string.format("Time to load: %f", endTime-startTime))
|
Engine.Log(string.format("Time to load: %fms", (endTime - startTime)*1000))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Update function called every frame
|
-- Update function called every frame
|
||||||
function OnUpdate(deltaTime)
|
function OnUpdate(deltaTime)
|
||||||
|
Engine.Expose("GameObjectName", GameObjectName)
|
||||||
|
Engine.Expose("new_rotation", new_rotation)
|
||||||
|
Engine.Expose("elapsedTime", elapsedTime)
|
||||||
|
Engine.Expose("bobAmplitude", bobAmplitude)
|
||||||
|
Engine.Expose("bobFrequency", bobFrequency)
|
||||||
-- Ensure that the Gun and its Transform component are valid
|
-- Ensure that the Gun and its Transform component are valid
|
||||||
if not gun then
|
if not gun then
|
||||||
gun = Engine.GetGameObjectByTag(GameObjectName)
|
gun = Engine.GetGameObjectByTag(GameObjectName)
|
||||||
@ -76,10 +90,10 @@ function OnUpdate(deltaTime)
|
|||||||
transform = gun:GetComponent("Transform")
|
transform = gun:GetComponent("Transform")
|
||||||
if transform then
|
if transform then
|
||||||
local pos = transform:GetPosition()
|
local pos = transform:GetPosition()
|
||||||
initial_position = {x = pos.x, y = pos.y, z = pos.z}
|
initial_position = { x = pos.x, y = pos.y, z = pos.z }
|
||||||
Engine.Log("Gun found and initial position updated.", {1, 1, 1, 1})
|
Engine.Log("Gun found and initial position updated.", { 1, 1, 1, 1 })
|
||||||
else
|
else
|
||||||
Engine.Log("Transform component not found on Gun.", {1, 1, 0, 1})
|
Engine.Log("Transform component not found on Gun.", { 1, 1, 0, 1 })
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -89,8 +103,8 @@ function OnUpdate(deltaTime)
|
|||||||
transform = gun:GetComponent("Transform")
|
transform = gun:GetComponent("Transform")
|
||||||
if transform then
|
if transform then
|
||||||
local pos = transform:GetPosition()
|
local pos = transform:GetPosition()
|
||||||
initial_position = {x = pos.x, y = pos.y, z = pos.z}
|
initial_position = { x = pos.x, y = pos.y, z = pos.z }
|
||||||
Engine.Log("Transform component found and initial position updated.", {1, 1, 1, 1})
|
Engine.Log("Transform component found and initial position updated.", { 1, 1, 1, 1 })
|
||||||
else
|
else
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -110,9 +124,9 @@ function OnUpdate(deltaTime)
|
|||||||
|
|
||||||
-- Define the new rotation (spinning around the Y-axis)
|
-- Define the new rotation (spinning around the Y-axis)
|
||||||
local rotation = {
|
local rotation = {
|
||||||
x = 0, -- Preserving existing rotation on X-axis
|
x = 0, -- Preserving existing rotation on X-axis
|
||||||
y = new_rotation, -- Updated rotation on Y-axis for spinning
|
y = new_rotation, -- Updated rotation on Y-axis for spinning
|
||||||
z = 0 -- Preserving existing rotation on Z-axis
|
z = 0 -- Preserving existing rotation on Z-axis
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Apply the new rotation to the Transform component
|
-- Apply the new rotation to the Transform component
|
||||||
@ -124,9 +138,9 @@ function OnUpdate(deltaTime)
|
|||||||
|
|
||||||
-- Define the new position by adding the bobbing offset to the initial Y position
|
-- Define the new position by adding the bobbing offset to the initial Y position
|
||||||
local new_position = {
|
local new_position = {
|
||||||
x = initial_position.x, -- No change on X-axis
|
x = initial_position.x, -- No change on X-axis
|
||||||
y = initial_position.y + bobOffset, -- Bouncing up and down on Y-axis
|
y = initial_position.y + bobOffset, -- Bouncing up and down on Y-axis
|
||||||
z = initial_position.z -- No change on Z-axis
|
z = initial_position.z -- No change on Z-axis
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Apply the new position to the Transform component
|
-- Apply the new position to the Transform component
|
||||||
|
88
imgui.ini
88
imgui.ini
@ -74,28 +74,28 @@ Collapsed=0
|
|||||||
DockId=0x00000016,0
|
DockId=0x00000016,0
|
||||||
|
|
||||||
[Window][Editor##EditorWindow]
|
[Window][Editor##EditorWindow]
|
||||||
Pos=523,27
|
Pos=332,27
|
||||||
Size=1011,764
|
Size=1202,776
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000017,0
|
DockId=0x00000017,0
|
||||||
|
|
||||||
[Window][Performance##performance]
|
[Window][Performance##performance]
|
||||||
Pos=8,761
|
Pos=8,761
|
||||||
Size=513,408
|
Size=322,408
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x0000001C,0
|
DockId=0x0000001C,0
|
||||||
|
|
||||||
[Window][Logger##logger]
|
[Window][Logger##logger]
|
||||||
Pos=8,395
|
Pos=332,805
|
||||||
Size=513,364
|
Size=1202,364
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x0000001A,0
|
DockId=0x00000019,0
|
||||||
|
|
||||||
[Window][Lua Text Editor##LuaEditor]
|
[Window][Lua Text Editor##LuaEditor]
|
||||||
Pos=523,793
|
Pos=8,27
|
||||||
Size=1011,376
|
Size=322,732
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000018,0
|
DockId=0x0000001B,0
|
||||||
|
|
||||||
[Window][Scene Window@SceneWindow]
|
[Window][Scene Window@SceneWindow]
|
||||||
Pos=8,27
|
Pos=8,27
|
||||||
@ -105,9 +105,9 @@ DockId=0x0000000F,0
|
|||||||
|
|
||||||
[Window][Scene Window##SceneWindow]
|
[Window][Scene Window##SceneWindow]
|
||||||
Pos=8,27
|
Pos=8,27
|
||||||
Size=513,366
|
Size=322,732
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000019,0
|
DockId=0x0000001B,0
|
||||||
|
|
||||||
[Window][Game Objects]
|
[Window][Game Objects]
|
||||||
Pos=182,27
|
Pos=182,27
|
||||||
@ -116,10 +116,10 @@ Collapsed=0
|
|||||||
DockId=0x00000011,0
|
DockId=0x00000011,0
|
||||||
|
|
||||||
[Window][Profiler]
|
[Window][Profiler]
|
||||||
Pos=523,793
|
Pos=935,805
|
||||||
Size=1011,376
|
Size=599,364
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000018,1
|
DockId=0x0000001A,0
|
||||||
|
|
||||||
[Table][0xE9E836E4,4]
|
[Table][0xE9E836E4,4]
|
||||||
Column 0 Weight=1.2999
|
Column 0 Weight=1.2999
|
||||||
@ -128,34 +128,34 @@ Column 2 Weight=0.6474
|
|||||||
Column 3 Weight=1.0088
|
Column 3 Weight=1.0088
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
DockSpace ID=0x14621557 Window=0x3DA2F1DE Pos=8,50 Size=1904,1142 Split=X Selected=0xF7365A5A
|
DockSpace ID=0x14621557 Window=0x3DA2F1DE Pos=8,50 Size=1904,1142 Split=X Selected=0xF7365A5A
|
||||||
DockNode ID=0x00000013 Parent=0x14621557 SizeRef=513,1142 Split=Y Selected=0x818D04BB
|
DockNode ID=0x00000013 Parent=0x14621557 SizeRef=322,1142 Split=Y Selected=0x818D04BB
|
||||||
DockNode ID=0x0000001B Parent=0x00000013 SizeRef=264,456 Split=Y Selected=0x1D5D92B6
|
DockNode ID=0x0000001B Parent=0x00000013 SizeRef=264,456 HiddenTabBar=1 Selected=0x1D5D92B6
|
||||||
DockNode ID=0x00000019 Parent=0x0000001B SizeRef=264,366 HiddenTabBar=1 Selected=0x1D5D92B6
|
DockNode ID=0x0000001C Parent=0x00000013 SizeRef=264,254 HiddenTabBar=1 Selected=0x818D04BB
|
||||||
DockNode ID=0x0000001A Parent=0x0000001B SizeRef=264,364 HiddenTabBar=1 Selected=0x1C0788A1
|
DockNode ID=0x00000014 Parent=0x14621557 SizeRef=1580,1142 Split=X
|
||||||
DockNode ID=0x0000001C Parent=0x00000013 SizeRef=264,254 HiddenTabBar=1 Selected=0x818D04BB
|
DockNode ID=0x00000015 Parent=0x00000014 SizeRef=1202,1142 Split=X
|
||||||
DockNode ID=0x00000014 Parent=0x14621557 SizeRef=749,1142 Split=X
|
DockNode ID=0x00000011 Parent=0x00000015 SizeRef=265,1142 Selected=0x1D5D92B6
|
||||||
DockNode ID=0x00000015 Parent=0x00000014 SizeRef=371,1142 Split=X
|
DockNode ID=0x00000012 Parent=0x00000015 SizeRef=1259,1142 Split=X
|
||||||
DockNode ID=0x00000011 Parent=0x00000015 SizeRef=265,1142 Selected=0x1D5D92B6
|
DockNode ID=0x00000009 Parent=0x00000012 SizeRef=364,1142 Split=Y Selected=0x3DC5AC3F
|
||||||
DockNode ID=0x00000012 Parent=0x00000015 SizeRef=1259,1142 Split=X
|
DockNode ID=0x00000005 Parent=0x00000009 SizeRef=364,745 Split=Y Selected=0x3DC5AC3F
|
||||||
DockNode ID=0x00000009 Parent=0x00000012 SizeRef=364,1142 Split=Y Selected=0x3DC5AC3F
|
DockNode ID=0x0000000B Parent=0x00000005 SizeRef=364,452 HiddenTabBar=1 Selected=0x3DC5AC3F
|
||||||
DockNode ID=0x00000005 Parent=0x00000009 SizeRef=364,745 Split=Y Selected=0x3DC5AC3F
|
DockNode ID=0x0000000C Parent=0x00000005 SizeRef=364,291 Selected=0xAE3C694A
|
||||||
DockNode ID=0x0000000B Parent=0x00000005 SizeRef=364,452 HiddenTabBar=1 Selected=0x3DC5AC3F
|
DockNode ID=0x00000006 Parent=0x00000009 SizeRef=364,395 HiddenTabBar=1 Selected=0x726D8899
|
||||||
DockNode ID=0x0000000C Parent=0x00000005 SizeRef=364,291 Selected=0xAE3C694A
|
DockNode ID=0x0000000A Parent=0x00000012 SizeRef=1538,1142 Split=X
|
||||||
DockNode ID=0x00000006 Parent=0x00000009 SizeRef=364,395 HiddenTabBar=1 Selected=0x726D8899
|
DockNode ID=0x00000007 Parent=0x0000000A SizeRef=357,1142 Selected=0x7737E8B2
|
||||||
DockNode ID=0x0000000A Parent=0x00000012 SizeRef=1538,1142 Split=X
|
DockNode ID=0x00000008 Parent=0x0000000A SizeRef=1545,1142 Split=X
|
||||||
DockNode ID=0x00000007 Parent=0x0000000A SizeRef=357,1142 Selected=0x7737E8B2
|
DockNode ID=0x00000001 Parent=0x00000008 SizeRef=1202,1142 Split=Y Selected=0xDF0EC458
|
||||||
DockNode ID=0x00000008 Parent=0x0000000A SizeRef=1545,1142 Split=X
|
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=1202,849 Split=Y Selected=0xDF0EC458
|
||||||
DockNode ID=0x00000001 Parent=0x00000008 SizeRef=1202,1142 Split=Y Selected=0xDF0EC458
|
DockNode ID=0x0000000D Parent=0x00000003 SizeRef=1202,571 Split=Y Selected=0xDFF75B3F
|
||||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=1202,849 Split=Y Selected=0xDF0EC458
|
DockNode ID=0x00000017 Parent=0x0000000D SizeRef=1202,776 CentralNode=1 Selected=0xDFF75B3F
|
||||||
DockNode ID=0x0000000D Parent=0x00000003 SizeRef=1202,571 Split=Y Selected=0xDFF75B3F
|
DockNode ID=0x00000018 Parent=0x0000000D SizeRef=1202,364 Split=X Selected=0x1C0788A1
|
||||||
DockNode ID=0x00000017 Parent=0x0000000D SizeRef=1303,764 CentralNode=1 HiddenTabBar=1 Selected=0xDFF75B3F
|
DockNode ID=0x00000019 Parent=0x00000018 SizeRef=601,364 Selected=0x1C0788A1
|
||||||
DockNode ID=0x00000018 Parent=0x0000000D SizeRef=1303,376 Selected=0x9B5D3198
|
DockNode ID=0x0000001A Parent=0x00000018 SizeRef=599,364 Selected=0x9B5D3198
|
||||||
DockNode ID=0x0000000E Parent=0x00000003 SizeRef=1202,569 Selected=0xE98146C5
|
DockNode ID=0x0000000E Parent=0x00000003 SizeRef=1202,569 Selected=0xE98146C5
|
||||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=1202,291 Selected=0x9DD4E196
|
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=1202,291 Selected=0x9DD4E196
|
||||||
DockNode ID=0x00000002 Parent=0x00000008 SizeRef=334,1142 HiddenTabBar=1 Selected=0x36DC96AB
|
DockNode ID=0x00000002 Parent=0x00000008 SizeRef=334,1142 HiddenTabBar=1 Selected=0x36DC96AB
|
||||||
DockNode ID=0x00000016 Parent=0x00000014 SizeRef=376,1142 HiddenTabBar=1 Selected=0x8D0E8380
|
DockNode ID=0x00000016 Parent=0x00000014 SizeRef=376,1142 HiddenTabBar=1 Selected=0x8D0E8380
|
||||||
DockSpace ID=0xC6145A92 Pos=8,27 Size=1904,1142 Split=X
|
DockSpace ID=0xC6145A92 Pos=8,27 Size=1904,1142 Split=X
|
||||||
DockNode ID=0x0000000F Parent=0xC6145A92 SizeRef=301,1142 Selected=0xA8433A03
|
DockNode ID=0x0000000F Parent=0xC6145A92 SizeRef=301,1142 Selected=0xA8433A03
|
||||||
DockNode ID=0x00000010 Parent=0xC6145A92 SizeRef=1601,1142 CentralNode=1
|
DockNode ID=0x00000010 Parent=0xC6145A92 SizeRef=1601,1142 CentralNode=1
|
||||||
|
|
||||||
|
@ -6,13 +6,10 @@
|
|||||||
#include "gcml.h"
|
#include "gcml.h"
|
||||||
|
|
||||||
// External pointer to LoggerWindow (Assuming it's defined globally)
|
// External pointer to LoggerWindow (Assuming it's defined globally)
|
||||||
extern LoggerWindow* g_LoggerWindow;
|
extern LoggerWindow *g_LoggerWindow;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const std::string ScriptComponent::name = "ScriptComponent";
|
const std::string ScriptComponent::name = "ScriptComponent";
|
||||||
|
|
||||||
|
|
||||||
ScriptComponent::ScriptComponent()
|
ScriptComponent::ScriptComponent()
|
||||||
: ScriptPath("assets/scripts/script.lua"), m_LastErrorMessage("")
|
: ScriptPath("assets/scripts/script.lua"), m_LastErrorMessage("")
|
||||||
{
|
{
|
||||||
@ -45,17 +42,16 @@ YAML::Node ScriptComponent::Serialize()
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptComponent::Deserialize(const YAML::Node& node)
|
void ScriptComponent::Deserialize(const YAML::Node &node)
|
||||||
{
|
{
|
||||||
if (node["ScriptPath"])
|
if (node["ScriptPath"])
|
||||||
{
|
{
|
||||||
ScriptPath = node["ScriptPath"].as<std::string>();
|
ScriptPath = node["ScriptPath"].as<std::string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_PRINT("Script Path: %s", ScriptPath.c_str());
|
DEBUG_PRINT("Script Path: %s", ScriptPath.c_str());
|
||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptComponent::Initialize()
|
bool ScriptComponent::Initialize()
|
||||||
@ -80,8 +76,6 @@ bool ScriptComponent::Initialize()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_LuaManager.PrintEngineVariables();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,9 +85,18 @@ void ScriptComponent::Update(float deltaTime)
|
|||||||
m_LuaManager.Update(deltaTime);
|
m_LuaManager.Update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ScriptComponent::Init()
|
void ScriptComponent::Init()
|
||||||
{
|
{
|
||||||
// Call the Update method of LuaManager
|
// Call the Update method of LuaManager
|
||||||
m_LuaManager.CallLuaFunction("OnInit");
|
m_LuaManager.CallLuaFunction("OnInit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptComponent::UpdateVariable(const std::string &name, const LuaManager::LuaExposedVariant &value)
|
||||||
|
{
|
||||||
|
m_LuaManager.UpdateVariable(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::string, LuaManager::LuaExposedVariant> ScriptComponent::GetExposedVariables()
|
||||||
|
{
|
||||||
|
return m_LuaManager.GetExposedVariables();
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <yaml-cpp/yaml.h>
|
#include <yaml-cpp/yaml.h>
|
||||||
#include "Windows/LoggerWindow.h"
|
#include "Windows/LoggerWindow.h"
|
||||||
#include "Engine/LuaAPI.h" // Include the LuaManager class
|
#include "Engine/LuaAPI.h" // Include the LuaManager class
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
class ScriptComponent : public Component
|
class ScriptComponent : public Component
|
||||||
{
|
{
|
||||||
@ -14,33 +15,31 @@ public:
|
|||||||
ScriptComponent();
|
ScriptComponent();
|
||||||
virtual ~ScriptComponent();
|
virtual ~ScriptComponent();
|
||||||
|
|
||||||
std::string ScriptPath; // Path to the Lua script
|
std::string ScriptPath; // Path to the Lua script
|
||||||
|
|
||||||
|
|
||||||
// Component interface implementation
|
// Component interface implementation
|
||||||
virtual const std::string& GetName() const override;
|
virtual const std::string &GetName() const override;
|
||||||
static const std::string& GetStaticName();
|
static const std::string &GetStaticName();
|
||||||
|
|
||||||
virtual YAML::Node Serialize() override;
|
virtual YAML::Node Serialize() override;
|
||||||
virtual void Deserialize(const YAML::Node& node) override;
|
virtual void Deserialize(const YAML::Node &node) override;
|
||||||
|
|
||||||
// Script management methods
|
// Script management methods
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
virtual void Update(float deltaTime);
|
virtual void Update(float deltaTime);
|
||||||
|
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
void UpdateVariable(const std::string &name, const LuaManager::LuaExposedVariant &value);
|
||||||
|
std::unordered_map<std::string, LuaManager::LuaExposedVariant> GetExposedVariables();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LuaManager m_LuaManager; // Instance of LuaManager
|
LuaManager m_LuaManager; // Instance of LuaManager
|
||||||
std::string m_LastErrorMessage; // To prevent duplicate error logs
|
std::string m_LastErrorMessage; // To prevent duplicate error logs
|
||||||
|
|
||||||
// block copying
|
// block copying
|
||||||
ScriptComponent(const ScriptComponent&) = delete;
|
ScriptComponent(const ScriptComponent &) = delete;
|
||||||
ScriptComponent& operator=(const ScriptComponent&) = delete;
|
ScriptComponent &operator=(const ScriptComponent &) = delete;
|
||||||
|
|
||||||
static const std::string name;
|
static const std::string name;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -260,7 +260,7 @@ void MyEngine::Run()
|
|||||||
m_PerformanceWindow->Show(m_Fps, m_Ms); // FPS & ms
|
m_PerformanceWindow->Show(m_Fps, m_Ms); // FPS & ms
|
||||||
m_LoggerWindow->Show(); // Logs
|
m_LoggerWindow->Show(); // Logs
|
||||||
m_SceneWindow->Show();
|
m_SceneWindow->Show();
|
||||||
m_luaEditor->Show();
|
//m_luaEditor->Show();
|
||||||
|
|
||||||
if (m_showProfiler)
|
if (m_showProfiler)
|
||||||
{
|
{
|
||||||
|
@ -63,7 +63,7 @@ AssetManager::AssetVariant AssetManager::loadAssetFromDisk(AssetType type, const
|
|||||||
}
|
}
|
||||||
case AssetType::SHADER:
|
case AssetType::SHADER:
|
||||||
{
|
{
|
||||||
Shader* shaderPtr = LoadShaderFromList(path); // Returns Shader*
|
Shader *shaderPtr = LoadShaderFromList(path); // Returns Shader*
|
||||||
if (shaderPtr != nullptr)
|
if (shaderPtr != nullptr)
|
||||||
{
|
{
|
||||||
// It's essential to ensure that shaderPtr is dynamically allocated and not managed elsewhere
|
// It's essential to ensure that shaderPtr is dynamically allocated and not managed elsewhere
|
||||||
@ -76,7 +76,7 @@ AssetManager::AssetVariant AssetManager::loadAssetFromDisk(AssetType type, const
|
|||||||
}
|
}
|
||||||
case AssetType::MODEL:
|
case AssetType::MODEL:
|
||||||
{
|
{
|
||||||
Model* modelPtr = LoadModelFromList(path); // Returns Model*
|
Model *modelPtr = LoadModelFromList(path); // Returns Model*
|
||||||
if (modelPtr != nullptr)
|
if (modelPtr != nullptr)
|
||||||
{
|
{
|
||||||
// It's essential to ensure that modelPtr is dynamically allocated and not managed elsewhere
|
// It's essential to ensure that modelPtr is dynamically allocated and not managed elsewhere
|
||||||
@ -139,7 +139,7 @@ GLuint LoadTextureFromList(const std::string &path)
|
|||||||
return texID;
|
return texID;
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader* LoadShaderFromList(const std::string &path)
|
Shader *LoadShaderFromList(const std::string &path)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Build actual paths from the base path
|
// Build actual paths from the base path
|
||||||
@ -160,12 +160,6 @@ Shader* LoadShaderFromList(const std::string &path)
|
|||||||
return newShader;
|
return newShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GLuint LoadTexture(const std::string &path, const std::string &directory)
|
GLuint LoadTexture(const std::string &path, const std::string &directory)
|
||||||
{
|
{
|
||||||
std::string fullPath = directory + path;
|
std::string fullPath = directory + path;
|
||||||
@ -173,7 +167,7 @@ GLuint LoadTexture(const std::string &path, const std::string &directory)
|
|||||||
unsigned char *data = stbi_load(fullPath.c_str(), &width, &height, &channels, 0);
|
unsigned char *data = stbi_load(fullPath.c_str(), &width, &height, &channels, 0);
|
||||||
if (!data)
|
if (!data)
|
||||||
{
|
{
|
||||||
DEBUG_PRINT("[AssetManager] failed to load texture: %s: %s", fullPath.c_str(),stbi_failure_reason());
|
DEBUG_PRINT("[AssetManager] failed to load texture: %s: %s", fullPath.c_str(), stbi_failure_reason());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,15 +184,15 @@ GLuint LoadTexture(const std::string &path, const std::string &directory)
|
|||||||
GLuint textureID;
|
GLuint textureID;
|
||||||
glGenTextures(1, &textureID);
|
glGenTextures(1, &textureID);
|
||||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0,
|
||||||
format, GL_UNSIGNED_BYTE, data);
|
format, GL_UNSIGNED_BYTE, data);
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
// Set texture parameters
|
// Set texture parameters
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
@ -207,15 +201,31 @@ GLuint LoadTexture(const std::string &path, const std::string &directory)
|
|||||||
return textureID;
|
return textureID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
// Custom hash function for Vertex
|
||||||
|
struct VertexHash
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Model* LoadModelFromList(const std::string &path)
|
|
||||||
{
|
{
|
||||||
|
std::size_t operator()(const Vertex &v) const
|
||||||
|
{
|
||||||
|
std::size_t h1 = std::hash<float>{}(v.position[0]);
|
||||||
|
std::size_t h2 = std::hash<float>{}(v.position[1]);
|
||||||
|
std::size_t h3 = std::hash<float>{}(v.position[2]);
|
||||||
|
std::size_t h4 = std::hash<float>{}(v.texCoord[0]);
|
||||||
|
std::size_t h5 = std::hash<float>{}(v.texCoord[1]);
|
||||||
|
std::size_t h6 = std::hash<float>{}(v.normal[0]);
|
||||||
|
std::size_t h7 = std::hash<float>{}(v.normal[1]);
|
||||||
|
std::size_t h8 = std::hash<float>{}(v.normal[2]);
|
||||||
|
return h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^ h7 ^ h8;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hash map for deduplication
|
||||||
|
std::unordered_map<Vertex, unsigned int, VertexHash> vertexCache;
|
||||||
|
|
||||||
|
Model *LoadModelFromList(const std::string &path)
|
||||||
|
{
|
||||||
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
std::ifstream objFile(path);
|
std::ifstream objFile(path);
|
||||||
if (!objFile.is_open())
|
if (!objFile.is_open())
|
||||||
@ -227,6 +237,10 @@ Model* LoadModelFromList(const std::string &path)
|
|||||||
std::vector<float> temp_texCoords;
|
std::vector<float> temp_texCoords;
|
||||||
std::vector<float> temp_normals;
|
std::vector<float> temp_normals;
|
||||||
|
|
||||||
|
temp_positions.reserve(100000);
|
||||||
|
temp_texCoords.reserve(100000);
|
||||||
|
temp_normals.reserve(100000);
|
||||||
|
|
||||||
std::string directory;
|
std::string directory;
|
||||||
size_t lastSlash = path.find_last_of("/\\");
|
size_t lastSlash = path.find_last_of("/\\");
|
||||||
if (lastSlash != std::string::npos)
|
if (lastSlash != std::string::npos)
|
||||||
@ -234,7 +248,6 @@ Model* LoadModelFromList(const std::string &path)
|
|||||||
else
|
else
|
||||||
directory = "";
|
directory = "";
|
||||||
|
|
||||||
|
|
||||||
std::string currentMaterial = "default";
|
std::string currentMaterial = "default";
|
||||||
|
|
||||||
// Map material name to Submesh
|
// Map material name to Submesh
|
||||||
@ -243,7 +256,14 @@ Model* LoadModelFromList(const std::string &path)
|
|||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
std::string mtlFileName;
|
std::string mtlFileName;
|
||||||
while (std::getline(objFile, line))
|
|
||||||
|
// Read file into memory for faster line parsing
|
||||||
|
std::stringstream fileBuffer;
|
||||||
|
fileBuffer << objFile.rdbuf();
|
||||||
|
objFile.close();
|
||||||
|
DEBUG_PRINT("OBJ READ");
|
||||||
|
|
||||||
|
while (std::getline(fileBuffer, line))
|
||||||
{
|
{
|
||||||
if (line.empty() || line[0] == '#')
|
if (line.empty() || line[0] == '#')
|
||||||
continue; // Skip empty lines and comments
|
continue; // Skip empty lines and comments
|
||||||
@ -296,32 +316,25 @@ Model* LoadModelFromList(const std::string &path)
|
|||||||
while (iss >> vertexStr)
|
while (iss >> vertexStr)
|
||||||
{
|
{
|
||||||
unsigned int vIdx = 0, tIdx = 0, nIdx = 0;
|
unsigned int vIdx = 0, tIdx = 0, nIdx = 0;
|
||||||
size_t firstSlash = vertexStr.find('/');
|
const char *ptr = vertexStr.c_str();
|
||||||
size_t secondSlash = vertexStr.find('/', firstSlash + 1);
|
|
||||||
|
|
||||||
if (firstSlash == std::string::npos)
|
// Parse vertex index (vIdx)
|
||||||
|
vIdx = std::strtol(ptr, const_cast<char **>(&ptr), 10);
|
||||||
|
|
||||||
|
if (*ptr == '/')
|
||||||
{
|
{
|
||||||
// Format: f v1 v2 v3
|
++ptr; // Skip the first '/'
|
||||||
vIdx = std::stoi(vertexStr);
|
if (*ptr != '/')
|
||||||
}
|
{
|
||||||
else if (secondSlash == std::string::npos)
|
// Parse texture index (tIdx)
|
||||||
{
|
tIdx = std::strtol(ptr, const_cast<char **>(&ptr), 10);
|
||||||
// Format: f v1/vt1 v2/vt2 v3/vt3
|
}
|
||||||
vIdx = std::stoi(vertexStr.substr(0, firstSlash));
|
if (*ptr == '/')
|
||||||
tIdx = std::stoi(vertexStr.substr(firstSlash + 1));
|
{
|
||||||
}
|
++ptr; // Skip the second '/'
|
||||||
else if (secondSlash > firstSlash + 1)
|
// Parse normal index (nIdx)
|
||||||
{
|
nIdx = std::strtol(ptr, const_cast<char **>(&ptr), 10);
|
||||||
// Format: f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3
|
}
|
||||||
vIdx = std::stoi(vertexStr.substr(0, firstSlash));
|
|
||||||
tIdx = std::stoi(vertexStr.substr(firstSlash + 1, secondSlash - firstSlash - 1));
|
|
||||||
nIdx = std::stoi(vertexStr.substr(secondSlash + 1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Format: f v1//vn1 v2//vn2 v3//vn3
|
|
||||||
vIdx = std::stoi(vertexStr.substr(0, firstSlash));
|
|
||||||
nIdx = std::stoi(vertexStr.substr(secondSlash + 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
faceVertices.emplace_back(vIdx, tIdx, nIdx);
|
faceVertices.emplace_back(vIdx, tIdx, nIdx);
|
||||||
@ -333,8 +346,10 @@ Model* LoadModelFromList(const std::string &path)
|
|||||||
// Current material's submesh
|
// Current material's submesh
|
||||||
Submesh ¤tSubmesh = materialToSubmesh[currentMaterial];
|
Submesh ¤tSubmesh = materialToSubmesh[currentMaterial];
|
||||||
|
|
||||||
auto addVertex = [&](unsigned int v, unsigned int t, unsigned int n) -> unsigned int {
|
auto addVertex = [&](unsigned int v, unsigned int t, unsigned int n) -> unsigned int
|
||||||
|
{
|
||||||
Vertex vertex;
|
Vertex vertex;
|
||||||
|
|
||||||
// OBJ indices are 1-based
|
// OBJ indices are 1-based
|
||||||
vertex.position[0] = temp_positions[(v - 1) * 3];
|
vertex.position[0] = temp_positions[(v - 1) * 3];
|
||||||
vertex.position[1] = temp_positions[(v - 1) * 3 + 1];
|
vertex.position[1] = temp_positions[(v - 1) * 3 + 1];
|
||||||
@ -364,16 +379,18 @@ Model* LoadModelFromList(const std::string &path)
|
|||||||
vertex.normal[2] = 0.0f;
|
vertex.normal[2] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the vertex already exists in the submesh
|
// Use the hash map to check for duplicates
|
||||||
auto it = std::find(currentSubmesh.vertices.begin(), currentSubmesh.vertices.end(), vertex);
|
auto it = vertexCache.find(vertex);
|
||||||
if (it != currentSubmesh.vertices.end())
|
if (it != vertexCache.end())
|
||||||
{
|
{
|
||||||
return static_cast<unsigned int>(std::distance(currentSubmesh.vertices.begin(), it));
|
return it->second;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
unsigned int newIndex = static_cast<unsigned int>(currentSubmesh.vertices.size());
|
||||||
currentSubmesh.vertices.push_back(vertex);
|
currentSubmesh.vertices.push_back(vertex);
|
||||||
return static_cast<unsigned int>(currentSubmesh.vertices.size() - 1);
|
vertexCache[vertex] = newIndex;
|
||||||
|
return newIndex;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -388,7 +405,10 @@ Model* LoadModelFromList(const std::string &path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
objFile.close();
|
temp_positions.shrink_to_fit();
|
||||||
|
temp_texCoords.shrink_to_fit();
|
||||||
|
temp_normals.shrink_to_fit();
|
||||||
|
DEBUG_PRINT("MTL READ");
|
||||||
|
|
||||||
// Load MTL file if specified
|
// Load MTL file if specified
|
||||||
std::unordered_map<std::string, std::vector<Texture>> materialTexturesMap;
|
std::unordered_map<std::string, std::vector<Texture>> materialTexturesMap;
|
||||||
@ -476,6 +496,8 @@ Model* LoadModelFromList(const std::string &path)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG_PRINT("MTL SUBASSIGN");
|
||||||
|
|
||||||
// Assign textures to submeshes based on their material
|
// Assign textures to submeshes based on their material
|
||||||
for (auto &pair : materialToSubmesh)
|
for (auto &pair : materialToSubmesh)
|
||||||
{
|
{
|
||||||
@ -504,13 +526,18 @@ Model* LoadModelFromList(const std::string &path)
|
|||||||
Model *model = new Model();
|
Model *model = new Model();
|
||||||
|
|
||||||
// Move submeshes to the model
|
// Move submeshes to the model
|
||||||
|
DEBUG_PRINT("SUB MIGRATE");
|
||||||
|
|
||||||
for (auto &pair : materialToSubmesh)
|
for (auto &pair : materialToSubmesh)
|
||||||
{
|
{
|
||||||
model->submeshes.emplace_back(std::move(pair.second));
|
model->submeshes.emplace_back(std::move(pair.second));
|
||||||
}
|
}
|
||||||
|
// Code to analyze
|
||||||
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
|
g_LoggerWindow->AddLog("Loaded Mesh in %.6f seconds",
|
||||||
|
std::chrono::duration_cast<std::chrono::duration<double>>(end - start).count());
|
||||||
|
|
||||||
DEBUG_PRINT("[AssetManager] Loaded model with %lld submeshes.", model->submeshes.size());
|
DEBUG_PRINT("[AssetManager] Loaded model with %lld submeshes.", model->submeshes.size());
|
||||||
|
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@ extern LoggerWindow *g_LoggerWindow;
|
|||||||
extern std::vector<std::unique_ptr<GameObject>> g_GameObjects;
|
extern std::vector<std::unique_ptr<GameObject>> g_GameObjects;
|
||||||
|
|
||||||
std::string LuaManager::m_ScriptName = "LUA_UNDEFINED";
|
std::string LuaManager::m_ScriptName = "LUA_UNDEFINED";
|
||||||
|
std::unordered_map<std::string, LuaManager::LuaExposedVariant> LuaManager::m_ExposedVariables;
|
||||||
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
LuaManager::LuaManager()
|
LuaManager::LuaManager()
|
||||||
@ -92,6 +94,9 @@ bool LuaManager::Initialize(const std::string &scriptPath)
|
|||||||
lua_pushcfunction(m_LuaState, Lua_Engine_Log);
|
lua_pushcfunction(m_LuaState, Lua_Engine_Log);
|
||||||
lua_setfield(m_LuaState, -2, "Log");
|
lua_setfield(m_LuaState, -2, "Log");
|
||||||
|
|
||||||
|
lua_pushcfunction(m_LuaState, Lua_Engine_Expose);
|
||||||
|
lua_setfield(m_LuaState, -2, "Expose");
|
||||||
|
|
||||||
// Add the ScriptName binding
|
// Add the ScriptName binding
|
||||||
lua_pushcfunction(m_LuaState, Lua_Engine_ScriptName);
|
lua_pushcfunction(m_LuaState, Lua_Engine_ScriptName);
|
||||||
lua_setfield(m_LuaState, -2, "ScriptName");
|
lua_setfield(m_LuaState, -2, "ScriptName");
|
||||||
@ -150,208 +155,122 @@ bool LuaManager::Initialize(const std::string &scriptPath)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implementation of GetGlobalVariables
|
std::unordered_map<std::string, LuaManager::LuaExposedVariant> LuaManager::GetExposedVariables() {
|
||||||
std::vector<LuaManager::LuaGlobalVariant> LuaManager::GetGlobalVariables()
|
return m_ExposedVariables;
|
||||||
{
|
}
|
||||||
std::vector<LuaManager::LuaGlobalVariant> globals;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void LuaManager::UpdateVariable(const std::string &name, const LuaManager::LuaExposedVariant &value) {
|
||||||
if (!m_LuaState)
|
if (!m_LuaState)
|
||||||
{
|
return;
|
||||||
// Handle error: Lua state not initialized
|
|
||||||
if (g_LoggerWindow)
|
// Update the variable in the map
|
||||||
{
|
m_ExposedVariables[name] = value;
|
||||||
g_LoggerWindow->AddLog("LuaManager: Lua state is not initialized.",
|
|
||||||
std::optional<ImVec4>(ImVec4(1.0f, 0.0f, 0.0f, 1.0f)));
|
// Push the variable to the Lua global environment
|
||||||
}
|
lua_pushglobaltable(m_LuaState); // Push the global table
|
||||||
else
|
|
||||||
{
|
// Push the variable name
|
||||||
DEBUG_PRINT("LuaManager: Lua state is not initialized.");
|
lua_pushstring(m_LuaState, name.c_str());
|
||||||
}
|
|
||||||
return globals;
|
// Push the new value based on its type
|
||||||
|
if (std::holds_alternative<int>(value)) {
|
||||||
|
lua_pushinteger(m_LuaState, std::get<int>(value));
|
||||||
|
} else if (std::holds_alternative<float>(value)) {
|
||||||
|
lua_pushnumber(m_LuaState, std::get<float>(value));
|
||||||
|
} else if (std::holds_alternative<std::string>(value)) {
|
||||||
|
lua_pushstring(m_LuaState, std::get<std::string>(value).c_str());
|
||||||
|
} else if (std::holds_alternative<bool>(value)) {
|
||||||
|
lua_pushboolean(m_LuaState, std::get<bool>(value));
|
||||||
|
} else {
|
||||||
|
lua_pop(m_LuaState, 1); // Clean up stack
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push the global table onto the stack
|
// Set the variable in the Lua global environment
|
||||||
#if LUA_VERSION_NUM >= 502
|
lua_settable(m_LuaState, -3);
|
||||||
lua_pushglobaltable(m_LuaState);
|
|
||||||
#else
|
|
||||||
lua_pushvalue(m_LuaState, LUA_GLOBALSINDEX);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Start iterating with a nil key
|
// Clean up stack
|
||||||
lua_pushnil(m_LuaState); // First key
|
lua_pop(m_LuaState, 1);
|
||||||
|
}
|
||||||
|
|
||||||
// Iterate over the global table
|
|
||||||
while (lua_next(m_LuaState, -2) != 0)
|
|
||||||
{
|
|
||||||
// Stack now contains key at -2 and value at -1
|
|
||||||
|
|
||||||
// Get the type of the value
|
|
||||||
int valueType = lua_type(m_LuaState, -1);
|
|
||||||
|
|
||||||
switch (valueType)
|
|
||||||
{
|
int LuaManager::Lua_Engine_Expose(lua_State* L) {
|
||||||
|
// Check that at least two arguments are passed: name and value
|
||||||
|
if (lua_gettop(L) < 2) {
|
||||||
|
luaL_error(L, "Expose function requires at least two arguments: name and value");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First argument: variable name (string)
|
||||||
|
if (!lua_isstring(L, 1)) {
|
||||||
|
luaL_error(L, "First argument to Expose must be a string (variable name)");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* varName = lua_tostring(L, 1);
|
||||||
|
|
||||||
|
// Second argument: variable value (supports int, float, string, bool)
|
||||||
|
LuaExposedVariant varValue;
|
||||||
|
int type = lua_type(L, 2);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
case LUA_TNUMBER:
|
case LUA_TNUMBER:
|
||||||
#if LUA_VERSION_NUM >= 503
|
#if LUA_VERSION_NUM >= 503
|
||||||
if (lua_isinteger(m_LuaState, -1))
|
if (lua_isinteger(L, 2)) {
|
||||||
{
|
varValue = static_cast<int>(lua_tointeger(L, 2));
|
||||||
lua_Integer intVal = lua_tointeger(m_LuaState, -1);
|
} else
|
||||||
// Assuming you want to store as int
|
|
||||||
globals.emplace_back(static_cast<int>(intVal));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lua_Number numVal = lua_tonumber(m_LuaState, -1);
|
|
||||||
// Store as float (you might choose double instead)
|
|
||||||
globals.emplace_back(static_cast<float>(numVal));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
lua_Number numVal = lua_tonumber(m_LuaState, -1);
|
|
||||||
// Lua 5.2 and earlier use double for all numbers
|
|
||||||
// Decide how to store: here, stored as float
|
|
||||||
globals.emplace_back(static_cast<float>(numVal));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
varValue = static_cast<float>(lua_tonumber(L, 2));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LUA_TSTRING:
|
case LUA_TSTRING:
|
||||||
{
|
varValue = std::string(lua_tostring(L, 2));
|
||||||
size_t len = 0;
|
|
||||||
const char *str = lua_tolstring(m_LuaState, -1, &len);
|
|
||||||
if (str)
|
|
||||||
{
|
|
||||||
globals.emplace_back(std::string(str, len));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Optionally handle other types or skip them
|
|
||||||
// For example, you might skip tables, functions, booleans, etc.
|
|
||||||
default:
|
|
||||||
// Skip other types
|
|
||||||
break;
|
break;
|
||||||
}
|
case LUA_TBOOLEAN:
|
||||||
|
varValue = static_cast<bool>(lua_toboolean(L, 2));
|
||||||
// Pop the value, keep the key for the next iteration
|
break;
|
||||||
lua_pop(m_LuaState, 1);
|
default:
|
||||||
|
luaL_error(L, "Unsupported variable type for Expose");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pop the global table from the stack
|
// Store the variable in the static m_ExposedVariables map
|
||||||
lua_pop(m_LuaState, 1);
|
m_ExposedVariables[varName] = varValue;
|
||||||
|
|
||||||
return globals;
|
// Push the variable to the Lua global environment
|
||||||
|
lua_pushglobaltable(L);
|
||||||
|
|
||||||
|
lua_pushstring(L, varName); // Push the variable name
|
||||||
|
|
||||||
|
// Push the value to Lua based on its type
|
||||||
|
if (std::holds_alternative<int>(varValue)) {
|
||||||
|
lua_pushinteger(L, std::get<int>(varValue));
|
||||||
|
} else if (std::holds_alternative<float>(varValue)) {
|
||||||
|
lua_pushnumber(L, std::get<float>(varValue));
|
||||||
|
} else if (std::holds_alternative<std::string>(varValue)) {
|
||||||
|
lua_pushstring(L, std::get<std::string>(varValue).c_str());
|
||||||
|
} else if (std::holds_alternative<bool>(varValue)) {
|
||||||
|
lua_pushboolean(L, std::get<bool>(varValue));
|
||||||
|
} else {
|
||||||
|
lua_pop(L, 1); // Clean up stack
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the variable in Lua global environment
|
||||||
|
lua_settable(L, -3);
|
||||||
|
|
||||||
|
// Clean up stack
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implementation of PrintEngineVariables
|
|
||||||
void LuaManager::PrintEngineVariables() {
|
|
||||||
if (!m_LuaState) {
|
|
||||||
std::cerr << "LuaManager: Lua state is not initialized." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push the _T_Engine_Variables table onto the stack
|
|
||||||
lua_getglobal(m_LuaState, "_T_Engine_Variables");
|
|
||||||
if (!lua_istable(m_LuaState, -1)) {
|
|
||||||
std::cerr << "LuaManager: _T_Engine_Variables is not a table or does not exist." << std::endl;
|
|
||||||
lua_pop(m_LuaState, 1); // Remove non-table value
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start iterating with a nil key
|
|
||||||
lua_pushnil(m_LuaState); // First key
|
|
||||||
|
|
||||||
std::cout << "Engine Variables:" << std::endl;
|
|
||||||
|
|
||||||
// Iterate over the _T_Engine_Variables table
|
|
||||||
while (lua_next(m_LuaState, -2) != 0) {
|
|
||||||
// Stack now contains key at -2 and value at -1
|
|
||||||
|
|
||||||
// Get the key
|
|
||||||
const char* key = nullptr;
|
|
||||||
if (lua_type(m_LuaState, -2) == LUA_TSTRING) {
|
|
||||||
key = lua_tostring(m_LuaState, -2);
|
|
||||||
} else {
|
|
||||||
// For non-string keys, skip
|
|
||||||
lua_pop(m_LuaState, 1); // Remove value, keep key for next iteration
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the type of the value
|
|
||||||
int valueType = lua_type(m_LuaState, -1);
|
|
||||||
|
|
||||||
// Print the key and value based on type
|
|
||||||
std::cout << key << " = ";
|
|
||||||
|
|
||||||
switch (valueType) {
|
|
||||||
case LUA_TNUMBER:
|
|
||||||
#if LUA_VERSION_NUM >= 503
|
|
||||||
if (lua_isinteger(m_LuaState, -1)) {
|
|
||||||
lua_Integer intVal = lua_tointeger(m_LuaState, -1);
|
|
||||||
std::cout << intVal;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
lua_Number numVal = lua_tonumber(m_LuaState, -1);
|
|
||||||
std::cout << numVal;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LUA_TSTRING:
|
|
||||||
{
|
|
||||||
const char* str = lua_tostring(m_LuaState, -1);
|
|
||||||
if (str) {
|
|
||||||
std::cout << "\"" << str << "\"";
|
|
||||||
} else {
|
|
||||||
std::cout << "nil";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LUA_TBOOLEAN:
|
|
||||||
{
|
|
||||||
int boolVal = lua_toboolean(m_LuaState, -1);
|
|
||||||
std::cout << (boolVal ? "true" : "false");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LUA_TTABLE:
|
|
||||||
std::cout << "table";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LUA_TFUNCTION:
|
|
||||||
std::cout << "function";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LUA_TUSERDATA:
|
|
||||||
std::cout << "userdata";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LUA_TLIGHTUSERDATA:
|
|
||||||
std::cout << "lightuserdata";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LUA_TTHREAD:
|
|
||||||
std::cout << "thread";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LUA_TNIL:
|
|
||||||
std::cout << "nil";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
std::cout << "unknown";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
// Pop the value, keep the key for the next iteration
|
|
||||||
lua_pop(m_LuaState, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pop the _T_Engine_Variables table from the stack
|
|
||||||
lua_pop(m_LuaState, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update function called every frame
|
// Update function called every frame
|
||||||
void LuaManager::Update(float deltaTime)
|
void LuaManager::Update(float deltaTime)
|
||||||
|
@ -14,6 +14,7 @@ extern "C"
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// Forward declarations to avoid circular dependencies
|
// Forward declarations to avoid circular dependencies
|
||||||
@ -59,10 +60,14 @@ public:
|
|||||||
|
|
||||||
void CallLuaFunction(std::string functionName);
|
void CallLuaFunction(std::string functionName);
|
||||||
|
|
||||||
using LuaGlobalVariant = std::variant<int, float, std::string>;
|
using LuaExposedVariant = std::variant<int, float, std::string, bool>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Retrieve exposed variables
|
||||||
|
std::unordered_map<std::string, LuaExposedVariant> GetExposedVariables();
|
||||||
|
void UpdateVariable(const std::string& name, const LuaExposedVariant& value);
|
||||||
|
|
||||||
std::vector<LuaGlobalVariant> GetGlobalVariables();
|
|
||||||
void PrintEngineVariables();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Lua state
|
// Lua state
|
||||||
@ -72,6 +77,9 @@ private:
|
|||||||
|
|
||||||
lua_State *m_LuaState;
|
lua_State *m_LuaState;
|
||||||
|
|
||||||
|
static std::unordered_map<std::string, LuaExposedVariant> m_ExposedVariables;
|
||||||
|
|
||||||
|
|
||||||
// Last error message to prevent duplicate logging
|
// Last error message to prevent duplicate logging
|
||||||
std::string m_LastErrorMessage;
|
std::string m_LastErrorMessage;
|
||||||
void RegisterAllMetatables();
|
void RegisterAllMetatables();
|
||||||
@ -106,6 +114,9 @@ private:
|
|||||||
// Binding functions for Engine table
|
// Binding functions for Engine table
|
||||||
static int Lua_Engine_Log(lua_State *L);
|
static int Lua_Engine_Log(lua_State *L);
|
||||||
static int Lua_Engine_ScriptName(lua_State *L);
|
static int Lua_Engine_ScriptName(lua_State *L);
|
||||||
|
|
||||||
static int Lua_Engine_GetGameObjectByTag(lua_State *L);
|
static int Lua_Engine_GetGameObjectByTag(lua_State *L);
|
||||||
|
static int Lua_Engine_Expose(lua_State* L);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -558,7 +558,6 @@ void InspectorWindow::Show()
|
|||||||
// Optionally, trigger reloading the mesh if the path changes
|
// Optionally, trigger reloading the mesh if the path changes
|
||||||
// Example:
|
// Example:
|
||||||
std::shared_ptr<Model> model = g_AssetManager->loadAsset<Model>(AssetType::MODEL, mesh->MeshPath.c_str());
|
std::shared_ptr<Model> model = g_AssetManager->loadAsset<Model>(AssetType::MODEL, mesh->MeshPath.c_str());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Submeshes Information ---
|
// --- Submeshes Information ---
|
||||||
@ -636,41 +635,83 @@ void InspectorWindow::Show()
|
|||||||
|
|
||||||
if (script && g_SelectedObject)
|
if (script && g_SelectedObject)
|
||||||
{
|
{
|
||||||
// Transform* transform = &g_SelectedObject->transform;
|
|
||||||
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
bool scriptOpen = ImGui::CollapsingHeader("Script##Main", ImGuiTreeNodeFlags_DefaultOpen);
|
bool scriptOpen = ImGui::CollapsingHeader("Script##Main", ImGuiTreeNodeFlags_DefaultOpen);
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
// printf("%p\n", &transform);
|
|
||||||
if (scriptOpen)
|
if (scriptOpen)
|
||||||
{
|
{
|
||||||
// Define a maximum buffer size
|
// Define a maximum buffer size for script path
|
||||||
const size_t BUFFER_SIZE = 256;
|
const size_t BUFFER_SIZE = 256;
|
||||||
|
|
||||||
// Allocate a buffer and initialize it with the current string
|
// Allocate a buffer and initialize it with the current script path
|
||||||
char buffer[BUFFER_SIZE];
|
char buffer[BUFFER_SIZE];
|
||||||
strncpy(buffer, script->ScriptPath.c_str(), BUFFER_SIZE - 1);
|
strncpy(buffer, script->ScriptPath.c_str(), BUFFER_SIZE - 1);
|
||||||
|
|
||||||
buffer[BUFFER_SIZE - 1] = '\0'; // Ensure null-termination
|
buffer[BUFFER_SIZE - 1] = '\0'; // Ensure null-termination
|
||||||
|
|
||||||
// Render the InputText widget
|
// Render the InputText widget for editing the script path
|
||||||
if (ImGui::InputText("Script Path", buffer, BUFFER_SIZE))
|
if (ImGui::InputText("Script Path", buffer, BUFFER_SIZE))
|
||||||
{
|
{
|
||||||
|
script->ScriptPath = buffer; // Update the script path if modified
|
||||||
// Update the string if user made changes
|
|
||||||
script->ScriptPath = buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reload Script Button
|
||||||
if (ImGui::Button("Reload Script"))
|
if (ImGui::Button("Reload Script"))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (script->Initialize())
|
if (script->Initialize())
|
||||||
{
|
{
|
||||||
script->Init();
|
script->Init();
|
||||||
g_LoggerWindow->AddLog("Reloaded Script: %s", ImVec4(0.0f, 1.0f, 0.0f, 1.0f), script->ScriptPath.c_str());
|
g_LoggerWindow->AddLog("Reloaded Script: %s", ImVec4(0.0f, 1.0f, 0.0f, 1.0f), script->ScriptPath.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assuming script->GetExposedVariables() returns std::unordered_map<std::string, LuaExposedVariant>
|
||||||
|
auto exposedVariables = script->GetExposedVariables();
|
||||||
|
|
||||||
|
for (const auto &[name, value] : exposedVariables)
|
||||||
|
{
|
||||||
|
ImGui::Text("%s:", name.c_str());
|
||||||
|
|
||||||
|
if (std::holds_alternative<int>(value))
|
||||||
|
{
|
||||||
|
int intValue = std::get<int>(value);
|
||||||
|
if (ImGui::InputInt(name.c_str(), &intValue))
|
||||||
|
{
|
||||||
|
script->UpdateVariable(name, intValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (std::holds_alternative<float>(value))
|
||||||
|
{
|
||||||
|
float floatValue = std::get<float>(value);
|
||||||
|
if (ImGui::InputFloat(name.c_str(), &floatValue))
|
||||||
|
{
|
||||||
|
script->UpdateVariable(name, floatValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (std::holds_alternative<std::string>(value))
|
||||||
|
{
|
||||||
|
const std::string &strValue = std::get<std::string>(value);
|
||||||
|
char buffer[256];
|
||||||
|
strncpy(buffer, strValue.c_str(), sizeof(buffer));
|
||||||
|
buffer[sizeof(buffer) - 1] = '\0'; // Ensure null termination
|
||||||
|
if (ImGui::InputText(name.c_str(), buffer, sizeof(buffer)))
|
||||||
|
{
|
||||||
|
script->UpdateVariable(name, std::string(buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (std::holds_alternative<bool>(value))
|
||||||
|
{
|
||||||
|
bool boolValue = std::get<bool>(value);
|
||||||
|
if (ImGui::Checkbox(name.c_str(), &boolValue))
|
||||||
|
{
|
||||||
|
script->UpdateVariable(name, boolValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui::TextDisabled("Unsupported Type");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user