Skip to content

Commit

Permalink
Improve OBJ loading
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Dec 11, 2018
1 parent b9103cd commit 22251e1
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 63 deletions.
6 changes: 0 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,3 @@ os:
branches:
except:
- staging.tmp

script:
- cargo check
- cargo test
- cargo test --all-features
- cargo test --features=m3d/obj
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ path = "bin/level/main.rs"
[[bin]]
name = "convert"
path = "bin/convert.rs"
required-features = ["m3d/obj"]

[dependencies]
# internals
Expand Down
2 changes: 1 addition & 1 deletion lib/m3d/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ authors = ["Dzmitry Malyshau <kvarkus@gmail.com>"]
[dependencies]
byteorder = "1.0"
log = "0.4"
obj = { version = "0.9", optional = true }
obj = "0.9"
ron = "0.4"
serde = "1.0"
serde_derive = "1.0"
51 changes: 42 additions & 9 deletions lib/m3d/src/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#[cfg(feature = "obj")]
use std::io::{self, Write};
#[cfg(feature = "obj")]
use std::path::PathBuf;

#[cfg(feature = "obj")]
use Polygon;


Expand Down Expand Up @@ -84,7 +81,27 @@ pub struct Geometry<P> {
pub polygons: Vec<P>,
}

#[cfg(feature = "obj")]
fn flatten_normal(poly: &[obj::IndexTuple], normals: &[[f32; 3]]) -> [i8; 3] {
let n = poly.iter().fold([0f32; 3], |u, obj::IndexTuple(_, _, ni)| {
let n = match ni {
Some(index) => normals[*index],
None => [0.0, 0.0, 0.0],
};
[u[0] + n[0], u[1] + n[1], u[2] + n[2]]
});
let m2 = n.iter().fold(0f32, |u, v| u + v*v);
let scale = if m2 == 0.0 { 0.0 } else { NORMALIZER / m2.sqrt() };
[(n[0] * scale) as i8, (n[1] * scale) as i8, (n[2] * scale) as i8]
}

fn flatten_pos(poly: &[obj::IndexTuple], positions: &[[f32; 3]]) -> [i8; 3] {
let m = poly.iter().fold([0f32; 3], |u, obj::IndexTuple(pi, _, _)| {
let p = positions[*pi];
[u[0] + p[0], u[1] + p[1], u[2] + p[2]]
});
[ (m[0] * 0.25) as i8, (m[1] * 0.25) as i8, (m[2] * 0.25) as i8 ]
}

impl<P: Polygon> Geometry<P> {
pub fn save_obj(&self, path: PathBuf) -> io::Result<()> {
use std::fs::File;
Expand Down Expand Up @@ -152,17 +169,33 @@ impl<P: Polygon> Geometry<P> {
.map(|id| format!("{:?}", ColorId::new(id)))
.collect::<Vec<_>>();

let polygons = obj.objects
.into_iter()
let obj::Obj { ref objects, ref position, ref normal, .. } = obj;
let polygons = objects
.iter()
.flat_map(|object| {
object.groups.into_iter().flat_map(|group| {
object.groups.iter().flat_map(|group| {
let mut vertices = Vec::new();
let color_id = color_names
.iter()
.position(|c| c == &group.name)
.unwrap_or(0);
group.polys
.into_iter()
.map(move |poly| P::from_obj(poly, color_id as u32))
.iter()
.map(move |poly| {
vertices.clear();
for &obj::IndexTuple(pi, _, ni) in poly {
vertices.push(Vertex {
pos: pi as u16,
normal: ni.unwrap_or(0) as u16,
})
}
P::new(
flatten_pos(poly, position),
flatten_normal(poly, normal),
[color_id as u32, 0],
&vertices
)
})
})
})
.collect();
Expand Down
46 changes: 0 additions & 46 deletions lib/m3d/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
extern crate byteorder;
#[macro_use]
extern crate log;
#[cfg(feature = "obj")]
extern crate obj;
extern crate ron;
extern crate serde;
Expand All @@ -16,10 +15,8 @@ pub use self::geometry::{
};

use byteorder::{LittleEndian as E, ReadBytesExt, WriteBytesExt};
#[cfg(feature = "obj")]
use std::fs::File;
use std::io::Write;
#[cfg(feature = "obj")]
use std::path::PathBuf;


Expand Down Expand Up @@ -172,7 +169,6 @@ pub struct Mesh<G> {
pub physics: Physics,
}

#[cfg(feature = "obj")]
impl<G> Mesh<G> {
fn with_geometry<T>(self, geometry: T) -> Mesh<T> {
Mesh {
Expand All @@ -192,10 +188,7 @@ pub trait Polygon: Sized {
) -> Self;
fn dump(&self, vertices: &mut Vec<Vertex>) -> ([i8; 3], [i8; 3], [u32; 2]);
fn num_vertices() -> u32;
#[cfg(feature = "obj")]
fn color_id(&self) -> u32;
#[cfg(feature = "obj")]
fn from_obj(poly: obj::SimplePolygon, color_id: u32) -> Self;
}
impl Polygon for DrawTriangle {
fn new(
Expand All @@ -215,25 +208,9 @@ impl Polygon for DrawTriangle {
fn num_vertices() -> u32 {
3
}
#[cfg(feature = "obj")]
fn color_id(&self) -> u32 {
self.material[0]
}
#[cfg(feature = "obj")]
fn from_obj(poly: obj::SimplePolygon, color_id: u32) -> Self {
assert_eq!(poly.len(), 3);
fn vert(obj::IndexTuple(pi, _, ni): obj::IndexTuple) -> Vertex {
Vertex {
pos: pi as u16,
normal: ni.unwrap_or(0) as u16,
}
}
DrawTriangle {
vertices: [ vert(poly[0]), vert(poly[1]), vert(poly[2]) ],
flat_normal: [0, 0, 1], //TODO
material: [color_id, 0],
}
}
}
impl Polygon for CollisionQuad {
fn new(
Expand All @@ -253,24 +230,9 @@ impl Polygon for CollisionQuad {
fn num_vertices() -> u32 {
4
}
#[cfg(feature = "obj")]
fn color_id(&self) -> u32 {
0
}
#[cfg(feature = "obj")]
fn from_obj(poly: obj::SimplePolygon, _color_id: u32) -> Self {
assert_eq!(poly.len(), 4);
CollisionQuad {
vertices: [
poly[0].0 as u16,
poly[1].0 as u16,
poly[2].0 as u16,
poly[3].0 as u16,
],
middle: [0, 0, 0], //TODO
flat_normal: [0, 0, 1], //TODO
}
}
}

impl<P: Polygon> Mesh<Geometry<P>> {
Expand Down Expand Up @@ -413,16 +375,11 @@ impl<P: Polygon> Mesh<Geometry<P>> {
pub type DrawMesh = Mesh<Geometry<DrawTriangle>>;
pub type CollisionMesh = Mesh<Geometry<CollisionQuad>>;

#[cfg(feature = "obj")]
pub type FullModel = Model<DrawMesh, CollisionMesh>;

#[cfg(feature = "obj")]
type RefModel = Model<Mesh<String>, Mesh<String>>;

#[cfg(feature = "obj")]
const MODEL_PATH: &str = "model.ron";

#[cfg(feature = "obj")]
pub fn convert_m3d(
mut input: File,
out_path: &PathBuf,
Expand Down Expand Up @@ -532,7 +489,6 @@ pub fn convert_m3d(



#[cfg(feature = "obj")]
impl Mesh<String> {
fn resolve<P: Polygon>(&self, source_dir: &PathBuf) -> Mesh<Geometry<P>> {
Mesh {
Expand All @@ -546,7 +502,6 @@ impl Mesh<String> {
}
}

#[cfg(feature = "obj")]
impl Slot<Mesh<String>> {
fn resolve<P: Polygon>(&self, source_dir: &PathBuf) -> Slot<Mesh<Geometry<P>>> {
Slot {
Expand All @@ -558,7 +513,6 @@ impl Slot<Mesh<String>> {
}
}

#[cfg(feature = "obj")]
impl FullModel {
pub fn import(dir_path: &PathBuf) -> Self {
let model_file = File::open(dir_path.join(MODEL_PATH)).unwrap();
Expand Down

0 comments on commit 22251e1

Please sign in to comment.