CedricGuillemet / ImGuizmo

Immediate mode 3D gizmo for scene editing and other controls based on Dear Imgui
MIT License
3.22k stars 907 forks source link

Guizmos not reacting to user input. #242

Closed Makogan closed 2 years ago

Makogan commented 2 years ago

Sorry to bother again, I managed to get the guizmos rendered but I have tried for a couple of hours to manupulate them without success:

image

As you can see the guizmo appears on the screen, but there is no highlighting of any sorte when the mouse is right on top of the guizmo.

This is my Imgui function:

bool show_demo_window = true;
bool show_another_window = false;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
int selected_vertex = 0;
bool hovering_imgui = false;
static ImGuiWindowFlags gizmoWindowFlags = 0;
static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::LOCAL);
static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::TRANSLATE);
static bool useSnap = true;
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;
float camDistance = 8.f;
Eigen::Matrix4f model = Eigen::Matrix4f::Identity();
void Demo_GUI(NECamera::ArcballCamera& camera)
{
    mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
    // Start the Dear ImGui frame
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();
    ImGuizmo::BeginFrame();

    ImGuiIO& io = ImGui::GetIO();
    float viewManipulateRight = io.DisplaySize.x;
    float viewManipulateTop = 0;
    static ImGuiWindowFlags gizmoWindowFlags = 0;

    ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);

    Eigen::Matrix4f view = camera.GetViewMatrix();
    Eigen::Matrix4f proj = camera.GetProjectionMatrix();
    proj(1, 1) *= -1;

    ImGuizmo::Enable(true);
    ImGuizmo::Manipulate(view.data(), proj.data(), mCurrentGizmoOperation, mCurrentGizmoMode, model.data(), NULL, useSnap ? &snap[0] : NULL, boundSizing ? bounds : NULL, boundSizingSnap ? boundsSnap : NULL);
    ImGui::InputFloat3("Snap", &snap[0]);

    std::cout << model << std::endl;

    // Rendering
    ImGui::Render();
}

All imgui proper widgets do behave normally, i.e. I can drag and scale windows as well as editing text parameters, this is a problem only with the ImGuizmo widgets.

I also tried copy pasting the EditTransform function from the readme and tweak it the least possible so that it compiles on my codebase, same problem, the guizmos are unresponsive.

Makogan commented 2 years ago

I added these 2 lines to the code:

    ImGui::Text(ImGuizmo::IsOver()?"Over gizmo":"");
    ImGui::Text(ImGuizmo::IsOver(ImGuizmo::TRANSLATE) ? "Over translate gizmo" : "not");

as far as the libraries are concerned the mouse is never hovering over the gizmo.

CedricGuillemet commented 2 years ago

Did you check it might be caused by a Y flip?

Makogan commented 2 years ago

I am using vulkan so the Y is indeed flipped, but to fix it normally you just have to negate the 1, 1 entry of the projection matrix, which I did. Whether I leave or take out the proj(1, 1) *= -1; I don;t see a difference.

Makogan commented 2 years ago

I have carefully stepped through the code using GDB and ran into a very, very, very, bizarre situation.

Inside:

 static void ComputeCameraRay(vec_t& rayOrigin, vec_t& rayDir, ImVec2 position = ImVec2(gContext.mX, gContext.mY), ImVec2 size = ImVec2(gContext.mWidth, gContext.mHeight))
   {
      ImGuiIO& io = ImGui::GetIO();

      matrix_t mViewProjInverse;
      mViewProjInverse.Inverse(gContext.mViewMat * gContext.mProjectionMat);

      const float mox = ((io.MousePos.x - position.x) / size.x) * 2.f - 1.f;
      const float moy = (1.f - ((io.MousePos.y - position.y) / size.y)) * 2.f - 1.f;

      const float zNear = gContext.mReversed ? (1.f - FLT_EPSILON) : 0.f;
      const float zFar = gContext.mReversed ? 0.f : (1.f - FLT_EPSILON);

      rayOrigin.Transform(makeVect(mox, moy, zNear, 1.f), mViewProjInverse);
      rayOrigin *= 1.f / rayOrigin.w;
      vec_t rayEnd;
      rayEnd.Transform(makeVect(mox, moy, zFar, 1.f), mViewProjInverse);
      rayEnd *= 1.f / rayEnd.w;
      rayDir = Normalized(rayEnd - rayOrigin);
   }

i put a breakpoint on the line ImGuiIO& io = ImGui::GetIO();. This is what gdb says:

(gdb) p io.MousePos.x
$15 = 0
(gdb) p ImGui::GetIO().MousePos.x
$16 = 73

So the assignment is somehow failing?

Makogan commented 2 years ago

If anyone ever runs into something like this in the future:

https://stackoverflow.com/questions/72118633/value-in-third-party-library-mysteriously-changes/72119552#72119552