I have a mesh loaded (assimp) in 3D environment in OpenGL. I want to move it along the mouse click (dragging) from one point to another. My present solution is behaving weirdly, the unprojected location is not correct and also I need to find a good way to move mesh along the mouse drag.
I am using unproject method as below:
glm::vec3 unProject(glm::vec3 win, glm::mat4 model, glm::mat4 proj, glm::vec4 viewport)
{
glm::mat4 Inverse = glm::inverse(proj * model);
glm::vec4 tmp = glm::vec4(win, 1);
tmp.x = (tmp.x - (viewport[0])) / (viewport[2]);
tmp.y = (tmp.y - (viewport[1])) / (viewport[3]);
tmp.x = tmp.x * (2) - (1);
tmp.y = tmp.y * (2) - (1);
glm::vec4 obj = Inverse * tmp;
obj /= obj.w;
return glm::vec3(obj);
}
along with a mouse callback
void mouse_callback(GLFWwindow* window, int button, int action, int mods)
{
if (button == GLFW_MOUSE_BUTTON_LEFT) {
if(GLFW_PRESS == action){
int screen_w, screen_h;
int pixel_w, pixel_h;
double xpos,ypos,zpos;
glfwGetWindowSize(window, &screen_w, &screen_h);
glfwGetFramebufferSize(window, &pixel_w, &pixel_h);
glfwGetCursorPos(window, &xpos, &ypos);
glm::vec2 screen_pos=glm::vec2(xpos, ypos);
glm::vec2 pixel_pos=screen_pos * glm::vec2(pixel_w, pixel_h) / glm::vec2(screen_w, screen_h);
glm::vec3 win=glm::vec3(pixel_pos.x, pixel_h-pixel_pos.y, 0.0f);
glReadPixels((GLint)win.x, (GLint)win.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &win.z);
//Fix
pixel_pos = pixel_pos + glm::vec2(0.5f, 0.5f); //Test
win = glm::vec3(pixel_pos.x, pixel_h-pixel_pos.y, win.z);
glm::vec4 viewport(0.0f,0.0f,(float)screen_w, (float)screen_h);
glm::mat4 transformMatrix = glm::mat4(1.0);
clickLocInWorld = unProject(win, camera.calculateViewMatrix() * transformMatrix, projection, viewport);
//clamp z-axis
if(clickLocInWorld.z > 10.0f)
clickLocInWorld.z = 10.0f;
if(clickLocInWorld.z < -10.0f)
clickLocInWorld.z = -10.0f;
std::cout << "screen " << xpos << " " << ypos << " " << zpos << std::endl;
std::cout << "world " << clickLocInWorld.x << " " << clickLocInWorld.y << " " << clickLocInWorld.z << std::endl;
}
}
}
I am trying to clamp z-axis, but need a proper way.
Also, I am trying to translate the model in 3D using
presentSpawnLoc = clickLocInWorld - presentSpawnLoc;
model = glm::translate(model, presentSpawnLoc);
model = glm::scale(model, glm::vec3(2.f, 2.f, 2.f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model));
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);