Jump to content

Converting 2d screen coordinates to a ray.


IRaconI

Recommended Posts

I'm trying to create functionality to take in a 2d screen coordinate and return the block type at that point, as well as the distance to that block. I've tried this function, but it returns a ray in seemingly a random direction. ScreenWidth and ScreenHeight are the Minecraft window size. (I didn't use the built in inverse function because it was giving the wrong result for some reason. I manually verified.)

public static Vec3 GetRay(float screenX, float screenY, Camera cam) {
		Matrix4f projectionMatrix = getProjectionMatrix();
		Matrix4f viewMatrix = getViewMatrix(cam);
		
		float ndcX = (2.0f * screenX) / ScreenWidth - 1.0f;
		float ndcY = 1.0f - (2.0f * screenY) / ScreenHeight;
		Vector4f screenVector = new Vector4f(ndcX, ndcY, -1.0f, 1.0f);
		
        Matrix4f inversePM = new Matrix4f(projectionMatrix);
        float detPM = inversePM.adjugateAndDet();
        inversePM.multiply(1.0f / detPM);
        screenVector.transform(inversePM);
        
        screenVector.setZ(-1.0f);
        screenVector.setW(0.0f);
        
        Matrix4f inverseVM = new Matrix4f(viewMatrix);
        float detVM = inverseVM.adjugateAndDet();
        inverseVM.multiply(1.0f / detVM);
        screenVector.transform(inverseVM);

        Vec3 direction = new Vec3(screenVector.x(), screenVector.y(), screenVector.z());
        direction = direction.normalize();

        return direction;
    }

private static Matrix4f getViewMatrix(Camera cam) {
        Vec3 cameraPos = cam.getPosition();
        Vector3f camPos = new Vector3f((float) cameraPos.x, (float) cameraPos.y, (float) cameraPos.z);

        Vector3f forward = cam.getLookVector();
        forward.normalize();
        Vector3f up = cam.getUpVector();
        up.normalize();
        Vector3f right = cam.getLeftVector();
        right.mul(-1.0f);
        right.normalize();
        
        float[] values = {
        	right.x(), up.x(), -forward.x(), 0,
        	right.y(), up.y(), -forward.y(), 0,
        	right.z(), up.z(), -forward.z(), 0,
            -camPos.dot(right), -camPos.dot(up), -camPos.dot(forward), 1.0f
        };
        
        Matrix4f viewMatrix = new Matrix4f(values);
        
        return viewMatrix;
    }

private static Matrix4f getProjectionMatrix() {
        double fov = Math.toRadians(90.0);
        double aspectRatio = ScreenWidth / ScreenHeight;
        double nearPlane = 0.05f;
        double farPlane = 1000.0f;

        double yScale = 1.0f / Math.tan(fov / 2.0f);
        double xScale = yScale / aspectRatio;
        double frustumLength = farPlane - nearPlane;

        float[] values = new float[]{
            (float) xScale, 0.0f, 0.0f, 0.0f,
            0.0f, (float) yScale, 0.0f, 0.0f,
            0.0f, 0.0f, (float) -((farPlane + nearPlane) / frustumLength), -1.0f,
            0.0f, 0.0f, (float) -((2.0f * nearPlane * farPlane) / frustumLength), 0.0f
        };

        return new Matrix4f(values);
    }

 

Edited by IRaconI
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.