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

Function load_gltf_with_textures

native/shared/src/models.rs:1020–1404  ·  view source on GitHub ↗
(
    data: &[u8],
    renderer: &mut crate::renderer::Renderer,
    base_dir: Option<&std::path::Path>,
)

Source from the content-addressed store, hash-verified

1018}
1019
1020fn load_gltf_with_textures(
1021 data: &[u8],
1022 renderer: &mut crate::renderer::Renderer,
1023 base_dir: Option<&std::path::Path>,
1024) -> Option<ModelData> {
1025 let gltf = gltf::Gltf::from_slice(data).ok()?;
1026
1027 // Get buffer data
1028 let mut buffer_data: Vec<Vec<u8>> = Vec::new();
1029 for buffer in gltf.buffers() {
1030 match buffer.source() {
1031 gltf::buffer::Source::Bin => {
1032 if let Some(blob) = gltf.blob.as_ref() { buffer_data.push(blob.clone()); }
1033 }
1034 gltf::buffer::Source::Uri(uri) => {
1035 if let Some(encoded) = uri.strip_prefix("data:application/octet-stream;base64,") {
1036 let mut decoded = Vec::new();
1037 let _ = base64_decode(encoded, &mut decoded);
1038 buffer_data.push(decoded);
1039 } else if let Some(dir) = base_dir {
1040 // External .bin file alongside the .gltf.
1041 let path = dir.join(uri);
1042 match std::fs::read(&path) {
1043 Ok(bytes) => buffer_data.push(bytes),
1044 Err(_) => buffer_data.push(Vec::new()),
1045 }
1046 } else {
1047 buffer_data.push(Vec::new());
1048 }
1049 }
1050 }
1051 }
1052
1053 // Pre-walk materials to identify which image indices are normal
1054 // maps. They need LEADR-style vector-space mip generation and per-
1055 // mip variance baked into alpha; see register_texture_kind.
1056 let mut normal_image_set: std::collections::HashSet<usize> = Default::default();
1057 for mat in gltf.materials() {
1058 if let Some(nt) = mat.normal_texture() {
1059 normal_image_set.insert(nt.texture().source().index());
1060 }
1061 }
1062
1063 // Extract and register textures
1064 let mut texture_indices: Vec<u32> = Vec::new(); // maps glTF image index -> renderer texture index
1065 for (image_idx, image) in gltf.images().enumerate() {
1066 let is_normal = normal_image_set.contains(&image_idx);
1067 match image.source() {
1068 gltf::image::Source::View { view, .. } => {
1069 let buf_idx = view.buffer().index();
1070 if buf_idx < buffer_data.len() {
1071 let offset = view.offset();
1072 let length = view.length();
1073 if offset + length <= buffer_data[buf_idx].len() {
1074 let img_data = &buffer_data[buf_idx][offset..offset + length];
1075 // Decode image (PNG/JPEG)
1076 if let Ok(img) = image::load_from_memory(img_data) {
1077 let rgba = img.to_rgba8();

Calls 15

base64_decodeFunction · 0.85
swap_extensionFunction · 0.85
decode_texture_bytesFunction · 0.85
specgloss_to_metalroughFunction · 0.85
apply_transmission_hackFunction · 0.85
mat3_transform_vecFunction · 0.85
buffersMethod · 0.80
cloneMethod · 0.80
bufferMethod · 0.80

Tested by

no test coverage detected