cedricguillemet / imguizmo Goto Github PK
View Code? Open in Web Editor NEWImmediate mode 3D gizmo for scene editing and other controls based on Dear Imgui
License: MIT License
Immediate mode 3D gizmo for scene editing and other controls based on Dear Imgui
License: MIT License
Seeing issues where translation doesn't appear to work correctly when in an Y-up environment (EDIT: Y-up or not doesn't seem to matter, tried with different view matrix since it did seem suspect as that should be handled by the view matrix!). Individual axis translate correctly, but the XY, YZ, XZ plates don't. The thin RGB lines in these images are my own debug rendering to check against the gizmos.
After rotating, the translation gizmo no longer reacts to the correct mouse positions either:
Any idea what may be the issue here? Rotation gizmo seems to work 100% fine (X, Y, Z & screen space rotation)
In case it's related, the Scale gizmo doesn't appear to do anything at all, it just draws as a circle:
when behind the camera the gizmo is still rendered but wrong.
Add the following stuff to prevent this.
gContext.mCameraNearPlane.x = (gContext.mViewProjection.m[0][2]); gContext.mCameraNearPlane.y = (gContext.mViewProjection.m[1][2]); gContext.mCameraNearPlane.z = (gContext.mViewProjection.m[2][2]); gContext.mCameraNearPlane.w = (gContext.mViewProjection.m[3][2]);
and this
`void Manipulate(const float view, const float *projection, OPERATION operation, MODE mode, float *matrix, float *deltaMatrix)
{
ComputeContext(view, projection, matrix, mode);
// set delta to identity
if (deltaMatrix)
((matrix_t)deltaMatrix)->SetToIdentity();
vec_t cameraEyeToGizmo = Normalized(gContext.mModel.v.position - gContext.mCameraEye);
if (cameraEyeToGizmo.Dot3(gContext.mCameraNearPlane) < 0)
return;'
Hi there,
I think that ImGUI::GetIO().WantCaptureMouse should be true when any ring is highlighted I think. Otherwise, there's no way to know whether a click in your scene was meant to select something in the scene, or if it was meant for the gizmo.
Perhaps there are other flags like this that also need to be managed?
PS - I know there is IsOver() and IsUsing() on ImGuizmo, but I feel like WantCaptureMouse is part of the puzzle
Super minor, but worth pointing out. With the change of Mogwai to Manipulate, the in header documentation should reflect this change.
ImGuizmo::Mogwai(gCurrentCamera->mView.m16, gCurrentCamera->mProjection.m16, mCurrentGizmoOperation, mCurrentGizmoMode, gizmoMatrix.m16);
should be
ImGuizmo::Manipulate(gCurrentCamera->mView.m16, gCurrentCamera->mProjection.m16, mCurrentGizmoOperation, mCurrentGizmoMode, gizmoMatrix.m16);
PS: Thanks for sharing ImGuizmo, just integrated it and am excited to use it more.
When using multiple gizmos at a time, they all seem to act as one, rather than individually:
Implementation side I guess Manipulate would need an ID, and take advantage of ImGuiStorage to store if a handle is being used or not. @CedricGuillemet, does this sound reasonable? I am happy to look at implementing and sending over a PR if it doesn't conflict with any ideas you have :)
I'm trying to use your library for my engine, but I can't properly integrate it.
I have that rendering model:
Scene -> Hierarchy -> GameObject -> Transform { position, rotation, scale } + EditorCamera as a GameObject
When I select a GameObject in hierarchy, I expect to edit its transform, but:
Code of transform editing function:
void EditTransform(Transform* t)
{
auto cam = EditorInstance::GetSingleton()->currentScene->Get("Editor Camera");
auto camCmp = cam->GetComponent<Camera>();
ImGuizmo::SetOrthographic(false);
ImGuizmo::BeginFrame();
ImGuizmo::Enable(true);
ImGuiIO& io = ImGui::GetIO();
ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
float* _view = new float[16];
glm::mat4 mmat = glm::mat4();
glm::translate(mmat, glm::vec3{t->globalPosition().x, t->globalPosition().y, t->globalPosition().z});
glm::scale(mmat, glm::vec3{t->scale.x, t->scale.y, t->scale.z});
glm::rotate(mmat, (float)t->rotation.x , glm::vec3{1, 0, 0});
glm::rotate(mmat, (float)t->rotation.y , glm::vec3{0, 1, 0});
glm::rotate(mmat, (float)t->rotation.z , glm::vec3{0, 0, 1});
// ==> WHAT AM I DOING WRONG? NOTHING OF NEXT WORKS PROPERLY.
//_view =(float*)glm::value_ptr(mmat);
glGetFloatv(GL_MODELVIEW_MATRIX, _view);
glm::fmat4 view = glm::mat4(*_view);
float* _proj = new float[16];
glm::mat4 pmat = glm::perspectiveFov(camCmp->fov, io.DisplaySize.x, io.DisplaySize.y, camCmp->_near, camCmp->_far);
// ==> AND HERE TOO
// _proj = (float*)glm::value_ptr(pmat);
// glGetFloatv(GL_PROJECTION_MATRIX, _proj);
glm::fmat4 projection = pmat; //(*_proj);
auto matrix = glm::lookAt(
glm::vec3{ cam->transform.globalPosition().x, cam->transform.globalPosition().y, cam->transform.globalPosition().z },
// { t->globalPosition().x, t->globalPosition().y, t->globalPosition().z },
{ cam->transform.globalPosition().x + cam->transform.direction().x, cam->transform.globalPosition().y + cam->transform.direction().y, cam->transform.globalPosition().z + cam->transform.direction().z },
{ 0, 1, 0});
ImGuizmo::DrawGrid(&view[0][0], &projection[0][0], &matrix[0][0], 200.0f);
ImGuizmo::Manipulate(&view[0][0], &projection[0][0], ImGuizmo::TRANSLATE, ImGuizmo::WORLD, &matrix[0][0], NULL, NULL);
}
Code of render window function:
void winRender(){
ImGui::Begin("Render", &win->render, window_flags);
ImVec2 pos = ImGui::GetWindowPos();
auto tex = dynamic_cast<NukeOGL*>(EditorInstance::GetSingleton()->render)->getRenderTexture();
ImVec2 maxPos = ImVec2(pos.x + ImGui::GetWindowSize().x, pos.y + ImGui::GetWindowSize().y + 2);
ImGui::GetWindowDrawList()->AddImage((void *)tex,
ImVec2(ImGui::GetItemRectMin().x + 0,
ImGui::GetItemRectMin().y - 2),
maxPos, ImVec2(0,1), ImVec2(1,0));
if(EditorInstance::GetSingleton()->selectedInHieararchy){
EditTransform(&EditorInstance::GetSingleton()->selectedInHieararchy->transform);
}
ImGui::End();
}
vec_t is not POD type and it can't be part of union.
I had to move constructors outside of struct to make it compile with clang and GCC.
See changes here:
https://github.com/bkaradzic/bgfx/blob/master/3rdparty/ocornut-imgui/widgets/gizmo.inl#L110
I believe i have a working multi view version which handles drawing the gizmos in any sized window anywhere on the screen .
I suggest change of BeginFrame to SetViewRect
void SetViewRect(float x, float y, float width, float height) { //ImGui::Begin("gizmo", NULL, ImVec2(width, height), 0, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBringToFrontOnFocus); // this should be optional gContext.mX = x; gContext.mY = y; gContext.mWidth = width; gContext.mHeight = height; gContext.mDrawList = ImGui::GetWindowDrawList(); //ImGui::End() this should be optional }
then replace most of the places that used io.DisplaySize with the width and height.
In worldToPos function
trans.x *= gContext.mWidth; trans.y *= gContext.mHeight; trans.x += gContext.mX; trans.y += gContext.mY;
In ComputeCameraRay function
float mox = ((io.MousePos.x - gContext.mX) / gContext.mWidth) * 2.f - 1.f; float moy = (1.f - ((io.MousePos.y - gContext.mY) / gContext.mHeight)) * 2.f - 1.f;
In DrawRotationGizmo function
drawList->AddCircle(worldToPos(gContext.mModel.v.position, gContext.mViewProjection), 0.06f * gContext.mWidth, colors[0], 64);
In GetRotateType function
if (dist >= 0.058f * gContext.mWidth && dist < 0.062f * gContext.mWidth) type = ROTATE_SCREEN;
thats pretty much it.
here is the code
#include "header.h"
#include <imgui.h>
#include "imgui_impl_glfw_gl3.h"
#include <stdio.h>
void init_graphics(DrawObject * obj, Camera * camera, int display_width, int display_height)
{
obj->genVA();
obj->genBuff();
obj->bindVA();
obj->bindBuff();
obj->updateVAP(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
obj->updateBuffData(3*4* sizeof(GLfloat));
obj->bufferdata[0] = 0.5f; obj->bufferdata[1] = 0.5f; obj->bufferdata[2] = 0.0f;
obj->bufferdata[3] = -0.5f; obj->bufferdata[4] = 0.5f; obj->bufferdata[5] = 0.0f;
obj->bufferdata[6] = -0.5f; obj->bufferdata[7] = -0.5f; obj->bufferdata[8] = 0.0f;
obj->bufferdata[9] = 0.5f; obj->bufferdata[10] = -0.5f; obj->bufferdata[11] = 0.0f;
//glm::perspective(camera->Zoom, (float) display_width/ (float) display_height, 1.0f, 1000.0f);
obj->modelLoc = glGetUniformLocation(obj->shader.Program, "model");
glUniformMatrix4fv(obj->modelLoc,1 ,GL_FALSE, glm::value_ptr(obj->model));
glBindVertexArray(0);
}
void draw_object(DrawObject * obj, Camera * camera, int display_width, int display_height){
obj->shader.Use();
obj->view = glm::lookAt(glm::vec3(camera->Position.x, camera->Position.y, camera->Position.z),
glm::vec3(camera->Position.x + camera->Front.x, camera->Position.y + camera->Front.y, camera->Position.z + camera->Front.z),
glm::vec3(camera->Up.x, camera->Up.y, camera->Up.z));
obj->projection = glm::perspective(camera->Zoom, (float) display_width/ (float) display_height, 1.0f, 1000.0f);
obj->modelLoc = glGetUniformLocation(obj->shader.Program, "model");
obj->viewLoc = glGetUniformLocation(obj->shader.Program, "view");
obj->projLoc = glGetUniformLocation(obj->shader.Program, "projection");
glUniformMatrix4fv(obj->viewLoc, 1, GL_FALSE, glm::value_ptr(obj->view));
glUniformMatrix4fv(obj->projLoc, 1, GL_FALSE, glm::value_ptr(obj->projection));
glUniformMatrix4fv(obj->modelLoc, 1, GL_FALSE, glm::value_ptr(obj->model));
obj->bindBuff();
obj->updateBuffData(3*4*sizeof(GLfloat));
glEnableVertexAttribArray(0);
obj->bindVA();
glUniformMatrix4fv(obj->modelLoc, 1, GL_FALSE, glm::value_ptr(obj->model));
glDrawArrays(GL_LINE_STRIP, 0, 4);
glUniformMatrix4fv(obj->modelLoc, 1, GL_FALSE, glm::value_ptr(obj->model));
glBindVertexArray(0);
}
void EditTransform(const Camera * camera, DrawObject * obj, float * matrix, float * view, float * proj)
{
static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::ROTATE);
static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::WORLD);
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;
float matrixTranslation[3], matrixRotation[3], matrixScale[3];
ImGuizmo::DecomposeMatrixToComponents(matrix, matrixTranslation, matrixRotation, matrixScale);
ImGui::InputFloat3("Tr", matrixTranslation, 3);
ImGui::InputFloat3("Rt", matrixRotation, 3);
ImGui::InputFloat3("Sc", matrixScale, 3);
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;
}
static bool useSnap(false);
if (ImGui::IsKeyPressed(83))
useSnap = !useSnap;
ImGui::Checkbox("", &useSnap);
ImGui::SameLine();
/*
vec_t snap;
switch (mCurrentGizmoOperation)
{
case ImGuizmo::TRANSLATE:
snap = config.mSnapTranslation;
ImGui::InputFloat3("Snap", &snap.x);
break;
case ImGuizmo::ROTATE:
snap = config.mSnapRotation;
ImGui::InputFloat("Angle Snap", &snap.x);
break;
case ImGuizmo::SCALE:
snap = config.mSnapScale;
ImGui::InputFloat("Scale Snap", &snap.x);
break;
}
*/
ImGuiIO& io = ImGui::GetIO();
ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
ImGuizmo::Manipulate(view, proj, mCurrentGizmoOperation, mCurrentGizmoMode, matrix, NULL, NULL);
}
int main(){
static Header * h = new Header();
glfwSetErrorCallback(h->error_callback);
if(!glfwInit())
exit;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
#if __MACOS_CORE__
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
h->window = (GLFWwindow *)glfwCreateWindow(1280, 800, "Troubleshooting OpenGL", NULL, NULL);
if(!h->window){
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(h->window);
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if(GLEW_OK != err){
std::cout << "Error: " << glewGetErrorString(err) << std::endl;
}
ImGui_ImplGlfwGL3_Init(h->window, true);
glfwSwapInterval(1);
bool show_test_window = true;
bool show_another_window = false;
ImVec4 clear_color = ImColor(114, 144, 154);
int display_width, display_height;
DrawObject * obj1 = new DrawObject("obj1VS.glsl", "obj1FS.glsl", 3 * 4);
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
init_graphics(obj1, h->camera, display_width, display_height);
int display_w, display_h;
glfwGetFramebufferSize(h->window, &display_w, &display_h);
glm::mat4 model;// = glm::mat4(0.0f);
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
float * mtx = (float *) glm::value_ptr(model);
float * pos = (float *) glm::value_ptr(glm::vec3(0.0f, 0.0f, 0.0f));
float * rot = (float *) glm::value_ptr(glm::vec3(0.0f, 0.0f, 0.0f));
float * scale = (float *) glm::value_ptr(glm::vec3(1.0f, 1.0f, 1.0f));
//glUniformMatrix4fv(obj1->modelLoc, 1, GL_FALSE, glm::value_ptr(model));
while( !glfwWindowShouldClose(h->window) )
{
glfwPollEvents();
float * view_float, * model_float, * proj_float;
view_float = (float *) glm::value_ptr(glm::lookAt(glm::vec3(h->camera->Position.x, h->camera->Position.y, h->camera->Position.z),
glm::vec3(h->camera->Position.x + h->camera->Front.x, h->camera->Position.y + h->camera->Front.y, h->camera->Position.z + h->camera->Front.z),
glm::vec3(h->camera->Up.x, h->camera->Up.y, h->camera->Up.z)));
model_float = mtx;
proj_float = (float *) glm::value_ptr(glm::perspective(h->camera->Zoom, (float) display_width/ (float) display_height, 1.0f, 1000.0f));
// pass projection matrix to shader (note that in this case it could change every frame)
ImGui_ImplGlfwGL3_NewFrame();
glfwGetFramebufferSize(h->window, &display_width, &display_height);
glViewport(0, 0, display_w, display_h);
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
ImGuizmo::BeginFrame();
// 1. Show a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
{
static float f = 0.0f;
ImGui::Text("Hello, world!");
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
ImGui::ColorEdit3("clear color", (float*)&clear_color);
if (ImGui::Button("Test Window")) show_test_window ^= 1;
if (ImGui::Button("Another Window")) show_another_window ^= 1;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
}
// 2. Show another simple window, this time using an explicit Begin/End pair
if (show_another_window)
{
ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &show_another_window);
ImGui::Text("Hello");
ImGui::End();
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (show_test_window)
{
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&show_test_window);
}
memcpy(glm::value_ptr(obj1->model), mtx, sizeof(float)*16);
draw_object(obj1,h->camera,display_width,display_height);
EditTransform(h->camera, obj1, mtx, view_float, proj_float);
for (int i = 0; i < 16; i++){
std::cout << mtx[i] << " ";
if(1 > 0)
if(i%4 == 0 )
std::cout << std::endl;
}
ImGui::Render();
glfwSwapBuffers(h->window);
}
}
I believe the correct one will be: (works with local and world coordiante system)
matrix_t deltaM = gContext.mModelInverse * deltaRotation * gContext.mModel; *(matrix_t*)matrix = gContext.mModelSource * deltaM; if (deltaMatrix) { *(matrix_t*)deltaMatrix = deltaM; }
Otherwise amazing job man :)
Hello @CedricGuillemet,
First of all thank you for this nice manipulator.
Here are the steps to reproduce the issue (maybe it's related to #72) :
launch ImGuizmoSample.exe
Select Rotate
Select World
Rotate the cube with the white circle
Click on the white circle
Behaviour is : Rotation components are reset to 0
Behaviour should be : Rotation components do not change
I must admit that this week I haven't time to look at it in details so I don't know if the following change is relevant but here is the small change (ImGuizmo.cpp) :
line 1795 was :
*(matrix_t*)matrix = scaleOrigin * deltaRotation * gContext.mModel;
is :
if (gContext.mMode == LOCAL) *(matrix_t*)matrix = scaleOrigin * deltaRotation * gContext.mModel; else *(matrix_t*)matrix = scaleOrigin * deltaRotation * @gContext.mModelSource;
I examine Sequencer and your idea is truly inspirational for me.
I try to understand some hard-codded values and ImGui uses.
Some explanatory comment would be great.
to understand your logic and learn some ImGui... I tried to replace this logic:
for (int i = 0; i <= sequence->frame_count; i += frameStep)
with this:
for (int i = first_visible_frame; i <= last_visible_frame; i += frameStep)
I am not good at ImGui so it was hard and time-consuming work for me.
Thank you.
First noticed it in the latest bgfx. Happens in the ImGuizmo example as well.
In bgfx it's less noticeable than the ImGuizmo example. It only breaks when the camera does not look straight at the gizmo, but in the ImGuizmo example, it breaks even then.
When there is already applied rotation then what should world space scale do? Maybe shear? Enginens like Unity seems to avoid this issue by just prohibiting it - there scaling via gizmos can only be done in local space
First,I am new to 3d programing.
I am trying to convert the ImGuizmo Sample from ImApp to glfw
but i always fail
can any one help??
Hi there,
I'd like to use this nice little gizmo to set a 2D transformation matrix. Basically I would like to "hide" one of the axes (e.g. Z). I've tried to "squish" things down by setting the Z scaling to 0/1e-3 for either the view matrix, or the manipulated matrix ... And neither of them really works well: with the former approach, I cannot select the Y axis (only the X), but the Z axis/XZ/YZ planes are well hidden; with the latter the Z/XZ/YZ are still visible, and there is some issue with the RectTransform (#20).
Looking at the code it looks like it shouldn't be too hard to add an option to mask one axis, but I'm open to other suggestions.
So currently, I'm using a perspective camera that is perfectly centred, Pos(0,0,1) facing (0,0,-1) with Up axis of (0,1,0)
I'm trying to achieve perspective view in 2D.
However, with this camera, the Y-arrow is not being detected at all and the X-arrow is constantly being detected. I can only get them to work when I rotate my objects revealing all 3 axes.
However, is there a way to solve this without even rotating my objects at all?
When scaling delta matrix gets absolute scale value on every frame while translation and rotation receive delta since the last frame. Could this be made consistent with translation and rotation?
Is there a way to make it so that rotation can't be done about some of the axes?
For example, I have a need to sometimes restrict the rotation so that an object can be rotated only about the y axis. So, in this case, I would like to disable rotation about x and z axes.
Can the library be built in linux or only Windows under Visual Studio?
gContext.mScaleValueOrigin must be updated when uniform scaling even when gContext.mbUsing is true
so when i have a matrix with lets' say 0.25, 0.25, 0.25 scale and scale it a bit by the X axis i get a delta scale output of 0.30, 0.25, 0.25, but i should get something like 1.1, 1.0, 1.0
When I render the scene to a framebuffer texture using ImGui the gizmo axis and start to rotate the camera the gizmo starts to move as well. When I don't render to the texture ImGui works perfectly fine. Do you maybe have an example rendering the gizmos on a framebuffer?
Currently the drawing is tied directly to the input projection matrix. If you input an orthographic projection then often the widget drawing is tiny.
A very minor issue I admit, but one that certain build systems / setups complain about.
Problem:
imGuizmo's BeginFrame function uses a dummy window in order to acquire a pointer to the drawlist. This dummy window has its position set to 0,0 and is made to take up the full size of the viewport.
Because of semantic changes (and some bug fixes) to setPos in dearImGUI when using viewports: 0,0 is actually the top-left of the screen, not the imgui application. So using imGuizmo with the docking branch & viewports causes a big black window to appear that cannot be interacted with in the top left of the screen.
The simplest change would be to alter line 744 of ImGuizmo.cpp to
#ifdef IMGUI_HAS_VIEWPORT
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->Pos);
#else
ImGui::SetNextWindowPos(ImVec2(0, 0))
#endif
But, it might not even be necessary to have a dummy window at all now due to the addition of GetBackgroundDrawList which could replace most of the function like so:
#ifdef IMGUI_HAS_VIEWPORT
gContext.mDrawList = ImGui::GetBackgroundDrawList(ImGui::GetMainViewport());
#else
gContext.mDrawList = ImGui::GetBackgroundDrawList();
#endif
I don't know if imGuizmo uses this dummy window for anything except the draw list.
When dragging one gizmo axis, perpendicular mouse movement causes incorrect movement. Gif below displays how dragging vertical axis sideways moves object up and down. Other two axis do not have this problem.
It is not always same axis. It depends on point of view which axis misbehaves. This happens when translating or scaling. Depending on angle of view small sideways movement may cause huge changes and cause object "fly" out of the view and sometimes finding it can be tricky.
PR #33 seems to make this less of a problem i think, but does not fix it entirely. Or i may be imagining things and it was less of a problem only due to my point of view when testing. I am no longer sure.
I have a directX11 based engine in which i wanted to add imGuizmo. i already have imgui running but even after following all the steps mentioned on the github page, after enabling the guizmo i still can't get it to show-up at all. and since there was not much code at all i can't seem to figure-out where it might be going wrong. plus where do i give my transformation matrices to the guizmo for it to render with my camera and projection matrices.
When hovering over any imgui UI element, the WantCaptureMouse is set to true for all native imgui controls. ImGuizmo doesn't respect that, and hovering over its transform manipulators keeps WantCaptureMouse as false.
Hi I went and downloaded the latest imgui. I integrated my own code into the sample and got it running. Looked through imguizmo and integrated it into my code too. But nothing of Imguizmo shows up...here is some code
`
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX11_Init(d3d11Device, d3d11DevCon);
// Setup style
//ImGui::StyleColorsDark();
ImGui::StyleColorsClassic();
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
// - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
// - Read 'misc/fonts/README.txt' for more instructions and details.
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
//io.Fonts->AddFontDefault();
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f);
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != NULL);
// Our state
bool show_demo_window = true;
bool show_another_window = false;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Main loop
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
// Poll and handle messages (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
// Start the Dear ImGui frame
ImGui_ImplDX11_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
ImGuizmo::BeginFrame();
/*float* view = matrix_to_float_array(camView);
float* projection = matrix_to_float_array(camProjection);
float* world = matrix_to_float_array(meshList[0].worldMat);*/
static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::TRANSLATE);
static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::LOCAL);
DirectX::XMFLOAT4X4 v = change_mat(camView);
DirectX::XMFLOAT4X4 p = change_mat(camProjection);
DirectX::XMFLOAT4X4 w = change_mat(meshList[0].worldMat);
ImGuizmo::Manipulate(&v.m[0][0], &p.m[0][0], mCurrentGizmoOperation, mCurrentGizmoMode, &w.m[0][0]);
`
Here are two of my conversion functions...I tried passing the matrices needed for the function two different ways
`DirectX::XMFLOAT4X4 change_mat(DirectX::XMMATRIX mat)
{
DirectX::XMFLOAT4X4 temp;
DirectX::XMStoreFloat4x4(&temp, mat);
return temp;
}`
`float* matrix_to_float_array(DirectX::XMMATRIX mat)
{
DirectX::XMFLOAT4X4* temp = new DirectX::XMFLOAT4X4();
DirectX::XMStoreFloat4x4(temp, mat);
float m16[16];
m16[0] = temp->_11;
m16[1] = temp->_12;
m16[2] = temp->_13;
m16[3] = temp->_14;
m16[4] = temp->_21;
m16[5] = temp->_22;
m16[6] = temp->_23;
m16[7] = temp->_24;
m16[8] = temp->_31;
m16[9] = temp->_32;
m16[10] = temp->_33;
m16[11] = temp->_34;
m16[12] = temp->_41;
m16[13] = temp->_42;
m16[14] = temp->_43;
m16[15] = temp->_44;
return m16;
}`
I saw someone else had this problem of no gizmo showing up and they didn't set the matrix to anything so thats why theirs didn't work. My matrices are set. The world matrix is set to Matrix.Identity. The models that the matrix represents is showing up so everything is set and working...just not the gizmo.
My Debug window shows most values not a number as well as it doesnt draw any obj?
anyhelp
Rotating object does not seem to fit the rotation order of my engine. The Gizmo and mesh end up not matching at all. Is there a particular rotation order that must be followed?
translation snap doesnt seem to work correctly when there is an applied rotation.
For example try rotating 45 degrees about the Y axis and then try translating with snap
Here is example:
https://twitter.com/CiroContns/status/816251953483227136
In the HandleRotation function at line 1795 the code
if (applyRotationLocaly) { *(matrix_t*)matrix = scaleOrigin * deltaRotation * gContext.mModel; }
assumes that you'd be handling the object matrix directly but my game engine has a system where it handles the matrix build every frame thus i only need the position, rotation and scale. I tried to replaced it with
if (applyRotationLocaly) { ImGuizmo::DecomposeMatrixToComponents(matrix, tx->pos_, tx->rot_, tx->scale_); }
tx
is my transform component
So it basically just keeps rotating/wobbling. Strangely enough it works for translation and scaling but not rotation with the above method. Any ideas?
EDIT: Nevermind, I found another way. My bad.
Is ImGuizmo depend on a particular coordinate system? I'm trying to retrofit a 3D editor with ImGuizmo, one that is based on Dx9+Gamebryo. Gamebryo's coordinate system, for some reason, is different from the usual left-hand/right-hand systems :
Unfortunately, using the view/perspective matrices of that coordinate system renders the gizmo incorrectly (it appears along the negative vertical axis and gets culled on the slightest movement of the camera). How would I go about resolving this issue? The gizmo does work with a regular LH coordinate system (tested it in a demo DirectX project).
Hi!
I was wondering what the difference between world space and local space was, and when I should use what. I was also wondering if this uses Z-Up or Y-Up by default. Thanks!
DrawCube does not actually render a cube if Manipulate() is not called
I think the incriminated line is:
1945: camSpacePosition.TransformPoint(faceCoords[iCoord] * 0.5f * invert, gContext.mMVP);
Maybe without Manipulate gContext.mMVP is not initialized
Just looking through it at the moment, and it appears that it's only setup to do a single fullscreen viewport. I hope to use it for multiple viewports at some point, and just curious if it's planned or not?
I have a few ideas of how to adapt this, possibly by doing something along the lines of adding something like:
void BeginView(Rect viewport, const float *view, const float *projection);
void EndView();
void Mogwai(MODE mode, float *matrix, float *deltaMatrix = 0);
That way the view & projection wouldn't even need to be passed up either, could be scoped nicely, and keep usage cleaner. Of course this would work on the assumption that ImGui is being rendered fullscreen at the end of all rendering (as I'm sure most people are using it anyway).
Hello,
As said in the title, the gizmo doesn't detect he mouse movement at all, but it detects the clics and my camera movements nicely.
I saw in the demo that you are using the ImApp class, i don't use this, i use the raw ImGui opengl implementation, maybe the problem comes from this ?
Another thing, i don't know if it's a bug or not, but as seen in my screenshot, the x and z axis doesn't align with the world axis, it just turns and flip when it reaches 180 degrees.
Thanks for your help.
More of a suggestion regarding personal preference here, "Mogwai" seems like quite a cryptic name for a function. To me it feels like having separate "Scale" "Rotate" "Translate" functions would be better, and more approachable.
FWIW I understand the reference, I just don't think everyone will :)
Opening the solution in VS leaves a ton of working changes that could be mostly avoided. How about we add a gitignore for the unneeded stuff like:
.vs
Debug
imgui.ini
*.vcxproj.user
There's also the main vcxproj which can show up due to toolset changes but nothing we can do about that. Still a big difference to discard one item prior to a pull.
The XZ and YZ planes are swapped versus their visual presentations.
Visual XY = 4, MOVE_XY
Visual XZ = 6, MOVE_YZ mismatch
Visual YZ = 5, MOVE_XZ mismatch
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.