tiny-game-framework 0.0.163

Tiny game framework for creating games!
Documentation
use std::path::Path;

use glam::{vec2, vec3, vec4, Vec3, Vec4};
use tobj::LoadOptions;

use crate::{EventLoop, Mesh, Renderer, Texture, Vertex};

#[derive(Default)]
pub struct Model {
    pub meshes: Vec<Mesh>,
    pub loaded_textures: Vec<Texture>,
}

impl Model {
    pub fn new(path: &str) -> Self {
        let mut model = Model::default();
        model.load(path);

        model
    }

    pub fn extract_mesh(&mut self, path: &str, u: usize) -> Mesh {
        let path = Path::new(path);
        
        let obj = tobj::load_obj(path, &LoadOptions::default()).expect("Failed to load OBJ file");
        let (models, _) = obj;

        for model in models {
            let mesh = &model.mesh;
            let num_vertices = mesh.positions.len() / 3;
            let indices: Vec<u32> = mesh.indices.clone();

            let mut vertices = Vec::with_capacity(num_vertices);

            let (p, n, t, c) = (&mesh.positions, &mesh.normals, &mesh.texcoords, &mesh.vertex_color);

            for i in 0..num_vertices {
                let pos = vec3(p[i*3], p[i*3+1], p[i*3+2]);
                let tex_coords = vec2(t[i*2], t[i*2+1]);
                let normal = if n.len() >= (i + 1) * 3 {
                    vec3(n[i * 3], n[i * 3 + 1], n[i * 3 + 2])
                } else {
                    Vec3::ZERO
                };
                let color = if c.len() >= (i + 1) * 3 {
                    vec4(c[i * 3], c[i * 3 + 1], c[i * 3 + 2], 1.0)
                } else {
                    Vec4::ONE
                };
                vertices.push(
                    Vertex::new(pos, color, tex_coords, normal)
                );
            }

            
            self.meshes.push(Mesh::new(&vertices, &indices));
        }

        self.meshes[u].clone()
    }

    pub fn load(&mut self, path: &str) {
        let path = Path::new(path);

        let obj = tobj::load_obj(path, &LoadOptions::default()).expect("Failed to load OBJ file");
        let (models, _) = obj;

        for model in models {
            let mesh = &model.mesh;
            let num_vertices = mesh.positions.len() / 3;
            let indices: Vec<u32> = mesh.indices.clone();

            let mut vertices = Vec::with_capacity(num_vertices);

            let (p, n, t, c) = (&mesh.positions, &mesh.normals, &mesh.texcoords, &mesh.vertex_color);

            for i in 0..num_vertices {
                let pos = vec3(p[i*3], p[i*3+1], p[i*3+2]);
                let tex_coords = vec2(t[i*2], t[i*2+1]);
                let normal = if n.len() >= (i + 1) * 3 {
                    vec3(n[i * 3], n[i * 3 + 1], n[i * 3 + 2])
                } else {
                    Vec3::ZERO
                };
                let color = if c.len() >= (i + 1) * 3 {
                    vec4(c[i * 3], c[i * 3 + 1], c[i * 3 + 2], 1.0)
                } else {
                    Vec4::ONE
                };
                vertices.push(
                    Vertex::new(pos, color, tex_coords, normal)
                );
            }

            let mut final_mesh = Mesh::new(&vertices, &indices);

            for face in &mut final_mesh.indices.chunks_mut(6) {
                face.reverse();
            }

            final_mesh.setup_mesh();

            self.meshes.push(final_mesh);
        }
    }

    pub fn load_texture(&mut self, path: &str) -> Texture {
        let texture = Texture::Path(path.to_owned());
        self.loaded_textures.push(texture.clone());
        texture
    }

    pub unsafe fn draw(&self) {
        for mesh in &self.meshes {
            mesh.draw();
        }
    } 
}


impl Renderer {
    pub fn add_model(&mut self, name: &str, model: Model) {
        self.models.insert(name.to_string(), model);
    }

    pub fn get_model(&self, name: &str) -> Option<&Model> {
        self.models.get(name)
    }

    pub fn get_model_mut(&mut self, name: &str) -> Option<&mut Model> {
        self.models.get_mut(name)
    }
}