From 24f44a21ff996bb56891cb9124cf8af97977f150 Mon Sep 17 00:00:00 2001 From: furiouzz Date: Tue, 3 Nov 2020 00:30:51 +0100 Subject: [PATCH 1/4] [gltf] Support camera and fix hierarchy --- crates/bevy_gltf/src/loader.rs | 113 ++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 29 deletions(-) diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index 5406ee6e8343e..14401286e1ad4 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -4,9 +4,12 @@ use bevy_ecs::{bevy_utils::BoxedFuture, World, WorldBuilderSource}; use bevy_math::Mat4; use bevy_pbr::prelude::{PbrComponents, StandardMaterial}; use bevy_render::{ + camera::{Camera, CameraProjection, OrthographicProjection, PerspectiveProjection}, + entity::{Camera2dComponents, Camera3dComponents}, mesh::{Indices, Mesh, VertexAttributeValues}, pipeline::PrimitiveTopology, prelude::{Color, Texture}, + render_graph::base, texture::{AddressMode, FilterMode, SamplerDescriptor, TextureFormat}, }; use bevy_scene::Scene; @@ -211,42 +214,94 @@ fn load_node( ) -> Result<(), GltfError> { let transform = node.transform(); let mut gltf_error = None; - world_builder - .spawn(( + + // create camera node + let world_builder = if let Some(camera) = node.camera() { + match camera.projection() { + gltf::camera::Projection::Orthographic(orthographic) => { + let xmag = orthographic.xmag(); + let ymag = orthographic.ymag(); + let mut projection: OrthographicProjection = Default::default(); + projection.left = -xmag; + projection.right = xmag; + projection.top = ymag; + projection.bottom = -ymag; + projection.far = orthographic.zfar(); + projection.near = orthographic.znear(); + projection.get_projection_matrix(); + world_builder.spawn(Camera2dComponents { + camera: Camera { + name: Some(base::camera::CAMERA2D.to_owned()), + projection_matrix: projection.get_projection_matrix(), + ..Default::default() + }, + transform: Transform::from_matrix(Mat4::from_cols_array_2d( + &transform.matrix(), + )), + orthographic_projection: projection, + ..Default::default() + }) + } + gltf::camera::Projection::Perspective(perspective) => { + let mut projection: PerspectiveProjection = Default::default(); + projection.fov = perspective.yfov(); + projection.near = perspective.znear(); + if let Some(zfar) = perspective.zfar() { + projection.far = zfar; + } + if let Some(aspect_ratio) = perspective.aspect_ratio() { + projection.aspect_ratio = aspect_ratio; + } + world_builder.spawn(Camera3dComponents { + camera: Camera { + name: Some(base::camera::CAMERA3D.to_owned()), + projection_matrix: projection.get_projection_matrix(), + ..Default::default() + }, + transform: Transform::from_matrix(Mat4::from_cols_array_2d( + &transform.matrix(), + )), + perspective_projection: projection, + ..Default::default() + }) + } + } + } + // or create empty node + else { + world_builder.spawn(( Transform::from_matrix(Mat4::from_cols_array_2d(&transform.matrix())), GlobalTransform::default(), )) - .with_children(|parent| { - if let Some(mesh) = node.mesh() { - for primitive in mesh.primitives() { - let primitive_label = primitive_label(&mesh, &primitive); - let mesh_asset_path = - AssetPath::new_ref(load_context.path(), Some(&primitive_label)); - let material = primitive.material(); - let material_label = material_label(&material); - let material_asset_path = - AssetPath::new_ref(load_context.path(), Some(&material_label)); - parent.spawn(PbrComponents { - mesh: load_context.get_handle(mesh_asset_path), - material: load_context.get_handle(material_asset_path), - ..Default::default() - }); - } + }; + + world_builder.with_children(|parent| { + if let Some(mesh) = node.mesh() { + // append primitives + for primitive in mesh.primitives() { + let primitive_label = primitive_label(&mesh, &primitive); + let mesh_asset_path = + AssetPath::new_ref(load_context.path(), Some(&primitive_label)); + let material = primitive.material(); + let material_label = material_label(&material); + let material_asset_path = + AssetPath::new_ref(load_context.path(), Some(&material_label)); + parent.spawn(PbrComponents { + mesh: load_context.get_handle(mesh_asset_path), + material: load_context.get_handle(material_asset_path), + ..Default::default() + }); } + } - if parent.current_entity().is_none() { + // append other nodes + for child in node.children() { + if let Err(err) = load_node(&child, parent, load_context, buffer_data) { + gltf_error = Some(err); return; } - - parent.with_children(|parent| { - for child in node.children() { - if let Err(err) = load_node(&child, parent, load_context, buffer_data) { - gltf_error = Some(err); - return; - } - } - }); - }); + } + }); if let Some(err) = gltf_error { Err(err) } else { From 010d8809f2fecb312c5b7b80a9ef4b741e5be791 Mon Sep 17 00:00:00 2001 From: furiouzz Date: Thu, 5 Nov 2020 09:45:13 +0100 Subject: [PATCH 2/4] [gltf] Share transform_matrix --- crates/bevy_gltf/src/loader.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index 14401286e1ad4..d0763db6c6140 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -213,6 +213,7 @@ fn load_node( buffer_data: &[Vec], ) -> Result<(), GltfError> { let transform = node.transform(); + let transform_matrix = Transform::from_matrix(Mat4::from_cols_array_2d(&transform.matrix())); let mut gltf_error = None; // create camera node @@ -235,9 +236,7 @@ fn load_node( projection_matrix: projection.get_projection_matrix(), ..Default::default() }, - transform: Transform::from_matrix(Mat4::from_cols_array_2d( - &transform.matrix(), - )), + transform: transform_matrix, orthographic_projection: projection, ..Default::default() }) @@ -258,9 +257,7 @@ fn load_node( projection_matrix: projection.get_projection_matrix(), ..Default::default() }, - transform: Transform::from_matrix(Mat4::from_cols_array_2d( - &transform.matrix(), - )), + transform: transform_matrix, perspective_projection: projection, ..Default::default() }) @@ -270,7 +267,7 @@ fn load_node( // or create empty node else { world_builder.spawn(( - Transform::from_matrix(Mat4::from_cols_array_2d(&transform.matrix())), + transform_matrix, GlobalTransform::default(), )) }; From 4ad8b44dee70a1f8c4675032e0d5ad455500ab2e Mon Sep 17 00:00:00 2001 From: furiouzz Date: Thu, 5 Nov 2020 09:48:39 +0100 Subject: [PATCH 3/4] [gltf] fmt --- crates/bevy_gltf/src/loader.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index d0763db6c6140..132ebf2c7b6df 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -266,10 +266,7 @@ fn load_node( } // or create empty node else { - world_builder.spawn(( - transform_matrix, - GlobalTransform::default(), - )) + world_builder.spawn((transform_matrix, GlobalTransform::default())) }; world_builder.with_children(|parent| { From d6216a3156dea5c79bac0a7265a928aa867f69ea Mon Sep 17 00:00:00 2001 From: furiouzz Date: Fri, 6 Nov 2020 22:44:10 +0100 Subject: [PATCH 4/4] [gltf] prefer .with method for component addition --- crates/bevy_gltf/src/loader.rs | 84 ++++++++++++++++------------------ 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index 132ebf2c7b6df..419a3b10519a2 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -4,8 +4,9 @@ use bevy_ecs::{bevy_utils::BoxedFuture, World, WorldBuilderSource}; use bevy_math::Mat4; use bevy_pbr::prelude::{PbrComponents, StandardMaterial}; use bevy_render::{ - camera::{Camera, CameraProjection, OrthographicProjection, PerspectiveProjection}, - entity::{Camera2dComponents, Camera3dComponents}, + camera::{ + Camera, CameraProjection, OrthographicProjection, PerspectiveProjection, VisibleEntities, + }, mesh::{Indices, Mesh, VertexAttributeValues}, pipeline::PrimitiveTopology, prelude::{Color, Texture}, @@ -207,70 +208,65 @@ async fn load_gltf<'a, 'b>( } fn load_node( - node: &gltf::Node, + gltf_node: &gltf::Node, world_builder: &mut WorldChildBuilder, load_context: &mut LoadContext, buffer_data: &[Vec], ) -> Result<(), GltfError> { - let transform = node.transform(); - let transform_matrix = Transform::from_matrix(Mat4::from_cols_array_2d(&transform.matrix())); + let transform = gltf_node.transform(); let mut gltf_error = None; + let node = world_builder.spawn(( + Transform::from_matrix(Mat4::from_cols_array_2d(&transform.matrix())), + GlobalTransform::default(), + )); // create camera node - let world_builder = if let Some(camera) = node.camera() { + if let Some(camera) = gltf_node.camera() { + node.with(VisibleEntities { + ..Default::default() + }); + match camera.projection() { gltf::camera::Projection::Orthographic(orthographic) => { let xmag = orthographic.xmag(); let ymag = orthographic.ymag(); - let mut projection: OrthographicProjection = Default::default(); - projection.left = -xmag; - projection.right = xmag; - projection.top = ymag; - projection.bottom = -ymag; - projection.far = orthographic.zfar(); - projection.near = orthographic.znear(); - projection.get_projection_matrix(); - world_builder.spawn(Camera2dComponents { - camera: Camera { - name: Some(base::camera::CAMERA2D.to_owned()), - projection_matrix: projection.get_projection_matrix(), - ..Default::default() - }, - transform: transform_matrix, - orthographic_projection: projection, + let mut orthographic_projection: OrthographicProjection = Default::default(); + orthographic_projection.left = -xmag; + orthographic_projection.right = xmag; + orthographic_projection.top = ymag; + orthographic_projection.bottom = -ymag; + orthographic_projection.far = orthographic.zfar(); + orthographic_projection.near = orthographic.znear(); + orthographic_projection.get_projection_matrix(); + node.with(Camera { + name: Some(base::camera::CAMERA2D.to_owned()), + projection_matrix: orthographic_projection.get_projection_matrix(), ..Default::default() - }) + }); + node.with(orthographic_projection); } gltf::camera::Projection::Perspective(perspective) => { - let mut projection: PerspectiveProjection = Default::default(); - projection.fov = perspective.yfov(); - projection.near = perspective.znear(); + let mut perspective_projection: PerspectiveProjection = Default::default(); + perspective_projection.fov = perspective.yfov(); + perspective_projection.near = perspective.znear(); if let Some(zfar) = perspective.zfar() { - projection.far = zfar; + perspective_projection.far = zfar; } if let Some(aspect_ratio) = perspective.aspect_ratio() { - projection.aspect_ratio = aspect_ratio; + perspective_projection.aspect_ratio = aspect_ratio; } - world_builder.spawn(Camera3dComponents { - camera: Camera { - name: Some(base::camera::CAMERA3D.to_owned()), - projection_matrix: projection.get_projection_matrix(), - ..Default::default() - }, - transform: transform_matrix, - perspective_projection: projection, + node.with(Camera { + name: Some(base::camera::CAMERA3D.to_owned()), + projection_matrix: perspective_projection.get_projection_matrix(), ..Default::default() - }) + }); + node.with(perspective_projection); } } } - // or create empty node - else { - world_builder.spawn((transform_matrix, GlobalTransform::default())) - }; - world_builder.with_children(|parent| { - if let Some(mesh) = node.mesh() { + node.with_children(|parent| { + if let Some(mesh) = gltf_node.mesh() { // append primitives for primitive in mesh.primitives() { let primitive_label = primitive_label(&mesh, &primitive); @@ -289,7 +285,7 @@ fn load_node( } // append other nodes - for child in node.children() { + for child in gltf_node.children() { if let Err(err) = load_node(&child, parent, load_context, buffer_data) { gltf_error = Some(err); return;