Source code for genesis.options.sensors.camera

"""
Camera sensor options for Rasterizer, Raytracer, and Batch Renderer backends.
"""

from typing import TYPE_CHECKING, Any, Literal

from pydantic import Field, StrictBool

import genesis as gs
from genesis.typing import (
    Matrix4x4Type,
    PositiveFloat,
    PositiveInt,
    PositiveVec2IType,
    UnitVec4FType,
    ValidFloat,
    Vec3FType,
)

from .options import KinematicSensorOptionsMixin, SensorT

if TYPE_CHECKING:
    from genesis.engine.sensors.camera import BatchRendererCameraSensor, RasterizerCameraSensor, RaytracerCameraSensor


class BaseCameraOptions(KinematicSensorOptionsMixin[SensorT]):
    """
    Base class for camera sensor options containing common properties.

    Parameters
    ----------
    res : tuple[int, int]
        Resolution as (width, height). Default is (512, 512).
    pos : array-like[float, float, float]
        Camera position offset. If attached to a link, this is relative to the link frame.
        If not attached, this is relative to the world origin. Default is (3.5, 0.0, 1.5).
    lookat : array-like[float, float, float]
        Point the camera looks at in world frame.
    up : array-like[float, float, float]
        Up vector for camera orientation. Default is (0, 0, 1).
    fov : float
        Vertical field of view in degrees. Default is 60.0.
    lights : list[dict], optional
        List of lights to add for this camera backend. Each light is a dict with
        backend-specific parameters. Default is empty list.
    offset_T : array-like, shape (4, 4), optional
        4x4 transformation matrix specifying the camera's pose relative to the attached link.
        If provided, this takes priority over pos_offset and euler_offset. Default is None.
    entity_idx : int
        The global entity index of the RigidEntity to which this sensor is attached. -1 or None for static sensors.
    link_idx_local : int, optional
        The local index of the RigidLink of the RigidEntity to which this sensor is attached.
    """

    res: PositiveVec2IType = (512, 512)
    pos: Vec3FType = (3.5, 0.0, 1.5)
    lookat: Vec3FType = (0.0, 0.0, 0.0)
    up: Vec3FType = (0.0, 0.0, 1.0)
    fov: ValidFloat = Field(default=60.0, gt=0, lt=180)
    lights: list[dict[str, Any]] = []
    offset_T: Matrix4x4Type | None = None

    def model_post_init(self, context: Any) -> None:
        if self.history_length > 0:
            gs.raise_exception(
                "Camera sensors do not support `history_length`. The camera read path renders lazily on read() "
                "and bypasses the shared sensor cache that backs the history buffer."
            )


[docs]class RasterizerCameraOptions(BaseCameraOptions["RasterizerCameraSensor"]): """ Options for Rasterizer camera sensor (OpenGL-based rendering). Parameters ---------- near : float Near clipping plane distance. Default is 0.01. far : float Far clipping plane distance. Default is 100.0. """ near: PositiveFloat = 0.01 far: PositiveFloat = 100.0 def model_post_init(self, context: Any) -> None: super().model_post_init(context) if self.far <= self.near: gs.raise_exception(f"far must be greater than near, got near={self.near}, far={self.far}")
[docs]class RaytracerCameraOptions(BaseCameraOptions["RaytracerCameraSensor"]): """ Options for Raytracer camera sensor (LuisaRender path tracing). Parameters ---------- model : str Camera model: "pinhole" or "thinlens". Default is "pinhole". spp : int Samples per pixel for path tracing. Default is 256. denoise : bool Whether to apply denoising. Default is False. aperture : float Aperture size for thinlens camera (depth of field). Default is 2.8. focal_len : float Focal length in meters for thinlens camera. Default is 0.05. focus_dist : float Focus distance in meters for thinlens camera. Default is 3.0. env_surface : gs.surfaces.Surface | None Environment surface for skybox. Default is None. env_radius : float Environment sphere radius. Default is 15.0. env_pos : tuple[float, float, float] Environment sphere position. Default is (0, 0, 0). env_quat : tuple[float, float, float, float] Environment sphere quaternion (w, x, y, z). Default is (1, 0, 0, 0). """ model: Literal["pinhole", "thinlens"] = "pinhole" spp: PositiveInt = 256 denoise: StrictBool = False aperture: PositiveFloat = 2.8 focal_len: PositiveFloat = 0.05 focus_dist: PositiveFloat = 3.0 env_surface: Any = None # gs.surfaces.Surface env_radius: PositiveFloat = 15.0 env_pos: Vec3FType = (0.0, 0.0, 0.0) env_quat: UnitVec4FType = (1.0, 0.0, 0.0, 0.0)
[docs]class BatchRendererCameraOptions(BaseCameraOptions["BatchRendererCameraSensor"]): """ Options for Batch Renderer camera sensor (Madrona GPU batch rendering). Note: All batch renderer cameras must have the same resolution. Parameters ---------- use_rasterizer : bool Whether to use rasterizer mode. Default is True. """ model: Literal["pinhole", "thinlens", "fisheye"] = "pinhole" near: PositiveFloat = 0.01 far: PositiveFloat = 100.0 use_rasterizer: StrictBool = True def model_post_init(self, context: Any) -> None: super().model_post_init(context) if self.far <= self.near: gs.raise_exception(f"far must be greater than near, got near={self.near}, far={self.far}")