[gltf] Support camera and fix hierarchy (#772)
[gltf] Support camera and fix hierarchy
This commit is contained in:
parent
1c38106f75
commit
35d4fca0d0
@ -4,9 +4,13 @@ use bevy_ecs::{bevy_utils::BoxedFuture, World, WorldBuilderSource};
|
|||||||
use bevy_math::Mat4;
|
use bevy_math::Mat4;
|
||||||
use bevy_pbr::prelude::{PbrComponents, StandardMaterial};
|
use bevy_pbr::prelude::{PbrComponents, StandardMaterial};
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
|
camera::{
|
||||||
|
Camera, CameraProjection, OrthographicProjection, PerspectiveProjection, VisibleEntities,
|
||||||
|
},
|
||||||
mesh::{Indices, Mesh, VertexAttributeValues},
|
mesh::{Indices, Mesh, VertexAttributeValues},
|
||||||
pipeline::PrimitiveTopology,
|
pipeline::PrimitiveTopology,
|
||||||
prelude::{Color, Texture},
|
prelude::{Color, Texture},
|
||||||
|
render_graph::base,
|
||||||
texture::{AddressMode, FilterMode, SamplerDescriptor, TextureFormat},
|
texture::{AddressMode, FilterMode, SamplerDescriptor, TextureFormat},
|
||||||
};
|
};
|
||||||
use bevy_scene::Scene;
|
use bevy_scene::Scene;
|
||||||
@ -204,49 +208,90 @@ async fn load_gltf<'a, 'b>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn load_node(
|
fn load_node(
|
||||||
node: &gltf::Node,
|
gltf_node: &gltf::Node,
|
||||||
world_builder: &mut WorldChildBuilder,
|
world_builder: &mut WorldChildBuilder,
|
||||||
load_context: &mut LoadContext,
|
load_context: &mut LoadContext,
|
||||||
buffer_data: &[Vec<u8>],
|
buffer_data: &[Vec<u8>],
|
||||||
) -> Result<(), GltfError> {
|
) -> Result<(), GltfError> {
|
||||||
let transform = node.transform();
|
let transform = gltf_node.transform();
|
||||||
let mut gltf_error = None;
|
let mut gltf_error = None;
|
||||||
world_builder
|
let node = world_builder.spawn((
|
||||||
.spawn((
|
Transform::from_matrix(Mat4::from_cols_array_2d(&transform.matrix())),
|
||||||
Transform::from_matrix(Mat4::from_cols_array_2d(&transform.matrix())),
|
GlobalTransform::default(),
|
||||||
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()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if parent.current_entity().is_none() {
|
// create camera node
|
||||||
|
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 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 perspective_projection: PerspectiveProjection = Default::default();
|
||||||
|
perspective_projection.fov = perspective.yfov();
|
||||||
|
perspective_projection.near = perspective.znear();
|
||||||
|
if let Some(zfar) = perspective.zfar() {
|
||||||
|
perspective_projection.far = zfar;
|
||||||
|
}
|
||||||
|
if let Some(aspect_ratio) = perspective.aspect_ratio() {
|
||||||
|
perspective_projection.aspect_ratio = aspect_ratio;
|
||||||
|
}
|
||||||
|
node.with(Camera {
|
||||||
|
name: Some(base::camera::CAMERA3D.to_owned()),
|
||||||
|
projection_matrix: perspective_projection.get_projection_matrix(),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
node.with(perspective_projection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
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()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// append other nodes
|
||||||
|
for child in gltf_node.children() {
|
||||||
|
if let Err(err) = load_node(&child, parent, load_context, buffer_data) {
|
||||||
|
gltf_error = Some(err);
|
||||||
return;
|
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 {
|
if let Some(err) = gltf_error {
|
||||||
Err(err)
|
Err(err)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user