MCPcopy Create free account
hub / github.com/Bloom-Engine/engine / bloom_scene_attach_model

Function bloom_scene_attach_model

native/watchos/src/lib.rs:881–952  ·  view source on GitHub ↗
(node_handle: f64, model_handle: f64, mesh_idx: f64)

Source from the content-addressed store, hash-verified

879/// hierarchy — it picks which mesh to instantiate into `node_handle`.
880#[no_mangle]
881pub extern "C" fn bloom_scene_attach_model(node_handle: f64, model_handle: f64, mesh_idx: f64) {
882 let Some(model) = models::get(model_handle as u32) else { return; };
883 let root = node_handle as u32;
884
885 // If the model has a scene graph with non-trivial hierarchy (>1 node or a
886 // transform on the root), walk it. Otherwise fall back to single-mesh
887 // mode so mesh_idx still picks which mesh to attach.
888 let single_mesh = model.nodes.len() <= 1
889 && model.scene_roots.len() <= 1
890 && model.nodes.first().map(|n| n.matrix.is_none()
891 && n.translation == [0.0; 3]
892 && n.rotation == [0.0, 0.0, 0.0, 1.0]
893 && n.scale == [1.0; 3]).unwrap_or(true);
894
895 if single_mesh {
896 let mesh_i = mesh_idx as usize;
897 let Some(mesh) = model.meshes.get(mesh_i) else { return; };
898 attach_mesh(root, mesh);
899 return;
900 }
901
902 // Scene-hierarchy path: one bloom scene node per glTF node. The attach
903 // target `root` itself doesn't gain geometry — it's the hierarchy's
904 // anchor. Children materialize via scene::create + scene::set_parent.
905 // We build a gltf_node_idx → bloom_handle map during the walk, then
906 // resolve skin joint references once everyone's in place.
907 let mut gltf_to_bloom: std::collections::HashMap<usize, u32> = std::collections::HashMap::new();
908 let mut skinned_nodes: Vec<(u32, usize)> = Vec::new(); // (bloom_handle, gltf_node_idx)
909 for scene_root in &model.scene_roots {
910 spawn_node_subtree(&model, *scene_root, root, &mut gltf_to_bloom, &mut skinned_nodes);
911 }
912 // Second pass: attach skin data to each skinned mesh-node. Joints are
913 // resolved to the bloom handles we just created.
914 for (bloom_handle, gltf_idx) in skinned_nodes {
915 let gltf_node = &model.nodes[gltf_idx];
916 let Some(skin_idx) = gltf_node.skin else { continue };
917 let Some(skin) = model.skins.get(skin_idx) else { continue };
918 let Some(mesh_idx) = gltf_node.mesh else { continue };
919 let Some(mesh) = model.meshes.get(mesh_idx) else { continue };
920 let Some(prim) = mesh.primitives.first() else { continue };
921
922 let joint_handles: Vec<u32> = skin.joints.iter()
923 .map(|&gi| *gltf_to_bloom.get(&gi).unwrap_or(&0))
924 .collect();
925 scene::set_skin(bloom_handle,
926 joint_handles,
927 skin.inverse_bind_matrices.clone(),
928 prim.joint_indices.clone(),
929 prim.weights.clone(),
930 );
931
932 // Animation tracks — resolve channel targets to bloom handles.
933 // Auto-select animation 0 for now (typically the idle/survey clip).
934 // Follow-up: bloom_update_model_animation to switch between them.
935 if let Some(anim) = model.animations.first() {
936 let mut tracks: Vec<scene::AnimTrack> = Vec::new();
937 for ch in &anim.channels {
938 let Some(&bone_h) = gltf_to_bloom.get(&ch.target_node) else { continue };

Callers

nothing calls this directly

Calls 9

getFunction · 0.85
attach_meshFunction · 0.85
spawn_node_subtreeFunction · 0.85
set_skinFunction · 0.85
set_anim_tracksFunction · 0.85
iterMethod · 0.80
cloneMethod · 0.80
getMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected