use crate::components::{Transform, Sprite};
use super::super::resources::Vertex;
pub struct CoordinateTransform {
screen_width: f32,
screen_height: f32,
}
impl CoordinateTransform {
pub fn new(screen_width: f32, screen_height: f32) -> Self {
Self { screen_width, screen_height }
}
pub fn screen_to_ndc(&self, screen_x: f32, screen_y: f32) -> [f32; 2] {
let ndc_x = (screen_x / self.screen_width) * 2.0 - 1.0;
let ndc_y = 1.0 - (screen_y / self.screen_height) * 2.0; [ndc_x, ndc_y]
}
pub fn screen_size_to_ndc(&self, width: f32, height: f32) -> [f32; 2] {
[width / self.screen_width, height / self.screen_height]
}
}
pub struct Transform2D;
impl Transform2D {
pub fn apply_transform(
local_pos: [f32; 2],
center: [f32; 2],
rotation: f32
) -> [f32; 2] {
let rotation_rad = rotation.to_radians(); let cos_r = rotation_rad.cos();
let sin_r = rotation_rad.sin();
let rotated_x = local_pos[0] * cos_r - local_pos[1] * sin_r;
let rotated_y = local_pos[0] * sin_r + local_pos[1] * cos_r;
[center[0] + rotated_x, center[1] + rotated_y]
}
pub fn calculate_sprite_corners(
transform: &Transform,
sprite: &Sprite,
coord_transform: &CoordinateTransform,
) -> [Vertex; 4] {
let width = sprite.size.x * transform.scale.x;
let height = sprite.size.y * transform.scale.y;
let color = [sprite.color.r, sprite.color.g, sprite.color.b, sprite.color.a];
let u_start = if sprite.flip_x { 1.0 } else { 0.0 };
let u_end = if sprite.flip_x { 0.0 } else { 1.0 };
let v_start = if sprite.flip_y { 1.0 } else { 0.0 };
let v_end = if sprite.flip_y { 0.0 } else { 1.0 };
let uv_coords = [
[u_start, v_start], [u_end, v_start], [u_end, v_end], [u_start, v_end], ];
let local_corners_screen = [
[-width / 2.0, -height / 2.0], [width / 2.0, -height / 2.0], [width / 2.0, height / 2.0], [-width / 2.0, height / 2.0], ];
let center_screen = [transform.position.x, transform.position.y];
let mut vertices = [Vertex::with_uv([0.0, 0.0], color, [0.0, 0.0]); 4];
for (i, &local_pos) in local_corners_screen.iter().enumerate() {
let rotated_screen = Self::apply_transform(local_pos, center_screen, transform.rotation);
let final_ndc = coord_transform.screen_to_ndc(rotated_screen[0], rotated_screen[1]);
vertices[i] = Vertex::with_uv(final_ndc, color, uv_coords[i]);
}
vertices
}
}