Skip to content
Snippets Groups Projects
Select Git revision
  • 4b69cb50c25b789151b9ac33ef3ce0e9027251bc
  • main default protected
  • QSPI-map
  • feat_dmax4
  • nanosoc_accel-2023
5 results

proj-branch

Blame
  • objects.rs 3.49 KiB
    use std::{collections::HashMap, io::Read, sync::Arc};
    
    use bytemuck::{Pod, Zeroable};
    use cgmath::{Deg, Euler, Matrix3, Point3, SquareMatrix, Vector3};
    use obj::{LoadConfig, ObjData};
    use vulkano::{
        buffer::{Buffer, BufferAllocateInfo, BufferUsage, Subbuffer},
        pipeline::graphics::vertex_input::Vertex,
    };
    
    use crate::MemoryAllocator;
    
    pub const PLATONIC_SOLIDS: [(&str, &[u8]); 1] = [("Buny", include_bytes!("bunny.obj"))];
    
    // We now create a buffer that will store the shape of our triangle.
    // We use #[repr(C)] here to force rustc to not do anything funky with our data, although for this
    // particular example, it doesn't actually change the in-memory representation.
    #[repr(C)]
    #[derive(Clone, Copy, Debug, Default, Zeroable, Pod, Vertex)]
    pub struct OVertex {
        #[format(R32G32B32_SFLOAT)]
        position: [f32; 3],
        #[format(R32G32B32_SFLOAT)]
        normal: [f32; 3],
    }
    
    #[derive(Debug)]
    pub struct Mesh {
        pub name: String,
        pub vertices: Subbuffer<[OVertex]>,
        pub indices: Subbuffer<[u32]>,
        pub pos: Point3<f32>,
        pub rot: Euler<Deg<f32>>,
        pub scale: f32,
    }
    
    pub fn load_obj(memory_allocator: &MemoryAllocator, input: &mut dyn Read, name: String) -> Mesh {
        let object = ObjData::load_buf_with_config(input, LoadConfig::default()).unwrap();
    
        let mut vertices = vec![];
    
        let mut indices = vec![];
    
        let mut temp_hash_map = HashMap::<(u32, u32), u32>::new();
    
        // We're gonna have to remap all the indices that OBJ uses. Annoying.
        // Get each pair of vertex position to vertex normal and assign it a new index. This might duplicate
        // vertices or normals but each *pair* needs a unique index
        // Uses the hash map to check that we're not duplicating unnecessarily
        for g in &object.objects[0].groups {
            for p in &g.polys {
                for v in &p.0 {
                    //println!("{:?}", v);
                    let mapping = ((v.0) as u32, (v.2.unwrap_or(0)) as u32);
                    if let Some(&exist) = &temp_hash_map.get(&mapping) {
                        //println!("{:?}", exist);
                        indices.push(exist);
                    } else {
                        vertices.push(OVertex {
                            position: object.position[mapping.0 as usize],
                            normal: object.normal[mapping.1 as usize],
                        });
                        temp_hash_map.insert(mapping, (vertices.len() - 1) as u32);
                        indices.push((vertices.len() - 1) as u32);
                    }
                }
            }
        }
    
        let vertex_buffer = Buffer::from_iter(
            memory_allocator,
            BufferAllocateInfo {
                buffer_usage: BufferUsage::VERTEX_BUFFER,
                ..Default::default()
            },
            vertices,
        )
        .unwrap();
    
        let index_buffer = Buffer::from_iter(
            memory_allocator,
            BufferAllocateInfo {
                buffer_usage: BufferUsage::INDEX_BUFFER,
                ..Default::default()
            },
            indices,
        )
        .unwrap();
    
        Mesh {
            vertices: vertex_buffer,
            indices: index_buffer,
            pos: Point3 {
                x: 0.,
                y: 0.,
                z: 0.,
            },
            rot: Euler::new(Deg(0.), Deg(0.), Deg(0.)),
            scale: 1.,
            name,
        }
    }
    
    #[derive(Debug)]
    pub struct Light {
        pub pos: Point3<f32>,
        pub colour: Vector3<f32>,
    }
    
    impl Light {
        pub fn new(pos: [f32; 3], colour: [f32; 3], intensity: f32) -> Light {
            let c: Vector3<f32> = colour.into();
            Light {
                pos: pos.into(),
                colour: c * intensity,
            }
        }
    }