♻️ Extract IQM crate
							parent
							
								
									cdea0ffbea
								
							
						
					
					
						commit
						6297079ae9
					
				| 
						 | 
					@ -99,6 +99,14 @@ dependencies = [
 | 
				
			||||||
 "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "inter_quake_model"
 | 
				
			||||||
 | 
					version = "0.1.0"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
 | 
					 "iota 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "iota"
 | 
					name = "iota"
 | 
				
			||||||
version = "0.2.1"
 | 
					version = "0.2.1"
 | 
				
			||||||
| 
						 | 
					@ -209,6 +217,7 @@ dependencies = [
 | 
				
			||||||
 "float-ord 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "float-ord 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
 "gl 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "gl 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
 "glam 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "glam 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
 | 
					 "inter_quake_model 0.1.0",
 | 
				
			||||||
 "iota 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "iota 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
 "maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
 "nom 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "nom 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,3 +23,5 @@ partial-min-max = "0.4.0"
 | 
				
			||||||
png = "0.15.3"
 | 
					png = "0.15.3"
 | 
				
			||||||
rand = "0.6.5"
 | 
					rand = "0.6.5"
 | 
				
			||||||
sdl2 = "0.32.2"
 | 
					sdl2 = "0.32.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inter_quake_model = {path = "../inter_quake_model"}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										314
									
								
								src/iqm.rs
								
								
								
								
							
							
						
						
									
										314
									
								
								src/iqm.rs
								
								
								
								
							| 
						 | 
					@ -1,314 +0,0 @@
 | 
				
			||||||
use nom::{
 | 
					 | 
				
			||||||
	IResult,
 | 
					 | 
				
			||||||
	bytes::complete::{tag},
 | 
					 | 
				
			||||||
	number::complete::{le_u32},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use std::convert::TryInto;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub mod consts {
 | 
					 | 
				
			||||||
use iota::iota;
 | 
					 | 
				
			||||||
iota! {
 | 
					 | 
				
			||||||
	pub const VERSION: usize = iota;
 | 
					 | 
				
			||||||
			, FILESIZE
 | 
					 | 
				
			||||||
			, FLAGS
 | 
					 | 
				
			||||||
			, NUM_TEXT
 | 
					 | 
				
			||||||
			, OFS_TEXT
 | 
					 | 
				
			||||||
			, NUM_MESHES
 | 
					 | 
				
			||||||
			, OFS_MESHES
 | 
					 | 
				
			||||||
			, NUM_VERTEXARRAYS
 | 
					 | 
				
			||||||
			, NUM_VERTEXES
 | 
					 | 
				
			||||||
			, OFS_VERTEXARRAYS
 | 
					 | 
				
			||||||
			, NUM_TRIANGLES
 | 
					 | 
				
			||||||
			, OFS_TRIANGLES
 | 
					 | 
				
			||||||
			, OFS_ADJACENCY
 | 
					 | 
				
			||||||
			, NUM_JOINTS
 | 
					 | 
				
			||||||
			, OFS_JOINTS
 | 
					 | 
				
			||||||
			, NUM_POSES
 | 
					 | 
				
			||||||
			, OFS_POSES
 | 
					 | 
				
			||||||
			, NUM_ANIMS
 | 
					 | 
				
			||||||
			, OFS_ANIMS
 | 
					 | 
				
			||||||
			, NUM_FRAMES
 | 
					 | 
				
			||||||
			, NUM_FRAMECHANNELS
 | 
					 | 
				
			||||||
			, OFS_FRAMES
 | 
					 | 
				
			||||||
			, OFS_BOUNDS
 | 
					 | 
				
			||||||
			, NUM_COMMENT
 | 
					 | 
				
			||||||
			, OFS_COMMENT
 | 
					 | 
				
			||||||
			, NUM_EXTENSIONS
 | 
					 | 
				
			||||||
			, OFS_EXTENSIONS
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub mod types {
 | 
					 | 
				
			||||||
iota! {
 | 
					 | 
				
			||||||
	pub const POSITION: usize = iota;
 | 
					 | 
				
			||||||
			, TEXCOORD
 | 
					 | 
				
			||||||
			, NORMAL
 | 
					 | 
				
			||||||
			, TANGENT
 | 
					 | 
				
			||||||
			, BLENDINDEXES
 | 
					 | 
				
			||||||
			, BLENDWEIGHTS
 | 
					 | 
				
			||||||
			, COLOR
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
	pub const CUSTOM: usize       = 0x10;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub mod formats {
 | 
					 | 
				
			||||||
iota! {
 | 
					 | 
				
			||||||
	pub const BYTE: u32 = iota;
 | 
					 | 
				
			||||||
			, UBYTE
 | 
					 | 
				
			||||||
			, SHORT
 | 
					 | 
				
			||||||
			, USHORT
 | 
					 | 
				
			||||||
			, INT
 | 
					 | 
				
			||||||
			, UINT
 | 
					 | 
				
			||||||
			, HALF
 | 
					 | 
				
			||||||
			, FLOAT
 | 
					 | 
				
			||||||
			, DOUBLE
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive (Debug)]
 | 
					 | 
				
			||||||
pub struct Mesh {
 | 
					 | 
				
			||||||
	pub name: u32,
 | 
					 | 
				
			||||||
	pub material: u32,
 | 
					 | 
				
			||||||
	pub first_vertex: u32,
 | 
					 | 
				
			||||||
	pub num_vertexes: u32,
 | 
					 | 
				
			||||||
	pub first_triangle: u32,
 | 
					 | 
				
			||||||
	pub num_triangles: u32,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive (Debug)]
 | 
					 | 
				
			||||||
pub struct Header {
 | 
					 | 
				
			||||||
	pub fields: [u32; 27],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive (Debug)]
 | 
					 | 
				
			||||||
pub struct VertexArray {
 | 
					 | 
				
			||||||
	va_type: u32,
 | 
					 | 
				
			||||||
	va_flags: u32,
 | 
					 | 
				
			||||||
	va_format: u32,
 | 
					 | 
				
			||||||
	va_size: u32,
 | 
					 | 
				
			||||||
	va_offset: u32,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive (Debug)]
 | 
					 | 
				
			||||||
pub struct Model <'a> {
 | 
					 | 
				
			||||||
	data: &'a [u8],
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	pub header: Header,
 | 
					 | 
				
			||||||
	text: Vec <u8>,
 | 
					 | 
				
			||||||
	pub meshes: Vec <Mesh>,
 | 
					 | 
				
			||||||
	vertexarrays: Vec <VertexArray>,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Header {
 | 
					 | 
				
			||||||
	pub fn from_slice (input: &[u8]) -> IResult <&[u8], Header> {
 | 
					 | 
				
			||||||
		let (input, _) = tag (b"INTERQUAKEMODEL\0")(input)?;
 | 
					 | 
				
			||||||
		let (input, version) = le_u32 (input)?;
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		// I only know how to parse version 2
 | 
					 | 
				
			||||||
		assert_eq! (version, 2);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		let mut input = input;
 | 
					 | 
				
			||||||
		let mut fields = [0; 27];
 | 
					 | 
				
			||||||
		fields [0] = version;
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		for field in fields.iter_mut ().skip (1) {
 | 
					 | 
				
			||||||
			let (i, h) = le_u32 (input)?;
 | 
					 | 
				
			||||||
			input = i;
 | 
					 | 
				
			||||||
			*field = h;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		Ok ((input, Header {
 | 
					 | 
				
			||||||
			fields,
 | 
					 | 
				
			||||||
		}))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Mesh {
 | 
					 | 
				
			||||||
	pub fn from_slice (input: &[u8]) -> IResult <&[u8], Mesh> {
 | 
					 | 
				
			||||||
		let mut result = Mesh {
 | 
					 | 
				
			||||||
			name: 0,
 | 
					 | 
				
			||||||
			material: 0,
 | 
					 | 
				
			||||||
			first_vertex: 0,
 | 
					 | 
				
			||||||
			num_vertexes: 0,
 | 
					 | 
				
			||||||
			first_triangle: 0,
 | 
					 | 
				
			||||||
			num_triangles: 0,
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		let mut input = input;
 | 
					 | 
				
			||||||
		for field in [
 | 
					 | 
				
			||||||
			&mut result.name,
 | 
					 | 
				
			||||||
			&mut result.material,
 | 
					 | 
				
			||||||
			&mut result.first_vertex,
 | 
					 | 
				
			||||||
			&mut result.num_vertexes,
 | 
					 | 
				
			||||||
			&mut result.first_triangle,
 | 
					 | 
				
			||||||
			&mut result.num_triangles,
 | 
					 | 
				
			||||||
		].iter_mut () {
 | 
					 | 
				
			||||||
			let (i, f) = le_u32 (input)?;
 | 
					 | 
				
			||||||
			input = i;
 | 
					 | 
				
			||||||
			**field = f;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		Ok ((input, result))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl VertexArray {
 | 
					 | 
				
			||||||
	pub fn from_slice (input: &[u8]) -> IResult <&[u8], VertexArray> {
 | 
					 | 
				
			||||||
		let mut result = VertexArray {
 | 
					 | 
				
			||||||
			va_type: 0,
 | 
					 | 
				
			||||||
			va_flags: 0,
 | 
					 | 
				
			||||||
			va_format: 0,
 | 
					 | 
				
			||||||
			va_size: 0,
 | 
					 | 
				
			||||||
			va_offset: 0,
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		let mut input = input;
 | 
					 | 
				
			||||||
		for field in [
 | 
					 | 
				
			||||||
			&mut result.va_type,
 | 
					 | 
				
			||||||
			&mut result.va_flags,
 | 
					 | 
				
			||||||
			&mut result.va_format,
 | 
					 | 
				
			||||||
			&mut result.va_size,
 | 
					 | 
				
			||||||
			&mut result.va_offset,
 | 
					 | 
				
			||||||
		].iter_mut () {
 | 
					 | 
				
			||||||
			let (i, f) = le_u32 (input)?;
 | 
					 | 
				
			||||||
			input = i;
 | 
					 | 
				
			||||||
			**field = f;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		Ok ((input, result))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive (Debug)]
 | 
					 | 
				
			||||||
pub enum ModelLoadErr {
 | 
					 | 
				
			||||||
	ParseHeaderFailed,
 | 
					 | 
				
			||||||
	ParseMeshFailed (usize),
 | 
					 | 
				
			||||||
	ParseVertexArrayFailed (usize),
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl <'a> Model <'a> {
 | 
					 | 
				
			||||||
	pub fn from_slice (data: &'a [u8]) -> Result <Model <'a>, ModelLoadErr> {
 | 
					 | 
				
			||||||
		let header = match Header::from_slice (data) {
 | 
					 | 
				
			||||||
			Ok ((_, h)) => h,
 | 
					 | 
				
			||||||
			Err (_) => return Err (ModelLoadErr::ParseHeaderFailed),
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		let text = {
 | 
					 | 
				
			||||||
			let offset: usize = header.fields [consts::OFS_TEXT].try_into ().unwrap ();
 | 
					 | 
				
			||||||
			let num: usize = header.fields [consts::NUM_TEXT].try_into ().unwrap ();
 | 
					 | 
				
			||||||
			Vec::from (&data [offset..offset + num])
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		let meshes = {
 | 
					 | 
				
			||||||
			let num: usize = header.fields [consts::NUM_MESHES].try_into ().unwrap ();
 | 
					 | 
				
			||||||
			let mut meshes = Vec::with_capacity (num);
 | 
					 | 
				
			||||||
			let mesh_size = 6 * 4;
 | 
					 | 
				
			||||||
			let meshes_offset: usize = header.fields [consts::OFS_MESHES].try_into ().unwrap ();
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			for i in 0..num {
 | 
					 | 
				
			||||||
				let offset = meshes_offset + i * mesh_size;
 | 
					 | 
				
			||||||
				let mesh_slice = &data [offset..offset + mesh_size];
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				let mesh = match Mesh::from_slice (mesh_slice) {
 | 
					 | 
				
			||||||
					Ok ((_, m)) => m,
 | 
					 | 
				
			||||||
					Err (_) => return Err (ModelLoadErr::ParseMeshFailed (i)),
 | 
					 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				meshes.push (mesh);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			meshes
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		let vertexarrays = {
 | 
					 | 
				
			||||||
			let num: usize = header.fields [consts::NUM_VERTEXARRAYS].try_into ().unwrap ();
 | 
					 | 
				
			||||||
			let mut vertexarrays = Vec::with_capacity (num);
 | 
					 | 
				
			||||||
			let vertexarray_size = 5 * 4;
 | 
					 | 
				
			||||||
			let vertexarrays_offset: usize = header.fields [consts::OFS_VERTEXARRAYS].try_into ().unwrap ();
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			for i in 0..num {
 | 
					 | 
				
			||||||
				let offset = vertexarrays_offset + i * vertexarray_size;
 | 
					 | 
				
			||||||
				let vertexarray_slice = &data [offset..offset + vertexarray_size];
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				let vertexarray = match VertexArray::from_slice (vertexarray_slice) {
 | 
					 | 
				
			||||||
					Ok ((_, va)) => va,
 | 
					 | 
				
			||||||
					Err (_) => return Err (ModelLoadErr::ParseVertexArrayFailed (i)),
 | 
					 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				vertexarrays.push (vertexarray);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			vertexarrays
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		Ok (Model {
 | 
					 | 
				
			||||||
			data,
 | 
					 | 
				
			||||||
			
 | 
					 | 
				
			||||||
			header,
 | 
					 | 
				
			||||||
			text,
 | 
					 | 
				
			||||||
			meshes,
 | 
					 | 
				
			||||||
			vertexarrays,
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	pub fn get_vertex_slice (&self, 
 | 
					 | 
				
			||||||
		vertexarray_index: usize
 | 
					 | 
				
			||||||
	) -> &[u8]
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		let vertexarray = &self.vertexarrays [vertexarray_index];
 | 
					 | 
				
			||||||
		let bytes_per_float = 4;
 | 
					 | 
				
			||||||
		let stride = bytes_per_float * vertexarray.va_size;
 | 
					 | 
				
			||||||
		//assert_eq! (stride, 12);
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		let offset: usize = (vertexarray.va_offset).try_into ().unwrap ();
 | 
					 | 
				
			||||||
		let num_bytes: usize = (stride * self.header.fields [consts::NUM_VERTEXES]).try_into ().unwrap ();
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		&self.data [offset..offset + num_bytes]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	pub fn get_index_slice (&self, mesh_index: usize) -> &[u8] {
 | 
					 | 
				
			||||||
		let mesh = &self.meshes [mesh_index];
 | 
					 | 
				
			||||||
		let bytes_per_u32 = 4;
 | 
					 | 
				
			||||||
		let indexes_per_tri = 3;
 | 
					 | 
				
			||||||
		let stride = bytes_per_u32 * indexes_per_tri;
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		let offset: usize = (self.header.fields [consts::OFS_TRIANGLES] + stride * mesh.first_triangle).try_into ().unwrap ();
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		let num_bytes: usize = (stride * mesh.num_triangles).try_into ().unwrap ();
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		&self.data [offset..offset + num_bytes]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	pub fn get_all_indexes (&self) -> &[u8] {
 | 
					 | 
				
			||||||
		let bytes_per_u32 = 4;
 | 
					 | 
				
			||||||
		let indexes_per_tri = 3;
 | 
					 | 
				
			||||||
		let stride = bytes_per_u32 * indexes_per_tri;
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		let offset: usize = self.header.fields [consts::OFS_TRIANGLES].try_into ().unwrap ();
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		let num_bytes: usize = (stride * self.header.fields [consts::NUM_TRIANGLES]).try_into ().unwrap ();
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		&self.data [offset..offset + num_bytes]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	// I don't think IQM makes any guarantees about UTF-8
 | 
					 | 
				
			||||||
	// so I will only say that the slice has no NULs
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	pub fn get_mesh_name (&self, index: usize) -> &[u8] {
 | 
					 | 
				
			||||||
		let mesh = &self.meshes [index];
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		let ofs: usize = (self.header.fields [consts::OFS_TEXT] + mesh.name).try_into ().unwrap ();
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		// There should be an easy way to do this with CString?
 | 
					 | 
				
			||||||
		let mut nul_index = None;
 | 
					 | 
				
			||||||
		for (j, c) in self.data [ofs..].iter ().enumerate () {
 | 
					 | 
				
			||||||
			if *c == 0 {
 | 
					 | 
				
			||||||
				nul_index = Some (j);
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		let nul_index = nul_index.unwrap ();
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		&self.data [ofs..ofs + nul_index]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,6 @@ pub mod file;
 | 
				
			||||||
pub mod glezz;
 | 
					pub mod glezz;
 | 
				
			||||||
pub mod gl_state;
 | 
					pub mod gl_state;
 | 
				
			||||||
pub mod gpu_buffers;
 | 
					pub mod gpu_buffers;
 | 
				
			||||||
pub mod iqm;
 | 
					 | 
				
			||||||
pub mod physics;
 | 
					pub mod physics;
 | 
				
			||||||
pub mod renderable_model;
 | 
					pub mod renderable_model;
 | 
				
			||||||
pub mod shader;
 | 
					pub mod shader;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,6 @@ use std::convert::TryInto;
 | 
				
			||||||
use std::ffi::c_void;
 | 
					use std::ffi::c_void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::gpu_buffers::*;
 | 
					use crate::gpu_buffers::*;
 | 
				
			||||||
use crate::iqm;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Takes ownership of mesh stuff in an opaque way that's abstract
 | 
					// Takes ownership of mesh stuff in an opaque way that's abstract
 | 
				
			||||||
// from the IQM model. IQM is zero-copy, but this is not.
 | 
					// from the IQM model. IQM is zero-copy, but this is not.
 | 
				
			||||||
| 
						 | 
					@ -49,10 +48,10 @@ pub const
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl RenderableModel {
 | 
					impl RenderableModel {
 | 
				
			||||||
	pub fn from_iqm (model: &iqm::Model) -> RenderableModel {
 | 
						pub fn from_iqm (model: &inter_quake_model::Model) -> RenderableModel {
 | 
				
			||||||
		let pos_bytes = model.get_vertex_slice (iqm::types::POSITION);
 | 
							let pos_bytes = model.get_vertex_slice (inter_quake_model::types::POSITION);
 | 
				
			||||||
		let uv_bytes = model.get_vertex_slice (iqm::types::TEXCOORD);
 | 
							let uv_bytes = model.get_vertex_slice (inter_quake_model::types::TEXCOORD);
 | 
				
			||||||
		let normal_bytes = model.get_vertex_slice (iqm::types::NORMAL);
 | 
							let normal_bytes = model.get_vertex_slice (inter_quake_model::types::NORMAL);
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		let num_pos = pos_bytes.len () / 4;
 | 
							let num_pos = pos_bytes.len () / 4;
 | 
				
			||||||
		let num_uv = uv_bytes.len () / 4;
 | 
							let num_uv = uv_bytes.len () / 4;
 | 
				
			||||||
| 
						 | 
					@ -147,7 +146,7 @@ pub fn renderable_from_iqm_file <P> (filename: P) -> RenderableModel
 | 
				
			||||||
where P: AsRef <std::path::Path>
 | 
					where P: AsRef <std::path::Path>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	let data = crate::file::load_small_file (filename, 1024 * 1024).unwrap ();
 | 
						let data = crate::file::load_small_file (filename, 1024 * 1024).unwrap ();
 | 
				
			||||||
	let model = crate::iqm::Model::from_slice (&data).unwrap ();
 | 
						let model = inter_quake_model::Model::from_slice (&data).unwrap ();
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	RenderableModel::from_iqm (&model)
 | 
						RenderableModel::from_iqm (&model)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue