Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upfeat: Load full scenes from GLTF files #435
Conversation
Rhuagh
requested review from
omni-viral,
Xaeroxe and
torkleyy
Oct 20, 2017
| [workspace] | ||
| -members = ["amethyst_assets", "amethyst_audio", "amethyst_config", "amethyst_core", "amethyst_input", "amethyst_renderer", "amethyst_utils"] | ||
| +members = ["amethyst_assets", "amethyst_audio", "amethyst_config", "amethyst_core", "amethyst_gltf", "amethyst_input", |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 20, 2017
Member
We should eventually make this a virtual workspace. I think those support kind of implicit members, not sure.
torkleyy
Oct 20, 2017
Member
We should eventually make this a virtual workspace. I think those support kind of implicit members, not sure.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| +travis-ci = { repository = "amethyst/amethyst" } | ||
| + | ||
| +[dependencies] | ||
| +amethyst_assets = { path = "../amethyst_assets/" } |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| +amethyst_assets = { path = "../amethyst_assets/" } | ||
| +amethyst_renderer = { path = "../amethyst_renderer/" } | ||
| +amethyst_core = { path = "../amethyst_core/" } | ||
| +base64 = "*" |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + let format = match mime_type { | ||
| + "image/png" => ImageFormat::Png, | ||
| + "image/jpeg" => ImageFormat::Jpeg, | ||
| + _ => unreachable!(), |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + let format = match ty { | ||
| + "image/png" => ImageFormat::Png, | ||
| + "image/jpeg" => ImageFormat::Jpeg, | ||
| + _ => unreachable!(), |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| +/// Gltf scene format, will cause the whole default scene to be loaded from the given file. | ||
| +/// | ||
| +/// Using the `GltfSceneLoaderSystem` a `Handle<GltfSceneAsset>` from this format can be attached | ||
| +/// to an entity in ECS, and the system will then load the full scene using the given entity |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + options: GltfSceneOptions, | ||
| + ) -> Result<GltfSceneAsset, BoxedErr> { | ||
| + let gltf = load_gltf(source, &name, options).map_err(|err| BoxedErr::new(err))?; | ||
| + match gltf.default_scene { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 20, 2017
Member
Should be
if gltf.default_scene.is_some() || gltf.scenes.len() == 1 {
Ok(gltf)
} else {
Err(..)
}
torkleyy
Oct 20, 2017
Member
Should be
if gltf.default_scene.is_some() || gltf.scenes.len() == 1 {
Ok(gltf)
} else {
Err(..)
}| + | ||
| +/// A GLTF scene loader, will transform `Handle<GltfSceneAsset>` into full entity hierarchies. | ||
| +/// | ||
| +/// Will also do the asset storage processing for `GltfSceneAsset`.s |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + | ||
| +impl GltfSceneLoaderSystem { | ||
| + pub fn new() -> Self { | ||
| + Self {} |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 20, 2017
Member
Meh, I don't like this syntax. And I guess we don't need this constructor, do we?
torkleyy
Oct 20, 2017
Member
Meh, I don't like this syntax. And I guess we don't need this constructor, do we?
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + // TODO: emissive factor | ||
| + // TODO: alpha | ||
| + // TODO: double sided | ||
| + let albedo = match material.base_color.0.handle { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
@alteous This is our gltf integration PR in case you're interested. |
| +} | ||
| + | ||
| +// Load a single node, attach all data to the given `node_entity`. | ||
| +fn load_node( |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| @@ -0,0 +1,328 @@ | ||
| +use std; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
alteous
Oct 20, 2017
I hope the burden of writing your own loader wasn't too annoying. It's a compromise between being high-level and not doing 'too much' on behalf of the user.
alteous
Oct 20, 2017
•
I hope the burden of writing your own loader wasn't too annoying. It's a compromise between being high-level and not doing 'too much' on behalf of the user.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Rhuagh
Oct 20, 2017
Member
No, it was fine, I started with using the importer to get the first implementation in place, then I basically copied the importer code and replaced the file loading parts only.
Rhuagh
Oct 20, 2017
Member
No, it was fine, I started with using the importer to get the first implementation in place, then I basically copied the importer code and replaced the file loading parts only.
| +} | ||
| + | ||
| +fn map_mode(mode: gltf::json::mesh::Mode) -> Result<Primitive, GltfError> { | ||
| + use gltf::json::mesh::Mode::*; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
alteous
Oct 20, 2017
I suggest gltf::mesh::Mode instead. The gltf::json module is deprecated and will be removed in 1.0.
alteous
Oct 20, 2017
I suggest gltf::mesh::Mode instead. The gltf::json module is deprecated and will be removed in 1.0.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Rhuagh
Oct 20, 2017
Member
Oh, I must have missed that, it did feel weird to have to go down to the json stuff.
Rhuagh
Oct 20, 2017
Member
Oh, I must have missed that, it did feel weird to have to go down to the json stuff.
| +} | ||
| + | ||
| +impl Format<GltfSceneAsset> for GltfSceneFormat { | ||
| + const NAME: &'static str = "GLTF"; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
self-requested a review
Oct 21, 2017
torkleyy
requested changes
Oct 21, 2017
Thanks for addressing, got a few other concerns but otherwise it's great!
| + } | ||
| +} | ||
| + | ||
| +fn import_standard<'a>( |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + let gltf = validate_standard(unvalidated)?; | ||
| + let bin = None; | ||
| + let mut buffers = Buffers(vec![]); | ||
| + for buffer in load_external_buffers(source, base_path, &gltf, bin)? { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 21, 2017
Member
Why are you iterating over a vec just to push the elements to another, intially empty one?
torkleyy
Oct 21, 2017
Member
Why are you iterating over a vec just to push the elements to another, intially empty one?
| + pub generate_tex_coords: Option<(f32, f32)>, | ||
| +} | ||
| + | ||
| +impl Default for GltfSceneOptions { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| +/// A GLTF scene loader, will transform `Handle<GltfSceneAsset>` into full entity hierarchies. | ||
| +/// | ||
| +/// Will also do the asset storage processing for `GltfSceneAsset`. | ||
| +pub struct GltfSceneLoaderSystem; |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + // process new texture handles, cache them in the textures | ||
| + for (material_index, texture_index, handle) in texture_handles { | ||
| + match texture_index { | ||
| + 0 => { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + // Use the default scene if set, otherwise use the first scene. | ||
| + // Note that the format will throw an error if the default scene is not set, | ||
| + // and there are more than one scene in the GLTF, so defaulting to scene 0 is safe | ||
| + let scene_index = match scene_asset.default_scene { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
| + }; | ||
| + | ||
| + // Load material for the primitive | ||
| + let material = match primitive.material { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
torkleyy
Oct 21, 2017
Member
I think it would be nicer to do this:
let material = primitive
.material
.map(|i| (i, scene_asset.materials.get(i)))
.and_then(|(i, m)| load_material(i, m, ..))
.unwrap_or_else(|| mat_defaults.0.clone());
torkleyy
Oct 21, 2017
Member
I think it would be nicer to do this:
let material = primitive
.material
.map(|i| (i, scene_asset.materials.get(i)))
.and_then(|(i, m)| load_material(i, m, ..))
.unwrap_or_else(|| mat_defaults.0.clone());
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Rhuagh
requested a review
from
torkleyy
Oct 21, 2017
Xaeroxe
approved these changes
Oct 21, 2017
I've got a couple organization nits but otherwise this looks awesome! Thanks for your work!
...I'm mostly just glad it wasn't me that had to write this :P Looks like loads of data to manage.
| +where | ||
| + P: AsRef<Path>, | ||
| +{ | ||
| + import_impl(source, path.as_ref()) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Xaeroxe
Oct 21, 2017
Member
You could replace this with the body of import_impl and just add
let path = path.as_ref()at the top.
Xaeroxe
Oct 21, 2017
Member
You could replace this with the body of import_impl and just add
let path = path.as_ref()at the top.
| +} | ||
| + | ||
| +fn read_to_end<P: AsRef<Path>>(source: Arc<AssetSource>, path: P) -> Result<Vec<u8>, BoxedErr> { | ||
| + read_to_end_impl(source, path.as_ref()) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
bors r+ |
Rhuagh commentedOct 20, 2017
•
edited
Edited 1 time
-
Rhuagh
edited Oct 20, 2017 (most recent)
Only have support for static scenes so far. Need to complete the Animation PR before I can finish loading that.
Also waiting on multiple features in other parts of the engine before I can add full material support, indexed meshes etc.