java旋转问题中鼠标手动拾取光线计算

Manual mouse ray picking ray calculation in java rotation problem

我在使用 java(和 opengl/lwjgl)创建的游戏中完成鼠标光线拾取算法时遇到问题。我使用来自 here and here. I followed a lwjgl book 的灵​​感实现了光线追踪来实现游戏。以下代码为鼠标光线拾取算法:

// Calculate the normalized device coordinates
Vector2d mouseCoords = mouseInput.getPositionVector();
mouseCoords.mul((float)2 / window.width(), (float)2 / window.height());           
Vector4f mouseNDS = new Vector4f((float)mouseCoords.x, (float)mouseCoords.y, -1f, 1f);     

// Calculate the ray in cam space 
Vector4f eyeRay = mouseNDS.mul(renderer.getTransformations().getProjectionMatrix().invert());
eyeRay = new Vector4f(eyeRay.x, eyeRay.y, eyeRay.z, 0f);

// Calculate the ray in world space
Vector4f worldRay4f = eyeRay.mul(renderer.getTransformations().getViewMatrix(camera).invert());
Vector3f worldRay = new Vector3f(worldRay4f.x, worldRay4f.y, -worldRay4f.z).normalize();    

最终,我想将它与地平面 (y = 0) 相交。这是我的代码:

float lambda = camera.getPos().dot(new Vector3f(0, 1f , 0)) / worldRay.dot(new Vector3f(0, 1f, 0));      

Vector3f ray_scaled = worldRay.mul(lambda);
Vector3f ground_vec = new Vector3f();
camera.getPos().sub(ray_scaled, ground_vec);

此代码仅在相机指向负 y 方向(即直接向下)时有效,并且在我应用位置更改时保持有效。但是,如果我旋转相机,代码就会中断,即地面矢量不再在鼠标位置下方结束。

我怀疑相机的viewMatrix反转有问题。 viewMatrix 是通过这段代码计算的:

public Matrix4f getViewMatrix(Camera camera) {
        Vector3f cameraPos = camera.getPos();
        Vector3f rotation = camera.getRot();

        viewMatrix.identity();
        viewMatrix.rotate((float)Math.toRadians(rotation.x), new Vector3f(1, 0, 0))
                  .rotate((float)Math.toRadians(rotation.y), new Vector3f(0, 1, 0))
                  .rotate((float)Math.toRadians(rotation.z), new Vector3f(0, 0, 1));
        viewMatrix.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z);
        return viewMatrix;
}

谁能指出我正确的方向?

设置世界射线 (worldRay) 时出现问题。 z 组件不必反转:

Vector3f worldRay = new Vector3f(worldRay4f.x, worldRay4f.y, -worldRay4f.z).normalize();

Vector3f worldRay = new Vector3f(worldRay4f.x, worldRay4f.y, worldRay4f.z).normalize();   

如果相机指向负 y 方向,则 worldRay4fxz 分量为 0.0,误差不明显。


window坐标原点在左上角。在标准化设备 space 中,左上角是 (-1, 1),左下角是 (-1, -1)。因此在将鼠标坐标转换为归一化设备时必须翻转 y 坐标 space:

Vector2d mouseCoords = mouseInput.getPositionVector();
Vector4f mouseNDS = new Vector4f(
    (float)mouseCoords.x * 2f / window.width() - 1f,
    1f - (float)mouseCoords.y * 2f / window.height(),
    -1f, 1f);