pub type TransformMatrix = [[f32; 4]; 4];
#[derive(Debug, Clone, Copy)]
pub struct Transform {
pub translation: [f32; 3],
pub rotation: [f32; 4], pub scale: [f32; 3],
pub model: TransformMatrix,
pub matrix_world: TransformMatrix,
}
impl Default for Transform {
fn default() -> Self {
let translation = [0.0; 3];
let rotation = [0.0, 0.0, 0.0, 1.0];
let scale = [1.0; 3];
let model = [
[scale[0], 0.0, 0.0, 0.0],
[0.0, scale[1], 0.0, 0.0],
[0.0, 0.0, scale[2], 0.0],
[translation[0], translation[1], translation[2], 1.0],
];
Self {
translation,
rotation,
scale,
model,
matrix_world: model,
}
}
}
impl Transform {
pub fn recompute_model(&mut self) {
let [tx, ty, tz] = self.translation;
let [sx, sy, sz] = self.scale;
let [x, y, z, w] = self.rotation;
let len2 = x * x + y * y + z * z + w * w;
let inv_len = if len2 > 0.0 { len2.sqrt().recip() } else { 1.0 };
let (x, y, z, w) = (x * inv_len, y * inv_len, z * inv_len, w * inv_len);
let xx = x * x;
let yy = y * y;
let zz = z * z;
let xy = x * y;
let xz = x * z;
let yz = y * z;
let wx = w * x;
let wy = w * y;
let wz = w * z;
let r00 = 1.0 - 2.0 * (yy + zz);
let r01 = 2.0 * (xy + wz);
let r02 = 2.0 * (xz - wy);
let r10 = 2.0 * (xy - wz);
let r11 = 1.0 - 2.0 * (xx + zz);
let r12 = 2.0 * (yz + wx);
let r20 = 2.0 * (xz + wy);
let r21 = 2.0 * (yz - wx);
let r22 = 1.0 - 2.0 * (xx + yy);
let c0 = [r00 * sx, r01 * sx, r02 * sx, 0.0];
let c1 = [r10 * sy, r11 * sy, r12 * sy, 0.0];
let c2 = [r20 * sz, r21 * sz, r22 * sz, 0.0];
let c3 = [tx, ty, tz, 1.0];
self.model = [c0, c1, c2, c3];
}
}
#[derive(Debug, Clone)]
pub struct Renderable {
pub mesh: CpuMeshHandle,
pub base_mesh: CpuMeshHandle,
pub material: MaterialHandle,
}
impl Renderable {
pub fn new(mesh: CpuMeshHandle, material: MaterialHandle) -> Self {
Self {
mesh,
base_mesh: mesh,
material,
}
}
pub fn with_base_mesh(mut self, base_mesh: CpuMeshHandle) -> Self {
self.base_mesh = base_mesh;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct GpuRenderable {
pub mesh: MeshHandle,
pub material: MaterialHandle,
}
impl GpuRenderable {
pub fn new(mesh: MeshHandle, material: MaterialHandle) -> Self {
Self { mesh, material }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct BufferHandle(pub u32);
#[derive(Debug, Clone)]
pub struct VertexLayout {
pub stride: u32,
pub attributes: &'static [VertexAttribute],
}
#[derive(Debug, Clone, Copy)]
pub struct VertexAttribute {
pub location: u32,
pub offset: u32,
pub format: VertexFormat,
}
#[derive(Debug, Clone, Copy)]
pub enum VertexFormat {
Float32x2,
Float32x3,
Float32x4,
Uint32,
}
impl MeshHandle {
pub const TRIANGLE: MeshHandle = MeshHandle(2);
pub const SQUARE: MeshHandle = MeshHandle(3);
pub const CUBE: MeshHandle = MeshHandle(0);
pub const TETRAHEDRON: MeshHandle = MeshHandle(1);
}
#[derive(Debug, Clone, Copy)]
pub struct GpuMesh {
pub vertex_buffer: BufferHandle,
pub index_buffer: BufferHandle,
pub index_count: u32,
pub vertex_layout: &'static VertexLayout,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MeshHandle(pub u32);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct CpuMeshHandle(pub u32);
impl CpuMeshHandle {
pub const TRIANGLE_2D: CpuMeshHandle = CpuMeshHandle(0);
pub const QUAD_2D: CpuMeshHandle = CpuMeshHandle(1);
pub const CUBE: CpuMeshHandle = CpuMeshHandle(2);
pub const TETRAHEDRON: CpuMeshHandle = CpuMeshHandle(3);
pub const SPHERE: CpuMeshHandle = CpuMeshHandle(4);
pub const CONE: CpuMeshHandle = CpuMeshHandle(5);
pub const CIRCLE_2D: CpuMeshHandle = CpuMeshHandle(6);
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MaterialHandle(pub u32);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct TextureHandle(pub u32);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct InstanceHandle(pub u32);
#[derive(Debug, Clone)]
pub struct Material {
pub vertex_shader: &'static str,
pub fragment_shader: &'static str,
}
impl Material {
pub const UNLIT_MESH: Material = Material {
vertex_shader: "assets/shaders/unlit-mesh.vert",
fragment_shader: "assets/shaders/unlit-mesh.frag",
};
pub const TOON_MESH: Material = Material {
vertex_shader: "assets/shaders/toon-mesh.vert",
fragment_shader: "assets/shaders/toon-mesh.frag",
};
pub const SKINNED_TOON_MESH: Material = Material {
vertex_shader: "assets/shaders/cached-skinned-toon-mesh.vert",
fragment_shader: "assets/shaders/toon-mesh.frag",
};
pub const EMISSIVE_TOON_MESH: Material = Material {
vertex_shader: "assets/shaders/toon-mesh.vert",
fragment_shader: "assets/shaders/emissive-toon-mesh.frag",
};
pub const SKINNED_EMISSIVE_TOON_MESH: Material = Material {
vertex_shader: "assets/shaders/cached-skinned-toon-mesh.vert",
fragment_shader: "assets/shaders/emissive-toon-mesh.frag",
};
pub const GRID_MESH: Material = Material {
vertex_shader: "assets/shaders/grid.vert",
fragment_shader: "assets/shaders/grid-square.frag",
};
pub const MIRROR: Material = Material {
vertex_shader: "assets/shaders/mirror-mesh.vert",
fragment_shader: "assets/shaders/mirror-mesh.frag",
};
}
impl MaterialHandle {
pub const UNLIT_MESH: MaterialHandle = MaterialHandle(0);
pub const TOON_MESH: MaterialHandle = MaterialHandle(1);
pub const SKINNED_TOON_MESH: MaterialHandle = MaterialHandle(2);
pub const EMISSIVE_TOON_MESH: MaterialHandle = MaterialHandle(3);
pub const SKINNED_EMISSIVE_TOON_MESH: MaterialHandle = MaterialHandle(4);
pub const GRID_MESH: MaterialHandle = MaterialHandle(5);
pub const MIRROR: MaterialHandle = MaterialHandle(6);
}