|
@@ -0,0 +1,81 @@
|
|
|
+extern crate glium;
|
|
|
+extern crate image;
|
|
|
+
|
|
|
+use glium::{VertexBuffer, IndexBuffer};
|
|
|
+use glium::texture::Texture2d;
|
|
|
+use therm_util::reader::ByteReader;
|
|
|
+
|
|
|
+#[derive(Debug, Copy, Clone)]
|
|
|
+pub struct V3D {
|
|
|
+ pub pos: [f32; 3],
|
|
|
+ pub nrm: [f32; 3],
|
|
|
+ pub tex: [f32; 2],
|
|
|
+}
|
|
|
+
|
|
|
+implement_vertex!(V3D, pos, nrm, tex);
|
|
|
+
|
|
|
+impl V3D {
|
|
|
+ pub fn from_reader<Rd>(reader: &mut ByteReader<Rd>) -> Result<V3D, String>
|
|
|
+ where Rd: Iterator<Item=u8>
|
|
|
+ {
|
|
|
+ Ok(V3D { pos: [ try!(reader.read_twip()) * 0.1,
|
|
|
+ try!(reader.read_twip()) * 0.1,
|
|
|
+ try!(reader.read_twip()) * 0.1],
|
|
|
+ nrm: [ try!(reader.read_twip()),
|
|
|
+ try!(reader.read_twip()),
|
|
|
+ try!(reader.read_twip()) ],
|
|
|
+ tex: [ try!(reader.read_ratio()),
|
|
|
+ try!(reader.read_ratio()) ],
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[derive(Debug, Clone)]
|
|
|
+pub struct Model {
|
|
|
+ pub points: Vec<V3D>,
|
|
|
+ pub tris: Vec<u16>,
|
|
|
+ pub texture: Option<Vec<u8>>,
|
|
|
+}
|
|
|
+
|
|
|
+impl Model {
|
|
|
+ pub fn load_from_file(path: &str) -> Result<Model, String> {
|
|
|
+ let mut reader = ByteReader::from_file(path).unwrap();
|
|
|
+ Model::from_reader(&mut reader)
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn from_reader<T>(reader: &mut ByteReader<T>) -> Result<Model, String>
|
|
|
+ where T: Iterator<Item=u8>
|
|
|
+ {
|
|
|
+ Ok(Model {
|
|
|
+ tris: try!(reader.read_several(|r| r.read_prefix_int().map(|x| x as u16))),
|
|
|
+ points: try!(reader.read_several(V3D::from_reader)),
|
|
|
+ texture: None,
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn get_vbuf(&self, display: &glium::Display) -> VertexBuffer<V3D> {
|
|
|
+ VertexBuffer::new(display, self.points.as_slice()).unwrap()
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn get_ibuf(&self, display: &glium::Display) -> IndexBuffer<u16> {
|
|
|
+ IndexBuffer::new(
|
|
|
+ display,
|
|
|
+ glium::index::PrimitiveType::TrianglesList,
|
|
|
+ &self.tris).unwrap()
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn get_tex(&self, display: &glium::Display) -> Option<Texture2d> {
|
|
|
+ use std::io::Cursor;
|
|
|
+ use glium::texture::RawImage2d;
|
|
|
+ if let Some(ref tex) = self.texture {
|
|
|
+ let img = image::load(Cursor::new(tex.clone()),
|
|
|
+ image::PNG).unwrap().to_rgba();
|
|
|
+ let dims = img.dimensions();
|
|
|
+ let img = RawImage2d::from_raw_rgba_reversed(img.into_raw(),
|
|
|
+ dims);
|
|
|
+ Some(Texture2d::new(display, img).unwrap())
|
|
|
+ } else {
|
|
|
+ None
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|