How to implement zoom towards mouse like in 3dsMax?

本秂侑毒 提交于 2019-12-06 07:31:21

A possible solution is to move the camera along a ray, from the camera position through the cursor (mouse) position and to move the target position in parallel.

self.eye    = self.eye    + ray_cursor * delta
self.target = self.target + ray_cursor * delta

For this the window position of the cursor has to be "un-projected" (unProject).

Calculate the cursor position in world space (e.g. on the far plane):

pt_wnd   = vec3(x, height - y, 1.0)
pt_world = unProject(pt_wnd, self.view, self.projection, viewport)

The ray from the eye position through the cursor is given by the the normalized vector from the eye position to the world space cursor position:

ray_cursor = normalize(pt_world - self.eye)

There is an issue in your code when you get the window height from the viewport rectangle, because the height is the .w component rather than the .z component:

v = glGetIntegerv(GL_VIEWPORT)
viewport = vec4(float(v[0]), float(v[1]), float(v[2]), float(v[3]))
width  = viewport.z
height = viewport.w

Full code listing of the function zoom_towards_cursor:

def zoom_towards_cursor(self, *args):
    x = args[2]
    y = args[3]
    v = glGetIntegerv(GL_VIEWPORT)
    viewport = vec4(float(v[0]), float(v[1]), float(v[2]), float(v[3]))
    width  = viewport.z
    height = viewport.w

    pt_wnd     = vec3(x, height - y, 1.0)
    pt_world   = unProject(pt_wnd, self.view, self.projection, viewport)
    ray_cursor = normalize(pt_world - self.eye)

    delta = -args[1]
    self.eye    = self.eye    + ray_cursor * delta
    self.target = self.target + ray_cursor * delta 

Preview:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!