📄 src/camera_controller.rs
use bevy::{
    app::{App, Plugin, Update},
    camera::Camera,
    ecs::{message::MessageReader, query::With, system::Single},
    math::Vec3,
    transform::components::Transform,
};

use crate::{face_detection::FaceMoved, virtual_window::VirtualWindow};

pub struct CameraControllerPlugin;

impl Plugin for CameraControllerPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(Update, move_camera_with_face);
    }
}

fn move_camera_with_face(
    camera: Single<(&mut Transform, &VirtualWindow), With<Camera>>,
    mut face_moved: MessageReader<FaceMoved>,
) {
    let Some(face) = face_moved.read().last() else {
        return;
    };

    let (mut camera, window) = camera.into_inner();

    let relative_face = Transform::IDENTITY
        .looking_to(window.camera_normal(), Vec3::Y)
        .rotation
        * face.0;

    camera.translation = window.camera_position() + relative_face;
    camera.look_at(window.center(), Vec3::Y);
}