diff --git a/3DEditor/CMakeLists.txt b/3DEditor/CMakeLists.txt index 1a410b4..4e22009 100644 --- a/3DEditor/CMakeLists.txt +++ b/3DEditor/CMakeLists.txt @@ -19,6 +19,5 @@ file(GLOB APP_SOURCES "./applications/*.cpp") add_executable(3DEditorApp ${APP_SOURCES}) target_link_libraries(3DEditorApp ${PROJECT_NAME}) -file(COPY "../RasterRender/rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") -file(COPY "../Graphics/rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") -file(COPY "../3DScene/rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") +file(COPY "rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") +file(COPY "rsc/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") diff --git a/3DEditor/private/Denoise.cpp b/3DEditor/private/Denoise.cpp index a20672a..7c4955a 100644 --- a/3DEditor/private/Denoise.cpp +++ b/3DEditor/private/Denoise.cpp @@ -37,4 +37,4 @@ void Editor::denoise() { if (device.getError(errorMessage) != oidn::Error::None) { std::cerr << "Error: " << errorMessage << std::endl; } -} +} \ No newline at end of file diff --git a/3DEditor/private/Editor.cpp b/3DEditor/private/Editor.cpp index 9641bf8..59facdf 100644 --- a/3DEditor/private/Editor.cpp +++ b/3DEditor/private/Editor.cpp @@ -24,10 +24,7 @@ Editor::Editor() { void Editor::renderViewport() { switch (mRenderType) { case RenderType::RASTER: - mRasterRenderer.beginRender(mScene, mScene.mRenderSettings.size); - mRasterRenderer.renderDefault(mScene); - if (mActive) mRasterRenderer.renderOutline(mScene.mCamera, *mActive); - mRasterRenderer.endRender(); + mRasterRenderer.render(mScene, mScene.mRenderSettings.size); break; case RenderType::PATH_TRACER: @@ -57,7 +54,6 @@ uint4 Editor::getViewportTexID() { void Editor::loadDefaults() { mScene.load("rsc/scene/script.lua"); - mResetCamera = mScene.mCamera; } void Editor::setViewportSize(const Vec2F& size) { @@ -77,7 +73,6 @@ Editor::~Editor() { } void Editor::renderPathFrame() { - mScene.updateCache(); mPathRenderer.render(mScene, mPathTracerBuffers, mScene.mRenderSettings); sendBuffersToGPU(); } @@ -121,20 +116,5 @@ void Editor::navigationZoom(halnf factor) { } void Editor::navigationReset() { - mScene.mCamera = mResetCamera; - // mScene.mCamera.lookAtPoint({ 0, 0, 0 }, { 1, 5, 1 }, { 0, 0, 1 }); -} - -void Editor::selectObject(const Vec2F& screenPos) { - mScene.updateCache(); - - auto dir = (mScene.mCamera.project(screenPos) - mScene.mCamera.getPos()).normalize(); - Ray ray = Ray( dir, mScene.mCamera.getPos() ); - - auto rayCastData = mScene.castRay(ray, 1000); - mActive = rayCastData.obj; -} - -Object* Editor::getActiveObject() { return mActive; } - -Scene* Editor::getScene() { return &mScene; } \ No newline at end of file + mScene.mCamera.lookAtPoint({ 0, 0, 0 }, { 1, 5, 1 }, { 0, 0, 1 }); +} \ No newline at end of file diff --git a/3DEditor/public/Editor.hpp b/3DEditor/public/Editor.hpp index a4c3b0f..ee16122 100644 --- a/3DEditor/public/Editor.hpp +++ b/3DEditor/public/Editor.hpp @@ -28,10 +28,6 @@ namespace tp { void navigationZoom(halnf factor); void navigationReset(); - void selectObject(const Vec2F& screenPos); - Object* getActiveObject(); - - Scene* getScene(); private: void sendBuffersToGPU(); @@ -40,8 +36,6 @@ namespace tp { private: Scene mScene; - Camera mResetCamera; - RenderType mRenderType = RenderType::RASTER; RasterRender mRasterRenderer; @@ -49,7 +43,5 @@ namespace tp { RayTracer::OutputBuffers mPathTracerBuffers; uint4 mPathRenderTexture = 0; - - Object* mActive = nullptr; }; } \ No newline at end of file diff --git a/3DEditor/public/EditorWidget.hpp b/3DEditor/public/EditorWidget.hpp index 7b4e748..0914937 100644 --- a/3DEditor/public/EditorWidget.hpp +++ b/3DEditor/public/EditorWidget.hpp @@ -66,13 +66,11 @@ namespace tp { mNavigationOrbit.setText("Orbit"); mNavigationZoom.setText("Zoom"); mNavigationReset.setText("Reset"); - mNavigationSelect.setText("Select"); mNavigationMenu.addToMenu(&mNavigationPan); mNavigationMenu.addToMenu(&mNavigationOrbit); mNavigationMenu.addToMenu(&mNavigationZoom); mNavigationMenu.addToMenu(&mNavigationReset); - mNavigationMenu.addToMenu(&mNavigationSelect); mNavigationMenu.setText("Navigation"); } @@ -87,25 +85,16 @@ namespace tp { mNavigationOrbit.setAction( [this]() { mNavigationType = ORBIT; }); mNavigationPan.setAction( [this]() { mNavigationType = PAN; }); mNavigationZoom.setAction( [this](){ mNavigationType = ZOOM; }); - mNavigationSelect.setAction( [this](){ mNavigationType = SELECT; }); mNavigationReset.setAction( [this]() { mEditor->navigationReset(); }); } void process(const EventHandler& events) override { DockWidget::process(events); - if (auto obj = mEditor->getActiveObject()) { // dummy rotate active object - auto rotator = obj->mTopology.Basis.rotatorDir({1, 1, 1}, 0.1); - obj->mTopology.Basis = rotator * obj->mTopology.Basis; - } - - mEditor->getScene()->updateCache(); - - const auto& activeArea = mViewport.getArea(); - auto pointer = events.getPointer(); auto pointerPrev = events.getPointerPrev(); - auto pointerRelative = (((pointer - activeArea.pos) / activeArea.size) - 0.5f) * 2; + + const auto& activeArea = mViewport.getArea(); if (activeArea.isInside(pointer) && events.isDown(InputID::MOUSE1)) { switch (mNavigationType) { @@ -113,13 +102,13 @@ namespace tp { case PAN: { + auto pointerRelative = (((pointer - activeArea.pos) / activeArea.size) - 0.5f) * 2; auto prevPointerRelative = (((pointerPrev - activeArea.pos) / activeArea.size) - 0.5f) * 2; mEditor->navigationPan(prevPointerRelative, pointerRelative); } break; case ZOOM: mEditor->navigationZoom(1 + (events.getPointerDelta().y / activeArea.size.y)); break; - case SELECT: mEditor->selectObject(pointerRelative * -1); break; } } } @@ -140,14 +129,13 @@ namespace tp { ButtonWidget mRenderDeNoise; // Navigation - enum NavigationType { SELECT, ORBIT, PAN, ZOOM } mNavigationType = ORBIT; + enum NavigationType { ORBIT, PAN, ZOOM } mNavigationType = ORBIT; FloatingMenu mNavigationMenu; ButtonWidget mNavigationPan; ButtonWidget mNavigationOrbit; ButtonWidget mNavigationZoom; ButtonWidget mNavigationReset; - ButtonWidget mNavigationSelect; RGBA mBaseColor; }; diff --git a/Graphics/rsc/Font.ttf b/3DEditor/rsc/Font.ttf similarity index 100% rename from Graphics/rsc/Font.ttf rename to 3DEditor/rsc/Font.ttf diff --git a/3DScene/rsc/scene/meshes.mtl b/3DEditor/rsc/scene/meshes.mtl similarity index 100% rename from 3DScene/rsc/scene/meshes.mtl rename to 3DEditor/rsc/scene/meshes.mtl diff --git a/3DScene/rsc/scene/meshes.obj b/3DEditor/rsc/scene/meshes.obj similarity index 100% rename from 3DScene/rsc/scene/meshes.obj rename to 3DEditor/rsc/scene/meshes.obj diff --git a/3DScene/rsc/scene/script.lua b/3DEditor/rsc/scene/script.lua similarity index 75% rename from 3DScene/rsc/scene/script.lua rename to 3DEditor/rsc/scene/script.lua index 42ea4c7..ef6d484 100644 --- a/3DScene/rsc/scene/script.lua +++ b/3DEditor/rsc/scene/script.lua @@ -2,10 +2,9 @@ Meshes = "meshes.obj" Camera = { - pos = { 0, 5, 0 }, - target = { 0, 0, 0 }, - up = { 0, 0, 1 }, - size = { 600, 800 }, + pos = { 0.5, 4.5, 0.2 }, + size_x = 600, + size_y = 800, } Lights = { diff --git a/RasterRender/rsc/shaders/default.frag b/3DEditor/rsc/shaders/default.frag similarity index 100% rename from RasterRender/rsc/shaders/default.frag rename to 3DEditor/rsc/shaders/default.frag diff --git a/3DEditor/rsc/shaders/default.vert b/3DEditor/rsc/shaders/default.vert new file mode 100644 index 0000000..7d1fd94 --- /dev/null +++ b/3DEditor/rsc/shaders/default.vert @@ -0,0 +1,11 @@ +#version 330 core + +layout(location = 0) in vec3 Point; + +uniform vec4 Origin; +uniform mat4 Basis; +uniform mat4 Camera; + +void main() { + gl_Position = Camera * vec4(Point.xyz, 1.0); +} \ No newline at end of file diff --git a/3DScene/private/LuaFormat.cpp b/3DScene/private/LuaFormat.cpp index acf4c9a..3d61aad 100644 --- a/3DScene/private/LuaFormat.cpp +++ b/3DScene/private/LuaFormat.cpp @@ -7,61 +7,6 @@ extern "C" { } #include -#include - -tp::Vec3F tp::Scene::getVec3(lua_State* state, const char* name) { - int stackSize = lua_gettop(state); - - // Access the "pos" field and validate it - lua_getfield(state, -1, name); - if (!lua_istable(state, -1) || lua_rawlen(state, -1) != 3) { - throw IOError(std::string("Invalid vec3 named ") + name); - } - - // Read the values from the table - float pos[3]; - for (int i = 0; i < 3; i++) { - lua_rawgeti(state, -1, i + 1); - if (lua_isnumber(state, -1)) { - pos[i] = lua_tonumber(state, -1); - } else { - throw IOError("vec3 values must be numbers"); - } - lua_pop(state, 1); // pop number - } - lua_pop(state, 1); // pop vec3 - - ASSERT(stackSize == lua_gettop(state)) - - return { pos[0], pos[1], pos[2] }; -} - -tp::Vec2F tp::Scene::getVec2(lua_State* state, const char* name) { - int stackSize = lua_gettop(state); - - // Access the "pos" field and validate it - lua_getfield(state, -1, name); - if (!lua_istable(state, -1) || lua_rawlen(state, -1) != 2) { - throw IOError(std::string("Invalid vec2 named ") + name); - } - - // Read the values from the table - float pos[2]; - for (int i = 0; i < 2; i++) { - lua_rawgeti(state, -1, i + 1); - if (lua_isnumber(state, -1)) { - pos[i] = lua_tonumber(state, -1); - } else { - throw IOError("vec3 values must be numbers"); - } - lua_pop(state, 1); // pop number - } - lua_pop(state, 1); // pop vec3 - - ASSERT(stackSize == lua_gettop(state)) - - return { pos[0], pos[1] }; -} // Function to read a Lua table representing RenderSettings int readRenderSettings(lua_State* L, tp::RenderSettings& settings) { @@ -108,8 +53,23 @@ int readRenderSettings(lua_State* L, tp::RenderSettings& settings) { } // Function to read a Lua table representing a light -int tp::Scene::readLight(lua_State* L, tp::PointLight* light) { - light->pos = getVec3(L, "pos"); +int readLight(lua_State* L, tp::PointLight* light) { + lua_getfield(L, -1, "pos"); // Get the "pos" field from the light table + if (!lua_istable(L, -1)) { + printf("Light is missing the 'pos' table.\n"); + return 0; // Error + } + for (int i = 0; i < 3; i++) { + lua_rawgeti(L, -1, i + 1); // Index is 1-based in Lua + if (!lua_isnumber(L, -1)) { + printf("Light 'pos' field is not a number at index %d.\n", i); + lua_pop(L, 2); // Pop both the number and the 'pos' table + return 0; // Error + } + light->pos[i] = lua_tonumber(L, -1); + lua_pop(L, 1); // Pop the number + } + lua_pop(L, 1); // Pop the 'pos' table lua_getfield(L, -1, "intensity"); // Get the "intensity" field from the light table if (!lua_isnumber(L, -1)) { @@ -161,29 +121,66 @@ bool tp::Scene::loadLuaFormat(const std::string& scenePath) { } // --- camera - { - lua_getglobal(L, "Camera"); - if (!lua_istable(L, -1)) { - printf("Camera is not a table.\n"); + + // Access Camera table + lua_getglobal(L, "Camera"); + if (!lua_istable(L, -1)) { + printf("Camera is not a table.\n"); + lua_close(L); + return false; + } + + // 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 false; + } + + // 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 false; } - - Vec3F camPos = getVec3(L, "pos"); - Vec3F camTarget = getVec3(L, "target"); - Vec3F camUp = getVec3(L, "up"); - Vec2F camSize = getVec2(L, "size"); - - mRenderSettings.size = camSize; - - mCamera.lookAtPoint(camTarget, camPos, camUp); - mCamera.setFOV(3.14 / 4); - mCamera.setFar(100); - mCamera.setRatio((tp::halnf) camSize.y / (tp::halnf) camSize.x); - 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 false; + } + 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 false; + } + int size_y = lua_tointeger(L, -1); + + mRenderSettings.size = { (tp::halnf) size_x, (tp::halnf) size_y }; + + mCamera.lookAtPoint({ 0, 0, 0 }, { pos[0], pos[1], pos[2] }, { 0, 0, 1 }); + mCamera.setFOV(3.14 / 4); + mCamera.setFar(100); + mCamera.setRatio((tp::halnf) size_y / (tp::halnf) size_x); + // ---------- LIGHTS { lua_getglobal(L, "Lights"); diff --git a/3DScene/private/OBJFormat.cpp b/3DScene/private/OBJFormat.cpp index b97b87f..3fcf8ad 100644 --- a/3DScene/private/OBJFormat.cpp +++ b/3DScene/private/OBJFormat.cpp @@ -48,39 +48,4 @@ bool tp::Scene::loadOBJFormat(const std::string& objetsPath) { } return mObjects.size(); -} - -const tp::RayCastData& tp::Scene::castRay(const Ray& ray, alnf farVal) { - auto& out = mRayCastData; - - out.hit = false; - out.obj = nullptr; - - farVal *= farVal; - - for (auto obj : mObjects) { - for (auto trig : obj->mCache.TrigCaches) { - if (trig->castRay(ray)) { - - auto dist = (TrigCache::getHitPos() - ray.pos).length2(); - - if (farVal > dist && dist > EPSILON) { - out.trig = &trig.data(); - out.hitPos = TrigCache::getHitPos(); - out.obj = &obj.data(); - out.hit = true; - - farVal = dist; - } - } - } - } - - return mRayCastData; -} - -void tp::Scene::updateCache() { - for (auto obj : mObjects) { - obj->mCache.updateCache(); - } } \ No newline at end of file diff --git a/3DScene/private/Scene.cpp b/3DScene/private/Scene.cpp index 6ef0399..f1927b2 100644 --- a/3DScene/private/Scene.cpp +++ b/3DScene/private/Scene.cpp @@ -2,13 +2,5 @@ #include "Scene.hpp" bool tp::Scene::load(const std::string& scenePath) { - try { - auto res = loadLuaFormat(scenePath); - if (!res) throw IOError("Failed loading lua script"); - } catch (const IOError& err) { - printf("Failed loading scene : %s\n", err.description.c_str()); - return false; - } - - return true; + return loadLuaFormat(scenePath); } \ No newline at end of file diff --git a/3DScene/public/Scene.hpp b/3DScene/public/Scene.hpp index ac872f5..f7aa56f 100644 --- a/3DScene/public/Scene.hpp +++ b/3DScene/public/Scene.hpp @@ -6,8 +6,6 @@ #include -struct lua_State; - namespace tp { struct RenderSettings { uhalni depth = 2; @@ -44,22 +42,7 @@ namespace tp { halnf intensity = 1.f; }; - struct RayCastData { - Object* obj = nullptr; - TrigCache* trig = nullptr; - Vec3F hitPos = { 0, 0, 0 }; - bool hit = false; - bool inv = false; - }; - class Scene { - struct IOError : public std::exception { - explicit IOError(std::string in) : - description(std::move(in)) {} - - std::string description; - }; - public: Scene() = default; @@ -68,23 +51,11 @@ namespace tp { bool loadLuaFormat(const std::string& scenePath); bool loadOBJFormat(const std::string& objectsPath); - const RayCastData& castRay(const Ray& ray, alnf farVal); - - void updateCache(); - - private: - Vec3F getVec3(lua_State* state, const char* name); - Vec2F getVec2(lua_State* state, const char* name); - - int readLight(lua_State* L, tp::PointLight* light); - public: Buffer mObjects; Buffer mLights; Camera mCamera; RenderSettings mRenderSettings; - - RayCastData mRayCastData; }; } diff --git a/Graphics/CMakeLists.txt b/Graphics/CMakeLists.txt index 3d4118b..1159d2a 100644 --- a/Graphics/CMakeLists.txt +++ b/Graphics/CMakeLists.txt @@ -19,5 +19,5 @@ target_link_libraries(Example${PROJECT_NAME} ${PROJECT_NAME} ${BINDINGS_LIBS}) target_include_directories(Example${PROJECT_NAME} PRIVATE ${BINDINGS_INCLUDE}) -file(COPY "../Graphics/rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") +file(COPY "examples/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") diff --git a/Graphics/examples/Font.ttf b/Graphics/examples/Font.ttf new file mode 100644 index 0000000..8a63054 Binary files /dev/null and b/Graphics/examples/Font.ttf differ diff --git a/Graphics/private/Canvas.cpp b/Graphics/private/Canvas.cpp index bc29a17..c108eff 100644 --- a/Graphics/private/Canvas.cpp +++ b/Graphics/private/Canvas.cpp @@ -27,7 +27,7 @@ Canvas::Canvas(Window* window) { mContext->vg = nvgCreateGL3(NVG_ANTIALIAS | NVG_STENCIL_STROKES); - if (nvgCreateFont(mContext->vg, "default", "rsc/Font.ttf") == -1) { + if (nvgCreateFont(mContext->vg, "default", "Font.ttf") == -1) { ASSERT(!"Cant create NVG font") } } diff --git a/Graphics/private/DebugGUI.cpp b/Graphics/private/DebugGUI.cpp index 5880db1..03f6b1f 100644 --- a/Graphics/private/DebugGUI.cpp +++ b/Graphics/private/DebugGUI.cpp @@ -36,7 +36,7 @@ DebugGUI::DebugGUI(Window* window) { ImGui_ImplOpenGL3_Init("#version 330"); ImGuiIO& io = ImGui::GetIO(); - io.Fonts->AddFontFromFileTTF("rsc/Font.ttf", 20.f); + io.Fonts->AddFontFromFileTTF("Font.ttf", 20.f); io.ConfigInputTrickleEventQueue = false; diff --git a/Graphics/public/EventHandler.hpp b/Graphics/public/EventHandler.hpp index ea35c89..c62bd89 100644 --- a/Graphics/public/EventHandler.hpp +++ b/Graphics/public/EventHandler.hpp @@ -87,7 +87,6 @@ namespace tp { [[nodiscard]] halnf getPointerPressure() const; void setEnableKeyEvents(bool); - [[nodiscard]] bool isKeyEventsEnabled() const { return mEnableKeyEvents; } private: void processEventUnguarded(); diff --git a/Math/private/Camera.cpp b/Math/private/Camera.cpp index 621297e..fffc32e 100644 --- a/Math/private/Camera.cpp +++ b/Math/private/Camera.cpp @@ -88,7 +88,7 @@ void Camera::lookAtPoint(const Vec3F& aTarget, const Vec3F& aPos, Vec3F aUp) { } mPos = aPos; mTarget = aTarget; - Vec3F f = (mTarget - mPos).normalize(); + Vec3F f = (mPos - mTarget).normalize(); mUp = f * (aUp.normalize() * f); } @@ -117,20 +117,16 @@ void Camera::rotate(halnf angleX, halnf angleY) { Vec3F wup(0, 0, 1); mPos -= mTarget; - Mat3F rotZ = Mat3F::rotatorDir(wup, angleX); + mat3f rotZ = mat3f::rotatorDir(wup, angleX); mPos = rotZ * mPos; mUp = rotZ * mUp; Vec3F f = mPos.unitV(); Vec3F s = mUp * f; - mPos = Mat3F::rotatorDir(s, -angleY) * mPos; + mPos = mat3f::rotatorDir(s, -angleY) * mPos; mPos += mTarget; lookAtPoint(mTarget, mPos, mUp); } - -void Camera::setPos(Vec3F pos) { - mPos = pos; -} diff --git a/Math/public/Camera.hpp b/Math/public/Camera.hpp index 6ebc5b3..2b2ba45 100644 --- a/Math/public/Camera.hpp +++ b/Math/public/Camera.hpp @@ -18,7 +18,6 @@ namespace tp { void setRatio(halnf ratio); void setFOV(halnf fov); void setFar(halnf far); - void setPos(Vec3F pos); [[nodiscard]] const Vec3F& getPos() const; [[nodiscard]] const Vec3F& getTarget() const; diff --git a/Math/public/Mat.hpp b/Math/public/Mat.hpp index 2483284..4c51bcd 100644 --- a/Math/public/Mat.hpp +++ b/Math/public/Mat.hpp @@ -465,7 +465,7 @@ namespace tp { } // Matrix Properties - MVec transform(const MVec& in) const { return MVec(i.x * in.x + i.y * in.y, j.x * in.x + j.y * in.y); } + MVec transform(const MVec& in) const { return MVec(i.x * in.x + i.y * in.y, j.x * in.y + j.y * in.x); } Mat transform(const Mat& in) const { Mat out; @@ -495,8 +495,8 @@ namespace tp { }; template - using Mat3 = Mat; - using Mat3F = Mat3; + using mat3 = Mat; + using mat3f = mat3; template class Mat { @@ -647,22 +647,22 @@ namespace tp { Mat inv() { return cofactors() /= det(); } - Mat rotatorX(alnf angle) const { + Mat rotatorX(alnf angle) { alnf cosA = (alnf) cos(angle); alnf sinA = (alnf) sin(angle); return { { 1, 0, 0 }, { 0, cosA, -sinA }, { 0, sinA, cosA } }; } - Mat rotatorY(alnf angle) const { + Mat rotatorY(alnf angle) { alnf cosA = (alnf) cos(angle); alnf sinA = (alnf) sin(angle); return { { cosA, 0, sinA }, { 0, 1, 0 }, { -sinA, 0, cosA } }; } - static Mat rotatorZ(alnf angle) { - Type cosA = (Type) cos(angle); - Type sinA = (Type) sin(angle); - return { vec{ cosA, -sinA, 0 }, vec{ sinA, cosA, 0 }, vec{ 0, 0, 1 } }; + Mat rotatorZ(alnf angle) { + alnf cosA = (alnf) cos(angle); + alnf sinA = (alnf) sin(angle); + return { { cosA, -sinA, 0 }, { sinA, cosA, 0 }, { 0, 0, 1 } }; } static Mat rotatorDir(vec dir, alnf angle) { @@ -707,14 +707,4 @@ namespace tp { Type det() { return Type(); } }; - - template - Mat toMat4(const Mat& in) { - Mat out; - out[0] = { in[0][0], in[0][1], in[0][2], 0 }; - out[1] = { in[1][0], in[1][1], in[1][2], 0 }; - out[2] = { in[2][0], in[2][1], in[2][2], 0 }; - out[3] = { Type(0), Type(0), Type(0), Type(1) }; - return out; - } } diff --git a/Math/public/Topology.hpp b/Math/public/Topology.hpp index 31efc10..92cb1a0 100644 --- a/Math/public/Topology.hpp +++ b/Math/public/Topology.hpp @@ -30,7 +30,7 @@ namespace tp { struct Topology { Vec3F Origin = { 0, 0, 0 }; - Mat3F Basis = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; + mat3f Basis = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; Buffer Points; Buffer Normals; diff --git a/Math/public/Vec.hpp b/Math/public/Vec.hpp index 0729046..0441fa8 100644 --- a/Math/public/Vec.hpp +++ b/Math/public/Vec.hpp @@ -110,13 +110,6 @@ namespace tp { return *this; } - Vec& operator=(Type val) { - for (ualni i = 0; i < tSize; i++) { - get(i) = val; - } - return *this; - } - void assign(Type val) { for (ualni i = 0; i < tSize; i++) { get(i) = val; @@ -583,14 +576,4 @@ namespace tp { using Vec4F = Vec4; using Vec4I = Vec4; - - template - Vec toVec4(const Vec& in) { - Vec out; - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = 0; - return out; - } } \ No newline at end of file diff --git a/RasterRender/private/FrameBuffer.cpp b/RasterRender/private/FrameBuffer.cpp index 0520051..fd61110 100644 --- a/RasterRender/private/FrameBuffer.cpp +++ b/RasterRender/private/FrameBuffer.cpp @@ -102,7 +102,7 @@ void RenderBuffer::setViewport(const RectF& viewport) { void RenderBuffer::clear() { AssertGL(glClearColor(mClearCol.r, mClearCol.g, mClearCol.b, mClearCol.a)); - AssertGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); + AssertGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); } void RenderBuffer::endDraw() { diff --git a/RasterRender/private/Render.cpp b/RasterRender/private/Render.cpp index 9b6da2c..25cea38 100644 --- a/RasterRender/private/Render.cpp +++ b/RasterRender/private/Render.cpp @@ -3,42 +3,26 @@ using namespace tp; -RasterRender::RasterRender() { +RasterRender::RasterRender() : + mRenderBuffer({ 100, 100 }) +{ mDefaultShader.load("rsc/shaders/default.vert", nullptr, "rsc/shaders/default.frag", true); - mSolidShader.load("rsc/shaders/default.vert", nullptr, "rsc/shaders/solid.frag", true); } RasterRender::~RasterRender() {} -void RasterRender::resize(const Vec2& size) { - auto sizeF = Vec2F(size.x, size.y); - mRenderBuffer.resize(sizeF); - mTempBuffer.resize(sizeF); -} - uint4 RasterRender::getRenderBufferID() { return mRenderBuffer.texId(); } Vec2F RasterRender::getBufferSize() { return mRenderBuffer.getSize(); } -void RasterRender::bindCameraShaderAttributes(const Mat4F& cameraMat) { - static auto camera = (GLint) mDefaultShader.getu("Camera"); - glUniformMatrix4fv(camera, 1, true, &cameraMat[0][0]); -} +void RasterRender::render(const Scene& geometry, const Vec2& size) { -void RasterRender::bindObjectShaderAttributes(const Object& object) { - static auto origin = (GLint) mDefaultShader.getu("Origin"); - static auto basis = (GLint) mDefaultShader.getu("Basis"); + for (auto object : geometry.mObjects) { + if (!object->mGUPBuffers) { + object->mGUPBuffers = new ObjectBuffers(&object.data()); + } + } - Mat4F basisMat = toMat4(object.mTopology.Basis); - Vec4F originPoint = toVec4(object.mTopology.Origin); - - basisMat = basisMat.transpose(); - - glUniform4fv(origin, 1, &originPoint[0]); - glUniformMatrix4fv(basis, 1, false, &basisMat[0][0]); -} - -void RasterRender::renderDefault(const Scene& geometry) { mRenderBuffer.mClearCol = { 0.0f, 0.0f, 0.0f, 0.f }; mRenderBuffer.beginDraw(); @@ -53,21 +37,24 @@ void RasterRender::renderDefault(const Scene& geometry) { // glPolygonMode(GL_FRONT, GL_LINE); // glPolygonMode(GL_BACK, GL_LINE); - // auto rotator = Mat3F::rotatorZ(alnf(0.001)); - - bindCameraShaderAttributes(cameraMat); - for (auto object : geometry.mObjects) { - // object->mTopology.Origin += 0.01; - // object->mTopology.Basis = rotator * object->mTopology.Basis; - bindObjectShaderAttributes(object.data()); + static auto origin = (GLint) mDefaultShader.getu("Origin"); + static auto basis = (GLint) mDefaultShader.getu("Basis"); + static auto camera = (GLint) mDefaultShader.getu("Camera"); + + Mat4F basisMat; + Vec4F originPoint; + + glUniform4fv(origin, 1, &originPoint[0]); + glUniformMatrix4fv(basis, 1, false, &basisMat[0][0]); + glUniformMatrix4fv(camera, 1, true, &cameraMat[0][0]); + object->mGUPBuffers->drawCall(); } mDefaultShader.unbind(); - glDisable(GL_DEPTH_TEST); // glPolygonMode(GL_FRONT, GL_FILL); // glPolygonMode(GL_BACK, GL_FILL); @@ -75,37 +62,4 @@ void RasterRender::renderDefault(const Scene& geometry) { mRenderBuffer.endDraw(); } -void RasterRender::renderOutline(const Camera& camera, const Object& object) { - mRenderBuffer.beginDraw(); - - // glEnable(GL_STENCIL_TEST); - - mSolidShader.bind(); - - bindCameraShaderAttributes(camera.calculateTransformationMatrix()); - bindObjectShaderAttributes(object); - - object.mGUPBuffers->drawCall(); - - mSolidShader.unbind(); - - // glDisable(GL_STENCIL_TEST); - - mRenderBuffer.endDraw(); -} - -void RasterRender::beginRender(const Scene& geometry, const Vec2& size) { - resize(size); - - for (auto object : geometry.mObjects) { - if (!object->mGUPBuffers) { - object->mGUPBuffers = new ObjectBuffers(&object.data()); - } - } -} - -void RasterRender::endRender() { - // pass -} - RenderBuffer* RasterRender::getRenderBuffer() { return &mRenderBuffer; } diff --git a/RasterRender/public/FrameBuffer.hpp b/RasterRender/public/FrameBuffer.hpp index 8c20aeb..09dc82a 100644 --- a/RasterRender/public/FrameBuffer.hpp +++ b/RasterRender/public/FrameBuffer.hpp @@ -7,7 +7,7 @@ namespace tp { class RenderBuffer { public: - explicit RenderBuffer(const Vec2F& size = { 10, 10 }); + explicit RenderBuffer(const Vec2F& size); RenderBuffer(const Vec2F& size, tp::uint1 samples); ~RenderBuffer(); diff --git a/RasterRender/public/RasterRender.hpp b/RasterRender/public/RasterRender.hpp index 4824c93..229029d 100644 --- a/RasterRender/public/RasterRender.hpp +++ b/RasterRender/public/RasterRender.hpp @@ -12,27 +12,13 @@ namespace tp { RasterRender(); ~RasterRender(); - void beginRender(const Scene& geometry, const Vec2& size); - void endRender(); - - void renderDefault(const Scene& geometry); - void renderOutline(const Camera& camera, const Object& object); - - void resize(const Vec2& size); - + void render(const Scene& geometry, const Vec2& size); uint4 getRenderBufferID(); RenderBuffer* getRenderBuffer(); Vec2F getBufferSize(); - private: - void bindObjectShaderAttributes(const Object& object); - void bindCameraShaderAttributes(const Mat4F& cameraMat); - private: RenderBuffer mRenderBuffer; - RenderBuffer mTempBuffer; - RenderShader mDefaultShader; - RenderShader mSolidShader; }; } \ No newline at end of file diff --git a/RasterRender/rsc/shaders/default.vert b/RasterRender/rsc/shaders/default.vert deleted file mode 100644 index 1d325ed..0000000 --- a/RasterRender/rsc/shaders/default.vert +++ /dev/null @@ -1,13 +0,0 @@ -#version 330 core - -layout(location = 0) in vec3 Point; - -uniform vec4 Origin; -uniform mat4 Basis; -uniform mat4 Camera; - -void main() { - // vec4 transformed = vec4(Point.xyz, 1.0); - vec4 transformed = (Basis * vec4(Point.xyz, 1.0)) + Origin; - gl_Position = Camera * transformed; -} \ No newline at end of file diff --git a/RasterRender/rsc/shaders/solid.frag b/RasterRender/rsc/shaders/solid.frag deleted file mode 100644 index 31e99ca..0000000 --- a/RasterRender/rsc/shaders/solid.frag +++ /dev/null @@ -1,7 +0,0 @@ -#version 330 core - -out vec4 FragColor; - -void main() { - FragColor = vec4(1, 0, 0, 1.f); -} \ No newline at end of file diff --git a/RayTracer/private/RayTracer.cpp b/RayTracer/private/RayTracer.cpp index b7b85f0..e8355e7 100644 --- a/RayTracer/private/RayTracer.cpp +++ b/RayTracer/private/RayTracer.cpp @@ -43,8 +43,6 @@ normal = n1 * barycentric.x + n2 * barycentric.y + n3 * barycentric.z; using namespace tp; - -// TODO : de-duplicate in Scene? void RayTracer::castRay(const Ray& ray, RayCastData& out, alnf farVal) { out.hit = false; out.obj = nullptr; diff --git a/RayTracer/public/RayTracer.hpp b/RayTracer/public/RayTracer.hpp index a21964a..4067247 100644 --- a/RayTracer/public/RayTracer.hpp +++ b/RayTracer/public/RayTracer.hpp @@ -30,6 +30,14 @@ namespace tp { void render(const Scene& scene, OutputBuffers& out, const RenderSettings& settings); private: + struct RayCastData { + const Object* obj = nullptr; + TrigCache* trig = nullptr; + Vec3F hitPos = { 0, 0, 0 }; + bool hit = false; + bool inv = false; + }; + struct LightData { halnf intensity = 0; }; diff --git a/Sketch3D/CMakeLists.txt b/Sketch3D/CMakeLists.txt index 34a642c..248c80d 100644 --- a/Sketch3D/CMakeLists.txt +++ b/Sketch3D/CMakeLists.txt @@ -19,4 +19,4 @@ add_executable(Sketch3DApp ./applications/Entry.cpp) target_link_libraries(Sketch3DApp ${PROJECT_NAME}) file(COPY "rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") -file(COPY "../Graphics/rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") +file(COPY "applications/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") diff --git a/Sketch3D/applications/Entry.cpp b/Sketch3D/applications/Entry.cpp index ef799c8..8574a62 100644 --- a/Sketch3D/applications/Entry.cpp +++ b/Sketch3D/applications/Entry.cpp @@ -11,7 +11,7 @@ public: Sketch3DApplication() { setRoot(&mGui); - mGui.createRenderWidget(mGraphics->getCanvas(), { 2560, 1440 }); + mGui.createRenderWidget(mGraphics->getCanvas(), { 1920, 1080 }); mGui.setProject(&mSketch); } @@ -25,4 +25,4 @@ void runApp() { app.run(); } -int main() { runApp(); } +int main() { runApp(); } \ No newline at end of file diff --git a/Sketch3D/applications/Font.ttf b/Sketch3D/applications/Font.ttf new file mode 100644 index 0000000..8a63054 Binary files /dev/null and b/Sketch3D/applications/Font.ttf differ diff --git a/Sketch3D/private/Sketch3D.cpp b/Sketch3D/private/Sketch3D.cpp index f366d47..183036b 100644 --- a/Sketch3D/private/Sketch3D.cpp +++ b/Sketch3D/private/Sketch3D.cpp @@ -280,7 +280,7 @@ void PencilBrush::draw(Renderer* render, const Camera* camera) { } PencilBrush::~PencilBrush() { - delete mStroke; + if (mStroke) delete mStroke; } void PencilBrush::finish(Project* proj) { diff --git a/Widgets/examples/Example.cpp b/Widgets/examples/Example.cpp index 37e2814..d0e7b31 100644 --- a/Widgets/examples/Example.cpp +++ b/Widgets/examples/Example.cpp @@ -14,7 +14,7 @@ using namespace tp; class Example : public WidgetApplication { public: Example() { - exampleNestedMenus(); + exampleColorPicker(); } void exampleAll() { @@ -64,7 +64,6 @@ public: static ButtonWidget buttons[10]; widget.setDirection(false); - // widget.setDirection(false); setRoot(&widget); diff --git a/Widgets/private/RootWidget.cpp b/Widgets/private/RootWidget.cpp index 065794c..41697b6 100644 --- a/Widgets/private/RootWidget.cpp +++ b/Widgets/private/RootWidget.cpp @@ -58,9 +58,7 @@ void RootWidget::processFrame(EventHandler* events, const RectF& screenArea) { updateAreaCache(&mRoot, false); // trigger some widgets by moise pointer - auto prevFocus = mUpdateManager.getFocusWidget(); - auto newFocus = mUpdateManager.findFocusWidget(&mRoot, *events); - mUpdateManager.handleFocusChanges(newFocus, prevFocus); + mUpdateManager.handleFocusChanges(&mRoot, *events); // check triggered widgets for removal mUpdateManager.clean(); @@ -150,11 +148,9 @@ void RootWidget::openPopup(Widget* widget) { } void RootWidget::closePopup(Widget* widget) { - if (mUpdateManager.canRemoveWidget(widget)) { - mPopups.removeChild(widget); - mUpdateManager.removeWidget(widget); - } + mPopups.removeChild(widget); + mUpdateManager.freeFocus(widget); } void RootWidget::lockFocus(Widget* widget) { mUpdateManager.lockFocus(widget); } -void RootWidget::freeFocus(Widget* widget) { mUpdateManager.freeFocus(widget); } \ No newline at end of file +void RootWidget::freeFocus(Widget* widget) { mUpdateManager.freeFocus(widget); } diff --git a/Widgets/private/managers/DebugManager.cpp b/Widgets/private/managers/DebugManager.cpp index 04a5738..921f7e1 100644 --- a/Widgets/private/managers/DebugManager.cpp +++ b/Widgets/private/managers/DebugManager.cpp @@ -113,17 +113,14 @@ void DebugManager::recursiveDraw(Canvas& canvas, Widget* active, const Vec2F& po canvas.text((active->mDebug.id + ":" + std::to_string(depthOrder)).c_str(), area, 22, Canvas::Align::LC, 2, color); } - if (mRootWidget->mUpdateManager.mFocusLockStack.find(active)) { - canvas.frame(area, { 0, 1, 0, 0.5f }); - } - if (active->mFlags.get(Widget::IN_FOCUS)) { if (active->isUpdate()) { canvas.circle(pos + active->mDebug.pLocal, 5, active->mDebug.col); canvas.circle(active->mDebug.pGlobal, 15, active->mDebug.col); } - canvas.debugCross(area, { 0, 1, 0, 1 }); + RGBA color = { 1, 0, 0, 0.3f }; + canvas.debugCross(area, color); } int orderIdx = 0; diff --git a/Widgets/private/managers/LayoutManager.cpp b/Widgets/private/managers/LayoutManager.cpp index acd8f8f..83f51ba 100644 --- a/Widgets/private/managers/LayoutManager.cpp +++ b/Widgets/private/managers/LayoutManager.cpp @@ -36,7 +36,7 @@ void LayoutManager::findDependencies(Widget* root) { if (!widget->isUpdate()) continue; for (auto child : widget->mChildren) { - if (!child->isUpdate()) continue; + // if (!child->isUpdate()) continue; mDepGraph.insert({ child, {} }); diff --git a/Widgets/private/managers/UpdateManager.cpp b/Widgets/private/managers/UpdateManager.cpp index aeacc42..d1af2cd 100644 --- a/Widgets/private/managers/UpdateManager.cpp +++ b/Widgets/private/managers/UpdateManager.cpp @@ -69,36 +69,35 @@ void UpdateManager::getWidgetPath(Widget* widget, std::vector& out) { } } -Widget* UpdateManager::findFocusWidget(Widget* root, EventHandler& events) { +void UpdateManager::handleFocusChanges(Widget* root, EventHandler& events) { + auto prevFocus = mInFocusWidget; + events.setCursorOrigin({ 0, 0 }); mInFocusWidget = nullptr; - findMouseFocusWidget(root, &mInFocusWidget, events.getPointer()); - if (mFocusLockStack.size()) { + findFocusWidget(root, &mInFocusWidget, events.getPointer()); + + if (mFocusLockWidget) { bool hasLockedWidget = false; for (auto iter = mInFocusWidget; iter; iter = iter->mParent) { - if (iter == mFocusLockStack.last()) { + if (iter == mFocusLockWidget) { hasLockedWidget = true; break; } } if (!hasLockedWidget) { - mInFocusWidget = mFocusLockStack.last(); + mInFocusWidget = mFocusLockWidget; } } - return mInFocusWidget; -} - -void UpdateManager::handleFocusChanges(Widget* active, Widget* prevActive) { // if (mInFocusWidget == prevFocus) return; - if (active) scheduleUpdate(active, "focus entered"); + if (mInFocusWidget) scheduleUpdate(mInFocusWidget, "focus entered"); - if (!active && !prevActive) return; + if (!mInFocusWidget && !prevFocus) return; std::vector path2; - getWidgetPath(active, path2); + getWidgetPath(mInFocusWidget, path2); size_t propLen2 = path2.size(); for (auto i = 0; i < path2.size(); i++) { if (!path2[i]->propagateEventsToChildren()) { @@ -108,7 +107,7 @@ void UpdateManager::handleFocusChanges(Widget* active, Widget* prevActive) { } std::vector path1; - getWidgetPath(prevActive, path1); + getWidgetPath(prevFocus, path1); size_t propLen1 = path1.size(); for (auto i = 0; i < path1.size(); i++) { if (!path1[i]->propagateEventsToChildren()) { @@ -136,7 +135,7 @@ void UpdateManager::handleFocusChanges(Widget* active, Widget* prevActive) { } } -void UpdateManager::findMouseFocusWidget(Widget* iter, Widget** focus, const Vec2F& pointer) { +void UpdateManager::findFocusWidget(Widget* iter, Widget** focus, const Vec2F& pointer) { if (!iter->mArea.getTargetRect().isInside(pointer) || !iter->mFlags.get(Widget::ENABLED)) return; if (iter->processesEvents()) { @@ -144,7 +143,7 @@ void UpdateManager::findMouseFocusWidget(Widget* iter, Widget** focus, const Vec } for (auto child = iter->mDepthOrder.lastNode(); child; child = child->prev) { - findMouseFocusWidget(child->data, focus, pointer - iter->mArea.getTargetRect().pos); + findFocusWidget(child->data, focus, pointer - iter->mArea.getTargetRect().pos); } } @@ -160,10 +159,8 @@ void UpdateManager::processActiveTree(Widget* iter, EventHandler& events, Vec2F procWidget(iter, events, false); } - for (auto child = iter->mDepthOrder.firstNode(); child;) { - auto next = child->next; // any child may be removed at runtime - processActiveTree(child->data, events, current); - child = next; + for (auto child : iter->mDepthOrder) { + processActiveTree(child.data(), events, current); } } @@ -214,24 +211,10 @@ void UpdateManager::procWidget(Widget* widget, EventHandler& events, bool withEv } void UpdateManager::lockFocus(tp::Widget* widget) { - DEBUG_ASSERT(mFocusLockStack.find(widget) == nullptr) - // TODO : check that widget is a child of top of the stack - mFocusLockStack.pushBack(widget); + mFocusLockWidget = widget; } void UpdateManager::freeFocus(tp::Widget* widget) { - DEBUG_ASSERT(mFocusLockStack.last() == widget) - mFocusLockStack.popBack(); -} - -bool UpdateManager::canRemoveWidget(Widget* widget) const { - if (auto node = mFocusLockStack.find(widget)) { - if (node->next) return false; - } - - return true; -} - -void UpdateManager::removeWidget(Widget* widget) { - freeFocus(widget); -} + // DEBUG_ASSERT(mFocusLockWidget == widget) + mFocusLockWidget = nullptr; +} \ No newline at end of file diff --git a/Widgets/private/widgets/DockWidget.cpp b/Widgets/private/widgets/DockWidget.cpp index 799bba7..b75a35c 100644 --- a/Widgets/private/widgets/DockWidget.cpp +++ b/Widgets/private/widgets/DockWidget.cpp @@ -86,7 +86,7 @@ void DockWidget::process(const EventHandler& events) { } } else if (events.isReleased(InputID::MOUSE1)) { layout()->endResize(); - if (layout()->isResizing()) freeFocus(); + freeFocus(); } if (layout()->isResizing()) { diff --git a/Widgets/private/widgets/ScrollableWidget.cpp b/Widgets/private/widgets/ScrollableWidget.cpp index 81836c1..e67f0fa 100644 --- a/Widgets/private/widgets/ScrollableWidget.cpp +++ b/Widgets/private/widgets/ScrollableWidget.cpp @@ -7,10 +7,9 @@ using namespace tp; void ScrollableBarWidget::process(const EventHandler& events) { // all content is visible no need to process anything if (mSizeFactor >= 1) { - if (mScrolling) freeFocus(); - mScrolling = false; mPosFactor = mSizeFactor / 2.f; + freeFocus(); return; } diff --git a/Widgets/public/Widget.hpp b/Widgets/public/Widget.hpp index 77c1c50..c44d718 100644 --- a/Widgets/public/Widget.hpp +++ b/Widgets/public/Widget.hpp @@ -31,8 +31,6 @@ namespace tp { using DFSAction = std::function; - protected: - enum Flags : int1 { ENABLED = 0, NEEDS_UPDATE, diff --git a/Widgets/public/mangers/DebugManager.hpp b/Widgets/public/mangers/DebugManager.hpp index 6c84ef8..0b4ce92 100644 --- a/Widgets/public/mangers/DebugManager.hpp +++ b/Widgets/public/mangers/DebugManager.hpp @@ -87,7 +87,7 @@ namespace tp { bool mDebug = false; bool mDebugStopProcessing = false; bool mDebugRedrawAlways = false; - bool mDetailed = true; + bool mDetailed = false; std::set mProcBreakpoints; std::set mLayBreakpoints; diff --git a/Widgets/public/mangers/UpdateManager.hpp b/Widgets/public/mangers/UpdateManager.hpp index 2a8f661..33c5ecf 100644 --- a/Widgets/public/mangers/UpdateManager.hpp +++ b/Widgets/public/mangers/UpdateManager.hpp @@ -25,26 +25,20 @@ namespace tp { void clean(); void updateTreeToProcess(Widget* root); - void handleFocusChanges(Widget* active, Widget* prevActive); - Widget* findFocusWidget(Widget* root, EventHandler& events); + void handleFocusChanges(Widget* root, EventHandler& events); - void findMouseFocusWidget(Widget* iter, Widget** focus, const Vec2F& pointer); + void findFocusWidget(Widget* iter, Widget** focus, const Vec2F& pointer); static void getWidgetPath(Widget* widget, std::vector& out); void processActiveTree(Widget* iter, EventHandler& events, Vec2F pos); void processFocusItems(EventHandler& events); - Widget* getFocusWidget() { return mInFocusWidget; } - - bool canRemoveWidget(Widget* widget) const; - void removeWidget(Widget* widget); - private: static void procWidget(Widget* widget, EventHandler& events, bool withEvents = false); private: std::map mTriggeredWidgets; Widget* mInFocusWidget = nullptr; - List mFocusLockStack; + Widget* mFocusLockWidget = nullptr; private: int mDebugWidgetsToProcess = 0;