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
113
114
115
116
117
118
119
120
121
122
123
124
extern crate amethyst_animation as animation;
extern crate amethyst_assets as assets;
extern crate amethyst_core as core;
extern crate amethyst_renderer as renderer;
extern crate base64;
extern crate fnv;
extern crate gfx;
extern crate gltf;
extern crate gltf_utils;
extern crate imagefmt;
extern crate itertools;
extern crate specs;

pub use format::GltfSceneFormat;
pub use systems::GltfSceneLoaderSystem;

use animation::{Animation, Sampler};
use assets::{Asset, Error as AssetError, Handle};
use core::transform::LocalTransform;
use gfx::Primitive;
use renderer::{MeshHandle, TextureData, TextureHandle, VertexBufferCombination};
use specs::VecStorage;

mod format;
mod systems;

/// A single graphics primitive
#[derive(Debug)]
pub struct GltfPrimitive {
    pub primitive: Primitive,
    pub material: Option<usize>,
    pub indices: Option<Vec<usize>>,
    pub attributes: VertexBufferCombination,
    pub handle: Option<MeshHandle>,
}

/// Alpha mode for material
#[derive(Debug)]
pub enum AlphaMode {
    Opaque,
    Mask,
    Blend,
}

/// GLTF material, PBR based
#[derive(Debug)]
pub struct GltfMaterial {
    base_color: (GltfTexture, [f32; 4]),
    metallic: (GltfTexture, f32),
    roughness: (GltfTexture, f32),
    emissive: (GltfTexture, [f32; 3]),
    normal: Option<(GltfTexture, f32)>,
    occlusion: Option<(GltfTexture, f32)>,
    alpha: (AlphaMode, f32),
    double_sided: bool,
}

/// A GLTF defined texture, will be in `TextureData` format in the output from the loader.
#[derive(Debug)]
pub struct GltfTexture {
    pub data: TextureData,
    pub handle: Option<TextureHandle>,
}

impl GltfTexture {
    pub fn new(data: TextureData) -> Self {
        Self { data, handle: None }
    }
}

/// A node in the scene hierarchy
#[derive(Debug)]
pub struct GltfNode {
    pub primitives: Vec<GltfPrimitive>,
    pub parent: Option<usize>,
    pub children: Vec<usize>,
    pub local_transform: LocalTransform,
}

/// A single scene is defined as a list of the root nodes in the node hierarchy for the full asset
#[derive(Debug)]
pub struct GltfScene {
    pub root_nodes: Vec<usize>,
}

/// A single animation
#[derive(Debug)]
pub struct GltfAnimation {
    // node index, vec will be same size as samplers, and reference the sampler at the same index
    pub nodes: Vec<usize>,
    pub samplers: Vec<Sampler>,
    pub handle: Option<Handle<Animation>>,
    //pub hierarchy_root: usize,
}

/// Options used when loading a GLTF file
#[derive(Debug, Clone, Default)]
pub struct GltfSceneOptions {
    pub generate_tex_coords: Option<(f32, f32)>,
    pub load_animations: bool,
}

/// Actual asset produced on finished loading of a GLTF scene file.
#[derive(Debug)]
pub struct GltfSceneAsset {
    pub nodes: Vec<GltfNode>,
    pub scenes: Vec<GltfScene>,
    pub materials: Vec<GltfMaterial>,
    pub animations: Vec<GltfAnimation>,
    pub default_scene: Option<usize>,
    pub options: GltfSceneOptions,
}

impl Into<Result<GltfSceneAsset, AssetError>> for GltfSceneAsset {
    fn into(self) -> Result<GltfSceneAsset, AssetError> {
        Ok(self)
    }
}

impl Asset for GltfSceneAsset {
    type Data = Self;
    // TODO: replace by tracked storage
    type HandleStorage = VecStorage<Handle<Self>>;
}