scion 0.6.0

Game making library on top of wgpu, winit, legion
Documentation
use ultraviolet::{Mat4, Rotor3, Similarity3, Vec3, Vec4};

use crate::core::components::maths::{
    camera::Camera, coordinates::Coordinates, transform::Transform,
};

#[repr(C)]
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
pub(crate) struct GlVec2 {
    pub x: f32,
    pub y: f32,
}

#[repr(C)]
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
pub(crate) struct GlVec3 {
    pub x: f32,
    pub y: f32,
    pub z: f32,
}

impl GlVec3 {
    pub(crate) fn append_position(&mut self, x: f32, y: f32, z: f32) {
        self.x += x;
        self.y += y;
        self.z += z;
    }
}

impl From<&Coordinates> for GlVec3 {
    fn from(position: &Coordinates) -> Self {
        Self { x: position.x(), y: position.y(), z: 0. }
    }
}

#[repr(C)]
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
pub(crate) struct GlColor {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32,
}

#[repr(C)]
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
pub(crate) struct GlVec4 {
    pub x: f32,
    pub y: f32,
    pub z: f32,
    pub w: f32,
}

impl From<Vec4> for GlVec4 {
    fn from(vec: Vec4) -> Self {
        GlVec4 { x: vec.x, y: vec.y, z: vec.z, w: vec.w }
    }
}

#[repr(C)]
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
pub(crate) struct ColoredGlVertex {
    pub position: GlVec3,
    pub color: GlColor,
}

impl ColoredGlVertex {
    pub fn _desc<'a>() -> wgpu::VertexBufferLayout<'a> {
        wgpu::VertexBufferLayout {
            array_stride: std::mem::size_of::<ColoredGlVertex>() as wgpu::BufferAddress,
            step_mode: wgpu::VertexStepMode::Vertex,
            attributes: &[
                wgpu::VertexAttribute {
                    offset: 0,
                    shader_location: 0,
                    format: wgpu::VertexFormat::Float32x3,
                },
                wgpu::VertexAttribute {
                    offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
                    shader_location: 1,
                    format: wgpu::VertexFormat::Float32x3,
                },
            ],
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
pub(crate) struct TexturedGlVertex {
    pub position: GlVec3,
    pub tex_translation: GlVec2,
}

impl TexturedGlVertex {
    pub fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
        use std::mem;
        wgpu::VertexBufferLayout {
            array_stride: mem::size_of::<TexturedGlVertex>() as wgpu::BufferAddress,
            step_mode: wgpu::VertexStepMode::Vertex,
            attributes: &[
                wgpu::VertexAttribute {
                    offset: 0,
                    shader_location: 0,
                    format: wgpu::VertexFormat::Float32x3,
                },
                wgpu::VertexAttribute {
                    offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
                    shader_location: 1,
                    format: wgpu::VertexFormat::Float32x2,
                },
            ],
        }
    }
}

impl From<(&Coordinates, &Coordinates)> for TexturedGlVertex {
    fn from(positions: (&Coordinates, &Coordinates)) -> Self {
        TexturedGlVertex {
            position: GlVec3 { x: positions.0.x(), y: positions.0.y(), z: 0.0 },
            tex_translation: GlVec2 { x: positions.1.x(), y: positions.1.y() },
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
pub(crate) struct GlUniform {
    pub model_trans: [[f32; 4]; 4],
    pub camera_view: [[f32; 4]; 4],
}

impl GlUniform {
    pub(crate) fn replace_with(&mut self, other: GlUniform) {
        self.model_trans = other.model_trans;
        self.camera_view = other.camera_view;
    }
}

pub(crate) fn create_glmat4(t: &mut Mat4) -> [[f32; 4]; 4] {
    let result = [
        create_glmat(&t.cols[0]),
        create_glmat(&t.cols[1]),
        create_glmat(&t.cols[2]),
        create_glmat(&t.cols[3]),
    ];
    result
}

pub(crate) fn create_glmat(t: &Vec4) -> [f32; 4] {
    [t.x, t.y, t.z, t.w]
}

pub(crate) struct UniformData<'a> {
    pub transform: &'a Transform,
    pub camera: (&'a Camera, &'a Transform),
    pub is_ui_component: bool,
}

impl From<UniformData<'_>> for GlUniform {
    fn from(uniform_data: UniformData) -> Self {
        let mut model_trans = Similarity3::identity();
        model_trans.prepend_scaling(uniform_data.transform.scale);
        model_trans.append_translation(Vec3 {
            x: uniform_data.transform.global_translation.x(),
            y: uniform_data.transform.global_translation.y(),
            z: uniform_data.transform.global_translation.z() as f32,
        });
        if !uniform_data.is_ui_component && !uniform_data.transform.use_screen_as_origin {
            model_trans.append_translation(Vec3 {
                x: -1. * uniform_data.camera.1.global_translation().x(),
                y: -1. * uniform_data.camera.1.global_translation().y(),
                z: 0.0,
            });
        }
        model_trans
            .prepend_rotation(Rotor3::from_rotation_xy(uniform_data.transform.angle).normalized());
        let mut model_trans = model_trans.into_homogeneous_matrix();
        let mut camera_view = ultraviolet::projection::lh_ydown::orthographic_wgpu_dx(
            uniform_data.camera.0.left,
            uniform_data.camera.0.right * uniform_data.camera.0.dpi as f32,
            uniform_data.camera.0.bottom * uniform_data.camera.0.dpi as f32,
            uniform_data.camera.0.top,
            uniform_data.camera.0.near,
            uniform_data.camera.0.far,
        );
        GlUniform {
            model_trans: create_glmat4(&mut model_trans),
            camera_view: create_glmat4(&mut camera_view),
        }
    }
}