scene viewer: can select a scene from the asset path (#6859)
# Objective - Fixes #6630, fixes #6679 - Improve scene viewer in cases where there are more than one scene in a gltf file ## Solution - Can select which scene to display using `#SceneN`, defaults to scene 0 if not present - Display the number of scenes available if there are more than one
This commit is contained in:
parent
ea8f74692f
commit
f4818bcd69
@ -1,8 +1,9 @@
|
|||||||
//! A simple glTF scene viewer made with Bevy.
|
//! A simple glTF scene viewer made with Bevy.
|
||||||
//!
|
//!
|
||||||
//! Just run `cargo run --release --example scene_viewer /path/to/model.gltf#Scene0`,
|
//! Just run `cargo run --release --example scene_viewer /path/to/model.gltf`,
|
||||||
//! replacing the path as appropriate.
|
//! replacing the path as appropriate.
|
||||||
//! With no arguments it will load the `FieldHelmet` glTF model from the repository assets subdirectory.
|
//! In case of multiple scenes, you can select which to display by adapting the file path: `/path/to/model.gltf#Scene1`.
|
||||||
|
//! With no arguments it will load the `FlightHelmet` glTF model from the repository assets subdirectory.
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{
|
||||||
asset::LoadState,
|
asset::LoadState,
|
||||||
@ -77,7 +78,8 @@ Controls:
|
|||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
struct SceneHandle {
|
struct SceneHandle {
|
||||||
handle: Handle<Gltf>,
|
gltf_handle: Handle<Gltf>,
|
||||||
|
scene_index: usize,
|
||||||
#[cfg(feature = "animation")]
|
#[cfg(feature = "animation")]
|
||||||
animations: Vec<Handle<AnimationClip>>,
|
animations: Vec<Handle<AnimationClip>>,
|
||||||
instance_id: Option<InstanceId>,
|
instance_id: Option<InstanceId>,
|
||||||
@ -85,13 +87,30 @@ struct SceneHandle {
|
|||||||
has_light: bool,
|
has_light: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_scene(scene_path: String) -> (String, usize) {
|
||||||
|
if scene_path.contains('#') {
|
||||||
|
let gltf_and_scene = scene_path.split('#').collect::<Vec<_>>();
|
||||||
|
if let Some((last, path)) = gltf_and_scene.split_last() {
|
||||||
|
if let Some(index) = last
|
||||||
|
.strip_prefix("Scene")
|
||||||
|
.and_then(|index| index.parse::<usize>().ok())
|
||||||
|
{
|
||||||
|
return (path.join("#"), index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(scene_path, 0)
|
||||||
|
}
|
||||||
|
|
||||||
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
let scene_path = std::env::args()
|
let scene_path = std::env::args()
|
||||||
.nth(1)
|
.nth(1)
|
||||||
.unwrap_or_else(|| "assets/models/FlightHelmet/FlightHelmet.gltf".to_string());
|
.unwrap_or_else(|| "assets/models/FlightHelmet/FlightHelmet.gltf".to_string());
|
||||||
info!("Loading {}", scene_path);
|
info!("Loading {}", scene_path);
|
||||||
|
let (file_path, scene_index) = parse_scene(scene_path);
|
||||||
commands.insert_resource(SceneHandle {
|
commands.insert_resource(SceneHandle {
|
||||||
handle: asset_server.load(&scene_path),
|
gltf_handle: asset_server.load(&file_path),
|
||||||
|
scene_index,
|
||||||
#[cfg(feature = "animation")]
|
#[cfg(feature = "animation")]
|
||||||
animations: Vec::new(),
|
animations: Vec::new(),
|
||||||
instance_id: None,
|
instance_id: None,
|
||||||
@ -109,9 +128,26 @@ fn scene_load_check(
|
|||||||
) {
|
) {
|
||||||
match scene_handle.instance_id {
|
match scene_handle.instance_id {
|
||||||
None => {
|
None => {
|
||||||
if asset_server.get_load_state(&scene_handle.handle) == LoadState::Loaded {
|
if asset_server.get_load_state(&scene_handle.gltf_handle) == LoadState::Loaded {
|
||||||
let gltf = gltf_assets.get(&scene_handle.handle).unwrap();
|
let gltf = gltf_assets.get(&scene_handle.gltf_handle).unwrap();
|
||||||
let gltf_scene_handle = gltf.scenes.first().expect("glTF file contains no scenes!");
|
if gltf.scenes.len() > 1 {
|
||||||
|
info!(
|
||||||
|
"Displaying scene {} out of {}",
|
||||||
|
scene_handle.scene_index,
|
||||||
|
gltf.scenes.len()
|
||||||
|
);
|
||||||
|
info!("You can select the scene by adding '#Scene' followed by a number to the end of the file path (e.g '#Scene1' to load the second scene).");
|
||||||
|
}
|
||||||
|
|
||||||
|
let gltf_scene_handle =
|
||||||
|
gltf.scenes
|
||||||
|
.get(scene_handle.scene_index)
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
panic!(
|
||||||
|
"glTF file doesn't contain scene {}!",
|
||||||
|
scene_handle.scene_index
|
||||||
|
)
|
||||||
|
});
|
||||||
let scene = scenes.get_mut(gltf_scene_handle).unwrap();
|
let scene = scenes.get_mut(gltf_scene_handle).unwrap();
|
||||||
|
|
||||||
let mut query = scene
|
let mut query = scene
|
||||||
|
Loading…
Reference in New Issue
Block a user