import numpy as np
[docs]
MVP_ZOOM_SCALE = -0.0015
[docs]
def compute_mvp_zoom_from_zoom(zoom_value: float) -> float:
"""
compute_mvp_zoom_from_zoom
:param zoom_value: float
:return: float
Compute the MVP zoom factor from a zoom value.
"""
return MVP_ZOOM_SCALE * zoom_value
[docs]
def compute_zoom_from_mvp_zoom(mvp_zoom: float) -> float:
"""
compute_zoom_from_mvp_zoom
:param mvp_zoom: float
:return: float
"""
return mvp_zoom / MVP_ZOOM_SCALE
[docs]
def invert_mvp_matrix(
projection: np.ndarray, model_view: np.ndarray
) -> np.ndarray | None:
"""
invert_mvp_matrix
:param projection: 4x4 projection matrix
:param model_view: np.ndarray
:return: np.ndarray
Compute inverse of MVP matrix
"""
mvp_matrix = np.dot(projection, model_view)
try:
inverse_mvp_matrix = np.linalg.inv(mvp_matrix)
return inverse_mvp_matrix
except np.linalg.LinAlgError:
return None
[docs]
def create_normalized_device_vector(
ndc_x: float, ndc_y: float, ndc_z: float
) -> np.ndarray:
"""
create_normalized_device_vector
:param ndc_x: float normalized device x coordinate 0.0-1.0
:param ndc_y: float normalized device y coordinate 0.0-1.0
:param ndc_z: float normalized device z coordinate 0.0-1.0
:return: np.ndarray normalized_device_vector
Create normalized device coordinate vector
"""
normalized_device_vector = np.array([ndc_x, ndc_y, ndc_z, 1.0], dtype=np.float32)
return normalized_device_vector
[docs]
def normalize_device_coordinates(depth, viewport, x, y):
"""
normalize_device_coordinates
:param depth: float
:param viewport: np.ndarray
:param x: int
:param y: int
:return: float, float, float
"""
# Normalize device coordinates
ndc_x = (x - viewport[0]) / viewport[2] * 2.0 - 1.0
ndc_y = (y - viewport[1]) / viewport[3] * 2.0 - 1.0
ndc_y = -ndc_y # Flip Y axis (OpenGL vertex_shader screen coordinates)
ndc_z = depth * 2.0 - 1.0
return ndc_x, ndc_y, ndc_z
[docs]
def convert_to_world_coordinates(inverse_mvp_matrix, normalized_device_vector):
"""
convert_to_world_coordinates
:param inverse_mvp_matrix: np.ndarray inverse_mvp_matrix
:param normalized_device_vector: np.ndarray normalized_device_vector
:return: np.ndarray world_coordinates
"""
world_coords = inverse_mvp_matrix @ normalized_device_vector
return world_coords