use crate::graphics::DrawImageParams;
#[repr(C)]
#[derive(Copy, Clone)]
pub(crate) struct ImageVertex {
pub(crate) pos: [f32; 2], pub(crate) uv: [f32; 2],
pub(crate) screen_xy: [f32; 2], pub(crate) mask_ox: f32,
pub(crate) mask_oy: f32,
pub(crate) mask_w: f32,
pub(crate) mask_h: f32,
pub(crate) mask_on: f32, pub(crate) alpha: f32,
}
pub(crate) fn build_image_quad_ex(
x: i32, y: i32,
image_w: u32, image_h: u32,
screen_w: u32, screen_h: u32,
mask_ox: f32, mask_oy: f32, mask_w: f32, mask_h: f32, mask_on: f32,
params: &DrawImageParams,
) -> [ImageVertex; 6] {
let sw = screen_w as f32;
let sh = screen_h as f32;
let draw_w = image_w as f32 * params.scale_x;
let draw_h = image_h as f32 * params.scale_y;
let cx = x as f32 + draw_w * 0.5;
let cy = y as f32 + draw_h * 0.5;
let hw = draw_w * 0.5;
let hh = draw_h * 0.5;
let rad = params.rotation.to_radians();
let cos = rad.cos();
let sin = rad.sin();
let rot = |lx: f32, ly: f32| -> (f32, f32) { (lx * cos - ly * sin, lx * sin + ly * cos) };
let (tl_x, tl_y) = rot(-hw, -hh);
let (tr_x, tr_y) = rot( hw, -hh);
let (bl_x, bl_y) = rot(-hw, hh);
let (br_x, br_y) = rot( hw, hh);
let corners = [
(cx + tl_x, cy + tl_y),
(cx + tr_x, cy + tr_y),
(cx + bl_x, cy + bl_y),
(cx + br_x, cy + br_y),
];
let (u0, u1) = if params.flip_x { (1.0f32, 0.0f32) } else { (0.0f32, 1.0f32) };
let (v0, v1) = if params.flip_y { (1.0f32, 0.0f32) } else { (0.0f32, 1.0f32) };
let ndc = |px: f32, py: f32| -> [f32; 2] { [px / sw * 2.0 - 1.0, 1.0 - py / sh * 2.0] };
let v = |idx: usize, u: f32, tv: f32| ImageVertex {
pos: ndc(corners[idx].0, corners[idx].1),
uv: [u, tv],
screen_xy: [corners[idx].0, corners[idx].1],
mask_ox, mask_oy, mask_w, mask_h, mask_on,
alpha: params.alpha,
};
let tl = v(0, u0, v0);
let tr = v(1, u1, v0);
let bl = v(2, u0, v1);
let br = v(3, u1, v1);
[tl, tr, bl, tr, br, bl]
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn build_image_quad_overlay(
x: i32, y: i32,
image_w: u32, image_h: u32,
display_w: u32, display_h: u32,
main_x: i32, main_y: i32,
win_scale_x: f32, win_scale_y: f32,
mask_ox: f32, mask_oy: f32, mask_w: f32, mask_h: f32, mask_on: f32,
params: &DrawImageParams,
) -> [ImageVertex; 6] {
let dw = display_w as f32;
let dh = display_h as f32;
let draw_w = image_w as f32 * params.scale_x * win_scale_x;
let draw_h = image_h as f32 * params.scale_y * win_scale_y;
let cx = x as f32 * win_scale_x + draw_w * 0.5 + main_x as f32;
let cy = y as f32 * win_scale_y + draw_h * 0.5 + main_y as f32;
let hw = draw_w * 0.5;
let hh = draw_h * 0.5;
let (dmox, dmoy, dmw, dmh) = if mask_on > 0.5 {
(mask_ox * win_scale_x + main_x as f32,
mask_oy * win_scale_y + main_y as f32,
mask_w * win_scale_x,
mask_h * win_scale_y)
} else {
(mask_ox, mask_oy, mask_w, mask_h)
};
let rad = params.rotation.to_radians();
let cos = rad.cos();
let sin = rad.sin();
let rot = |lx: f32, ly: f32| -> (f32, f32) { (lx * cos - ly * sin, lx * sin + ly * cos) };
let (tl_x, tl_y) = rot(-hw, -hh);
let (tr_x, tr_y) = rot( hw, -hh);
let (bl_x, bl_y) = rot(-hw, hh);
let (br_x, br_y) = rot( hw, hh);
let corners = [(cx+tl_x, cy+tl_y), (cx+tr_x, cy+tr_y), (cx+bl_x, cy+bl_y), (cx+br_x, cy+br_y)];
let (u0, u1) = if params.flip_x { (1.0f32, 0.0f32) } else { (0.0f32, 1.0f32) };
let (v0, v1) = if params.flip_y { (1.0f32, 0.0f32) } else { (0.0f32, 1.0f32) };
let ndc = |px: f32, py: f32| -> [f32; 2] { [px / dw * 2.0 - 1.0, 1.0 - py / dh * 2.0] };
let sv = |idx: usize, u: f32, tv: f32| ImageVertex {
pos: ndc(corners[idx].0, corners[idx].1),
uv: [u, tv],
screen_xy: [corners[idx].0, corners[idx].1],
mask_ox: dmox, mask_oy: dmoy, mask_w: dmw, mask_h: dmh, mask_on,
alpha: params.alpha,
};
let tl = sv(0, u0, v0); let tr = sv(1, u1, v0);
let bl = sv(2, u0, v1); let br = sv(3, u1, v1);
[tl, tr, bl, tr, br, bl]
}