Skip to content

Commit

Permalink
wip: Try to add a handle to an entity in a prefab
Browse files Browse the repository at this point in the history
  • Loading branch information
suspistew committed Feb 23, 2021
1 parent 56056fc commit 44ccdd1
Show file tree
Hide file tree
Showing 13 changed files with 195 additions and 123 deletions.
2 changes: 2 additions & 0 deletions amethyst_assets/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ fn asset_loading_tick(_: &mut World, resources: &mut Resources) {
let mut loader = resources
.get_mut::<DefaultLoader>()
.expect("Could not get_mut DefaultLoader");

loader
.process(resources)
.expect("Error in Loader processing");

}

/// starts the asset thread with distill_daemon
Expand Down
1 change: 1 addition & 0 deletions amethyst_assets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ mod source;
mod storage;

pub use distill::{
make_handle,
importer as distill_importer,
loader::{
handle::{AssetHandle, GenericHandle, Handle, WeakHandle},
Expand Down
6 changes: 4 additions & 2 deletions amethyst_assets/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ impl Loader for DefaultLoader {
Handle::new(
self.ref_sender.clone(),
self.loader
.add_ref_indirect(IndirectIdentifier::Path(path.to_string())),
.add_ref_indirect(IndirectIdentifier::PathWithType(path.to_string(), AssetTypeId(A::UUID))),
)
}
fn get_load(&self, id: AssetUuid) -> Option<WeakHandle> {
Expand Down Expand Up @@ -228,7 +228,9 @@ impl Loader for DefaultLoader {
match self.ref_receiver.try_recv() {
Err(TryRecvError::Empty) => break,
Err(TryRecvError::Disconnected) => panic!("RefOp receiver disconnected"),
Ok(RefOp::Decrease(handle)) => self.loader.remove_ref(handle),
Ok(RefOp::Decrease(handle)) => {
self.loader.remove_ref(handle);
},
Ok(RefOp::Increase(handle)) => {
self.loader
.get_load_info(handle)
Expand Down
8 changes: 0 additions & 8 deletions amethyst_gltf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@ amethyst_animation = { path = "../amethyst_animation", version = "0.15.3" }
amethyst_core = { path = "../amethyst_core", version = "0.15.3" }
amethyst_error = { path = "../amethyst_error", version = "0.15.3" }
amethyst_rendy = { path = "../amethyst_rendy", version = "0.15.3" }
atelier-assets = { git = "https://github.com/radium-io/atelier-assets.git", rev = "6987e6b4abe061f1810018efd7518866b62b70fb", features = [
"serde-1",
"type_uuid",
"serde_importers",
"parallel_hash",
"rpc_io",
"handle",
] }
err-derive = "0.2.3"
base64 = "0.11"
fnv = "1"
Expand Down
18 changes: 18 additions & 0 deletions amethyst_gltf/src/bundle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use amethyst_core::ecs::{SystemBundle, Resources, World};
use amethyst_error::Error;
use amethyst_core::dispatcher::DispatcherBuilder;
use crate::system::mesh_handle_loading;

/// Bundle that initializes needed resources to use GLTF
pub struct GltfBundle;

impl SystemBundle for GltfBundle {
fn load(&mut self, world: &mut World, resources: &mut Resources, builder: &mut DispatcherBuilder) -> Result<(), Error> {
builder.add_thread_local_fn(mesh_handle_loading);
Ok(())
}

fn unload(&mut self, _world: &mut World, _resources: &mut Resources) -> Result<(), Error> {
unimplemented!()
}
}
2 changes: 1 addition & 1 deletion amethyst_gltf/src/importer/gltf_bytes_converter.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use atelier_assets::importer::Error;
use amethyst_assets::distill_importer::Error;
use gltf::Document;

pub fn convert_bytes(
Expand Down
113 changes: 54 additions & 59 deletions amethyst_gltf/src/importer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
use std::{cmp::Ordering, io::Read};

use amethyst_assets::{
atelier_importer,
atelier_importer::{Error, ImportOp, ImportedAsset, Importer, ImporterValue},
};
use amethyst_assets::{distill_importer, distill_importer::{Error, ImportOp, ImportedAsset, Importer, ImporterValue}, Handle, AssetUuid, make_handle};
use amethyst_core::{
math::{convert, Quaternion, Unit, Vector3, Vector4},
transform::Transform,
Named,
};
use amethyst_rendy::{light::Light, Camera};
use atelier_assets::core::AssetUuid;
use gltf::{buffer, buffer::Data, Document, Gltf, Mesh, Node};
use serde::{Deserialize, Serialize};
use type_uuid::TypeUuid;
use log::debug;

use crate::{
importer::{gltf_bytes_converter::convert_bytes, mesh::load_mesh},
GltfAsset, GltfNodeExtent, GltfSceneOptions,
};
use crate::{importer::{gltf_bytes_converter::convert_bytes, mesh::load_mesh}, GltfNodeExtent, GltfSceneOptions};
use amethyst_assets::prefab::legion_prefab::{PrefabBuilder, CookedPrefab};
use amethyst_assets::prefab::{Prefab, legion_prefab};
use amethyst_core::ecs::World;
use amethyst_rendy::types::MeshData;
use crate::types::MeshHandle;

mod gltf_bytes_converter;
mod mesh;
Expand Down Expand Up @@ -50,7 +45,7 @@ pub struct GltfImporterState {
/// The importer for '.gltf' or '.glb' files.
#[derive(Default, TypeUuid)]
#[uuid = "6dbb4496-bd73-42cd-b817-11046e964e30"]
pub struct GltfImporter {}
pub struct GltfImporter;

impl Importer for GltfImporter {
fn version_static() -> u32 {
Expand All @@ -70,8 +65,9 @@ impl Importer for GltfImporter {
source: &mut dyn Read,
options: &Self::Options,
_state: &mut Self::State,
) -> amethyst_assets::atelier_importer::Result<ImporterValue> {
) -> amethyst_assets::distill_importer::Result<ImporterValue> {
log::info!("Importing scene");
let mut asset_accumulator = Vec::new();
let mut world = World::default();

let mut bytes = Vec::new();
Expand All @@ -80,7 +76,7 @@ impl Importer for GltfImporter {

if let Err(err) = result {
log::error!("GLTF Import error: {:?}", err);
return Err(atelier_importer::Error::Boxed(Box::new(err)));
return Err(distill_importer::Error::Boxed(Box::new(err)));
}

let (doc, buffers, _images) = result.unwrap();
Expand All @@ -97,25 +93,36 @@ impl Importer for GltfImporter {
let mut node_index: usize = 0;

scene.nodes().into_iter().for_each(|node| {
load_node(&node, &mut world, op, &options, &buffers, &mut node_index);
let mut node_assets = load_node(&node, &mut world, op, &options, &buffers, &mut node_index);
asset_accumulator.append(&mut node_assets);
});


let legion_prefab = legion_prefab::Prefab::new(world);
let prefab_asset = Prefab::new(legion_prefab);
let scene_prefab = Prefab::new(legion_prefab);

let prefab_id = op.new_asset_uuid();
println!("PREFAB HANDLE : {:?}", prefab_id);

asset_accumulator.push(ImportedAsset {
id: prefab_id,
search_tags: Vec::new(),
build_deps: Vec::new(),
load_deps: Vec::new(),
asset_data: Box::new(scene_prefab),
build_pipeline: None,
});

Ok(ImporterValue {
assets: vec![ImportedAsset {
id: op.new_asset_uuid(),
search_tags: Vec::new(),
build_deps: Vec::new(),
load_deps: Vec::new(),
asset_data: Box::new(prefab_asset),
build_pipeline: None,
}],
assets: asset_accumulator,
})
}
}

// This method will return the mesh assets that need to be loaded by distill.
// Contrary to the material, I've considered that loading a mesh is only mandatory is it's used somewhere
// For example, if I need to attach a mesh, I'll add the mesh as an ImportedAsset and set
// the matching uuid to the entry's component in an Handle
fn load_node(
node: &Node<'_>,
world: &mut World,
Expand All @@ -126,20 +133,9 @@ fn load_node(
) -> Vec<ImportedAsset> {
let current_node_entity = world.push(());
let mut imported_assets = Vec::new();
let mut node_asset = GltfAsset::default();

node_asset.index = *node_index;
*node_index += 1;

let mut search_tags: Vec<(String, Option<String>)> = vec![];

if let Some(name) = node.name() {
node_asset.name = Some(Named::new(name.to_string()));
search_tags.push(("node_name".to_string(), Some(name.to_string())));
search_tags.push(("node_index".to_string(), Some(node_asset.index.to_string())));
}
if let Some(transform) = load_transform(node) {
// world.entry(current_node_entity).expect("We just added this entity").add_component(transform);
world.entry(current_node_entity).expect("We just added this entity").add_component(transform);
}
if let Some(camera) = load_camera(node) {
debug!("Adding a camera component to to the current node entity");
Expand All @@ -166,32 +162,38 @@ fn load_node(
Ordering::Equal => {
// single primitive can be loaded directly onto the node
let (mesh, _material_index, bounds) = loaded_mesh.remove(0);
let mut mesh_search_tags: Vec<(String, Option<String>)> = vec![];
bounding_box.extend_range(&bounds);
let mut mesh_asset = GltfAsset::default();
mesh_asset.mesh = Some(mesh);
mesh_asset.index = *node_index;
mesh_search_tags
.push(("node_index".to_string(), Some(mesh_asset.index.to_string())));
*node_index += 1;
//TODO: material

// if we have a skin we need to track the mesh entities
if let Some(ref mut skin) = skin {
skin.mesh_indices.push(mesh_asset.index);
}
let mesh_asset_id = op.new_asset_uuid();
let mesh_data: MeshData = mesh.into();
imported_assets.push(ImportedAsset {
id: op.new_asset_uuid(),
search_tags: mesh_search_tags,
id: mesh_asset_id,
search_tags: vec![],
build_deps: vec![],
load_deps: vec![],
build_pipeline: None,
asset_data: Box::new(mesh_asset),
asset_data: Box::new(mesh_data),
});

println!("MESH HANDLE : {:?}", mesh_asset_id);

world.entry(current_node_entity)
.expect("We just added this entity")
.add_component(MeshHandle(make_handle(mesh_asset_id)));

debug!("Adding a mesh component to to the current node entity");
//TODO: material and skin

// if we have a skin we need to track the mesh entities
if let Some(ref mut skin) = skin {
//skin.mesh_indices.push(mesh_asset.index);
// TODO
}

}
Ordering::Greater => {
// if we have multiple primitives,
// we need to add each primitive as a child entity to the node
// TODO reimplement here
}
Ordering::Less => {
// Nothing to do here
Expand All @@ -201,17 +203,10 @@ fn load_node(

// load childs
for child in node.children() {
load_node(&child, world, op, options, buffers, node_index);
let mut child_assets = load_node(&child, world, op, options, buffers, node_index);
imported_assets.append(&mut child_assets);
}

imported_assets.push(ImportedAsset {
id: op.new_asset_uuid(),
search_tags,
build_deps: vec![],
load_deps: vec![],
build_pipeline: None,
asset_data: Box::new(node_asset),
});
imported_assets
}

Expand Down
53 changes: 12 additions & 41 deletions amethyst_gltf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ use std::{collections::HashMap, ops::Range};

use amethyst_animation::Skin;
use amethyst_assets::{
inventory,register_asset_type, prefab::{Prefab, register_component_type}, Asset, AssetProcessorSystem, AssetStorage, Handle, Loader,
inventory,register_asset_type, prefab::{Prefab, register_component_type}, Asset, AssetProcessorSystem, AssetStorage, Handle, Loader,distill_importer, distill_importer::{ImportedAsset, typetag, SerdeImportable},
ProgressCounter,
};
use amethyst_core::{
ecs::{Entity, Read, ReadExpect, Write, WriteStorage},
ecs::*,
math::{convert, Point3, Vector3},
transform::Transform,
Expand All @@ -35,9 +34,18 @@ use derivative::Derivative;
use serde::{Deserialize, Serialize};
use type_uuid::TypeUuid;

pub mod bundle;
mod importer;
mod types;
mod system;

pub use importer::GltfImporter;
use amethyst_assets::prefab::SerdeDiff;
use amethyst_assets::erased_serde::private::serde::ser::SerializeSeq;
use amethyst_assets::erased_serde::private::serde::de::SeqAccess;
use amethyst_assets::prefab::serde_diff::{DiffContext, ApplyContext};
use amethyst_assets::erased_serde::private::serde::de;
use amethyst_rendy::types::MeshData;

inventory::submit! {
amethyst_assets::SourceFileImporter {
Expand All @@ -55,6 +63,8 @@ inventory::submit! {

register_component_type!(Camera);
register_component_type!(Light);
register_component_type!(Transform);


/// A GLTF node extent
#[derive(Clone, Debug, Serialize)]
Expand Down Expand Up @@ -177,42 +187,3 @@ pub struct GltfSceneOptions {
/// or the first scene (only if there is only one scene, otherwise an `Error` will be returned).
pub scene_index: Option<usize>,
}

/// `AssetData` for gltf objects.
#[derive(Default, TypeUuid, Serialize)]
#[uuid = "8a7b7733-d770-4400-8ea8-b82dbc10aae2"]
pub struct GltfAsset {
/// `Transform` will almost always be placed, the only exception is for the main `Entity` for
/// certain scenarios (based on the data in the Gltf file)
pub transform: Option<Transform>,
/// `Camera` will always be placed
pub camera: Option<Camera>,
/// Lights can be added to a prefab with the `KHR_lights_punctual` feature enabled
pub light: Option<Light>,
/// `MeshData` is placed on all `Entity`s with graphics primitives
pub mesh: Option<MeshBuilder<'static>>,
/// Mesh handle after sub asset loading is done
pub mesh_handle: Option<Handle<Mesh>>,
/// `Material` is placed on all `Entity`s with graphics primitives with material
pub material: Option<Material>,
/// Loaded animations, if applicable, will always only be placed on the main `Entity`
// pub animatable: Option<Animatable<usize, Transform>>,
/// Skin data is placed on `Entity`s involved in the skin, skeleton or graphical primitives
/// using the skin
pub skin: Option<Skin>,
/// Node extent
pub extent: Option<GltfNodeExtent>,
/// Node name
pub name: Option<Named>,
/// Node index when loading a full scene
pub index: usize,
pub(crate) materials: Option<GltfMaterialSet>,
pub(crate) material_id: Option<usize>,
}

impl Asset for GltfAsset {
fn name() -> &'static str {
"Texture"
}
type Data = ();
}
9 changes: 9 additions & 0 deletions amethyst_gltf/src/system.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use amethyst_core::ecs::{World, Resources, Entity, IntoQuery};
use crate::types::MeshHandle;
use amethyst_rendy::Camera;
use amethyst_assets::Handle;

/// This will attach a Mesh to any Entity with a MeshHandle
pub(crate) fn mesh_handle_loading(world: &mut World, _resources: &mut Resources) {
//<(Entity, &Handle<GltfScene>)>::query().for_each(world, |(e)| println!("Heullkjhkjhkhjkhkjhjkooooh"));
}
Loading

0 comments on commit 44ccdd1

Please sign in to comment.