#[allow(unused_imports)] use log::{debug, error, info, trace, warn}; use crate:: utils::Position; use super::{Uniform, WgpuRenderer}; use cgmath::{ Deg, Vector2, Matrix3, }; pub const MATRIX_SIZE: usize = 48;//std::mem::size_of::>(); //--ModelMatrix struct------------------------------------------------------------------------------ pub struct ModelMatrix { position: Position, rotation: Deg, scale: f32, aspect_matrix: Matrix3, uniform: Uniform, is_synced: bool, } impl ModelMatrix { pub fn new(renderer: &WgpuRenderer, pos: Position, rot: f32, scale: f32) -> Self { let surface_size: Vector2 = renderer.get_surface_size().into(); //A factor 2 is used so scales and offsets can be in sync with the translations wich are //smaller by a factor 2, and I have no idea why. let aspect_matrix = Matrix3::from_nonuniform_scale(2.0/surface_size.x, 2.0/surface_size.y) * Matrix3::from_translation(-surface_size/2.0); Self { position: pos, rotation: Deg (rot), scale, aspect_matrix, uniform: Uniform::create(renderer, &renderer.matrix_layout), is_synced: false, } } pub fn default(renderer: &WgpuRenderer) -> Self { Self::new(renderer, Position::origin(), 0.0, 1.0) } pub fn set_position(&mut self, pos: Position) { self.position = pos; self.is_synced = false; } pub fn set_rotation(&mut self, rot: f32) { self.rotation = Deg (rot); self.is_synced = false; } pub fn set_scale(&mut self, scale: f32) { self.scale = scale; self.is_synced = false; } pub fn get_uniform(&mut self) -> &mut Uniform { use cgmath::{Basis3, Rotation3}; if self.is_synced == false { let translation_mat = Matrix3::from_translation(self.position.into()); let rotation_mat = Matrix3::from(Basis3::from_angle_z(self.rotation)); //same factor 2 as for the aspect ratio and the offset, no idea why its needed either let scale_mat = Matrix3::from_scale(self.scale/2.0); let matrix = self.aspect_matrix * translation_mat * scale_mat * rotation_mat; let mat_bytes: [u8; 36] = bytemuck::bytes_of(&matrix).try_into().unwrap(); //wgsl uses 16 bytes-aligned matrixes, but ours is 12 bytes-aligned. Fix that by adding //4 paddings bytes after each 12 bytes let mut bytes = [0; 48]; for i in 0..12 { bytes[i] = mat_bytes[i]; } for i in 0..12 { bytes[i+16] = mat_bytes[i+12]; } for i in 0..12 { bytes[i+32] = mat_bytes[i+24]; } self.uniform.update(bytes); self.is_synced = true; } &mut self.uniform } }