Repository: Genesis-Embodied-AI/Genesis
File: genesis/engine/sensors/camera.py (Python)

Code before:
        elif self._link is not None:
            # Link exists but not built yet - use configured pose as-is (treat as world coordinates for now)
            # This will be corrected when move_to_attach is called
            pass

        transform = pos_lookat_up_to_T(pos, lookat, up)
        camera_wrapper = self._get_camera_wrapper()
        camera_wrapper.transform = tensor_to_array(transform)
        self._shared_metadata.renderer.update_camera(camera_wrapper)

    def _get_camera_wrapper(self):
        """Get (and lazily create) the persistent camera wrapper for the renderer."""
        if self._camera_wrapper is None:
            self._camera_wrapper = RasterizerCameraWrapper(self)
        return self._camera_wrapper

    def _apply_camera_transform(self, camera_T: torch.Tensor):
        """Update rasterizer camera wrapper from a world transform."""
        camera_wrapper = self._get_camera_wrapper()
        camera_wrapper.transform = tensor_to_array(camera_T)
        self._shared_metadata.renderer.update_camera(camera_wrapper)

    def _render_current_state(self):
        """Perform the actual render for the current state."""
        # Deferred registration for when using visualizer's rasterizer (visualizer now built)
        if not self._camera_registered:
            self._register_camera_with_renderer()

        self._shared_metadata.context.update(force_render=True)

        rgb_arr, _, _, _ = self._shared_metadata.renderer.render_camera(
            self._get_camera_wrapper(),
            rgb=True,
            depth=False,
            segmentation=False,
            normal=False,
        )

        rgb_tensor = torch.from_numpy(rgb_arr.copy()).to(dtype=torch.uint8, device=gs.device)

        if len(rgb_tensor.shape) == 3:
            # Single environment rendered - add batch dimension.
            rgb_tensor = rgb_tensor.unsqueeze(0)
        self._shared_metadata.image_cache[self._idx][:] = rgb_tensor


# ========================== Raytracer Camera Sensor ==========================
@register_sensor(RaytracerCameraOptions, RaytracerCameraSharedMetadata, CameraData)
class RaytracerCameraSensor(BaseCameraSensor):
    """
    Raytracer camera sensor using LuisaRender path tracing.

Review comment (suggestion):
The `if` condition is useless since `self._register_camera_with_renderer()` is already an no-op if already registered.

Code after:
            # This will be corrected when move_to_attach is called
            pass

        transform = pos_lookat_up_to_T(pos, lookat, up)
        self._camera_wrapper.transform = tensor_to_array(transform)
        self._shared_metadata.renderer.update_camera(self._camera_wrapper)

    def _apply_camera_transform(self, camera_T: torch.Tensor):
        """Update rasterizer camera wrapper from a world transform."""
        self._ensure_camera_registered()
        self._camera_wrapper.transform = tensor_to_array(camera_T)
        self._shared_metadata.renderer.update_camera(self._camera_wrapper)

    def _render_current_state(self):
        """Perform the actual render for the current state."""
        self._ensure_camera_registered()

        self._shared_metadata.context.update(force_render=True)

        rgb_arr, _, _, _ = self._shared_metadata.renderer.render_camera(
            self._camera_wrapper,
            rgb=True,
            depth=False,
            segmentation=False,
            normal=False,
        )

        # Ensure contiguous layout because the rendered array may have negative strides.
        rgb_tensor = torch.from_numpy(np.ascontiguousarray(rgb_arr)).to(dtype=torch.uint8, device=gs.device)

        if len(rgb_tensor.shape) == 3:
            # Single environment rendered - add batch dimension.
            rgb_tensor = rgb_tensor.unsqueeze(0)
        self._shared_metadata.image_cache[self._idx][:] = rgb_tensor


# ========================== Raytracer Camera Sensor ==========================
@register_sensor(RaytracerCameraOptions, RaytracerCameraSharedMetadata, CameraData)
class RaytracerCameraSensor(BaseCameraSensor):
    """
    Raytracer camera sensor using LuisaRender path tracing.
    """

    def __init__(
        self,
        options: RaytracerCameraOptions,
        idx: int,
        data_cls: Type[CameraData],
        manager: "gs.SensorManager",
    ):
        super().__init__(options, idx, data_cls, manager)