A big commit
This commit is contained in:
		
							parent
							
								
									6cb76e9986
								
							
						
					
					
						commit
						211f7fc5c5
					
				
							
								
								
									
										19
									
								
								src/model.rs
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/model.rs
									
									
									
									
									
								
							| @ -171,10 +171,23 @@ impl Part { | ||||
|         let mut shape = vec![]; | ||||
|         for face in &self.faces { | ||||
|             for &&v in &[&face.a, &face.b, &face.c] { | ||||
|                 let vertex = vertices[v.vertex].into(); | ||||
|                 let tex_coord = if let Some(tex_index) = v.texture_coordinate { | ||||
|                     tex_coords[tex_index].into() | ||||
|                 } else { | ||||
|                     [0.0, 0.0] | ||||
|                 }; | ||||
| 
 | ||||
|                 let normal = if let Some(normal_index) = v.normal { | ||||
|                     normals[normal_index].into() | ||||
|                 } else { | ||||
|                     [0.0, 0.0, 0.0] | ||||
|                 }; | ||||
| 
 | ||||
|                 shape.push(Vertex { | ||||
|                     vertex:     vertices[v.vertex].into(), | ||||
|                     tex_coords: tex_coords[v.texture_coordinate.unwrap()].into(), | ||||
|                     normal:     normals[v.normal.unwrap()].into(), | ||||
|                     vertex:     vertex, | ||||
|                     tex_coords: tex_coord, | ||||
|                     normal:     normal, | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @ -4,7 +4,7 @@ pub mod obj; | ||||
| pub mod mtl; | ||||
| 
 | ||||
| use std::fmt; | ||||
| use std::path::Path; | ||||
| use std::path::{Path, PathBuf}; | ||||
| use std::fs::File; | ||||
| use std::io::{BufReader, Error}; | ||||
| use math::vector::{Vector2, Vector3}; | ||||
| @ -19,6 +19,9 @@ pub enum Element { | ||||
|     /// An empty element (correspond to an empty line for example).
 | ||||
|     None, | ||||
| 
 | ||||
|     /// Declares the use of a material file.
 | ||||
|     MaterialLib(String), | ||||
| 
 | ||||
|     /// Changes the material used for the next faces.
 | ||||
|     UseMaterial(String), | ||||
| 
 | ||||
| @ -48,6 +51,9 @@ pub enum Element { | ||||
| 
 | ||||
|     /// An unknown material instruction that will be copied into the mtl file.
 | ||||
|     UnknownMaterialInstruction(String), | ||||
| 
 | ||||
|     /// Declares multiple faces.
 | ||||
|     Faces(Vec<Face>), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| @ -225,6 +231,16 @@ impl<LP: LineParser> Parser for LP { | ||||
|                 Element::TextureCoordinate(v) => model.texture_coordinates.push(v), | ||||
|                 Element::Normal(v) => model.normals.push(v), | ||||
| 
 | ||||
|                 Element::MaterialLib(ref material_path) => { | ||||
|                     // Append material_path to path
 | ||||
|                     let mut path = PathBuf::from(path); | ||||
|                     path.pop(); | ||||
|                     path.push(material_path); | ||||
|                     if let Err(err) = parse_into_model(path.to_str().unwrap(), model) { | ||||
|                         return Err(err); | ||||
|                     } | ||||
|                 }, | ||||
| 
 | ||||
|                 Element::Face(f) => { | ||||
|                     if let Err(ModelError::IndexError(index, size)) = model.add_face(f) { | ||||
|                         return Err(ParserError::IndexOutOfBound(path.to_owned(), num, index, size)); | ||||
| @ -274,7 +290,16 @@ impl<LP: LineParser> Parser for LP { | ||||
|                     } | ||||
| 
 | ||||
|                     current_material.unwrap().add_unknown_instruction(s); | ||||
|                 }, | ||||
| 
 | ||||
|                 Element::Faces(faces) => { | ||||
|                     for f in faces { | ||||
|                         if let Err(ModelError::IndexError(index, size)) = model.add_face(f) { | ||||
|                             return Err(ParserError::IndexOutOfBound(path.to_owned(), num, index, size)); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -153,7 +153,6 @@ impl ObjParser { | ||||
|             if let Some(texture_coordinate_string) = texture_coordinate_string { | ||||
|                 if texture_coordinate_string.len() != 0 { | ||||
|                     let texture_coordinate_index = texture_coordinate_string.parse::<usize>(); | ||||
| 
 | ||||
|                     if texture_coordinate_index.is_err() { | ||||
|                         return Err(ParserError::ParseNumberError( | ||||
|                             path.to_owned(),line_number, texture_coordinate_string.to_owned() | ||||
| @ -185,10 +184,15 @@ impl ObjParser { | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         if face_vertices.len() != 3 { | ||||
|             Err(ParserError::TooManyVertices(path.to_owned(), line_number, face_vertices.len())) | ||||
|         } else { | ||||
|         if face_vertices.len() == 3 { | ||||
|             Ok(Element::Face(Face::new(face_vertices[0], face_vertices[1], face_vertices[2]))) | ||||
|         } else if face_vertices.len() == 4 { | ||||
|             Ok(Element::Faces(vec![ | ||||
|                 Face::new(face_vertices[0], face_vertices[1], face_vertices[2]), | ||||
|                 Face::new(face_vertices[0], face_vertices[2], face_vertices[3]), | ||||
|             ])) | ||||
|         } else { | ||||
|             Err(ParserError::TooManyVertices(path.to_owned(), line_number, face_vertices.len())) | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
| @ -203,12 +207,14 @@ impl LineParser for ObjParser { | ||||
| 
 | ||||
|         if let Some(first) = split.nth(0) { | ||||
|             match first { | ||||
| 
 | ||||
|                 "mtllib" => Ok(Element::MaterialLib(split.nth(0).unwrap().to_owned())), | ||||
|                 "v"  => self.parse_vertex(line_number, line, path), | ||||
|                 "vt" => self.parse_texture_coordinate(line_number, line, path), | ||||
|                 "vn" => self.parse_normal(line_number, line, path), | ||||
|                 "usemtl" => Ok(Element::UseMaterial(split.nth(0).unwrap().to_owned())), | ||||
|                 "f" => self.parse_face(line_number, line, path), | ||||
|                 "#" | "g" | "s" | "o" | "mtllib"  => Ok(Element::None), | ||||
|                 "#" | "g" | "s" | "o" => Ok(Element::None), | ||||
|                 key if key.len() != 0 => Err(ParserError::UnexpectedKeyword(path.to_owned(), line_number, key.to_owned())), | ||||
|                 _  => Ok(Element::None), | ||||
|             } | ||||
|  | ||||
| @ -1,6 +1,9 @@ | ||||
| extern crate glium; | ||||
| extern crate model_converter; | ||||
| 
 | ||||
| use std::env; | ||||
| use std::process::exit; | ||||
| 
 | ||||
| use glium::Display; | ||||
| use glium::glutin; | ||||
| use glium::glutin::{ | ||||
| @ -14,15 +17,45 @@ use glium::glutin::VirtualKeyCode; | ||||
| 
 | ||||
| 
 | ||||
| use model_converter::math::vector::Vector3; | ||||
| use model_converter::parser::{parse, parse_into_model}; | ||||
| use model_converter::parser::parse_into_model; | ||||
| use model_converter::renderer::Renderer; | ||||
| use model_converter::renderer::controls::OrbitControls; | ||||
| use model_converter::renderer::camera::Camera; | ||||
| use model_converter::model::Model; | ||||
| 
 | ||||
| fn main() { | ||||
| 
 | ||||
|     let mut model = parse("./assets/models/link/link.mtl").unwrap(); | ||||
|     parse_into_model("./assets/models/link/link.obj", &mut model).unwrap(); | ||||
|     let mut model = Model::new(); | ||||
|     let mut inputs = vec![]; | ||||
|     let mut iterator = env::args(); | ||||
| 
 | ||||
|     // Skip the name of the program
 | ||||
|     iterator.next(); | ||||
| 
 | ||||
|     while let Some(argument) = iterator.next() { | ||||
|         match argument.as_ref() { | ||||
|             "-i" | "--input" => { | ||||
|                 if let Some(path) = iterator.next() { | ||||
|                     inputs.push(path); | ||||
|                 } else { | ||||
|                     eprintln!("Expecting path after {}", argument); | ||||
|                     exit(-1); | ||||
|                 } | ||||
|             }, | ||||
| 
 | ||||
|             arg => { | ||||
|                 eprintln!("Argument unkown: {}", arg); | ||||
|                 exit(-1); | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     for input in inputs { | ||||
|         if let Err(e) = parse_into_model(&input, &mut model) { | ||||
|             eprintln!("Error while parsing file: {}", e); | ||||
|             exit(1); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let mut events_loop = EventsLoop::new(); | ||||
|     let window = WindowBuilder::new(); | ||||
|  | ||||
| @ -11,24 +11,8 @@ pub trait RenderCamera { | ||||
|     fn get_view_matrix(&self) -> [[f32; 4]; 4]; | ||||
| 
 | ||||
|     /// Returns the perspective matrix of the camera.
 | ||||
|     fn get_perspective_matrix(&self, dimensions: (u32, u32)) -> [[f32; 4]; 4] { | ||||
|         let (width, height) = dimensions; | ||||
|         let aspect_ratio = height as f32 / width as f32; | ||||
|     fn get_perspective_matrix(&self) -> [[f32; 4]; 4] ; | ||||
| 
 | ||||
|         let fov = 3.141592 / 3.0; | ||||
|         let zfar = 1024.0; | ||||
|         let znear = 0.1; | ||||
| 
 | ||||
|         use num::Float; | ||||
|         let f = 1.0 / (fov / 2.0).tan(); | ||||
| 
 | ||||
|         [ | ||||
|             [f *   aspect_ratio   ,    0.0,              0.0              ,   0.0], | ||||
|             [         0.0         ,     f ,              0.0              ,   0.0], | ||||
|             [         0.0         ,    0.0,  (zfar+znear)/(zfar-znear)    ,   1.0], | ||||
|             [         0.0         ,    0.0, -(2.0*zfar*znear)/(zfar-znear),   0.0], | ||||
|         ] | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Creates a look at matrix from the center, the target pointed by the camera and the up vector.
 | ||||
| @ -71,6 +55,21 @@ pub fn look_at_matrix(position: [f32; 3], target: [f32; 3], up: [f32; 3]) -> [[f | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /// Creates a perspective matrix of a camera.
 | ||||
| pub fn perspective_matrix(aspect_ratio: f32, z_near: f32, z_far: f32) -> [[f32; 4]; 4] { | ||||
|     let fov = 3.141592 / 3.0; | ||||
| 
 | ||||
|     use num::Float; | ||||
|     let f = 1.0 / (fov / 2.0).tan(); | ||||
| 
 | ||||
|     [ | ||||
|         [f /   aspect_ratio   ,    0.0,              0.0              ,   0.0], | ||||
|         [         0.0         ,     f ,              0.0              ,   0.0], | ||||
|         [         0.0         ,    0.0,  (z_far+z_near)/(z_far-z_near)    ,   1.0], | ||||
|         [         0.0         ,    0.0, -(2.0*z_far*z_near)/(z_far-z_near),   0.0], | ||||
|     ] | ||||
| } | ||||
| 
 | ||||
| /// A simple camera with its position, target and up vector.
 | ||||
| pub struct Camera { | ||||
|     /// The position of the center of the camera.
 | ||||
| @ -81,6 +80,16 @@ pub struct Camera { | ||||
| 
 | ||||
|     /// The up vector of the camera.
 | ||||
|     pub up: Vector3<f32>, | ||||
| 
 | ||||
|     /// The minimum depth for visible things.
 | ||||
|     pub z_near: f32, | ||||
| 
 | ||||
|     /// The maximum depth for visible things.
 | ||||
|     pub z_far: f32, | ||||
| 
 | ||||
|     /// The aspect ratio of the camera.
 | ||||
|     pub aspect_ratio: f32, | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| impl Camera { | ||||
| @ -90,6 +99,9 @@ impl Camera { | ||||
|             position: position, | ||||
|             target: target, | ||||
|             up: up, | ||||
|             z_near: 0.01, | ||||
|             z_far: 1000.0, | ||||
|             aspect_ratio: 16.0 / 9.0 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -98,5 +110,9 @@ impl RenderCamera for Camera { | ||||
|     fn get_view_matrix(&self) -> [[f32; 4]; 4] { | ||||
|         look_at_matrix(self.position.into(), self.target.into(), self.up.into()) | ||||
|     } | ||||
| 
 | ||||
|     fn get_perspective_matrix(&self) -> [[f32; 4]; 4] { | ||||
|         perspective_matrix(self.aspect_ratio, self.z_near, self.z_far) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -99,6 +99,12 @@ impl Controls for OrbitControls { | ||||
|                 self.pressed = state == ElementState::Pressed; | ||||
|             }, | ||||
| 
 | ||||
|             Event::WindowEvent { | ||||
|                 event: WindowEvent::Resized(width, height), .. | ||||
|             } => { | ||||
|                 camera.aspect_ratio = width as f32 / height as f32; | ||||
|             }, | ||||
| 
 | ||||
|             Event::WindowEvent { | ||||
|                 event: WindowEvent::MouseWheel { | ||||
|                     delta: MouseScrollDelta::LineDelta(_, y), .. | ||||
|  | ||||
| @ -171,7 +171,7 @@ impl<'a, D: Drawer + Facade + Sized> Renderer<'a, D> { | ||||
| 
 | ||||
|             for &(ref material, ref buffer) in buffers { | ||||
| 
 | ||||
|                 let perspective = camera.get_perspective_matrix(target.get_dimensions()); | ||||
|                 let perspective = camera.get_perspective_matrix(); | ||||
|                 let view = camera.get_view_matrix(); | ||||
| 
 | ||||
|                 if let &Some(ref texture) = &material.texture { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user