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

Lua Scripting Support #50

Merged
merged 39 commits into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
829cd39
Added initial lua scripting component using sol2 library
gruco0002 Feb 11, 2024
c8642b7
Added external file script support with hot reload
tippesi Feb 11, 2024
073c070
Improved scripting, added serialization for scripts
gruco0002 Feb 11, 2024
8d23146
Added exported property support for lua scripts
gruco0002 Feb 13, 2024
7b74a84
Merge branch 'major-rework' into feature/lua-scripting
tippesi Feb 18, 2024
799dcc0
Should fix the resulting merge issues
tippesi Feb 18, 2024
6e0ff49
Merge branch 'major-rework' into feature/lua-scripting
tippesi Feb 25, 2024
a8a34b1
Moved lua state into LuaScriptManager
gruco0002 Feb 25, 2024
6c44a17
Script properties are now serialized
gruco0002 Feb 25, 2024
0ba5a4a
More bindings and fixes
tippesi Feb 25, 2024
aa8eca6
Push script as well
tippesi Feb 25, 2024
b009166
More script bindings
tippesi Feb 25, 2024
a856977
Attempt to fix build issues
tippesi Feb 25, 2024
18b1998
Many bug fixes related to/uncovered by scripting
tippesi Feb 26, 2024
375ce08
Fixed a bunch of issues + no more autosave
tippesi Feb 27, 2024
e1ff73a
Many adjustments
tippesi Feb 28, 2024
bc6e612
Update thirdparty license file
tippesi Feb 28, 2024
83277c7
Smaller fixes
tippesi Feb 28, 2024
d770d93
Smaller adjustments
tippesi Feb 29, 2024
a4f18f3
Update build.yml
tippesi Mar 5, 2024
c6a0a62
Some improvements
tippesi Mar 5, 2024
9fd3871
Merge branch 'feature/lua-scripting' of https://github.com/tippesi/At…
tippesi Mar 5, 2024
ba62ada
Fixed the import of a scene from mesh
tippesi Mar 6, 2024
eb2d8b7
Improved CPU performance for scenes with many meshes
tippesi Mar 6, 2024
3fcc7dd
More performance improvements
tippesi Mar 6, 2024
8cc88a9
Graphics queue submission can now be done async
tippesi Mar 7, 2024
e62e6fa
Merge branch 'major-rework' into feature/lua-scripting
tippesi Mar 7, 2024
0db1bd0
Fixed the pipeline again + more improvements
tippesi Mar 8, 2024
5f75b5e
Fixed many issues
tippesi Mar 9, 2024
8e776e2
Keyboard bindings for lua
tippesi Mar 9, 2024
613c2a1
Fix code smells and scene
tippesi Mar 9, 2024
b3673f8
More changes and an ongoing investigation into Vulkan queues
tippesi Mar 10, 2024
0c8c414
Fixed some synchronization/threading issues
tippesi Mar 11, 2024
51ba3b9
Even more fixes
tippesi Mar 11, 2024
76a780b
Many fixes and improvements
tippesi Mar 15, 2024
710bae7
Trying to find out why artifacts won't run
tippesi Mar 17, 2024
2ef1a74
Fix build pipeline issue
tippesi Mar 20, 2024
4b448de
Final updates
tippesi Mar 23, 2024
c2566ea
More fixes
tippesi Mar 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ find_package(glslang CONFIG REQUIRED)
find_package(SPIRV-Tools-opt CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
find_package(unofficial-joltphysics CONFIG REQUIRED)
find_package(Lua REQUIRED)
find_package(sol2 CONFIG REQUIRED)

if (ATLAS_TESTS)
find_package(GTest CONFIG REQUIRED)
Expand Down
8 changes: 8 additions & 0 deletions src/editor/FileImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "mesh/Mesh.h"
#include "scene/Scene.h"
#include "audio/AudioData.h"
#include "scripting/Script.h"

#include "loader/ModelLoader.h"
#include "scene/SceneSerializer.h"
Expand Down Expand Up @@ -49,6 +50,12 @@ namespace Atlas::Editor {
ResourceOrigin::User, Scene::SceneSerializer::DeserializeScene);
}
break;
case FileType::Script: {
auto handle = ResourceManager<Scripting::Script>::GetOrLoadResourceAsync(
filename, ResourceOrigin::User);
handle.GetResource()->permanent = true;
}
break;
default:
break;
}
Expand All @@ -63,6 +70,7 @@ namespace Atlas::Editor {
{ "fbx", FileType::Mesh },
{ "aeterrain", FileType::Terrain },
{ "aescene", FileType::Scene },
{ "lua", FileType::Script },
};

}
3 changes: 2 additions & 1 deletion src/editor/FileImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ namespace Atlas::Editor {
Audio = 0,
Mesh,
Terrain,
Scene
Scene,
Script
};

static const std::map<const std::string, FileType> fileTypeMapping;
Expand Down
7 changes: 7 additions & 0 deletions src/editor/ui/panels/EntityPropertiesPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ namespace Atlas::Editor::UI {
entity.RemoveComponent<AudioVolumeComponent>();
entity.AddComponent<AudioVolumeComponent>(comp);
}

if(entity.HasComponent<LuaScriptComponent>()){
RenderComponentPanel("Lua script component", entity, luaScriptComponentPanel,
entity.GetComponent<LuaScriptComponent>());
}
}

// Add components
Expand All @@ -56,6 +61,8 @@ namespace Atlas::Editor::UI {
entity.AddComponent<MeshComponent>();
if (!entity.HasComponent<AudioVolumeComponent>() && ImGui::MenuItem("Add audio volume component"))
entity.AddComponent<AudioVolumeComponent>();
if (!entity.HasComponent<LuaScriptComponent>() && ImGui::MenuItem("Add lua script component"))
entity.AddComponent<LuaScriptComponent>();

ImGui::EndPopup();
}
Expand Down
2 changes: 2 additions & 0 deletions src/editor/ui/panels/EntityPropertiesPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "components/MeshComponentPanel.h"
#include "components/LightComponentPanel.h"
#include "components/AudioVolumeComponentPanel.h"
#include "components/LuaScriptComponentPanel.h"

#include <imgui.h>

Expand All @@ -26,6 +27,7 @@ namespace Atlas::Editor::UI {
MeshComponentPanel meshComponentPanel;
LightComponentPanel lightComponentPanel;
AudioVolumeComponentPanel audioVolumeComponentPanel;
LuaScriptComponentPanel luaScriptComponentPanel;

template<class S, class T>
bool RenderComponentPanel(const std::string& name,
Expand Down
56 changes: 56 additions & 0 deletions src/editor/ui/panels/components/LuaScriptComponentPanel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "LuaScriptComponentPanel.h"
#include "resource/ResourceManager.h"

#include "imgui_stdlib.h"

namespace Atlas::Editor::UI
{
bool LuaScriptComponentPanel::Render(Scene::Entity entity, LuaScriptComponent &luaScriptComponent)
{
auto buttonName = luaScriptComponent.script.IsValid() ? luaScriptComponent.script.GetResource()->GetFileName() : "Drop script resource here";
ImGui::Button(buttonName.c_str(), {-FLT_MIN, 0});

if (ImGui::BeginDragDropTarget())
{
if (auto dropPayload = ImGui::AcceptDragDropPayload(typeid(Scripting::Script).name()))
{
Resource<Scripting::Script> *resource;
std::memcpy(&resource, dropPayload->Data, dropPayload->DataSize);
// We know this mesh is loaded, so we can just request a handle without loading
luaScriptComponent.script = ResourceManager<Scripting::Script>::GetResource(resource->path);
// Usually we need to also keep track of resource in the scene, ignore for now
// resourceChanged = true;
}

ImGui::EndDragDropTarget();
}

if (!luaScriptComponent.script.IsLoaded())
return false;

ImGui::InputTextMultiline("Code", &luaScriptComponent.script->code, ImVec2(0, 0), ImGuiInputTextFlags_ReadOnly);

ImGui::Separator();
ImGui::Text("Script defined properties:");
for (auto &property : luaScriptComponent.properties)
{
switch (property.type)
{
case LuaScriptComponent::PropertyType::Boolean:
ImGui::Checkbox(property.name.c_str(), &property.booleanValue);
break;
case LuaScriptComponent::PropertyType::Integer:
ImGui::InputInt(property.name.c_str(), &property.integerValue);
break;
case LuaScriptComponent::PropertyType::Double:
ImGui::InputDouble(property.name.c_str(), &property.doubleValue);
break;
case LuaScriptComponent::PropertyType::String:
ImGui::InputText(property.name.c_str(), &property.stringValue);
break;
}
}

return false;
}
}
19 changes: 19 additions & 0 deletions src/editor/ui/panels/components/LuaScriptComponentPanel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include "../Panel.h"

#include "scene/components/LuaScriptComponent.h"

namespace Atlas::Editor::UI
{

class LuaScriptComponentPanel : public Panel
{

public:
LuaScriptComponentPanel() : Panel("Lua script component") {}

bool Render(Scene::Entity entity, LuaScriptComponent &luaScriptComponent);
};

}
5 changes: 4 additions & 1 deletion src/editor/ui/windows/ContentBrowserWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ namespace Atlas::Editor::UI {
ImGui::End();

ImGui::Begin("ResourceTypeSelection", nullptr);
const char *items[] = {"Audio", "Mesh", "Terrain", "Scene"};
const char *items[] = {"Audio", "Mesh", "Terrain", "Scene", "Script"};
static int currentSelection = 0;
ImGui::BeginListBox("##Listbox", ImVec2(-FLT_MIN, 9 * ImGui::GetTextLineHeightWithSpacing()));
for (int i = 0; i < IM_ARRAYSIZE(items); i++) {
Expand All @@ -73,6 +73,9 @@ namespace Atlas::Editor::UI {
break;
case 3:
RenderResourceType<Scene::Scene>(IconType::Scene);
break;
case 4:
RenderResourceType<Scripting::Script>(IconType::Document);
default:
break;
}
Expand Down
4 changes: 2 additions & 2 deletions src/editor/ui/windows/SceneWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ namespace Atlas::Editor::UI {
auto offset = region.x / 2.0f - buttonSize.x - 8.0f;
ImGui::SetCursorPos(ImVec2(offset, 0.0f));
if (ImGui::ImageButton(set, buttonSize, uvMin, uvMax)) {

scene->physicsWorld->pauseSimulation = false;
}

auto& stopIcon = Singletons::icons->Get(IconType::Stop);
Expand All @@ -153,7 +153,7 @@ namespace Atlas::Editor::UI {
offset = region.x / 2.0f + 8.0f;
ImGui::SetCursorPos(ImVec2(offset, 0.0f));
if (ImGui::ImageButton(set, buttonSize, uvMin, uvMax)) {

scene->physicsWorld->pauseSimulation = true;
}

ImGui::PopStyleColor();
Expand Down
11 changes: 7 additions & 4 deletions src/engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ if(WIN32)

set(ATLAS_ENGINE_LIBS assimp::assimp SDL2::SDL2 SDL2::SDL2main SPIRV-Tools-opt
volk::volk volk::volk_headers GPUOpen::VulkanMemoryAllocator
unofficial::spirv-reflect::spirv-reflect glslang::SPIRV unofficial::joltphysics::Jolt)
unofficial::spirv-reflect::spirv-reflect glslang::SPIRV unofficial::joltphysics::Jolt
${LUA_LIBRARIES} sol2)
endif()

if (MINGW)
Expand All @@ -56,13 +57,14 @@ if(APPLE)
set(ATLAS_ENGINE_LIBS assimp::assimp SDL2::SDL2 SDL2::SDL2main SDL2::SDL2-static
volk::volk SPIRV-Tools-opt unofficial::joltphysics::Jolt
GPUOpen::VulkanMemoryAllocator Vulkan::Vulkan Vulkan::Headers
unofficial::spirv-reflect::spirv-reflect glslang::SPIRV)
unofficial::spirv-reflect::spirv-reflect glslang::SPIRV ${LUA_LIBRARIES} sol2)
endif()

if(ANDROID)
set(ATLAS_ENGINE_COMPILE_DEFINITIONS ${ATLAS_ENGINE_COMPILE_DEFINITIONS} AE_OS_ANDROID)

set(ATLAS_ENGINE_LIBS assimp::assimp SDL2::SDL2 SDL2::SDL2main SDL2::SDL2-static hidapi)
set(ATLAS_ENGINE_LIBS assimp::assimp SDL2::SDL2 SDL2::SDL2main SDL2::SDL2-static hidapi
${LUA_LIBRARIES} sol2)
set(ATLAS_ENGINE_SYSTEM_LIBS android m)
endif()

Expand All @@ -79,7 +81,7 @@ if(UNIX AND NOT APPLE AND NOT ANDROID)

set(ATLAS_ENGINE_LIBS assimp::assimp SDL2::SDL2 SDL2::SDL2main SDL2::SDL2-static
volk::volk volk::volk_headers GPUOpen::VulkanMemoryAllocator unofficial::joltphysics::Jolt
unofficial::spirv-reflect::spirv-reflect SPIRV-Tools-opt glslang::SPIRV)
unofficial::spirv-reflect::spirv-reflect SPIRV-Tools-opt glslang::SPIRV ${LUA_LIBRARIES} sol2)
endif()

# Add source files ################################################################################
Expand Down Expand Up @@ -151,6 +153,7 @@ target_include_directories(${PROJECT_NAME}
${VULKAN_HEADERS_INCLUDE_DIRS}
${STB_INCLUDE_DIRS}
${GLM_INCLUDE_DIRS}
${LUA_INCLUDE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../../libs)

Expand Down
18 changes: 18 additions & 0 deletions src/engine/resource/Resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "ResourceLoadException.h"
#include "../common/Hash.h"
#include "../common/Path.h"
#include "../loader/AssetLoader.h"

#include <vector>
#include <mutex>
Expand Down Expand Up @@ -86,6 +87,21 @@ namespace Atlas {

}

bool WasModified() const {

std::filesystem::file_time_type lastModified = std::filesystem::file_time_type::min();
lastModified = Loader::AssetLoader::GetFileLastModifiedTime(path, lastModified);

return loadModifiedTime < lastModified;

}

void UpdateModifiedTime() {

loadModifiedTime = Loader::AssetLoader::GetFileLastModifiedTime(path, loadModifiedTime);

}

void Unload() {
isLoaded = false;
errorOnLoad = false;
Expand All @@ -108,6 +124,8 @@ namespace Atlas {
bool errorOnLoad = false;
std::exception exceptionOnLoad;

std::filesystem::file_time_type loadModifiedTime;

private:
Ref<T> data;

Expand Down
7 changes: 7 additions & 0 deletions src/engine/scene/EntitySerializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ namespace Atlas::Scene {
j["entities"] = entities;
j["root"] = hierarchyComponent.root;
}
if (p.HasComponent<LuaScriptComponent>()) {
j["luaScript"] = p.GetComponent<LuaScriptComponent>();
}
}

void EntityFromJson(const json& j, Entity& p, Ref<Scene>& scene) {
Expand Down Expand Up @@ -106,6 +109,10 @@ namespace Atlas::Scene {
comp.AddChild(entity);
}
}
if(j.contains("luaScript")){
LuaScriptComponent comp = j["luaScript"];
p.AddComponent<LuaScriptComponent>(comp);
}
}

}
7 changes: 7 additions & 0 deletions src/engine/scene/Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ namespace Atlas {
// Do cleanup first such that we work with valid data
CleanupUnusedResources();

// Update scripting components
auto luaScriptComponentSubset = entityManager.GetSubset<LuaScriptComponent>();
for(auto entity : luaScriptComponentSubset){
auto& luaScriptComponent = luaScriptComponentSubset.Get<LuaScriptComponent>(entity);
luaScriptComponent.Update(deltaTime);
}

TransformComponent rootTransform = {};

auto hierarchyTransformSubset = entityManager.GetSubset<HierarchyComponent, TransformComponent>();
Expand Down
1 change: 1 addition & 0 deletions src/engine/scene/SceneSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ namespace Atlas {
if (j.contains("physicsWorld")) {
scene->physicsWorld = CreateRef<Physics::PhysicsWorld>();
*scene->physicsWorld = j["physicsWorld"];
scene->physicsWorld->pauseSimulation = true;
}

scene->rayTracingWorld = CreateRef<RayTracing::RayTracingWorld>();
Expand Down
19 changes: 19 additions & 0 deletions src/engine/scene/components/ComponentSerializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,5 +193,24 @@ namespace Atlas::Scene::Components {
j.at("matrix").get_to(p.matrix);
j.at("isStatic").get_to(p.isStatic);
}

void to_json(json& j, const LuaScriptComponent& p) {
j = json {};

if (p.script.IsValid())
j["resourcePath"] = p.script.GetResource()->path;
}

void from_json(const json& j, LuaScriptComponent& p) {

if (j.contains("resourcePath")) {
std::string resourcePath;
j.at("resourcePath").get_to(resourcePath);

p.script = ResourceManager<Scripting::Script>::GetOrLoadResourceAsync(
resourcePath, ResourceOrigin::User);
}

}

}
3 changes: 2 additions & 1 deletion src/engine/scene/components/Components.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
#include "NameComponent.h"
#include "TransformComponent.h"
#include "ObjectComponent.h"
#include "RigidBodyComponent.h"
#include "RigidBodyComponent.h"
#include "LuaScriptComponent.h"
Loading
Loading