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
use crate::{
shape::{FromShape, ShapePrefab},
types::{Mesh, MeshData},
};
use amethyst_assets::{
AssetPrefab, AssetStorage, Format, Handle, Loader, PrefabData, ProgressCounter,
};
use amethyst_core::ecs::{Entity, Read, ReadExpect, WriteStorage};
use amethyst_error::Error;
use rendy::mesh::MeshBuilder;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct ObjFormat;
amethyst_assets::register_format_type!(MeshData);
amethyst_assets::register_format!("OBJ", ObjFormat as MeshData);
impl Format<MeshData> for ObjFormat {
fn name(&self) -> &'static str {
"OBJ"
}
fn import_simple(&self, bytes: Vec<u8>) -> Result<MeshData, Error> {
rendy::mesh::obj::load_from_obj(&bytes)
.map(|mut builders| {
let mut iter = builders.drain(..);
let builder = iter.next().unwrap();
if iter.next().is_some() {
log::warn!("OBJ file contains more than one object, only loading the first");
}
builder.0.into()
})
.map_err(|e| e.compat().into())
}
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(bound = "")]
pub enum MeshPrefab<V> {
Asset(AssetPrefab<Mesh>),
Shape(ShapePrefab<V>),
}
impl<'a, V> PrefabData<'a> for MeshPrefab<V>
where
V: FromShape + Into<MeshBuilder<'static>>,
{
type SystemData = (
ReadExpect<'a, Loader>,
WriteStorage<'a, Handle<Mesh>>,
Read<'a, AssetStorage<Mesh>>,
);
type Result = ();
fn add_to_entity(
&self,
entity: Entity,
system_data: &mut Self::SystemData,
entities: &[Entity],
children: &[Entity],
) -> Result<(), Error> {
match self {
MeshPrefab::Asset(m) => {
m.add_to_entity(entity, system_data, entities, children)?;
}
MeshPrefab::Shape(s) => {
s.add_to_entity(entity, system_data, entities, children)?;
}
}
Ok(())
}
fn load_sub_assets(
&mut self,
progress: &mut ProgressCounter,
system_data: &mut Self::SystemData,
) -> Result<bool, Error> {
Ok(match self {
MeshPrefab::Asset(m) => m.load_sub_assets(progress, system_data)?,
MeshPrefab::Shape(s) => s.load_sub_assets(progress, system_data)?,
})
}
}