{"action":"created","issue":{"url":"https://api.github.com/repos/wjakob/nanogui/issues/323","repository_url":"https://api.github.com/repos/wjakob/nanogui","labels_url":"https://api.github.com/repos/wjakob/nanogui/issues/323/labels{/name}","comments_url":"https://api.github.com/repos/wjakob/nanogui/issues/323/comments","events_url":"https://api.github.com/repos/wjakob/nanogui/issues/323/events","html_url":"https://github.com/wjakob/nanogui/issues/323","id":304748370,"number":323,"title":"Updating values in a FormHelper","user":{"login":"NathanGarrett","id":32485927,"avatar_url":"https://avatars3.githubusercontent.com/u/32485927?v=4","gravatar_id":"","url":"https://api.github.com/users/NathanGarrett","html_url":"https://github.com/NathanGarrett","followers_url":"https://api.github.com/users/NathanGarrett/followers","following_url":"https://api.github.com/users/NathanGarrett/following{/other_user}","gists_url":"https://api.github.com/users/NathanGarrett/gists{/gist_id}","starred_url":"https://api.github.com/users/NathanGarrett/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NathanGarrett/subscriptions","organizations_url":"https://api.github.com/users/NathanGarrett/orgs","repos_url":"https://api.github.com/users/NathanGarrett/repos","events_url":"https://api.github.com/users/NathanGarrett/events{/privacy}","received_events_url":"https://api.github.com/users/NathanGarrett/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-03-13T12:40:59Z","updated_at":"2018-03-14T00:00:01Z","closed_at":null,"author_association":"NONE","body":"Hi, this may be a noob question but I am currently strugling with making the values in the form helper update according to what is happening in my scene. Currently my program allows the user to change the transform (scale, position and rotation) of a 3D model. \r\nThe core issue is that the focus (the object being transformed) is set to the 0th object in the scene which allows me to edit its parameters in the gui, however when I change the focus in the application it is not changed in the gui. \r\nI've tried using a boolean to tell the application when the gui has been drawn so as not to create a new menu every frame. When I don't use this boolean the gui does update but only because the entire gui is being drawn again and again. \r\nAm I missing something obvious?\r\n`Window::Window()\r\n{\r\n\tglfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);\r\n\tglfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);\r\n\tglfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);\r\n\tglfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);\r\n\tglfwWindowHint(GLFW_RESIZABLE, GL_TRUE);\r\n\r\n}\r\n\r\nWindow::~Window()\r\n{\r\n}\r\n\r\nvoid Window::InitWindow()\r\n{\r\n\r\n\t// initialise a window and let GLFW know that it should target opengl version 4.3\r\n\tglfwInit();\r\n\twindow = glfwCreateWindow(m_kiWidth, m_kiHeight, \"3DModeller\", nullptr, nullptr);\r\n\t\r\n\t\r\n\tif (window == nullptr)\r\n\t{\r\n\t\tstd::cout << \"Failed to create GLFW window\" << std::endl;\r\n\t\tglfwTerminate();\r\n\t}\r\n\r\n\t// make this new window our current context, THEN try to initialise GLAD function ptrs\r\n\tglfwMakeContextCurrent(window);\r\n\r\n\r\n\r\n#pragma region nanoCallBacks\r\n\tglfwSetCursorPosCallback(window,[](GLFWwindow *, double x, double y)\r\n\t{\r\n\t\tscreen->cursorPosCallbackEvent(x, y);\r\n\t\tGLfloat\tfxPos = static_cast<GLfloat>(x);\r\n\t\tGLfloat\tfyPos = static_cast<GLfloat>(y);\r\n\r\n\t\tif (abkeys[GLFW_KEY_LEFT_SHIFT])\r\n\t\t{\r\n\r\n\t\t\tif (bFirstMouse)\r\n\t\t\t{\r\n\t\t\t\tflastX = fxPos;\r\n\t\t\t\tflastY = fyPos;\r\n\t\t\t\tbFirstMouse = false;\r\n\t\t\t}\r\n\t\t\tGLfloat xOffset = fxPos - flastX;\r\n\t\t\tGLfloat yOffset = flastY - fyPos;\r\n\r\n\r\n\r\n\t\t\tcamera->MouseProc(xOffset, yOffset);\r\n\t\t}\r\n\t\tflastX = fxPos;\r\n\t\tflastY = fyPos;\r\n\r\n\t}\r\n\t);\r\n\r\n\tglfwSetMouseButtonCallback(window,[](GLFWwindow *, int button, int action, int modifiers) \r\n\t{\r\n\t\tscreen->mouseButtonCallbackEvent(button, action, modifiers);\r\n\t}\r\n\t);\r\n\r\n\tglfwSetKeyCallback(window,[](GLFWwindow *, int key, int scancode, int action, int mods) \r\n\t{\r\n\t\tscreen->keyCallbackEvent(key, scancode, action, mods);\r\n\t\tif (key >= 0 && key <= 1024)\r\n\t\t{\r\n\t\t\tif (action == GLFW_PRESS)\r\n\t\t\t{\r\n\t\t\t\tabkeys[key] = true;\r\n\t\t\t}\r\n\r\n\t\t\telse if (action == GLFW_RELEASE)\r\n\t\t\t{\r\n\t\t\t\tabkeys[key] = false;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\t);\r\n\r\n\tglfwSetCharCallback(window,[](GLFWwindow *, unsigned int codepoint) \r\n\t{\r\n\t\tscreen->charCallbackEvent(codepoint);\r\n\t}\r\n\t);\r\n\r\n\tglfwSetDropCallback(window,[](GLFWwindow *, int count, const char **filenames)\r\n\t{\r\n\t\tscreen->dropCallbackEvent(count, filenames);\r\n\t});\r\n\r\n\tglfwSetScrollCallback(window,[](GLFWwindow *, double x, double y) \r\n\t{\r\n\t\tscreen->scrollCallbackEvent(x, y);\r\n\t});\r\n\r\n\tglfwSetFramebufferSizeCallback(window,[](GLFWwindow *, int width, int height) \r\n\t{\r\n\t\tscreen->resizeCallbackEvent(width, height);\r\n\t});\r\n#pragma endregion\r\n\t\r\n\tglfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);\r\n\t//Glad init\r\n\tif(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))\r\n\t{\r\n\t\tstd::cout << \"Failed to initialise GLAD\" << std::endl;\r\n\t}\r\n\t//Check if window\r\n\tif (nullptr == window)\r\n\t{\r\n\t\tstd::cout << \"Failed to create GLFW window\" << std::endl;\r\n\t\tglfwTerminate();\r\n\t}\r\n\t\r\n\r\n\tscene = new Scene();\r\n\tscene->initScene(*camera);\r\n\t\r\n\tscreen = new nanogui::Screen();\r\n\tscreen->initialize(window, true);\r\n\t\r\n}\r\n\r\nvoid Window::InitUI()\r\n{\r\n\tif (!m_bGUIActive)\r\n\t{\r\n\t\tnanogui::FormHelper *gui = new nanogui::FormHelper(screen);\r\n\t\tnanogui::ref<nanogui::Window> nanoguiWindow = gui->addWindow(Eigen::Vector2i(10, 10), \"Transform\");\r\n\t\tgui->addGroup(\"Scale\");\r\n\t\tgui->addVariable(\"X\", scene->m_Objects[scene->GetFocus()]->getComponent<TransformComponent>()->m_scale.x)->setSpinnable(true);\r\n\t\tgui->addVariable(\"Y\", scene->m_Objects[scene->GetFocus()]->getComponent<TransformComponent>()->m_scale.y);\r\n\t\tgui->addVariable(\"Z\", scene->m_Objects[scene->GetFocus()]->getComponent<TransformComponent>()->m_scale.z);\r\n\t\tgui->addGroup(\"Position\");\r\n\t\tgui->addVariable(\"X\", scene->m_Objects[scene->GetFocus()]->getComponent<TransformComponent>()->m_position.x);\r\n\t\tgui->addVariable(\"Y\", scene->m_Objects[scene->GetFocus()]->getComponent<TransformComponent>()->m_position.y);\r\n\t\tgui->addVariable(\"Z\", scene->m_Objects[scene->GetFocus()]->getComponent<TransformComponent>()->m_position.z);\r\n\t\tgui->addGroup(\"Rotation\");\r\n\t\tgui->addVariable(\"Roll\", scene->m_Objects[scene->GetFocus()]->getComponent<TransformComponent>()->m_orientation.x);\r\n\t\tgui->addVariable(\"Pitch\", scene->m_Objects[scene->GetFocus()]->getComponent<TransformComponent>()->m_orientation.y);\r\n\t\tgui->addVariable(\"Yaw\", scene->m_Objects[scene->GetFocus()]->getComponent<TransformComponent>()->m_orientation.z);\r\n\t\t\r\n\t\tscreen->setVisible(true);\r\n\t\tscreen->performLayout();\r\n\t\tnanoguiWindow->setPosition(nanogui::Vector2i(10, 10));\r\n\t\tscreen->updateFocus(nanoguiWindow);\r\n\t\tm_bGUIActive = true;\r\n\t}\t\r\n\t\r\n}\r\n\r\nvoid Window::Update()\r\n{\r\n\twhile (!glfwWindowShouldClose(window))\r\n\t{\r\n\t\tGLfloat currentFrame = static_cast<GLfloat>(glfwGetTime());\r\n\t\tfDeltaTime = currentFrame - lastframe;\r\n\t\tlastframe = currentFrame;\r\n\t\t\r\n\t\tglClearColor(0.5f, 0.5f, 0.5f, 0.f);\r\n\t\t\r\n\t\tglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\r\n\t\t\t\t\r\n\t\tglfwWaitEvents();\r\n\r\n\t\tDoMovement();\r\n\t\t\t\tglDisable(GL_DEPTH_TEST);\r\n\r\n\t\tscreen->drawContents();\r\n\t\tscreen->drawWidgets();\r\n\r\n\t\tglEnable(GL_DEPTH_TEST);\r\n\t\tRender();\r\n\r\n\t\t// swap buffers i.e. draw to screen\r\n\t\tglfwSwapBuffers(window);\r\n\t\t//onCLick();\r\n\t\t\r\n\t}\r\n}\r\n\r\nvoid Window::Render()\r\n{\r\n\tif (scene->m_Objects.size() < 1) { scene->GenModel(\"cube.obj\"); }\r\n\tif (abkeys[GLFW_KEY_W])\r\n\t{\r\n\t\tscene->m_Objects[0]->getComponent<TransformComponent>()->translate(glm::vec3(0, 1, 0));\r\n\t}\r\n\tif (abkeys[GLFW_KEY_LEFT_CONTROL] && abkeys[GLFW_KEY_TAB])\r\n\t{\r\n\t\tscene->CycleFoci();\r\n\t\tstd::cout << scene->GetFocus() << std::endl;\r\n\t}\r\n\tif (abkeys[GLFW_KEY_LEFT_CONTROL] && abkeys[GLFW_KEY_LEFT_SHIFT])\r\n\t{\r\n\t\tscene->CycleModes();\r\n\t}\r\n\tif (abkeys[GLFW_KEY_RIGHT_CONTROL] && abkeys[GLFW_KEY_C])\r\n\t{\r\n\t\tscene->GenModel(\"cube.obj\");\r\n\t}\r\n\tInitUI();\r\n\tscene->render(*camera);\r\n}`\r\n\r\nI hope having such a large snippet doesn't break the rules haha. Any advice you can give would be greatly appreciated thank you."},"comment":{"url":"https://api.github.com/repos/wjakob/nanogui/issues/comments/372859495","html_url":"https://github.com/wjakob/nanogui/issues/323#issuecomment-372859495","issue_url":"https://api.github.com/repos/wjakob/nanogui/issues/323","id":372859495,"user":{"login":"svenevs","id":5871461,"avatar_url":"https://avatars0.githubusercontent.com/u/5871461?v=4","gravatar_id":"","url":"https://api.github.com/users/svenevs","html_url":"https://github.com/svenevs","followers_url":"https://api.github.com/users/svenevs/followers","following_url":"https://api.github.com/users/svenevs/following{/other_user}","gists_url":"https://api.github.com/users/svenevs/gists{/gist_id}","starred_url":"https://api.github.com/users/svenevs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/svenevs/subscriptions","organizations_url":"https://api.github.com/users/svenevs/orgs","repos_url":"https://api.github.com/users/svenevs/repos","events_url":"https://api.github.com/users/svenevs/events{/privacy}","received_events_url":"https://api.github.com/users/svenevs/received_events","type":"User","site_admin":false},"created_at":"2018-03-14T00:00:01Z","updated_at":"2018-03-14T00:00:01Z","author_association":"CONTRIBUTOR","body":"1. Please fix the markdown.  You started and ended with a single back-tick, for code-blocks you need to use three:\r\n\r\n        ```cpp\r\n        // paste code\r\n        ```\r\n    noting that the three back-ticks are on their own lines.\r\n2. That's quite a lot of code.  I don't think many people will have the bandwidth to figure it all out.\r\n3. I'm not actually sure you can do this.  Here is the real issue:\r\n\r\n    ```cpp\r\n    gui->addVariable(\"Y\", scene->m_Objects[scene->GetFocus()]->getComponent()->m_scale.y);\r\n    ```\r\n\r\n    Suppose you had two meshes, `A` and `B` and `scene->m_Objects = {A, B}`, and `scene->GetFocus()` is `0`.  This means that variable `\"Y\"` is constructed and bound to `A->getComponent()->m_scale.y`.  At some later point `scene->GetFocus()` is returning `1` to indicate `B->getComponent()->m_scale.y` should be changed, **but this will never happen** because when the variable was created you bound it directly to `A->getComponent()->m_scale.y`.\r\n4. I'm not sure there is a way around that in the FormHelper, but you can look in the source code to see.  It may just be better to set this up manually.  You can create a `FloatBox<float>` for example, and set its callback (see `example1.cpp`).  Then in the callback, you can capture `[scene]` and update the current object in focus.  Or at least I think that's what you're trying to do?  "}}
{"actor":{"display_login":"svenevs"}}