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

Gizmo is misaligned with the model #354

Open
NazarAX opened this issue Dec 17, 2024 · 6 comments
Open

Gizmo is misaligned with the model #354

NazarAX opened this issue Dec 17, 2024 · 6 comments

Comments

@NazarAX
Copy link

NazarAX commented Dec 17, 2024

While integrating ImGuizmo into my engine, I've encountered an issue - my gizmo is not aligned on the model that i am rendering, even though I pass exactly the same MVP matrices in both ImGuizmo::Manipulate as I do in my renderer and shader. I render my scene as a framebuffer and then draw it as ImGui::Image and render gizmo in the same window.
Screenshot 2024-12-17 at 9 52 48 AM
Screenshot 2024-12-17 at 9 52 53 AM
Screenshot 2024-12-17 at 9 52 57 AM
As you can see, the gizmo is supposed to be aligned on the object, however it is shifted to the left. Furthermore, for some reason my ImGui::DrawGrid leaves gaps on the edge of my frustum, and the grid does not render properly.
The code below demonstrates how I render my ImGuizmo:

void DrawSceneViewPanel(FrameBuffer* frameBuffer, Camera& viewCamera, entt::entity selected, Scene* scene)
{
    ImGui::Begin("Scene View");
    static ImVec2 prevSize(0,0);

    // Check if the size has changed
    ImVec2 currentPanelSize = ImGui::GetContentRegionAvail();
    if (currentPanelSize.x != prevSize.x || currentPanelSize.y != prevSize.y)
    {
        prevSize = currentPanelSize;
        viewCamera.Reset(currentPanelSize.x, currentPanelSize.y);
        frameBuffer->Update(currentPanelSize.x, currentPanelSize.y);
    }

    // Check if the texture ID is valid
    if (!(frameBuffer && frameBuffer->GetTextureId() != 0))
    {
        ImGui::Text("Invalid framebuffer texture");
        ImGui::End();
    }

    // Render the framebuffer texture
    ImGui::Image(frameBuffer->GetTextureId(),
                 ImVec2(frameBuffer->GetWidth(), frameBuffer->GetHeight()),
                 ImVec2(0, 1), ImVec2(1, 0)); // Flip texture coordinates (bottom-left to top-left)

    ImGuizmo::SetDrawlist();
    ImGuizmo::SetOrthographic(false);
    ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, ImGui::GetWindowSize().x, ImGui::GetWindowSize().y);


    // Drawing Gizmo for selected entity
    if (scene->HasComponent<Model>(selected))
    {
        Transform& transform = scene->GetComponent<Transform>(selected);

        // Set up Gizmo

        glm::mat4 model = transform.GetModel();
        ImGuizmo::DrawGrid(glm::value_ptr(viewCamera.GetView()), glm::value_ptr(viewCamera.GetProjection()), glm::value_ptr(model), 100.f);
        ImGuizmo::DrawCubes(glm::value_ptr(viewCamera.GetView()),
            glm::value_ptr(viewCamera.GetProjection()),
            glm::value_ptr(model), 1);

        // Manipulate Gizmo
        ImGuizmo::Manipulate(glm::value_ptr(viewCamera.GetView()),
                             glm::value_ptr(viewCamera.GetProjection()),
                             ImGuizmo::OPERATION::TRANSLATE,
                             ImGuizmo::WORLD,
                             glm::value_ptr(model));

        if (ImGuizmo::IsUsing())
        {
            glm::vec3 newPosition, newRotation, newScale;
            ImGuizmo::DecomposeMatrixToComponents(glm::value_ptr(model),
                                                  glm::value_ptr(newPosition),
                                                  glm::value_ptr(newRotation),
                                                  glm::value_ptr(newScale));

            transform.position = newPosition;
            transform.rotation = newRotation;
            transform.scale = newScale;
        }
    }

    ImGui::End();
}

Maybe my issue is somehow related to my renderer so I will include it as well:

void Renderer::DrawModel(const Model& model, Material material, const Transform& transform)
{
	std::vector<Mesh> meshes = model.GetMeshes();

	for (Mesh mesh : meshes)
	{
		mesh.vertexArray.Bind();
		mesh.indexBuffer.Bind();


		material.Shader.Bind();
		material.Albedo.Bind();

		material.Shader.SetUniformMatrix4fv("uModel", transform.GetModel());
		material.Shader.SetUniformMatrix4fv("uView", camera.GetView());
		material.Shader.SetUniformMatrix4fv("uProjection", camera.GetProjection());
		material.Shader.SetUniformMatrix4fv("uTexture", material.Albedo.GetId());


		PointLight light = sceneLight.PointLights[0];
		material.Shader.SetUniform3f("uLightColor", light.Color);
		material.Shader.SetUniform3f("uLightPos", light.Position);
		material.Shader.SetUniform1f("uLightIntensity", light.Intensity);
		material.Shader.SetUniform3f("uAmbientLight", glm::vec3(0.5f, 0.5f, 0.5f));

		glDrawElements(GL_TRIANGLES, mesh.indexBuffer.GetCount(), GL_UNSIGNED_INT, 0);
	}
}

My full git repository is https://github.com/NazarAX/OpenRenderer/. Please let me know if you have any suggestions on what I'm doing wrong and how to fix my issue. Thank you for your time!

@CedricGuillemet
Copy link
Owner

grid rendering is part of the example and should not be used as a grid rendering in engine/app.
In these kind of situations, I try to use values that gives identity (or close). Like placing camera at (0,0,-1), aiming at (0,0,0). with a matrix at identity, object should be visible at the center of the screen.

@NazarAX
Copy link
Author

NazarAX commented Dec 17, 2024

Thank you for your response! I’ve identified that the issue is related to the scaling of the ImGui viewport. The gizmo renders perfectly when the viewport is in full-screen mode. However, when additional panels are introduced and the viewport becomes windowed, the gizmo shifts away from the object's coordinates.

As you can see here, the gizmo is aligned at the middle of the object:
Screenshot 2024-12-17 at 1 05 43 PM

But when the scene viewport becomes windowed this happens:
Screenshot 2024-12-17 at 1 05 54 PM

Any suggestions on how I could fix this issue?

@CedricGuillemet
Copy link
Owner

for imguizmo, check the setrect call. the 3d mesh looks flatten. maybe the ratio is bad? do screenshot and count pixels, compare with calls to matrices creation.

@NazarAX
Copy link
Author

NazarAX commented Dec 17, 2024

The 3D mesh looks stretched because I update camera aspect ratio here:

 if (currentPanelSize.x != prevSize.x || currentPanelSize.y != prevSize.y)
    {
        prevSize = currentPanelSize;
        viewCamera.Reset(currentPanelSize.x, currentPanelSize.y);
        frameBuffer->Update(currentPanelSize.x, currentPanelSize.y);
    }

I compared MVP matrices and they are identical in renderer and ImGuizmo calls. SetRect has the same dimensions as my framebuffer and ImGui::Image.

@NazarAX
Copy link
Author

NazarAX commented Dec 18, 2024

Screen.Recording.2024-12-17.at.6.20.36.PM.mov

@CedricGuillemet
Copy link
Owner

I think it's the difference between corner of window vs corner of app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants