Skip to content

Commit

Permalink
Merge pull request #13 from davidedmonds/v2
Browse files Browse the repository at this point in the history
V2
  • Loading branch information
David Edmonds authored Jul 12, 2018
2 parents 43efd04 + 8415b67 commit b892f02
Show file tree
Hide file tree
Showing 11 changed files with 325 additions and 238 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dot_vox"
version = "1.0.1"
version = "2.0.0"
authors = ["David Edmonds <[email protected]>"]
description = "A Rust library for loading MagicaVoxel .vox files."
license = "MIT"
Expand All @@ -14,6 +14,7 @@ readme = "README.md"
bitflags = "^1.0.0"
byteorder = "^1.0"
lazy_static = "^1.0"
log = "^0.4"
nom = "^3.0"

[dev-dependencies]
Expand Down
55 changes: 20 additions & 35 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ extern crate byteorder;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
#[macro_use]
extern crate nom;

#[cfg(test)]
extern crate avow;

mod dot_vox_data;
mod palette;
mod parser;
mod material;
mod model;

Expand All @@ -24,39 +27,18 @@ pub use material::material_properties::MaterialProperties;
pub use material::material_type::MaterialType;

pub use model::Model;
pub use model::size::Size;
pub use model::voxel::Voxel;
pub use model::Size;
pub use model::Voxel;

pub use palette::DEFAULT_PALETTE;
use nom::IResult;

use material::extract_materials;
use model::extract_models;
use palette::extract_palette;
pub use palette::DEFAULT_PALETTE;

use nom::IResult::Done;
use nom::le_u32;
use parser::parse_vox_file;

use std::fs::File;
use std::io::Read;

const MAGIC_NUMBER: &'static str = "VOX ";

named!(parse_vox_file <&[u8], DotVoxData>, do_parse!(
tag!(MAGIC_NUMBER) >>
version: le_u32 >>
take!(12) >>
models: extract_models >>
palette: opt_res!(extract_palette) >>
opt_res!(complete!(take!(4))) >>
materials: opt_res!(extract_materials) >>
(DotVoxData {
version: version,
models: models,
palette: palette.unwrap_or_else(|_| DEFAULT_PALETTE.to_vec()),
materials: materials.unwrap_or_else(|_| vec![]),
})
));

/// Loads the supplied MagicaVoxel .vox file
///
/// Loads the supplied file, parses it, and returns a `DotVoxData` containing
Expand Down Expand Up @@ -103,7 +85,7 @@ pub fn load(filename: &str) -> Result<DotVoxData, &'static str> {
let mut buffer = Vec::new();
f.read_to_end(&mut buffer).expect("Unable to read file");
match parse_vox_file(&buffer) {
Done(_, parsed) => Ok(parsed),
IResult::Done(_, parsed) => Ok(parsed),
_ => Err("Not a valid MagicaVoxel .vox file"),
}
}
Expand All @@ -119,12 +101,11 @@ mod tests {
use byteorder::{ByteOrder, LittleEndian};

lazy_static! {
/// The default palette used by MagicaVoxel - this is supplied if no palette is included in the .vox file.
static ref MODIFIED_PALETTE: Vec<u32> = include_bytes!("resources/modified_palette.bytes")
.chunks(4)
.map(LittleEndian::read_u32)
.collect();
}
static ref MODIFIED_PALETTE: Vec<u32> = include_bytes!("resources/modified_palette.bytes")
.chunks(4)
.map(LittleEndian::read_u32)
.collect();
}

fn placeholder(palette: Vec<u32>, materials: Vec<Material>) -> DotVoxData {
DotVoxData {
Expand All @@ -141,13 +122,17 @@ mod tests {
},
],
palette: palette,
materials: materials
materials: materials,
}
}

fn compare_data(actual: DotVoxData, expected: DotVoxData) {
assert_eq!(actual.version, expected.version);
assert_eq!(actual.models, expected.models);
actual.models.into_iter().zip(expected.models.into_iter())
.for_each(|(actual, expected)| {
assert_eq!(actual.size, expected.size);
vec::are_eq(actual.voxels, expected.voxels);
});
vec::are_eq(actual.palette, expected.palette);
vec::are_eq(actual.materials, expected.materials);
}
Expand Down
83 changes: 1 addition & 82 deletions src/material/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ pub struct Material {
pub properties: MaterialProperties,
}

named!(parse_material <&[u8], Material>, do_parse!(
take!(12) >>
named!(pub parse_material <&[u8], Material>, do_parse!(
id: le_u32 >>
material_type: parse_material_type >>
properties: parse_material_properties >>
Expand All @@ -30,83 +29,3 @@ named!(parse_material <&[u8], Material>, do_parse!(
properties: properties
})
));

named!(pub extract_materials <&[u8], Vec<Material> >, do_parse!(
models: many0!(complete!(parse_material)) >>
(models)
));

#[cfg(test)]
mod tests {
use super::*;
use avow::vec;

#[test]
fn can_parse_material_chunk() {
let bytes = include_bytes!("../resources/valid_material.bytes").to_vec();
let result = super::parse_material(&bytes);
assert!(result.is_done());
let (_, material) = result.unwrap();
assert_eq!(248, material.id);
assert_eq!(MaterialType::Metal(1.0), material.material_type);
assert_eq!(
MaterialProperties {
plastic: Some(1.0),
roughness: Some(0.0),
specular: Some(1.0),
ior: Some(0.3),
power: Some(4.0),
glow: Some(0.589474),
..Default::default()
},
material.properties
);
}

#[test]
fn can_parse_multiple_materials() {
let bytes = include_bytes!("../resources/multi-materials.bytes").to_vec();
let result = super::extract_materials(&bytes);
assert!(result.is_done());
let (_, materials) = result.unwrap();
vec::are_eq(
materials,
vec![
Material {
id: 78,
material_type: MaterialType::Metal(1.0),
properties: MaterialProperties {
plastic: Some(0.0),
roughness: Some(0.1),
specular: Some(0.5),
ior: Some(0.3),
..Default::default()
},
},
Material {
id: 84,
material_type: MaterialType::Metal(0.526316),
properties: MaterialProperties {
plastic: Some(0.0),
roughness: Some(0.252632),
specular: Some(0.736842),
ior: Some(0.3),
..Default::default()
},
},
Material {
id: 248,
material_type: MaterialType::Glass(0.810526),
properties: MaterialProperties {
plastic: Some(0.0),
roughness: Some(0.189474),
specular: Some(0.5),
ior: Some(0.547368),
attenuation: Some(0.021053),
..Default::default()
},
},
],
);
}
}
50 changes: 30 additions & 20 deletions src/model/voxel.rs → src/model.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
use nom::{le_u8, le_u32};

/// A renderable voxel Model
#[derive(Debug, PartialEq)]
pub struct Model {
/// The size of the model in voxels
pub size: Size,
/// The voxels to be displayed.
pub voxels: Vec<Voxel>,
}

/// The size of a model in voxels
///
/// Indicates the size of the model in Voxels.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Size {
/// The width of the model in voxels.
pub x: u32,
/// The height of the model in voxels.
pub y: u32,
/// The depth of the model in voxels.
pub z: u32,
}

/// A Voxel
///
/// A Voxel is a point in 3D space, with an indexed colour attached.
Expand Down Expand Up @@ -30,6 +52,13 @@ impl Voxel {
}
}

named!(pub parse_size <&[u8], Size>, do_parse!(
x: le_u32 >>
y: le_u32 >>
z: le_u32 >>
(Size { x: x, y: y, z: z })
));

named!(parse_voxel <&[u8], Voxel>, do_parse!(
x: le_u8 >>
y: le_u8 >>
Expand All @@ -39,26 +68,7 @@ named!(parse_voxel <&[u8], Voxel>, do_parse!(
));

named!(pub parse_voxels <&[u8], Vec<Voxel> >, do_parse!(
take!(12) >>
num_voxels: le_u32 >>
voxels: many_m_n!(num_voxels as usize, num_voxels as usize, parse_voxel) >>
(voxels)
));

#[cfg(test)]
mod tests {
use super::*;
use avow::vec;

#[test]
fn can_parse_voxels_chunk() {
let bytes = include_bytes!("../resources/valid_voxels.bytes").to_vec();
let result = super::parse_voxels(&bytes);
assert!(result.is_done());
let (_, voxels) = result.unwrap();
vec::are_eq(
voxels,
vec![Voxel::new(0, 12, 22, 225), Voxel::new(12, 23, 13, 225)],
);
}
}
));
36 changes: 0 additions & 36 deletions src/model/mod.rs

This file was deleted.

44 changes: 0 additions & 44 deletions src/model/size.rs

This file was deleted.

21 changes: 1 addition & 20 deletions src/palette.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,4 @@ lazy_static! {
.collect();
}

named!(pub extract_palette <&[u8], Vec<u32> >, complete!(do_parse!(
take!(12) >>
colors: many_m_n!(255, 255, le_u32) >>
(colors)
)));

#[cfg(test)]
mod tests {
use super::*;
use avow::vec;

#[test]
fn can_parse_palette_chunk() {
let bytes = include_bytes!("resources/valid_palette.bytes").to_vec();
let result = super::extract_palette(&bytes);
assert!(result.is_done());
let (_, palette) = result.unwrap();
vec::are_eq(palette, DEFAULT_PALETTE.to_vec());
}
}
named!(pub extract_palette <&[u8], Vec<u32> >, many1!(le_u32));
Loading

0 comments on commit b892f02

Please sign in to comment.