/** * Project a world point through the matrix to get its screen position. * * @param world the point to project * @return its screen position */ @Nullable public Vec2i project(@NotNull Vec3f world) { Vec4f vec = Matrix.mul(getPmvMatrix(), new Vec4f(world, 1.0f)); Vec2i screen = null; if (vec.getW() != 0.0f) { double z = vec.getZ() / vec.getW(); if (z < 1) { int x = (int) ((vec.getX() / vec.getW() * 0.5 + 0.5) * viewport.getWidth()); int y = (int) (viewport.getHeight() - (vec.getY() / vec.getW() * 0.5 + 0.5) * viewport.getHeight()); screen = new Vec2i(x, y); } } return screen; }
/** Transforms a pixel in window coordinates to a ray in world coordinates. */ public static Ray windowToWorld(Camera camera, Viewport viewport, Point windowCoords) { Vec2f ndc = viewport.windowToNDC(windowCoords); Vec4f n = camera .getViewInverse() .times(camera.getProjectionInverse().times(new Vec4f(ndc.x, ndc.y, -1, 1))); n.divide(n.w); Vec4f f = camera .getViewInverse() .times(camera.getProjectionInverse().times(new Vec4f(ndc.x, ndc.y, 1, 1))); f.divide(f.w); return new Ray(n.xyz(), f.minus(n).xyz().normalized()); }
/** Transforms a point in world coordinates to a pixel in window coordinates. */ public static Point worldToWindow(Camera camera, Viewport viewport, Vec3f worldCoords) { Vec4f clip = camera.getProjection().times(camera.getView().times(new Vec4f(worldCoords, 1))); Vec2f ndc = clip.over(clip.w).xy(); return viewport.ndcToWindow(ndc); }