如何将鼠标坐标保持在窗口高度/宽度限制内

问题描述

假设我通过 glfwCreateWindow() 创建了一个 600 x 600 的窗口。

我在场景中渲染了一些模型,为了在 3D 空间中围绕它们移动,我使用了一个相机类,该类随我的光标以及 AWSD/空格键键移动。

为了使运动“无缝”,我使用 glfwSetInputMode(this->window,GLFW_CURSOR,GLFW_CURSOR_disABLED)

现在的问题是,我还试图实现各种鼠标选择器(从光标位置向场景投射光线)。

所以我从我在 yt 上找到的视频中实现了鼠标选择器,但它无法正常工作。原因是我的鼠标 X 和 Y 坐标比宽度和高度大,例如,如果我原地旋转(我可以无限增加它)。

我了解发生这种情况的原因是由于 glfwSetInputMode(this->window,GLFW_CURSOR_disABLED),我没有将光标限制在分辨率限制内。我在问我应该如何纠正这个问题,以便我可以保持无缝并能够将光标坐标限制在宽度和高度内(否则鼠标选择器功能将无法工作,因为标准化鼠标坐标完全超过 [1,1]打破它等等)。

我将不胜感激。

编辑:

@httpdigest 的答案放入非常基本的代码中:

        //store offsetX and offsetY values (and dont forget to give them 0 as initial value)
        overshootX = mouseX - offsetX;
        overshootY = mouseY - offsetY;

        if (overshootX > width) {
            offsetX = offsetX + overshootX - width;
        }
        if (overshootX < 0) {
            offsetX = offsetX + overshootX;
        }
        if (overshootY > height) {
            offsetY = offsetY + overshootY - height;
        }
        if (overshootY < 0) {
            offsetY = offsetY + overshootY;
        }

        float withinWindowCursorPosX = mouseX - offsetX;
        float withinWindowCursorPosY = mouseY - offsetY;

解决方法

一种方法是通过光标移动超出窗口/视口边界(X 和 Y 分开)的量来存储 if ( class_exists(S3Client::class) ) { echo 'Class exists: ' . S3Client::class; } else { echo 'Class does not exist: ' . S3Client::class; } (最初为 offset)。

基本上,每次当您读取当前光标位置或被事件告知更新时,您都会计算 (0,0)(X 和 Y 分开)。如果 overshoot = cursorPos - offset 超过 overshoot,您将 (width,height) 增加超过 offset 的超出部分。同样,如果 (width,height) 小于 overshoot,则将 (0,0) 减少负超调。

这样,您就有了一个“滑动”窗口/矩形,当您继续将鼠标光标移出屏幕的任一边缘时,该窗口/矩形就会四处滑动。

现在,只要您想获得更正的光标位置(在您的窗口内),您只需使用 offset

然后,您可以使用 withinWindowCursorPos = cursorPos - offset 进行需要窗口/视口内的光标的拾取计算。