Browse Source

Added model code to therm_model crate

Getty Ritter 7 years ago
parent
commit
2cc33b9ce6
3 changed files with 91 additions and 0 deletions
  1. 3 0
      therm_model/Cargo.toml
  2. 7 0
      therm_model/src/lib.rs
  3. 81 0
      therm_model/src/model.rs

+ 3 - 0
therm_model/Cargo.toml

@@ -4,3 +4,6 @@ version = "0.1.0"
 authors = ["Getty Ritter <gdritter@galois.com>"]
 
 [dependencies]
+glium = "*"
+image = "*"
+therm_util = { path = "../therm_util" }

+ 7 - 0
therm_model/src/lib.rs

@@ -1,3 +1,10 @@
+#[macro_use]
+extern crate glium;
+extern crate image;
+extern crate therm_util;
+
+pub mod model;
+
 #[cfg(test)]
 mod tests {
     #[test]

+ 81 - 0
therm_model/src/model.rs

@@ -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
+        }
+    }
+}