mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 14:10:19 +00:00
glTF labels: add enum to avoid misspelling and keep up-to-date list documented (#13586)
# Objective - Followup to #13548 - It added a list of all possible labels to documentation. This seems hard to keep up and doesn't stop people from making spelling mistake ## Solution - Add an enum that can create all the labels possible, and encourage its use rather than manually typed labels --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Rob Parrett <robparrett@gmail.com>
This commit is contained in:
parent
ce46d52536
commit
5559632977
30 changed files with 293 additions and 117 deletions
|
@ -19,12 +19,14 @@
|
||||||
//! # use bevy_asset::prelude::*;
|
//! # use bevy_asset::prelude::*;
|
||||||
//! # use bevy_scene::prelude::*;
|
//! # use bevy_scene::prelude::*;
|
||||||
//! # use bevy_transform::prelude::*;
|
//! # use bevy_transform::prelude::*;
|
||||||
|
//! # use bevy_gltf::prelude::*;
|
||||||
//!
|
//!
|
||||||
//! fn spawn_gltf(mut commands: Commands, asset_server: Res<AssetServer>) {
|
//! fn spawn_gltf(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
//! commands.spawn(SceneBundle {
|
//! commands.spawn(SceneBundle {
|
||||||
|
//! // This is equivalent to "models/FlightHelmet/FlightHelmet.gltf#Scene0"
|
||||||
//! // The `#Scene0` label here is very important because it tells bevy to load the first scene in the glTF file.
|
//! // The `#Scene0` label here is very important because it tells bevy to load the first scene in the glTF file.
|
||||||
//! // If this isn't specified bevy doesn't know which part of the glTF file to load.
|
//! // If this isn't specified bevy doesn't know which part of the glTF file to load.
|
||||||
//! scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
|
//! scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||||
//! // You can use the transform to give it a position
|
//! // You can use the transform to give it a position
|
||||||
//! transform: Transform::from_xyz(2.0, 0.0, -5.0),
|
//! transform: Transform::from_xyz(2.0, 0.0, -5.0),
|
||||||
//! ..Default::default()
|
//! ..Default::default()
|
||||||
|
@ -91,18 +93,7 @@
|
||||||
//!
|
//!
|
||||||
//! Be careful when using this feature, if you misspell a label it will simply ignore it without warning.
|
//! Be careful when using this feature, if you misspell a label it will simply ignore it without warning.
|
||||||
//!
|
//!
|
||||||
//! Here's the list of supported labels (`{}` is the index in the file):
|
//! You can use [`GltfAssetLabel`] to ensure you are using the correct label.
|
||||||
//!
|
|
||||||
//! - `Scene{}`: glTF Scene as a Bevy `Scene`
|
|
||||||
//! - `Node{}`: glTF Node as a `GltfNode`
|
|
||||||
//! - `Mesh{}`: glTF Mesh as a `GltfMesh`
|
|
||||||
//! - `Mesh{}/Primitive{}`: glTF Primitive as a Bevy `Mesh`
|
|
||||||
//! - `Mesh{}/Primitive{}/MorphTargets`: Morph target animation data for a glTF Primitive
|
|
||||||
//! - `Texture{}`: glTF Texture as a Bevy `Image`
|
|
||||||
//! - `Material{}`: glTF Material as a Bevy `StandardMaterial`
|
|
||||||
//! - `DefaultMaterial`: as above, if the glTF file contains a default material with no index
|
|
||||||
//! - `Animation{}`: glTF Animation as Bevy `AnimationClip`
|
|
||||||
//! - `Skin{}`: glTF mesh skin as Bevy `SkinnedMeshInverseBindposes`
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_animation")]
|
#[cfg(feature = "bevy_animation")]
|
||||||
use bevy_animation::AnimationClip;
|
use bevy_animation::AnimationClip;
|
||||||
|
@ -113,7 +104,7 @@ mod vertex_attributes;
|
||||||
pub use loader::*;
|
pub use loader::*;
|
||||||
|
|
||||||
use bevy_app::prelude::*;
|
use bevy_app::prelude::*;
|
||||||
use bevy_asset::{Asset, AssetApp, Handle};
|
use bevy_asset::{Asset, AssetApp, AssetPath, Handle};
|
||||||
use bevy_ecs::{prelude::Component, reflect::ReflectComponent};
|
use bevy_ecs::{prelude::Component, reflect::ReflectComponent};
|
||||||
use bevy_pbr::StandardMaterial;
|
use bevy_pbr::StandardMaterial;
|
||||||
use bevy_reflect::{Reflect, TypePath};
|
use bevy_reflect::{Reflect, TypePath};
|
||||||
|
@ -124,6 +115,12 @@ use bevy_render::{
|
||||||
};
|
};
|
||||||
use bevy_scene::Scene;
|
use bevy_scene::Scene;
|
||||||
|
|
||||||
|
/// The `bevy_gltf` prelude.
|
||||||
|
pub mod prelude {
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub use crate::{Gltf, GltfAssetLabel, GltfExtras};
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds support for glTF file loading to the app.
|
/// Adds support for glTF file loading to the app.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct GltfPlugin {
|
pub struct GltfPlugin {
|
||||||
|
@ -251,3 +248,118 @@ pub struct GltfExtras {
|
||||||
/// Content of the extra data.
|
/// Content of the extra data.
|
||||||
pub value: String,
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Labels that can be used to load part of a glTF
|
||||||
|
///
|
||||||
|
/// You can use [`GltfAssetLabel::from_asset`] to add it to an asset path
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use bevy_ecs::prelude::*;
|
||||||
|
/// # use bevy_asset::prelude::*;
|
||||||
|
/// # use bevy_scene::prelude::*;
|
||||||
|
/// # use bevy_gltf::prelude::*;
|
||||||
|
///
|
||||||
|
/// fn load_gltf_scene(asset_server: Res<AssetServer>) {
|
||||||
|
/// let gltf_scene: Handle<Scene> = asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"));
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Or when formatting a string for the path
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use bevy_ecs::prelude::*;
|
||||||
|
/// # use bevy_asset::prelude::*;
|
||||||
|
/// # use bevy_scene::prelude::*;
|
||||||
|
/// # use bevy_gltf::prelude::*;
|
||||||
|
///
|
||||||
|
/// fn load_gltf_scene(asset_server: Res<AssetServer>) {
|
||||||
|
/// let gltf_scene: Handle<Scene> = asset_server.load(format!("models/FlightHelmet/FlightHelmet.gltf#{}", GltfAssetLabel::Scene(0)));
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum GltfAssetLabel {
|
||||||
|
/// `Scene{}`: glTF Scene as a Bevy `Scene`
|
||||||
|
Scene(usize),
|
||||||
|
/// `Node{}`: glTF Node as a `GltfNode`
|
||||||
|
Node(usize),
|
||||||
|
/// `Mesh{}`: glTF Mesh as a `GltfMesh`
|
||||||
|
Mesh(usize),
|
||||||
|
/// `Mesh{}/Primitive{}`: glTF Primitive as a Bevy `Mesh`
|
||||||
|
Primitive {
|
||||||
|
/// Index of the mesh for this primitive
|
||||||
|
mesh: usize,
|
||||||
|
/// Index of this primitive in its parent mesh
|
||||||
|
primitive: usize,
|
||||||
|
},
|
||||||
|
/// `Mesh{}/Primitive{}/MorphTargets`: Morph target animation data for a glTF Primitive
|
||||||
|
MorphTarget {
|
||||||
|
/// Index of the mesh for this primitive
|
||||||
|
mesh: usize,
|
||||||
|
/// Index of this primitive in its parent mesh
|
||||||
|
primitive: usize,
|
||||||
|
},
|
||||||
|
/// `Texture{}`: glTF Texture as a Bevy `Image`
|
||||||
|
Texture(usize),
|
||||||
|
/// `Material{}`: glTF Material as a Bevy `StandardMaterial`
|
||||||
|
Material {
|
||||||
|
/// Index of this material
|
||||||
|
index: usize,
|
||||||
|
/// Used to set the [`Face`](bevy_render::render_resource::Face) of the material, useful if it is used with negative scale
|
||||||
|
is_scale_inverted: bool,
|
||||||
|
},
|
||||||
|
/// `DefaultMaterial`: as above, if the glTF file contains a default material with no index
|
||||||
|
DefaultMaterial,
|
||||||
|
/// `Animation{}`: glTF Animation as Bevy `AnimationClip`
|
||||||
|
Animation(usize),
|
||||||
|
/// `Skin{}`: glTF mesh skin as Bevy `SkinnedMeshInverseBindposes`
|
||||||
|
Skin(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for GltfAssetLabel {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
GltfAssetLabel::Scene(index) => f.write_str(&format!("Scene{index}")),
|
||||||
|
GltfAssetLabel::Node(index) => f.write_str(&format!("Node{index}")),
|
||||||
|
GltfAssetLabel::Mesh(index) => f.write_str(&format!("Mesh{index}")),
|
||||||
|
GltfAssetLabel::Primitive { mesh, primitive } => {
|
||||||
|
f.write_str(&format!("Mesh{mesh}/Primitive{primitive}"))
|
||||||
|
}
|
||||||
|
GltfAssetLabel::MorphTarget { mesh, primitive } => {
|
||||||
|
f.write_str(&format!("Mesh{mesh}/Primitive{primitive}/MorphTargets"))
|
||||||
|
}
|
||||||
|
GltfAssetLabel::Texture(index) => f.write_str(&format!("Texture{index}")),
|
||||||
|
GltfAssetLabel::Material {
|
||||||
|
index,
|
||||||
|
is_scale_inverted,
|
||||||
|
} => f.write_str(&format!(
|
||||||
|
"Material{index}{}",
|
||||||
|
if *is_scale_inverted {
|
||||||
|
" (inverted)"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
)),
|
||||||
|
GltfAssetLabel::DefaultMaterial => f.write_str("DefaultMaterial"),
|
||||||
|
GltfAssetLabel::Animation(index) => f.write_str(&format!("Animation{index}")),
|
||||||
|
GltfAssetLabel::Skin(index) => f.write_str(&format!("Skin{index}")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GltfAssetLabel {
|
||||||
|
/// Add this label to an asset path
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use bevy_ecs::prelude::*;
|
||||||
|
/// # use bevy_asset::prelude::*;
|
||||||
|
/// # use bevy_scene::prelude::*;
|
||||||
|
/// # use bevy_gltf::prelude::*;
|
||||||
|
///
|
||||||
|
/// fn load_gltf_scene(asset_server: Res<AssetServer>) {
|
||||||
|
/// let gltf_scene: Handle<Scene> = asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"));
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn from_asset(&self, path: impl Into<AssetPath<'static>>) -> AssetPath<'static> {
|
||||||
|
path.into().with_label(self.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::GltfAssetLabel;
|
||||||
use crate::{vertex_attributes::convert_attribute, Gltf, GltfExtras, GltfNode};
|
use crate::{vertex_attributes::convert_attribute, Gltf, GltfExtras, GltfNode};
|
||||||
#[cfg(feature = "bevy_animation")]
|
#[cfg(feature = "bevy_animation")]
|
||||||
use bevy_animation::{AnimationTarget, AnimationTargetId};
|
use bevy_animation::{AnimationTarget, AnimationTargetId};
|
||||||
|
@ -316,8 +317,10 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let handle = load_context
|
let handle = load_context.add_labeled_asset(
|
||||||
.add_labeled_asset(format!("Animation{}", animation.index()), animation_clip);
|
GltfAssetLabel::Animation(animation.index()).to_string(),
|
||||||
|
animation_clip,
|
||||||
|
);
|
||||||
if let Some(name) = animation.name() {
|
if let Some(name) = animation.name() {
|
||||||
named_animations.insert(name.into(), handle.clone());
|
named_animations.insert(name.into(), handle.clone());
|
||||||
}
|
}
|
||||||
|
@ -337,7 +340,9 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||||
texture: ImageOrPath,
|
texture: ImageOrPath,
|
||||||
) {
|
) {
|
||||||
let handle = match texture {
|
let handle = match texture {
|
||||||
ImageOrPath::Image { label, image } => load_context.add_labeled_asset(label, image),
|
ImageOrPath::Image { label, image } => {
|
||||||
|
load_context.add_labeled_asset(label.to_string(), image)
|
||||||
|
}
|
||||||
ImageOrPath::Path {
|
ImageOrPath::Path {
|
||||||
path,
|
path,
|
||||||
is_srgb,
|
is_srgb,
|
||||||
|
@ -435,7 +440,10 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||||
for gltf_mesh in gltf.meshes() {
|
for gltf_mesh in gltf.meshes() {
|
||||||
let mut primitives = vec![];
|
let mut primitives = vec![];
|
||||||
for primitive in gltf_mesh.primitives() {
|
for primitive in gltf_mesh.primitives() {
|
||||||
let primitive_label = primitive_label(&gltf_mesh, &primitive);
|
let primitive_label = GltfAssetLabel::Primitive {
|
||||||
|
mesh: gltf_mesh.index(),
|
||||||
|
primitive: primitive.index(),
|
||||||
|
};
|
||||||
let primitive_topology = get_primitive_topology(primitive.mode())?;
|
let primitive_topology = get_primitive_topology(primitive.mode())?;
|
||||||
|
|
||||||
let mut mesh = Mesh::new(primitive_topology, settings.load_meshes);
|
let mut mesh = Mesh::new(primitive_topology, settings.load_meshes);
|
||||||
|
@ -478,14 +486,17 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||||
{
|
{
|
||||||
let morph_target_reader = reader.read_morph_targets();
|
let morph_target_reader = reader.read_morph_targets();
|
||||||
if morph_target_reader.len() != 0 {
|
if morph_target_reader.len() != 0 {
|
||||||
let morph_targets_label = morph_targets_label(&gltf_mesh, &primitive);
|
let morph_targets_label = GltfAssetLabel::MorphTarget {
|
||||||
|
mesh: gltf_mesh.index(),
|
||||||
|
primitive: primitive.index(),
|
||||||
|
};
|
||||||
let morph_target_image = MorphTargetImage::new(
|
let morph_target_image = MorphTargetImage::new(
|
||||||
morph_target_reader.map(PrimitiveMorphAttributesIter),
|
morph_target_reader.map(PrimitiveMorphAttributesIter),
|
||||||
mesh.count_vertices(),
|
mesh.count_vertices(),
|
||||||
RenderAssetUsages::default(),
|
RenderAssetUsages::default(),
|
||||||
)?;
|
)?;
|
||||||
let handle =
|
let handle = load_context
|
||||||
load_context.add_labeled_asset(morph_targets_label, morph_target_image.0);
|
.add_labeled_asset(morph_targets_label.to_string(), morph_target_image.0);
|
||||||
|
|
||||||
mesh.set_morph_targets(handle);
|
mesh.set_morph_targets(handle);
|
||||||
let extras = gltf_mesh.extras().as_ref();
|
let extras = gltf_mesh.extras().as_ref();
|
||||||
|
@ -540,7 +551,7 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let mesh = load_context.add_labeled_asset(primitive_label, mesh);
|
let mesh = load_context.add_labeled_asset(primitive_label.to_string(), mesh);
|
||||||
primitives.push(super::GltfPrimitive {
|
primitives.push(super::GltfPrimitive {
|
||||||
mesh,
|
mesh,
|
||||||
material: primitive
|
material: primitive
|
||||||
|
@ -553,7 +564,7 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let handle = load_context.add_labeled_asset(
|
let handle = load_context.add_labeled_asset(
|
||||||
mesh_label(&gltf_mesh),
|
GltfAssetLabel::Mesh(gltf_mesh.index()).to_string(),
|
||||||
super::GltfMesh {
|
super::GltfMesh {
|
||||||
primitives,
|
primitives,
|
||||||
extras: get_gltf_extras(gltf_mesh.extras()),
|
extras: get_gltf_extras(gltf_mesh.extras()),
|
||||||
|
@ -808,7 +819,7 @@ async fn load_image<'a, 'b>(
|
||||||
)?;
|
)?;
|
||||||
Ok(ImageOrPath::Image {
|
Ok(ImageOrPath::Image {
|
||||||
image,
|
image,
|
||||||
label: texture_label(&gltf_texture),
|
label: GltfAssetLabel::Texture(gltf_texture.index()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
gltf::image::Source::Uri { uri, mime_type } => {
|
gltf::image::Source::Uri { uri, mime_type } => {
|
||||||
|
@ -830,7 +841,7 @@ async fn load_image<'a, 'b>(
|
||||||
ImageSampler::Descriptor(sampler_descriptor),
|
ImageSampler::Descriptor(sampler_descriptor),
|
||||||
render_asset_usages,
|
render_asset_usages,
|
||||||
)?,
|
)?,
|
||||||
label: texture_label(&gltf_texture),
|
label: GltfAssetLabel::Texture(gltf_texture.index()),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let image_path = parent_path.join(uri);
|
let image_path = parent_path.join(uri);
|
||||||
|
@ -1247,12 +1258,15 @@ fn load_node(
|
||||||
load_material(&material, load_context, document, is_scale_inverted);
|
load_material(&material, load_context, document, is_scale_inverted);
|
||||||
}
|
}
|
||||||
|
|
||||||
let primitive_label = primitive_label(&mesh, &primitive);
|
let primitive_label = GltfAssetLabel::Primitive {
|
||||||
|
mesh: mesh.index(),
|
||||||
|
primitive: primitive.index(),
|
||||||
|
};
|
||||||
let bounds = primitive.bounding_box();
|
let bounds = primitive.bounding_box();
|
||||||
|
|
||||||
let mut mesh_entity = parent.spawn(PbrBundle {
|
let mut mesh_entity = parent.spawn(PbrBundle {
|
||||||
// TODO: handle missing label handle errors here?
|
// TODO: handle missing label handle errors here?
|
||||||
mesh: load_context.get_label_handle(&primitive_label),
|
mesh: load_context.get_label_handle(primitive_label.to_string()),
|
||||||
material: load_context.get_label_handle(&material_label),
|
material: load_context.get_label_handle(&material_label),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
@ -1400,8 +1414,12 @@ fn load_node(
|
||||||
// Only include meshes in the output if they're set to be retained in the MAIN_WORLD and/or RENDER_WORLD by the load_meshes flag
|
// Only include meshes in the output if they're set to be retained in the MAIN_WORLD and/or RENDER_WORLD by the load_meshes flag
|
||||||
if !settings.load_meshes.is_empty() {
|
if !settings.load_meshes.is_empty() {
|
||||||
if let (Some(mesh), Some(weights)) = (gltf_node.mesh(), morph_weights) {
|
if let (Some(mesh), Some(weights)) = (gltf_node.mesh(), morph_weights) {
|
||||||
let primitive_label = mesh.primitives().next().map(|p| primitive_label(&mesh, &p));
|
let primitive_label = mesh.primitives().next().map(|p| GltfAssetLabel::Primitive {
|
||||||
let first_mesh = primitive_label.map(|label| load_context.get_label_handle(label));
|
mesh: mesh.index(),
|
||||||
|
primitive: p.index(),
|
||||||
|
});
|
||||||
|
let first_mesh =
|
||||||
|
primitive_label.map(|label| load_context.get_label_handle(label.to_string()));
|
||||||
node.insert(MorphWeights::new(weights, first_mesh)?);
|
node.insert(MorphWeights::new(weights, first_mesh)?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1413,16 +1431,6 @@ fn load_node(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the label for the `mesh`.
|
|
||||||
fn mesh_label(mesh: &gltf::Mesh) -> String {
|
|
||||||
format!("Mesh{}", mesh.index())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the label for the `mesh` and `primitive`.
|
|
||||||
fn primitive_label(mesh: &gltf::Mesh, primitive: &Primitive) -> String {
|
|
||||||
format!("Mesh{}/Primitive{}", mesh.index(), primitive.index())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn primitive_name(mesh: &gltf::Mesh, primitive: &Primitive) -> String {
|
fn primitive_name(mesh: &gltf::Mesh, primitive: &Primitive) -> String {
|
||||||
let mesh_name = mesh.name().unwrap_or("Mesh");
|
let mesh_name = mesh.name().unwrap_or("Mesh");
|
||||||
if mesh.primitives().len() > 1 {
|
if mesh.primitives().len() > 1 {
|
||||||
|
@ -1432,37 +1440,23 @@ fn primitive_name(mesh: &gltf::Mesh, primitive: &Primitive) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the label for the morph target of `primitive`.
|
|
||||||
fn morph_targets_label(mesh: &gltf::Mesh, primitive: &Primitive) -> String {
|
|
||||||
format!(
|
|
||||||
"Mesh{}/Primitive{}/MorphTargets",
|
|
||||||
mesh.index(),
|
|
||||||
primitive.index()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the label for the `material`.
|
/// Returns the label for the `material`.
|
||||||
fn material_label(material: &Material, is_scale_inverted: bool) -> String {
|
fn material_label(material: &Material, is_scale_inverted: bool) -> String {
|
||||||
if let Some(index) = material.index() {
|
if let Some(index) = material.index() {
|
||||||
format!(
|
GltfAssetLabel::Material {
|
||||||
"Material{index}{}",
|
index,
|
||||||
if is_scale_inverted { " (inverted)" } else { "" }
|
is_scale_inverted,
|
||||||
)
|
}
|
||||||
|
.to_string()
|
||||||
} else {
|
} else {
|
||||||
"MaterialDefault".to_string()
|
GltfAssetLabel::DefaultMaterial.to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the label for the `texture`.
|
|
||||||
fn texture_label(texture: &gltf::Texture) -> String {
|
|
||||||
format!("Texture{}", texture.index())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn texture_handle(load_context: &mut LoadContext, texture: &gltf::Texture) -> Handle<Image> {
|
fn texture_handle(load_context: &mut LoadContext, texture: &gltf::Texture) -> Handle<Image> {
|
||||||
match texture.source().source() {
|
match texture.source().source() {
|
||||||
Source::View { .. } => {
|
Source::View { .. } => {
|
||||||
let label = texture_label(texture);
|
load_context.get_label_handle(GltfAssetLabel::Texture(texture.index()).to_string())
|
||||||
load_context.get_label_handle(&label)
|
|
||||||
}
|
}
|
||||||
Source::Uri { uri, .. } => {
|
Source::Uri { uri, .. } => {
|
||||||
let uri = percent_encoding::percent_decode_str(uri)
|
let uri = percent_encoding::percent_decode_str(uri)
|
||||||
|
@ -1470,8 +1464,7 @@ fn texture_handle(load_context: &mut LoadContext, texture: &gltf::Texture) -> Ha
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let uri = uri.as_ref();
|
let uri = uri.as_ref();
|
||||||
if let Ok(_data_uri) = DataUri::parse(uri) {
|
if let Ok(_data_uri) = DataUri::parse(uri) {
|
||||||
let label = texture_label(texture);
|
load_context.get_label_handle(GltfAssetLabel::Texture(texture.index()).to_string())
|
||||||
load_context.get_label_handle(&label)
|
|
||||||
} else {
|
} else {
|
||||||
let parent = load_context.path().parent().unwrap();
|
let parent = load_context.path().parent().unwrap();
|
||||||
let image_path = parent.join(uri);
|
let image_path = parent.join(uri);
|
||||||
|
@ -1501,16 +1494,16 @@ fn texture_handle_from_info(
|
||||||
|
|
||||||
/// Returns the label for the `node`.
|
/// Returns the label for the `node`.
|
||||||
fn node_label(node: &Node) -> String {
|
fn node_label(node: &Node) -> String {
|
||||||
format!("Node{}", node.index())
|
GltfAssetLabel::Node(node.index()).to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the label for the `scene`.
|
/// Returns the label for the `scene`.
|
||||||
fn scene_label(scene: &gltf::Scene) -> String {
|
fn scene_label(scene: &gltf::Scene) -> String {
|
||||||
format!("Scene{}", scene.index())
|
GltfAssetLabel::Scene(scene.index()).to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn skin_label(skin: &gltf::Skin) -> String {
|
fn skin_label(skin: &gltf::Skin) -> String {
|
||||||
format!("Skin{}", skin.index())
|
GltfAssetLabel::Skin(skin.index()).to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts the texture sampler data from the glTF texture.
|
/// Extracts the texture sampler data from the glTF texture.
|
||||||
|
@ -1687,7 +1680,7 @@ fn resolve_node_hierarchy(
|
||||||
enum ImageOrPath {
|
enum ImageOrPath {
|
||||||
Image {
|
Image {
|
||||||
image: Image,
|
image: Image,
|
||||||
label: String,
|
label: GltfAssetLabel,
|
||||||
},
|
},
|
||||||
Path {
|
Path {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
|
|
|
@ -66,3 +66,7 @@ pub use crate::gilrs::*;
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[cfg(feature = "bevy_state")]
|
#[cfg(feature = "bevy_state")]
|
||||||
pub use crate::state::prelude::*;
|
pub use crate::state::prelude::*;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[cfg(feature = "bevy_gltf")]
|
||||||
|
pub use crate::gltf::prelude::*;
|
||||||
|
|
|
@ -42,7 +42,13 @@ fn setup(
|
||||||
mut materials: ResMut<Assets<CustomMaterial>>,
|
mut materials: ResMut<Assets<CustomMaterial>>,
|
||||||
) {
|
) {
|
||||||
// Add a mesh loaded from a glTF file. This mesh has data for `ATTRIBUTE_BARYCENTRIC`.
|
// Add a mesh loaded from a glTF file. This mesh has data for `ATTRIBUTE_BARYCENTRIC`.
|
||||||
let mesh = asset_server.load("models/barycentric/barycentric.gltf#Mesh0/Primitive0");
|
let mesh = asset_server.load(
|
||||||
|
GltfAssetLabel::Primitive {
|
||||||
|
mesh: 0,
|
||||||
|
primitive: 0,
|
||||||
|
}
|
||||||
|
.from_asset("models/barycentric/barycentric.gltf"),
|
||||||
|
);
|
||||||
commands.spawn(MaterialMesh2dBundle {
|
commands.spawn(MaterialMesh2dBundle {
|
||||||
mesh: Mesh2dHandle(mesh),
|
mesh: Mesh2dHandle(mesh),
|
||||||
material: materials.add(CustomMaterial {}),
|
material: materials.add(CustomMaterial {}),
|
||||||
|
|
|
@ -282,7 +282,8 @@ fn setup(
|
||||||
|
|
||||||
// Flight Helmet
|
// Flight Helmet
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,8 @@ fn setup_terrain_scene(
|
||||||
|
|
||||||
// Terrain
|
// Terrain
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/terrain/Mountains.gltf#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/terrain/Mountains.gltf")),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,8 @@ fn spawn_coated_glass_bubble_sphere(
|
||||||
fn spawn_golf_ball(commands: &mut Commands, asset_server: &AssetServer) {
|
fn spawn_golf_ball(commands: &mut Commands, asset_server: &AssetServer) {
|
||||||
commands
|
commands
|
||||||
.spawn(SceneBundle {
|
.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/GolfBall/GolfBall.glb#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/GolfBall/GolfBall.glb")),
|
||||||
transform: Transform::from_xyz(1.0, 1.0, 0.0).with_scale(Vec3::splat(SPHERE_SCALE)),
|
transform: Transform::from_xyz(1.0, 1.0, 0.0).with_scale(Vec3::splat(SPHERE_SCALE)),
|
||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
|
|
|
@ -381,13 +381,16 @@ fn add_camera(commands: &mut Commands, asset_server: &AssetServer, color_grading
|
||||||
fn add_basic_scene(commands: &mut Commands, asset_server: &AssetServer) {
|
fn add_basic_scene(commands: &mut Commands, asset_server: &AssetServer) {
|
||||||
// Spawn the main scene.
|
// Spawn the main scene.
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/TonemappingTest/TonemappingTest.gltf#Scene0"),
|
scene: asset_server.load(
|
||||||
|
GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
|
||||||
|
),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
||||||
// Spawn the flight helmet.
|
// Spawn the flight helmet.
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||||
transform: Transform::from_xyz(0.5, 0.0, -0.5)
|
transform: Transform::from_xyz(0.5, 0.0, -0.5)
|
||||||
.with_rotation(Quat::from_rotation_y(-0.15 * PI)),
|
.with_rotation(Quat::from_rotation_y(-0.15 * PI)),
|
||||||
..default()
|
..default()
|
||||||
|
|
|
@ -80,7 +80,8 @@ fn setup(
|
||||||
});
|
});
|
||||||
|
|
||||||
// FlightHelmet
|
// FlightHelmet
|
||||||
let helmet_scene = asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0");
|
let helmet_scene = asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"));
|
||||||
|
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: helmet_scene.clone(),
|
scene: helmet_scene.clone(),
|
||||||
|
|
|
@ -88,7 +88,10 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, app_settings: R
|
||||||
|
|
||||||
// Spawn the scene.
|
// Spawn the scene.
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/DepthOfFieldExample/DepthOfFieldExample.glb#Scene0"),
|
scene: asset_server.load(
|
||||||
|
GltfAssetLabel::Scene(0)
|
||||||
|
.from_asset("models/DepthOfFieldExample/DepthOfFieldExample.glb"),
|
||||||
|
),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -503,16 +503,19 @@ fn handle_mouse_clicks(
|
||||||
|
|
||||||
impl FromWorld for ExampleAssets {
|
impl FromWorld for ExampleAssets {
|
||||||
fn from_world(world: &mut World) -> Self {
|
fn from_world(world: &mut World) -> Self {
|
||||||
let fox_animation = world.load_asset("models/animated/Fox.glb#Animation1");
|
let fox_animation =
|
||||||
|
world.load_asset(GltfAssetLabel::Animation(1).from_asset("models/animated/Fox.glb"));
|
||||||
let (fox_animation_graph, fox_animation_node) =
|
let (fox_animation_graph, fox_animation_node) =
|
||||||
AnimationGraph::from_clip(fox_animation.clone());
|
AnimationGraph::from_clip(fox_animation.clone());
|
||||||
|
|
||||||
ExampleAssets {
|
ExampleAssets {
|
||||||
main_sphere: world.add_asset(Sphere::default().mesh().uv(32, 18)),
|
main_sphere: world.add_asset(Sphere::default().mesh().uv(32, 18)),
|
||||||
fox: world.load_asset("models/animated/Fox.glb#Scene0"),
|
fox: world.load_asset(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||||
main_sphere_material: world.add_asset(Color::from(SILVER)),
|
main_sphere_material: world.add_asset(Color::from(SILVER)),
|
||||||
main_scene: world
|
main_scene: world.load_asset(
|
||||||
.load_asset("models/IrradianceVolumeExample/IrradianceVolumeExample.glb#Scene0"),
|
GltfAssetLabel::Scene(0)
|
||||||
|
.from_asset("models/IrradianceVolumeExample/IrradianceVolumeExample.glb"),
|
||||||
|
),
|
||||||
irradiance_volume: world.load_asset("irradiance_volumes/Example.vxgi.ktx2"),
|
irradiance_volume: world.load_asset("irradiance_volumes/Example.vxgi.ktx2"),
|
||||||
fox_animation_graph: world.add_asset(fox_animation_graph),
|
fox_animation_graph: world.add_asset(fox_animation_graph),
|
||||||
fox_animation_node,
|
fox_animation_node,
|
||||||
|
|
|
@ -14,7 +14,8 @@ fn main() {
|
||||||
|
|
||||||
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/CornellBox/CornellBox.glb#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/CornellBox/CornellBox.glb")),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,8 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ fn setup(
|
||||||
// Spawns the cubes, light, and camera.
|
// Spawns the cubes, light, and camera.
|
||||||
fn spawn_scene(commands: &mut Commands, asset_server: &AssetServer) {
|
fn spawn_scene(commands: &mut Commands, asset_server: &AssetServer) {
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/cubes/Cubes.glb#Scene0"),
|
scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/cubes/Cubes.glb")),
|
||||||
..SceneBundle::default()
|
..SceneBundle::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ fn setup(
|
||||||
});
|
});
|
||||||
|
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/animated/Fox.glb#Scene0"),
|
scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,8 @@ fn spawn_cube(
|
||||||
fn spawn_flight_helmet(commands: &mut Commands, asset_server: &AssetServer) {
|
fn spawn_flight_helmet(commands: &mut Commands, asset_server: &AssetServer) {
|
||||||
commands
|
commands
|
||||||
.spawn(SceneBundle {
|
.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||||
transform: Transform::from_scale(Vec3::splat(2.5)),
|
transform: Transform::from_scale(Vec3::splat(2.5)),
|
||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
|
|
|
@ -93,7 +93,9 @@ fn setup_basic_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
// Main scene
|
// Main scene
|
||||||
commands
|
commands
|
||||||
.spawn(SceneBundle {
|
.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/TonemappingTest/TonemappingTest.gltf#Scene0"),
|
scene: asset_server.load(
|
||||||
|
GltfAssetLabel::Scene(0).from_asset("models/TonemappingTest/TonemappingTest.gltf"),
|
||||||
|
),
|
||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
.insert(SceneNumber(1));
|
.insert(SceneNumber(1));
|
||||||
|
@ -101,7 +103,8 @@ fn setup_basic_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
// Flight Helmet
|
// Flight Helmet
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
SceneBundle {
|
SceneBundle {
|
||||||
scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||||
transform: Transform::from_xyz(0.5, 0.0, -0.5)
|
transform: Transform::from_xyz(0.5, 0.0, -0.5)
|
||||||
.with_rotation(Quat::from_rotation_y(-0.15 * PI)),
|
.with_rotation(Quat::from_rotation_y(-0.15 * PI)),
|
||||||
..default()
|
..default()
|
||||||
|
|
|
@ -40,14 +40,16 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
// Spawn the scene as a child of this entity at the given transform
|
// Spawn the scene as a child of this entity at the given transform
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
transform: Transform::from_xyz(-1.0, 0.0, 0.0),
|
transform: Transform::from_xyz(-1.0, 0.0, 0.0),
|
||||||
scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
||||||
// Spawn a second scene, and add a tag component to be able to target it later
|
// Spawn a second scene, and add a tag component to be able to target it later
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
SceneBundle {
|
SceneBundle {
|
||||||
scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
MovedScene,
|
MovedScene,
|
||||||
|
|
|
@ -104,14 +104,18 @@ fn setup(
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn(SceneBundle {
|
.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf")),
|
||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
.insert(MainModel::HighPoly);
|
.insert(MainModel::HighPoly);
|
||||||
|
|
||||||
commands
|
commands
|
||||||
.spawn(SceneBundle {
|
.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/FlightHelmetLowPoly/FlightHelmetLowPoly.gltf#Scene0"),
|
scene: asset_server.load(
|
||||||
|
GltfAssetLabel::Scene(0)
|
||||||
|
.from_asset("models/FlightHelmetLowPoly/FlightHelmetLowPoly.gltf"),
|
||||||
|
),
|
||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
.insert(MainModel::LowPoly);
|
.insert(MainModel::LowPoly);
|
||||||
|
|
|
@ -29,7 +29,10 @@ fn main() {
|
||||||
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
// Spawn the glTF scene.
|
// Spawn the glTF scene.
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/VolumetricFogExample/VolumetricFogExample.glb#Scene0"),
|
scene: asset_server.load(
|
||||||
|
GltfAssetLabel::Scene(0)
|
||||||
|
.from_asset("models/VolumetricFogExample/VolumetricFogExample.glb"),
|
||||||
|
),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,9 @@ fn setup(
|
||||||
let animations = graph
|
let animations = graph
|
||||||
.add_clips(
|
.add_clips(
|
||||||
[
|
[
|
||||||
"models/animated/Fox.glb#Animation2",
|
GltfAssetLabel::Animation(2).from_asset("models/animated/Fox.glb"),
|
||||||
"models/animated/Fox.glb#Animation1",
|
GltfAssetLabel::Animation(1).from_asset("models/animated/Fox.glb"),
|
||||||
"models/animated/Fox.glb#Animation0",
|
GltfAssetLabel::Animation(0).from_asset("models/animated/Fox.glb"),
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|path| asset_server.load(path)),
|
.map(|path| asset_server.load(path)),
|
||||||
|
@ -91,7 +91,7 @@ fn setup(
|
||||||
|
|
||||||
// Fox
|
// Fox
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/animated/Fox.glb#Scene0"),
|
scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -160,17 +160,17 @@ fn setup_assets_programmatically(
|
||||||
let mut animation_graph = AnimationGraph::new();
|
let mut animation_graph = AnimationGraph::new();
|
||||||
let blend_node = animation_graph.add_blend(0.5, animation_graph.root);
|
let blend_node = animation_graph.add_blend(0.5, animation_graph.root);
|
||||||
animation_graph.add_clip(
|
animation_graph.add_clip(
|
||||||
asset_server.load("models/animated/Fox.glb#Animation0"),
|
asset_server.load(GltfAssetLabel::Animation(0).from_asset("models/animated/Fox.glb")),
|
||||||
1.0,
|
1.0,
|
||||||
animation_graph.root,
|
animation_graph.root,
|
||||||
);
|
);
|
||||||
animation_graph.add_clip(
|
animation_graph.add_clip(
|
||||||
asset_server.load("models/animated/Fox.glb#Animation1"),
|
asset_server.load(GltfAssetLabel::Animation(1).from_asset("models/animated/Fox.glb")),
|
||||||
1.0,
|
1.0,
|
||||||
blend_node,
|
blend_node,
|
||||||
);
|
);
|
||||||
animation_graph.add_clip(
|
animation_graph.add_clip(
|
||||||
asset_server.load("models/animated/Fox.glb#Animation2"),
|
asset_server.load(GltfAssetLabel::Animation(2).from_asset("models/animated/Fox.glb")),
|
||||||
1.0,
|
1.0,
|
||||||
blend_node,
|
blend_node,
|
||||||
);
|
);
|
||||||
|
@ -236,7 +236,7 @@ fn setup_scene(
|
||||||
});
|
});
|
||||||
|
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/animated/Fox.glb#Scene0"),
|
scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||||
transform: Transform::from_scale(Vec3::splat(0.07)),
|
transform: Transform::from_scale(Vec3::splat(0.07)),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -27,7 +27,8 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
|
|
||||||
// Spawn the first scene in `models/SimpleSkin/SimpleSkin.gltf`
|
// Spawn the first scene in `models/SimpleSkin/SimpleSkin.gltf`
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/SimpleSkin/SimpleSkin.gltf#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/SimpleSkin/SimpleSkin.gltf")),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,11 +36,19 @@ struct MorphData {
|
||||||
|
|
||||||
fn setup(asset_server: Res<AssetServer>, mut commands: Commands) {
|
fn setup(asset_server: Res<AssetServer>, mut commands: Commands) {
|
||||||
commands.insert_resource(MorphData {
|
commands.insert_resource(MorphData {
|
||||||
the_wave: asset_server.load("models/animated/MorphStressTest.gltf#Animation2"),
|
the_wave: asset_server
|
||||||
mesh: asset_server.load("models/animated/MorphStressTest.gltf#Mesh0/Primitive0"),
|
.load(GltfAssetLabel::Animation(2).from_asset("models/animated/MorphStressTest.gltf")),
|
||||||
|
mesh: asset_server.load(
|
||||||
|
GltfAssetLabel::Primitive {
|
||||||
|
mesh: 0,
|
||||||
|
primitive: 0,
|
||||||
|
}
|
||||||
|
.from_asset("models/animated/MorphStressTest.gltf"),
|
||||||
|
),
|
||||||
});
|
});
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/animated/MorphStressTest.gltf#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/animated/MorphStressTest.gltf")),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
commands.spawn(DirectionalLightBundle {
|
commands.spawn(DirectionalLightBundle {
|
||||||
|
|
|
@ -16,15 +16,27 @@ fn setup(
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||||
) {
|
) {
|
||||||
// By default AssetServer will load assets from inside the "assets" folder.
|
// By default AssetServer will load assets from inside the "assets" folder.
|
||||||
// For example, the next line will load "ROOT/assets/models/cube/cube.gltf#Mesh0/Primitive0",
|
// For example, the next line will load GltfAssetLabel::Primitive{mesh:0,primitive:0}.from_asset("ROOT/assets/models/cube/cube.gltf"),
|
||||||
// where "ROOT" is the directory of the Application.
|
// where "ROOT" is the directory of the Application.
|
||||||
//
|
//
|
||||||
// This can be overridden by setting the "CARGO_MANIFEST_DIR" environment variable (see
|
// This can be overridden by setting the "CARGO_MANIFEST_DIR" environment variable (see
|
||||||
// https://doc.rust-lang.org/cargo/reference/environment-variables.html)
|
// https://doc.rust-lang.org/cargo/reference/environment-variables.html)
|
||||||
// to another directory. When the Application is run through Cargo, "CARGO_MANIFEST_DIR" is
|
// to another directory. When the Application is run through Cargo, "CARGO_MANIFEST_DIR" is
|
||||||
// automatically set to your crate (workspace) root directory.
|
// automatically set to your crate (workspace) root directory.
|
||||||
let cube_handle = asset_server.load("models/cube/cube.gltf#Mesh0/Primitive0");
|
let cube_handle = asset_server.load(
|
||||||
let sphere_handle = asset_server.load("models/sphere/sphere.gltf#Mesh0/Primitive0");
|
GltfAssetLabel::Primitive {
|
||||||
|
mesh: 0,
|
||||||
|
primitive: 0,
|
||||||
|
}
|
||||||
|
.from_asset("models/cube/cube.gltf"),
|
||||||
|
);
|
||||||
|
let sphere_handle = asset_server.load(
|
||||||
|
GltfAssetLabel::Primitive {
|
||||||
|
mesh: 0,
|
||||||
|
primitive: 0,
|
||||||
|
}
|
||||||
|
.from_asset("models/sphere/sphere.gltf"),
|
||||||
|
);
|
||||||
|
|
||||||
// All assets end up in their Assets<T> collection once they are done loading:
|
// All assets end up in their Assets<T> collection once they are done loading:
|
||||||
if let Some(sphere) = meshes.get(&sphere_handle) {
|
if let Some(sphere) = meshes.get(&sphere_handle) {
|
||||||
|
@ -49,7 +61,13 @@ fn setup(
|
||||||
// It will _not_ be loaded a second time.
|
// It will _not_ be loaded a second time.
|
||||||
// The LoadedFolder asset will ultimately also hold handles to the assets, but waiting for it to load
|
// The LoadedFolder asset will ultimately also hold handles to the assets, but waiting for it to load
|
||||||
// and finding the right handle is more work!
|
// and finding the right handle is more work!
|
||||||
let torus_handle = asset_server.load("models/torus/torus.gltf#Mesh0/Primitive0");
|
let torus_handle = asset_server.load(
|
||||||
|
GltfAssetLabel::Primitive {
|
||||||
|
mesh: 0,
|
||||||
|
primitive: 0,
|
||||||
|
}
|
||||||
|
.from_asset("models/torus/torus.gltf"),
|
||||||
|
);
|
||||||
|
|
||||||
// You can also add assets directly to their Assets<T> storage:
|
// You can also add assets directly to their Assets<T> storage:
|
||||||
let material_handle = materials.add(StandardMaterial {
|
let material_handle = materials.add(StandardMaterial {
|
||||||
|
|
|
@ -16,7 +16,8 @@ fn main() {
|
||||||
|
|
||||||
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
// Load our mesh:
|
// Load our mesh:
|
||||||
let scene_handle = asset_server.load("models/torus/torus.gltf#Scene0");
|
let scene_handle =
|
||||||
|
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/torus/torus.gltf"));
|
||||||
|
|
||||||
// Any changes to the mesh will be reloaded automatically! Try making a change to torus.gltf.
|
// Any changes to the mesh will be reloaded automatically! Try making a change to torus.gltf.
|
||||||
// You should see the changes immediately show up in your app.
|
// You should see the changes immediately show up in your app.
|
||||||
|
|
|
@ -133,7 +133,8 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut game: ResMu
|
||||||
});
|
});
|
||||||
|
|
||||||
// spawn the game board
|
// spawn the game board
|
||||||
let cell_scene = asset_server.load("models/AlienCake/tile.glb#Scene0");
|
let cell_scene =
|
||||||
|
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/AlienCake/tile.glb"));
|
||||||
game.board = (0..BOARD_SIZE_J)
|
game.board = (0..BOARD_SIZE_J)
|
||||||
.map(|j| {
|
.map(|j| {
|
||||||
(0..BOARD_SIZE_I)
|
(0..BOARD_SIZE_I)
|
||||||
|
@ -163,14 +164,16 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>, mut game: ResMu
|
||||||
rotation: Quat::from_rotation_y(-PI / 2.),
|
rotation: Quat::from_rotation_y(-PI / 2.),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
scene: asset_server.load("models/AlienCake/alien.glb#Scene0"),
|
scene: asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/AlienCake/alien.glb")),
|
||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
.id(),
|
.id(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// load the scene for the cake
|
// load the scene for the cake
|
||||||
game.bonus.handle = asset_server.load("models/AlienCake/cakeBirthday.glb#Scene0");
|
game.bonus.handle =
|
||||||
|
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/AlienCake/cakeBirthday.glb"));
|
||||||
|
|
||||||
// scoreboard
|
// scoreboard
|
||||||
commands.spawn(
|
commands.spawn(
|
||||||
|
|
|
@ -150,7 +150,7 @@ fn load_level_1(
|
||||||
));
|
));
|
||||||
|
|
||||||
// Save the asset into the `loading_assets` vector.
|
// Save the asset into the `loading_assets` vector.
|
||||||
let fox = asset_server.load("models/animated/Fox.glb#Scene0");
|
let fox = asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb"));
|
||||||
loading_data.loading_assets.push(fox.clone().into());
|
loading_data.loading_assets.push(fox.clone().into());
|
||||||
// Spawn the fox.
|
// Spawn the fox.
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
|
@ -192,7 +192,8 @@ fn load_level_2(
|
||||||
));
|
));
|
||||||
|
|
||||||
// Spawn the helmet.
|
// Spawn the helmet.
|
||||||
let helmet_scene = asset_server.load("models/FlightHelmet/FlightHelmet.gltf#Scene0");
|
let helmet_scene = asset_server
|
||||||
|
.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"));
|
||||||
loading_data
|
loading_data
|
||||||
.loading_assets
|
.loading_assets
|
||||||
.push(helmet_scene.clone().into());
|
.push(helmet_scene.clone().into());
|
||||||
|
|
|
@ -118,9 +118,9 @@ fn setup(
|
||||||
|
|
||||||
// Insert a resource with the current scene information
|
// Insert a resource with the current scene information
|
||||||
let animation_clips = [
|
let animation_clips = [
|
||||||
asset_server.load("models/animated/Fox.glb#Animation2"),
|
asset_server.load(GltfAssetLabel::Animation(2).from_asset("models/animated/Fox.glb")),
|
||||||
asset_server.load("models/animated/Fox.glb#Animation1"),
|
asset_server.load(GltfAssetLabel::Animation(1).from_asset("models/animated/Fox.glb")),
|
||||||
asset_server.load("models/animated/Fox.glb#Animation0"),
|
asset_server.load(GltfAssetLabel::Animation(0).from_asset("models/animated/Fox.glb")),
|
||||||
];
|
];
|
||||||
let mut animation_graph = AnimationGraph::new();
|
let mut animation_graph = AnimationGraph::new();
|
||||||
let node_indices = animation_graph
|
let node_indices = animation_graph
|
||||||
|
@ -136,7 +136,8 @@ fn setup(
|
||||||
// The foxes in each ring are spaced at least 2m apart around its circumference.'
|
// The foxes in each ring are spaced at least 2m apart around its circumference.'
|
||||||
|
|
||||||
// NOTE: This fox model faces +z
|
// NOTE: This fox model faces +z
|
||||||
let fox_handle = asset_server.load("models/animated/Fox.glb#Scene0");
|
let fox_handle =
|
||||||
|
asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb"));
|
||||||
|
|
||||||
let ring_directions = [
|
let ring_directions = [
|
||||||
(
|
(
|
||||||
|
|
|
@ -13,7 +13,7 @@ fn main() {
|
||||||
fn setup_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
|
fn setup_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
// add entities to the world
|
// add entities to the world
|
||||||
commands.spawn(SceneBundle {
|
commands.spawn(SceneBundle {
|
||||||
scene: asset_server.load("models/torus/torus.gltf#Scene0"),
|
scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/torus/torus.gltf")),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
// light
|
// light
|
||||||
|
|
Loading…
Reference in a new issue