Allow setting RenderAssetUsages for gLTF meshes & materials during load (#12302)
# Objective - Closes #11954 ## Solution Change the load_meshes field in `GltfLoaderSettings` from a bool to `RenderAssetUsages` flag, and add a new load_materials flag. Use these to determine where the gLTF mesh and material assets are retained in memory (if the provided flags are empty, then the assets are skipped during load). --- ## Migration Guide When loading gLTF assets with `asset_server.load_with_settings`, use `RenderAssetUsages` instead of `bool` when setting load_meshes e.g. ```rust let _ = asset_server.load_with_settings("...", |s: &mut GltfLoaderSettings| { s.load_meshes = RenderAssetUsages::RENDER_WORLD; }); ``` Use the new load_materials field for controlling material load & retention behaviour instead of load_meshes. gLTF .meta files need similar updates e.g ``` load_meshes: true, ``` to ``` load_meshes: ("MAIN_WORLD | RENDER_WORLD"), ``` --------- Co-authored-by: 66OJ66 <hi0obxud@anonaddy.me>
This commit is contained in:
parent
686d354d28
commit
c7298599ee
@ -130,8 +130,14 @@ pub struct GltfLoader {
|
||||
/// ```
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct GltfLoaderSettings {
|
||||
/// If true, the loader will load mesh nodes and the associated materials.
|
||||
pub load_meshes: bool,
|
||||
/// If empty, the gltf mesh nodes will be skipped.
|
||||
///
|
||||
/// Otherwise, nodes will be loaded and retained in RAM/VRAM according to the active flags.
|
||||
pub load_meshes: RenderAssetUsages,
|
||||
/// If empty, the gltf materials will be skipped.
|
||||
///
|
||||
/// Otherwise, materials will be loaded and retained in RAM/VRAM according to the active flags.
|
||||
pub load_materials: RenderAssetUsages,
|
||||
/// If true, the loader will spawn cameras for gltf camera nodes.
|
||||
pub load_cameras: bool,
|
||||
/// If true, the loader will spawn lights for gltf light nodes.
|
||||
@ -143,7 +149,8 @@ pub struct GltfLoaderSettings {
|
||||
impl Default for GltfLoaderSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
load_meshes: true,
|
||||
load_meshes: RenderAssetUsages::default(),
|
||||
load_materials: RenderAssetUsages::default(),
|
||||
load_cameras: true,
|
||||
load_lights: true,
|
||||
include_source: false,
|
||||
@ -340,6 +347,7 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||
&linear_textures,
|
||||
parent_path,
|
||||
loader.supported_compressed_formats,
|
||||
settings.load_materials,
|
||||
)
|
||||
.await?;
|
||||
process_loaded_texture(load_context, &mut _texture_handles, image);
|
||||
@ -359,6 +367,7 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||
linear_textures,
|
||||
parent_path,
|
||||
loader.supported_compressed_formats,
|
||||
settings.load_materials,
|
||||
)
|
||||
.await
|
||||
});
|
||||
@ -377,13 +386,16 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||
|
||||
let mut materials = vec![];
|
||||
let mut named_materials = HashMap::default();
|
||||
// NOTE: materials must be loaded after textures because image load() calls will happen before load_with_settings, preventing is_srgb from being set properly
|
||||
for material in gltf.materials() {
|
||||
let handle = load_material(&material, load_context, false);
|
||||
if let Some(name) = material.name() {
|
||||
named_materials.insert(name.into(), handle.clone());
|
||||
// Only include materials in the output if they're set to be retained in the MAIN_WORLD and/or RENDER_WORLD by the load_materials flag
|
||||
if !settings.load_materials.is_empty() {
|
||||
// NOTE: materials must be loaded after textures because image load() calls will happen before load_with_settings, preventing is_srgb from being set properly
|
||||
for material in gltf.materials() {
|
||||
let handle = load_material(&material, load_context, false);
|
||||
if let Some(name) = material.name() {
|
||||
named_materials.insert(name.into(), handle.clone());
|
||||
}
|
||||
materials.push(handle);
|
||||
}
|
||||
materials.push(handle);
|
||||
}
|
||||
let mut meshes = vec![];
|
||||
let mut named_meshes = HashMap::default();
|
||||
@ -404,7 +416,7 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||
let primitive_label = primitive_label(&gltf_mesh, &primitive);
|
||||
let primitive_topology = get_primitive_topology(primitive.mode())?;
|
||||
|
||||
let mut mesh = Mesh::new(primitive_topology, RenderAssetUsages::default());
|
||||
let mut mesh = Mesh::new(primitive_topology, settings.load_meshes);
|
||||
|
||||
// Read vertex attributes
|
||||
for (semantic, accessor) in primitive.attributes() {
|
||||
@ -744,6 +756,7 @@ async fn load_image<'a, 'b>(
|
||||
linear_textures: &HashSet<usize>,
|
||||
parent_path: &'b Path,
|
||||
supported_compressed_formats: CompressedImageFormats,
|
||||
render_asset_usages: RenderAssetUsages,
|
||||
) -> Result<ImageOrPath, GltfError> {
|
||||
let is_srgb = !linear_textures.contains(&gltf_texture.index());
|
||||
let sampler_descriptor = texture_sampler(&gltf_texture);
|
||||
@ -764,7 +777,7 @@ async fn load_image<'a, 'b>(
|
||||
supported_compressed_formats,
|
||||
is_srgb,
|
||||
ImageSampler::Descriptor(sampler_descriptor),
|
||||
RenderAssetUsages::default(),
|
||||
render_asset_usages,
|
||||
)?;
|
||||
Ok(ImageOrPath::Image {
|
||||
image,
|
||||
@ -788,7 +801,7 @@ async fn load_image<'a, 'b>(
|
||||
supported_compressed_formats,
|
||||
is_srgb,
|
||||
ImageSampler::Descriptor(sampler_descriptor),
|
||||
RenderAssetUsages::default(),
|
||||
render_asset_usages,
|
||||
)?,
|
||||
label: texture_label(&gltf_texture),
|
||||
})
|
||||
@ -1100,7 +1113,8 @@ fn load_node(
|
||||
let mut morph_weights = None;
|
||||
|
||||
node.with_children(|parent| {
|
||||
if settings.load_meshes {
|
||||
// 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 let Some(mesh) = gltf_node.mesh() {
|
||||
// append primitives
|
||||
for primitive in mesh.primitives() {
|
||||
@ -1264,7 +1278,8 @@ fn load_node(
|
||||
}
|
||||
});
|
||||
|
||||
if settings.load_meshes {
|
||||
// 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 let (Some(mesh), Some(weights)) = (gltf_node.mesh(), morph_weights) {
|
||||
let primitive_label = mesh.primitives().next().map(|p| primitive_label(&mesh, &p));
|
||||
let first_mesh = primitive_label.map(|label| load_context.get_label_handle(label));
|
||||
|
Loading…
Reference in New Issue
Block a user