Load each glTF skin at most once. (#18026)
Currently, we reload a glTF skin each time we encounter a node that references it. By checking for duplicates, PR #18013 turned this into a fatal error. But this was always wasteful. This commit fixes the issue by caching each skin by its index as we load it. The Maya babylon.js export plugin likes to emit glTFs with multiple nodes that reference the same skin, so this effectively unbreaks Maya rigs.
This commit is contained in:
parent
20813aed64
commit
df5e3a7b96
@ -801,7 +801,7 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||
|
||||
let mut nodes = HashMap::<usize, Handle<GltfNode>>::default();
|
||||
let mut named_nodes = <HashMap<_, _>>::default();
|
||||
let mut skins = vec![];
|
||||
let mut skins = <HashMap<_, _>>::default();
|
||||
let mut named_skins = <HashMap<_, _>>::default();
|
||||
|
||||
// First, create the node handles.
|
||||
@ -817,39 +817,43 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||
// Now populate the nodes.
|
||||
for node in gltf.nodes() {
|
||||
let skin = node.skin().map(|skin| {
|
||||
let joints: Vec<_> = skin
|
||||
.joints()
|
||||
.map(|joint| nodes.get(&joint.index()).unwrap().clone())
|
||||
.collect();
|
||||
skins
|
||||
.entry(skin.index())
|
||||
.or_insert_with(|| {
|
||||
let joints: Vec<_> = skin
|
||||
.joints()
|
||||
.map(|joint| nodes.get(&joint.index()).unwrap().clone())
|
||||
.collect();
|
||||
|
||||
if joints.len() > MAX_JOINTS {
|
||||
warn!(
|
||||
"The glTF skin {} has {} joints, but the maximum supported is {}",
|
||||
skin.name()
|
||||
.map(ToString::to_string)
|
||||
.unwrap_or_else(|| skin.index().to_string()),
|
||||
joints.len(),
|
||||
MAX_JOINTS
|
||||
);
|
||||
}
|
||||
if joints.len() > MAX_JOINTS {
|
||||
warn!(
|
||||
"The glTF skin {} has {} joints, but the maximum supported is {}",
|
||||
skin.name()
|
||||
.map(ToString::to_string)
|
||||
.unwrap_or_else(|| skin.index().to_string()),
|
||||
joints.len(),
|
||||
MAX_JOINTS
|
||||
);
|
||||
}
|
||||
|
||||
let gltf_skin = GltfSkin::new(
|
||||
&skin,
|
||||
joints,
|
||||
skinned_mesh_inverse_bindposes[skin.index()].clone(),
|
||||
get_gltf_extras(skin.extras()),
|
||||
);
|
||||
let gltf_skin = GltfSkin::new(
|
||||
&skin,
|
||||
joints,
|
||||
skinned_mesh_inverse_bindposes[skin.index()].clone(),
|
||||
get_gltf_extras(skin.extras()),
|
||||
);
|
||||
|
||||
let handle = load_context
|
||||
.add_labeled_asset(skin_label(&skin), gltf_skin)
|
||||
.expect("skin indices are unique, so the label is unique");
|
||||
let handle = load_context
|
||||
.add_labeled_asset(skin_label(&skin), gltf_skin)
|
||||
.expect("skin indices are unique, so the label is unique");
|
||||
|
||||
skins.push(handle.clone());
|
||||
if let Some(name) = skin.name() {
|
||||
named_skins.insert(name.into(), handle.clone());
|
||||
}
|
||||
if let Some(name) = skin.name() {
|
||||
named_skins.insert(name.into(), handle.clone());
|
||||
}
|
||||
|
||||
handle
|
||||
handle
|
||||
})
|
||||
.clone()
|
||||
});
|
||||
|
||||
let children = node
|
||||
@ -984,7 +988,7 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||
named_scenes,
|
||||
meshes,
|
||||
named_meshes,
|
||||
skins,
|
||||
skins: skins.into_values().collect(),
|
||||
named_skins,
|
||||
materials,
|
||||
named_materials,
|
||||
|
Loading…
Reference in New Issue
Block a user