1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
pub mod material_properties;
pub mod material_type;
use {MaterialProperties, MaterialType};
use material::material_type::parse_material_type;
use material::material_properties::parse_material_properties;
use nom::le_u32;
#[derive(Debug, PartialEq)]
pub struct Material {
pub id: u8,
pub material_type: MaterialType,
pub properties: MaterialProperties,
}
named!(parse_material <&[u8], Material>, do_parse!(
take!(12) >>
id: le_u32 >>
material_type: parse_material_type >>
properties: parse_material_properties >>
(Material {
id: (id as u8).saturating_sub(1),
material_type: material_type,
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()
},
},
],
);
}
}