diff --git a/CMakeLists.txt b/CMakeLists.txt index 216d5bb..3fd318f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ target_include_directories( PUBLIC $ PUBLIC $ PUBLIC $ + PUBLIC $ PUBLIC $ PUBLIC $ ) @@ -82,6 +83,7 @@ target_sources(vissim PRIVATE 3rdparty/imgui/imgui_demo.cpp 3rdparty/imgui/backends/imgui_impl_glfw.cpp 3rdparty/imgui/backends/imgui_impl_opengl3.cpp + 3rdparty/ImGuizmo/ImGuizmo.cpp src/vissim.cc src/sthstry.c src/simulator.cc diff --git a/include/simulator.h b/include/simulator.h index 515d0c3..90391e7 100644 --- a/include/simulator.h +++ b/include/simulator.h @@ -10,6 +10,7 @@ typedef struct srcmdbuf srcmdbuf; void simulator_init(); void simulator_reset(); +void simulator_gui(); void simulator_update(double dt); void simulator_step(double dt); void simulator_draw(srcmdbuf* cmdbuf); diff --git a/src/sconvcol.h b/src/sconvcol.h index 439308c..7aa43c0 100644 --- a/src/sconvcol.h +++ b/src/sconvcol.h @@ -524,6 +524,7 @@ float sch_query_edge_directions (const sch_hull* hull_A, const sch_hull* hull_B, axis = simd4f_sub(simd4f_zero(), axis); } + // TODO: properly handle touching parallel edges. if (simd4f_get_x(simd4f_length3_squared(axis)) < SCH_EPS) { continue; } diff --git a/src/simulator.cc b/src/simulator.cc index 0ed02dd..99fdf76 100644 --- a/src/simulator.cc +++ b/src/simulator.cc @@ -115,7 +115,7 @@ void simulator_reset() { sSimTimeAccumulator = 0.; } -void simulator_update(double dt) { +void simulator_gui() { ZoneScoped; ImGui::Begin("Simulator"); @@ -186,6 +186,10 @@ void simulator_update(double dt) { } ImGui::End(); +} + +void simulator_update(double dt) { + ZoneScoped; if (!sIsPaused) { sSimTimeAccumulator += dt; diff --git a/src/srender.h b/src/srender.h index 004f334..0222ced 100644 --- a/src/srender.h +++ b/src/srender.h @@ -736,6 +736,8 @@ void srview_cleanup_framebuffer(srview* sv) { void srview_set_size(srview* sv, int width, int height) { if (sv->width == width && sv->height == height) { return; + } else { + gLog("Resizing view to %d, %d", width, height); } sv->width = width; diff --git a/src/vissim.cc b/src/vissim.cc index 849be0c..e3cc4a4 100644 --- a/src/vissim.cc +++ b/src/vissim.cc @@ -4,20 +4,22 @@ // clang-format on #include -#include -#include -#include +#include #include #include #include -#include #include -#include #include "backends/imgui_impl_glfw.h" #include "backends/imgui_impl_opengl3.h" #include "imgui.h" +#include "ImGuizmo.h" + +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif +#include "imgui_internal.h" #include "simulator.h" #include "srender.h" #include "utils.h" @@ -30,9 +32,38 @@ srndr* gRndr = nullptr; srview* gView = nullptr; srcmdbuf* gRndrCmds = nullptr; +simd4x4f gViewMatrix = { + simd4f_create(1.f, 0.f, 0.0, 0.f), + simd4f_create(0.f, 1.f, 0.f, 0.f), + simd4f_create(0.f, 0.f, 1.f, 0.f), + simd4f_create(0.f, 0.f, 0.f, 1.f)}; +simd4x4f gProjMatrix{ + simd4f_create(1.f, 0.f, 0.0, 0.f), + simd4f_create(0.f, 1.f, 0.f, 0.f), + simd4f_create(0.f, 0.f, 1.f, 0.f), + simd4f_create(0.f, 0.f, 0.f, 1.f)}; +simd4x4f gTransformMatrix{ + simd4f_create(1.0f, 0.f, 0.0, 0.f), + simd4f_create(0.f, 1.0f, 0.f, 0.f), + simd4f_create(0.f, 0.f, 1.0f, 0.f), + simd4f_create(0.f, 0.f, 0.f, 1.f)}; + +vectorial_inline simd4x4f simd4x4f_scale(simd4f s) { + return simd4x4f_create( + simd4f_create(simd4f_get_x(s), 0.f, 0.f, 0.f), + simd4f_create(0.f, simd4f_get_y(s), 0.f, 0.f), + simd4f_create(0.f, 0.f, simd4f_get_z(s), 0.f), + simd4f_create(0.f, 0.f, 0.f, simd4f_get_w(s))); +} + double mouse_scroll_x = 0.; double mouse_scroll_y = 0.; +enum ViewMode { ViewModeSimulation = 0, ViewModeGuizmoTest = 1 }; + +ViewMode gViewMode = ViewModeSimulation; +bool gGizmoEnabled = true; + using namespace std; static void error_callback(int error, const char* description) { @@ -146,30 +177,210 @@ void ShowDockspace(bool open) { ImGui::End(); } +static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::TRANSLATE); +int gizmoCount = 1; +float camDistance = 8.f; + +void RenderGuizmoTest(srcmdbuf* cmdbuf) { + srcmd rcmd; + srcmd_clear(&rcmd); + + rcmd.type = SRndrCmdTypeGrid; + for (int i = -1; i <= 1; i++) { + for (int j = -1; j <= 1; j++) { + simd4x4f_translation(&rcmd.mat, 0.0f, 0.0f, 0.0f); + srcmdbuf_add(cmdbuf, &rcmd); + } + } + + rcmd.type = SRndrCmdTypeCube; + rcmd.mat = gTransformMatrix; + srcmdbuf_add(cmdbuf, &rcmd); +} + +void ShowViewManip() { + const ImGuiStyle& imgui_style = ImGui::GetStyle(); + + ImGuizmo::SetDrawlist(); + float windowWidth = (float)ImGui::GetWindowWidth(); + float windowHeight = (float)ImGui::GetWindowHeight(); + ImGuizmo::SetRect( + ImGui::GetWindowPos().x, + ImGui::GetWindowPos().y, + windowWidth, + windowHeight); + float viewManipulateRight = ImGui::GetWindowPos().x + windowWidth; + + int title_height = ImGui::GetFontSize() + imgui_style.FramePadding.y * 2; + ImVec2 window_pos = ImGui::GetWindowPos(); + + ImVec2 view_manip_widget_size(128, 128); + ImVec2 view_manip_widget_pos( + viewManipulateRight - 128 - imgui_style.WindowPadding.x, + window_pos.y + title_height + imgui_style.WindowPadding.y); + ImGui::SetCursorPos(view_manip_widget_pos - ImGui::GetWindowPos()); + ImGui::InvisibleButton("ViewManipulator", view_manip_widget_size); + ImGuizmo::ViewManipulate( + (float*)&(gViewMatrix.x), + 10.0f, + view_manip_widget_pos, + view_manip_widget_size, + 0x40404040); +} + +void ShowTransformManip( + float* cameraView, + float* cameraProjection, + float* matrix) { + static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::LOCAL); + static bool useSnap = false; + static float snap[3] = {1.f, 1.f, 1.f}; + static float bounds[] = {-0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f}; + static float boundsSnap[] = {0.1f, 0.1f, 0.1f}; + static bool boundSizing = false; + static bool boundSizingSnap = false; + bool useWindow = false; + bool editTransformDecomposition = true; + + ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_pos = ImGui::GetWindowPos(); + + ImGuiStyle imgui_style = ImGui::GetStyle(); + int title_height = ImGui::GetFontSize() + imgui_style.FramePadding.y * 2; + + window_pos.x += imgui_style.WindowPadding.x; + window_pos.y += imgui_style.WindowPadding.y + title_height; + + window_size.x -= imgui_style.WindowPadding.x * 2; + window_size.y -= imgui_style.WindowPadding.y * 2 + title_height; + + ImGui::Begin("Guizmo"); + + if (editTransformDecomposition) { + if (ImGui::IsKeyPressed(90)) mCurrentGizmoOperation = ImGuizmo::TRANSLATE; + if (ImGui::IsKeyPressed(69)) mCurrentGizmoOperation = ImGuizmo::ROTATE; + if (ImGui::IsKeyPressed(82)) // r Key + mCurrentGizmoOperation = ImGuizmo::SCALE; + if (ImGui::RadioButton( + "Translate", + mCurrentGizmoOperation == ImGuizmo::TRANSLATE)) + mCurrentGizmoOperation = ImGuizmo::TRANSLATE; + ImGui::SameLine(); + if (ImGui::RadioButton( + "Rotate", + mCurrentGizmoOperation == ImGuizmo::ROTATE)) + mCurrentGizmoOperation = ImGuizmo::ROTATE; + ImGui::SameLine(); + if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE)) + mCurrentGizmoOperation = ImGuizmo::SCALE; + if (ImGui::RadioButton( + "Universal", + mCurrentGizmoOperation == ImGuizmo::UNIVERSAL)) + mCurrentGizmoOperation = ImGuizmo::UNIVERSAL; + float matrixTranslation[3], matrixRotation[3], matrixScale[3]; + ImGuizmo::DecomposeMatrixToComponents( + matrix, + matrixTranslation, + matrixRotation, + matrixScale); + ImGui::InputFloat3("Tr", matrixTranslation); + ImGui::InputFloat3("Rt", matrixRotation); + ImGui::InputFloat3("Sc", matrixScale); + ImGuizmo::RecomposeMatrixFromComponents( + matrixTranslation, + matrixRotation, + matrixScale, + matrix); + + if (mCurrentGizmoOperation != ImGuizmo::SCALE) { + if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL)) + mCurrentGizmoMode = ImGuizmo::LOCAL; + ImGui::SameLine(); + if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD)) + mCurrentGizmoMode = ImGuizmo::WORLD; + } + if (ImGui::IsKeyPressed(83)) useSnap = !useSnap; + ImGui::Checkbox("", &useSnap); + ImGui::SameLine(); + + switch (mCurrentGizmoOperation) { + case ImGuizmo::TRANSLATE: + ImGui::InputFloat3("Snap", &snap[0]); + break; + case ImGuizmo::ROTATE: + ImGui::InputFloat("Angle Snap", &snap[0]); + break; + case ImGuizmo::SCALE: + ImGui::InputFloat("Scale Snap", &snap[0]); + break; + } + ImGui::Checkbox("Bound Sizing", &boundSizing); + if (boundSizing) { + ImGui::PushID(3); + ImGui::Checkbox("", &boundSizingSnap); + ImGui::SameLine(); + ImGui::InputFloat3("Snap", boundsSnap); + ImGui::PopID(); + } + } + + ImGui::End(); + + ImGuiIO& io = ImGui::GetIO(); + float viewManipulateRight = io.DisplaySize.x; + float viewManipulateTop = 0; + if (useWindow) { + ImGui::SetNextWindowSize(ImVec2(800, 400)); + ImGui::SetNextWindowPos(ImVec2(400, 20)); + ImGui::PushStyleColor( + ImGuiCol_WindowBg, + (ImVec4)ImColor(0.35f, 0.3f, 0.3f)); + ImGui::Begin("Gizmo", 0); + ImGuizmo::SetDrawlist(); + float windowWidth = (float)ImGui::GetWindowWidth(); + ImGuizmo::SetRect(window_pos.x, window_pos.y, window_size.x, window_size.y); + } else { + ImGuizmo::SetDrawlist(); + ImGuizmo::SetRect(window_pos.x, window_pos.y, window_size.x, window_size.y); + } + + simd4x4f identity_mat; + simd4x4f_identity(&identity_mat); + + ImGuizmo::Manipulate( + cameraView, + cameraProjection, + mCurrentGizmoOperation, + mCurrentGizmoMode, + matrix, + NULL, + useSnap ? &snap[0] : NULL, + boundSizing ? bounds : NULL, + boundSizingSnap ? boundsSnap : NULL); + + if (useWindow) { + ImGui::End(); + ImGui::PopStyleColor(1); + } +} + void DoRender() { ZoneScoped; - // Render Output - ImGui::Begin("Render Output"); + const ImGuiStyle& imgui_style = ImGui::GetStyle(); - // Update the view + // Render Output + ImGui::Begin("Render Output", nullptr, ImGuiWindowFlags_NoScrollbar); + + // Update the gViewMatrix const ImVec2 content_avail = ImGui::GetContentRegionAvail(); srview_set_size(gView, content_avail.x, content_avail.y); - simd4x4f view; - simd4x4f proj; - simd4x4f_translation(&view, 0.1f, 0.1f, -0.5f); - simd4f eye = simd4f_create(0.f, 3.f, 10.f, 1.f); - simd4x4f_lookat( - &view, - eye, - simd4f_create(0.f, 1.f, 0.f, 1.f), - simd4f_create(0.f, 1.f, 0.f, 1.f)); float view_width = content_avail.x / 50.f; float view_height = content_avail.y / 50.f; simd4x4f_ortho( - &proj, + &gProjMatrix, -0.5f * view_width, 0.5f * view_width, -0.5f * view_height, @@ -177,13 +388,13 @@ void DoRender() { -50.0f, 50.0f); simd4x4f_perspective( - &proj, + &gProjMatrix, 70.f * (M_PI / 180.f), view_width / view_height, 0.1f, 50.f); - srview_set_view(gView, view); - srview_set_proj(gView, proj); + srview_set_view(gView, gViewMatrix); + srview_set_proj(gView, gProjMatrix); // Populate render commands srcmdbuf_clear(gRndrCmds); @@ -194,7 +405,12 @@ void DoRender() { rcmd.type = SRndrCmdTypeFrame; srcmdbuf_add(gRndrCmds, &rcmd); - simulator_draw(gRndrCmds); + if (gViewMode == ViewModeSimulation) { + simulator_draw(gRndrCmds); + simulator_gui(); + } else { + RenderGuizmoTest(gRndrCmds); + } // Perform the actual render srndr_render(gRndr, gView, gRndrCmds); @@ -207,6 +423,22 @@ void DoRender() { ImVec2(0.0f, 1.0f), ImVec2(1.0f, 0.0f)); + ImGuiIO& io = ImGui::GetIO(); + + ShowViewManip(); + ShowTransformManip((float*)&(gViewMatrix), + (float*)&(gProjMatrix), + (float*)(&gTransformMatrix)); + + /* + EditTransform( + (float*)&(gViewMatrix), + (float*)&(gProjMatrix), + (float*)(&gTransformMatrix), + true, + window_pos, + window_size); +*/ ImGui::End(); } @@ -249,6 +481,10 @@ int main(void) { std::cout << "GLSL Version : " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl; + glEnable(GL_DEBUG_OUTPUT); + // glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + glDebugMessageCallback(opengl_error_callback, nullptr); + // During init, enable debug output // glEnable ( GL_DEBUG_OUTPUT ); // glDebugMessageCallback( (GLDEBUGPROC) opengl_error_callback, 0 ); @@ -290,6 +526,18 @@ int main(void) { gRndrCmds = srcmdbuf_create(1024); simulator_init(); + simd4x4f_translation(&gViewMatrix, 0.1f, 0.1f, -0.5f); + simd4f eye = simd4f_create(0.f, 3.f, 10.f, 1.f); + + simd4x4f_lookat( + &gViewMatrix, + eye, + simd4f_create(0.f, 0.f, 0.f, 1.f), + simd4f_create(0.f, 1.f, 0.f, 1.f)); + + simd4x4f scale_mat = simd4x4f_scale(simd4f_create(1.f, 1.f, 1.f, 1.f)); + simd4x4f_mul(&gTransformMatrix, &scale_mat, &gTransformMatrix); + while (!glfwWindowShouldClose(gWindow)) { FrameMark; frame_counter++; @@ -307,6 +555,8 @@ int main(void) { ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); + ImGuizmo::BeginFrame(); + ImGuizmo::Enable(gGizmoEnabled); } frame_time_last = frame_time_current;