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

Code before:

        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,
        )

        rgb_tensor = torch.from_numpy(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)
        self._options: RaytracerCameraOptions
        self._camera_obj = None


Review comment (bug):
The CI is currently failing with the error:
```python
>       rgb_tensor = torch.from_numpy(rgb_arr).to(dtype=torch.uint8, device=gs.device)
E       ValueError: At least one stride in the given numpy array is negative, and tensors with negative strides are not currently supported. (You can probably work around this by making a copy of your array  with array.copy().)
```

This line should be replaced by:
```python
rgb_tensor = torch.tensor(rgb_arr, dtype=torch.uint8, device=gs.device)
```
With a comment of course explaining why this is necessary.

Code after:

        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)
        self._options: RaytracerCameraOptions
        self._camera_obj = None