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

Code before:
                self._shared_metadata.renderer = Rasterizer(viewer=None, context=self._shared_metadata.context)
                self._shared_metadata.renderer.build()

        self._shared_metadata.sensors.append(self)

        # Register camera now if standalone (offscreen), or defer to first render if using visualizer's rasterizer
        # (visualizer isn't built yet at sensor.build() time)
        if self._shared_metadata.renderer.offscreen:
            self._register_camera_with_renderer()

        _B = max(self._manager._sim.n_envs, 1)
        w, h = self._options.res
        self._shared_metadata.image_cache[self._idx] = torch.zeros((_B, h, w, 3), dtype=torch.uint8, device=gs.device)

    def _register_camera_with_renderer(self):
        """Register this camera with the renderer."""
        if self._camera_registered:
            return

        # Add lights from options to the context
        for light_config in self._options.lights:
            if self._shared_metadata.lights is not None:
                light_dict = self._convert_light_config_to_rasterizer(light_config)
                self._shared_metadata.context.add_light(light_dict)

        camera_wrapper = self._get_camera_wrapper()
        self._shared_metadata.renderer.add_camera(camera_wrapper)
        self._update_camera_pose()
        self._camera_registered = True

    def _create_standalone_context(self, scene):
        """Create a simplified RasterizerContext for camera sensors."""
        if not scene.sim._rigid_only and scene.n_envs > 1:
            gs.raise_exception("Rasterizer with n_envs > 1, does not work when using non rigid simulation")
        if sys.platform == "darwin":
            if scene.n_envs > 1:
                gs.raise_exception(
                    "Rasterizer with n_envs > 1, does not work on Metal because it doesn't support OpenGL 4.2"
                )
            env_separate_rigid = False
        else:
            if scene.n_envs > 1:
                gs.logger.warning(
                    "Rasterizer with n_envs > 1 is slow as it doesn't do batched rendering consider using BatchRenderer instead."
                )
            env_separate_rigid = True
        vis_options = VisOptions(
            show_world_frame=False,
            show_link_frame=False,
            show_cameras=False,
            rendered_envs_idx=range(max(self._manager._sim._B, 1)),

Review comment (suggestion):
While you are here, what is the point of `_get_camera_wrapper` ? This function seems useless. It was already the case because, but it is even worse now. Could you remove `_get_camera_wrapper` entirely and replace it direct access to `self._camera_wrapper` ? just add `self._register_camera_with_renderer()` on top of all functions that requires a valid camera.

Code after:
        self._shared_metadata.sensors.append(self)

        # Register camera now if standalone (offscreen), or defer to first render if using visualizer's rasterizer
        # (visualizer isn't built yet at sensor.build() time)
        if self._shared_metadata.renderer.offscreen:
            self._ensure_camera_registered()

        _B = max(self._manager._sim.n_envs, 1)
        w, h = self._options.res
        self._shared_metadata.image_cache[self._idx] = torch.zeros((_B, h, w, 3), dtype=torch.uint8, device=gs.device)

    def _ensure_camera_registered(self):
        """Register this camera with the renderer (no-op if already registered)."""
        if self._is_camera_registered:
            return

        # Add lights from options to the context
        for light_config in self._options.lights:
            if self._shared_metadata.lights is not None:
                light_dict = self._convert_light_config_to_rasterizer(light_config)
                self._shared_metadata.context.add_light(light_dict)

        if self._camera_wrapper is None:
            self._camera_wrapper = RasterizerCameraWrapper(self)
        self._shared_metadata.renderer.add_camera(self._camera_wrapper)
        self._update_camera_pose()
        self._is_camera_registered = True

    def _create_standalone_context(self, scene):
        """Create a simplified RasterizerContext for camera sensors."""
        if not scene.sim._rigid_only and scene.n_envs > 1:
            gs.raise_exception("Rasterizer with n_envs > 1, does not work when using non rigid simulation")
        if sys.platform == "darwin":
            if scene.n_envs > 1:
                gs.raise_exception(
                    "Rasterizer with n_envs > 1, does not work on Metal because it doesn't support OpenGL 4.2"
                )
            env_separate_rigid = False
        else:
            if scene.n_envs > 1:
                gs.logger.warning(
                    "Rasterizer with n_envs > 1 is slow as it doesn't do batched rendering consider using BatchRenderer instead."
                )
            env_separate_rigid = True
        vis_options = VisOptions(
            show_world_frame=False,
            show_link_frame=False,
            show_cameras=False,
            rendered_envs_idx=range(max(self._manager._sim._B, 1)),
            env_separate_rigid=env_separate_rigid,
        )