Source code for picogl.backend.modern.core.unproject

"""
Modern OpenGL Unproject Function
"""

from typing import Any, Tuple

import numpy as np

from picogl.backend.modern.core.mvp import (
    convert_to_world_coordinates,
    create_normalized_device_vector,
    invert_mvp_matrix,
    normalize_device_coordinates,
)


[docs] def unproject( x: int, y: int, depth: float, model_view: np.ndarray, projection: np.ndarray, viewport: Tuple[int, int, int, int], ) -> tuple[Any, ...] | None: """ unproject :param x: X screen coordinate :param y: Y screen coordinate :param depth: Depth value from depth buffer (range 0.0 - 1.0) :param model_view: 4x4 model_matrix-view matrix :param projection: 4x4 projection matrix :param viewport: Viewport tuple (x, y, width, height) :return: (x, y, z) in world space, or None if invalid Unprojects 2D screen coordinates into 3D world coordinates in modern OpenGL. """ if depth == 1.0: return None # Depth of 1.0 means background ndc_x, ndc_y, ndc_z = normalize_device_coordinates(depth, viewport, x, y) normalized_device_vector = create_normalized_device_vector(ndc_x, ndc_y, ndc_z) inverse_mvp_matrix = invert_mvp_matrix(projection, model_view) world_coords = convert_to_world_coordinates( inverse_mvp_matrix, normalized_device_vector ) if world_coords[3] == 0.0: return None # Perspective divide world_coords /= world_coords[3] return tuple(world_coords[:3])