53 lines
1.6 KiB
Rust
53 lines
1.6 KiB
Rust
//! Camera and input state management
|
|
|
|
/// GPU-compatible camera uniform data
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
|
pub struct CameraUniform {
|
|
/// x: scale_x, y: scale_y, z: translate_x, w: translate_y
|
|
pub params: [f32; 4],
|
|
/// x: is_dark (1.0 for dark, 0.0 for light), y,z,w: padding
|
|
pub theme: [f32; 4],
|
|
}
|
|
|
|
/// Camera state for 2D map view
|
|
pub struct Camera {
|
|
pub x: f32,
|
|
pub y: f32,
|
|
pub zoom: f32,
|
|
pub aspect: f32,
|
|
}
|
|
|
|
impl Camera {
|
|
pub fn to_uniform(&self, is_dark: bool) -> CameraUniform {
|
|
// Simple 2D orthographic projection-like transform
|
|
// We want to map world coordinates to clip space [-1, 1]
|
|
// zoom controls how much of the world we see.
|
|
// aspect ratio correction is needed for non-square windows.
|
|
|
|
// Scale:
|
|
// If zoom is 1.0, we see 2.0 units of world height (from -1 to 1).
|
|
// scale_y = zoom
|
|
// scale_x = zoom / aspect
|
|
|
|
CameraUniform {
|
|
params: [
|
|
self.zoom / self.aspect, // scale_x
|
|
-self.zoom, // scale_y (flipped for North-Up)
|
|
-self.x * (self.zoom / self.aspect), // translate_x
|
|
self.y * self.zoom, // translate_y (flipped sign)
|
|
],
|
|
theme: [
|
|
if is_dark { 1.0 } else { 0.0 },
|
|
0.0, 0.0, 0.0
|
|
],
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Mouse/touch input state for drag operations
|
|
pub struct InputState {
|
|
pub is_dragging: bool,
|
|
pub last_cursor: Option<(f64, f64)>,
|
|
}
|