diff --git a/Externals/CMakeLists.txt b/Externals/CMakeLists.txt index 39c80c3..2365b3f 100644 --- a/Externals/CMakeLists.txt +++ b/Externals/CMakeLists.txt @@ -13,7 +13,7 @@ set(${PROJECT_NAME}_SOURCES imgui/backends/imgui_impl_glfw.cpp imgui/backends/imgui_impl_opengl3.cpp - ) +) add_library(${PROJECT_NAME} STATIC ${${PROJECT_NAME}_SOURCES}) include_directories(${PROJECT_NAME} ./glfw/include) @@ -22,7 +22,27 @@ target_include_directories(${PROJECT_NAME} PUBLIC ./imgui/ ./imgui/backends/) project(Nanovg) set(${PROJECT_NAME}_SOURCES nanovg/src/nanovg.c - ) +) add_library(${PROJECT_NAME} STATIC ${${PROJECT_NAME}_SOURCES}) target_include_directories(${PROJECT_NAME} PUBLIC ./nanovg/src/ ./nanovg/obsolete/) + +project(Lua) + +# Add the Lua source files +#file(GLOB ${PROJECT_NAME}_SOURCES "./lua/luaone.c") +# list(FILTER ${PROJECT_NAME}_SOURCES EXCLUDE REGEX "./lua/lua.c$") + +# Create the Lua library +add_library(${PROJECT_NAME} STATIC "lua/onelua.c") + +target_compile_definitions(${PROJECT_NAME} PUBLIC MAKE_LIB) + +# Include directories for Lua headers +target_include_directories(${PROJECT_NAME} PUBLIC "./lua") + +# Set compilation options, e.g., for compilation with C99 +set_target_properties(${PROJECT_NAME} PROPERTIES + C_STANDARD 99 + C_STANDARD_REQUIRED ON +) \ No newline at end of file diff --git a/Externals/lua b/Externals/lua new file mode 160000 index 0000000..6baee9e --- /dev/null +++ b/Externals/lua @@ -0,0 +1 @@ +Subproject commit 6baee9ef9d5657ab582c8a4b9f885ec58ed502d0 diff --git a/RayTracer/CMakeLists.txt b/RayTracer/CMakeLists.txt index 89bf676..c4a75b0 100644 --- a/RayTracer/CMakeLists.txt +++ b/RayTracer/CMakeLists.txt @@ -15,15 +15,16 @@ target_include_directories(${PROJECT_NAME} PUBLIC ./public/) target_link_libraries(${PROJECT_NAME} PUBLIC Math CommandLine Connection) ### -------------------------- Applications -------------------------- ### -add_executable(rayt ./applications/Rayt.cpp ) +add_executable(rayt ./applications/Rayt.cpp applications/SceneLoad.cpp + applications/Rayt.hpp) -target_link_libraries(rayt ${PROJECT_NAME}) +target_link_libraries(rayt ${PROJECT_NAME} Lua) ### -------------------------- Tests -------------------------- ### enable_testing() file(GLOB TEST_SOURCES "./tests/*.cpp" "./tests/*/*.cpp") add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES}) -target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils) +target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils) add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests) install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/lib) diff --git a/RayTracer/applications/Rayt.cpp b/RayTracer/applications/Rayt.cpp index 59088bb..4cfee71 100644 --- a/RayTracer/applications/Rayt.cpp +++ b/RayTracer/applications/Rayt.cpp @@ -1,47 +1,16 @@ // #include "NewPlacement.hpp" -#include "Buffer.hpp" -#include "CommandLine.hpp" -#include "RayTracer.hpp" -#include "Strings.hpp" -#include "Timing.hpp" -#include "Vec.hpp" +#include "Rayt.hpp" -#include "OBJ_Loader.h" +#include "CommandLine.hpp" +#include "Timing.hpp" #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" using namespace tp; -void loadScene(Scene& scene, const String& scenePath) { - objl::Loader Loader; - - if (!Loader.LoadFile(scenePath.read())) { - std::cout << "Failed to Load File. May have failed to find it or it was not an .obj file.\n"; - return; - } - - for (auto& curMesh : Loader.LoadedMeshes) { - scene.mObjects.append(Topology()); - auto object = &scene.mObjects.last(); - - for (int j = 0; j < curMesh.Indices.size(); j += 3) { - unsigned int idx1 = curMesh.Indices[j]; - unsigned int idx2 = curMesh.Indices[j + 1]; - unsigned int idx3 = curMesh.Indices[j + 2]; - - Vec3F v1 = {curMesh.Vertices[idx1].Position.X, curMesh.Vertices[idx1].Position.Y, curMesh.Vertices[idx1].Position.Z}; - Vec3F v2 = {curMesh.Vertices[idx2].Position.X, curMesh.Vertices[idx2].Position.Y, curMesh.Vertices[idx2].Position.Z}; - Vec3F v3 = {curMesh.Vertices[idx3].Position.X, curMesh.Vertices[idx3].Position.Y, curMesh.Vertices[idx3].Position.Z}; - - object->addTrig(v1, v2, v3); - } - object->updateTransformed(); - } -} - void writeImage(const RayTracer::RenderBuffer& output) { // Save the data to a PNG file struct urgb { @@ -62,24 +31,21 @@ void writeImage(const RayTracer::RenderBuffer& output) { if (stbi_write_png("output.png", converted.size().x, converted.size().y, 4, converted.getBuff(), converted.size().x * 4) != 0) { // Image saved successfully - std::cout << "Image saved successfully." << std::endl; + printf("Image saved successfully.\n"); } else { - std::cerr << "Error saving the image." << std::endl; + printf("Error saving the image.\n"); } } -void renderCommand(const String& scenePath, RayTracer::RenderBuffer::Index2D size) { +void renderCommand(const String& scenePath) { Scene scene; - loadScene(scene, scenePath); + RayTracer::RenderSettings settings; - scene.mCamera.lookAtPoint({0, 0, 0}, {-3, -3, 3}, {1, 1, 1}); - scene.mCamera.setFOV(3.14 / 4); - scene.mCamera.setFar(100); - scene.mCamera.setRatio((halnf) size.y / (halnf) size.x); + loadScene(scene, scenePath, settings); RayTracer::RenderBuffer output; - output.reserve(size); + output.reserve(RayTracer::RenderBuffer::Index2D(settings.size.x, settings.size.y)); RayTracer rayt; @@ -99,7 +65,7 @@ int main(int argc, const char** argv) { tp::ModuleManifest module("Rayt", nullptr, nullptr, deps); if (module.initialize()) { - renderCommand("scene.obj", {600, 600}); + renderCommand("scene.lua"); module.deinitialize(); } diff --git a/RayTracer/applications/Rayt.hpp b/RayTracer/applications/Rayt.hpp new file mode 100644 index 0000000..b5202b7 --- /dev/null +++ b/RayTracer/applications/Rayt.hpp @@ -0,0 +1,6 @@ +#pragma once + +#include "RayTracer.hpp" +#include "Strings.hpp" + +void loadScene(tp::Scene& scene, const tp::String& scenePath, tp::RayTracer::RenderSettings& settings); diff --git a/RayTracer/applications/SceneLoad.cpp b/RayTracer/applications/SceneLoad.cpp new file mode 100644 index 0000000..d88b2c7 --- /dev/null +++ b/RayTracer/applications/SceneLoad.cpp @@ -0,0 +1,151 @@ + +#include "Rayt.hpp" + +extern "C" { +#include "lauxlib.h" +#include "lualib.h" +} + +#include "OBJ_Loader.h" + +bool loadMeshes(tp::Scene& scene, const tp::String& objetsPath) { + using namespace tp; + + objl::Loader Loader; + + if (!Loader.LoadFile(objetsPath.read())) { + std::cout << "Failed to Load File. May have failed to find it or it was not an .obj file.\n"; + return false; + } + + for (auto& curMesh : Loader.LoadedMeshes) { + scene.mObjects.append(Topology()); + auto object = &scene.mObjects.last(); + + for (int j = 0; j < curMesh.Indices.size(); j += 3) { + unsigned int idx1 = curMesh.Indices[j]; + unsigned int idx2 = curMesh.Indices[j + 1]; + unsigned int idx3 = curMesh.Indices[j + 2]; + + Vec3F v1 = {curMesh.Vertices[idx1].Position.X, curMesh.Vertices[idx1].Position.Y, curMesh.Vertices[idx1].Position.Z}; + Vec3F v2 = {curMesh.Vertices[idx2].Position.X, curMesh.Vertices[idx2].Position.Y, curMesh.Vertices[idx2].Position.Z}; + Vec3F v3 = {curMesh.Vertices[idx3].Position.X, curMesh.Vertices[idx3].Position.Y, curMesh.Vertices[idx3].Position.Z}; + + object->addTrig(v1, v2, v3); + } + object->updateTransformed(); + } + + return scene.mObjects.size(); +} + +bool getVector(lua_State* L, const char* name, tp::Vec3F& out, const char* parent) { + lua_getglobal(L, name); + + if (lua_istable(L, -1)) { + lua_pushstring(L, "x"); + lua_gettable(L, -2); + + if (lua_isnumber(L, -1)) { + out.x = lua_tonumber(L, -1); + } else { + printf("Component of vector '%s' is not found in %s\n\n", name, parent); + return false; + } + + lua_pop(L, 1); + + } else { + printf("Vector '%s' is not found in %s\n\n", name, parent); + return false; + } +} + +void loadScene(tp::Scene& scene, const tp::String& scenePath, tp::RayTracer::RenderSettings& settings) { + lua_State* L = luaL_newstate(); + luaL_openlibs(L); + + if (luaL_dofile(L, "script.lua") != 0) { + lua_close(L); + printf("Cant open scene script.\n"); + return; + } + + lua_getglobal(L, "Meshes"); + + if (lua_isstring(L, -1)) { + tp::String meshesPath = lua_tostring(L, -1); + + if (!loadMeshes(scene, meshesPath)) { + printf("No 'meshes' loaded - check ur .obj path and validate content of .obj .\n"); + return; + } + + } else { + printf("No 'meshes' path given.\n"); + return; + } + + // --- camera + + // Access Camera table + lua_getglobal(L, "Camera"); + if (!lua_istable(L, -1)) { + printf("Camera is not a table.\n"); + lua_close(L); + return; + } + + // Verify you are inside the "Camera" table + int cameraTableIndex = lua_gettop(L); // Get the index of the "Camera" table + + // Access the "pos" field and validate it + lua_getfield(L, cameraTableIndex, "pos"); + if (!lua_istable(L, -1) || lua_rawlen(L, -1) != 3) { + printf("Invalid 'pos' field in Camera table.\n"); + lua_close(L); + return; + } + + // Read the values from the table + float pos[3]; + for (int i = 0; i < 3; i++) { + lua_rawgeti(L, -1, i + 1); + if (lua_isnumber(L, -1)) { + pos[i] = lua_tonumber(L, -1); + } else { + printf("Invalid 'pos' field value at index %d.\n", i + 1); + lua_close(L); + return; + } + lua_pop(L, 1); + } + + // Access the "size_x" field and validate it + lua_getfield(L, cameraTableIndex, "size_x"); + if (!lua_isnumber(L, -1)) { + printf("Invalid or missing 'size_x' field in Camera table.\n"); + lua_close(L); + return; + } + int size_x = lua_tointeger(L, -1); + lua_pop(L, 1); // Pop the 'size_x' value from the stack + + // Access the "size_y" field and validate it + lua_getfield(L, cameraTableIndex, "size_y"); + if (!lua_isnumber(L, -1)) { + printf("Invalid or missing 'size_y' field in Camera table.\n"); + lua_close(L); + return; + } + int size_y = lua_tointeger(L, -1); + + settings.size = {(tp::halnf) size_x, (tp::halnf) size_y}; + + scene.mCamera.lookAtPoint({0, 0, 0}, {pos[0], pos[1], pos[2]}, {0, 0, 1}); + scene.mCamera.setFOV(3.14 / 4); + scene.mCamera.setFar(100); + scene.mCamera.setRatio((tp::halnf) size_x / (tp::halnf) size_y); + + lua_close(L); +} diff --git a/RayTracer/applications/rsc/normals.blend b/RayTracer/applications/rsc/normals.blend new file mode 100644 index 0000000..156e59b Binary files /dev/null and b/RayTracer/applications/rsc/normals.blend differ diff --git a/RayTracer/applications/rsc/scene.blend b/RayTracer/applications/rsc/scene.blend new file mode 100644 index 0000000..29deadc Binary files /dev/null and b/RayTracer/applications/rsc/scene.blend differ diff --git a/RayTracer/public/RayTracer.hpp b/RayTracer/public/RayTracer.hpp index 83327ff..6c5bbb1 100644 --- a/RayTracer/public/RayTracer.hpp +++ b/RayTracer/public/RayTracer.hpp @@ -31,6 +31,7 @@ namespace tp { struct RenderSettings { alni samplesiPerPixel = 1; alni rayBounces = 1; + Vec2I size; }; public: