(data: &[u8])
| 1653 | } |
| 1654 | |
| 1655 | fn load_gltf(data: &[u8]) -> Option<ModelData> { |
| 1656 | let gltf = gltf::Gltf::from_slice(data).ok()?; |
| 1657 | |
| 1658 | // Get buffer data (for .glb, embedded; for .gltf, inline base64) |
| 1659 | let mut buffer_data: Vec<Vec<u8>> = Vec::new(); |
| 1660 | for buffer in gltf.buffers() { |
| 1661 | match buffer.source() { |
| 1662 | gltf::buffer::Source::Bin => { |
| 1663 | if let Some(blob) = gltf.blob.as_ref() { |
| 1664 | buffer_data.push(blob.clone()); |
| 1665 | } |
| 1666 | } |
| 1667 | gltf::buffer::Source::Uri(uri) => { |
| 1668 | if let Some(encoded) = uri.strip_prefix("data:application/octet-stream;base64,") { |
| 1669 | // Try to decode base64 inline data |
| 1670 | let mut decoded = Vec::new(); |
| 1671 | let _ = base64_decode(encoded, &mut decoded); |
| 1672 | buffer_data.push(decoded); |
| 1673 | } else { |
| 1674 | buffer_data.push(Vec::new()); |
| 1675 | } |
| 1676 | } |
| 1677 | } |
| 1678 | } |
| 1679 | |
| 1680 | let mut meshes = Vec::new(); |
| 1681 | let mut bbox_min = [f32::MAX; 3]; |
| 1682 | let mut bbox_max = [f32::MIN; 3]; |
| 1683 | |
| 1684 | for mesh in gltf.meshes() { |
| 1685 | for primitive in mesh.primitives() { |
| 1686 | let reader = primitive.reader(|buf| buffer_data.get(buf.index()).map(|d| d.as_slice())); |
| 1687 | |
| 1688 | let positions: Vec<[f32; 3]> = match reader.read_positions() { |
| 1689 | Some(iter) => iter.collect(), |
| 1690 | None => continue, |
| 1691 | }; |
| 1692 | |
| 1693 | let normals: Vec<[f32; 3]> = reader.read_normals() |
| 1694 | .map(|iter| iter.collect()) |
| 1695 | .unwrap_or_else(|| vec![[0.0, 1.0, 0.0]; positions.len()]); |
| 1696 | |
| 1697 | let tex_coords: Vec<[f32; 2]> = reader.read_tex_coords(0) |
| 1698 | .map(|iter| iter.into_f32().collect()) |
| 1699 | .unwrap_or_else(|| vec![[0.0, 0.0]; positions.len()]); |
| 1700 | |
| 1701 | // Material base color |
| 1702 | let base_color = primitive.material().pbr_metallic_roughness() |
| 1703 | .base_color_factor(); |
| 1704 | let color = [base_color[0], base_color[1], base_color[2], base_color[3]]; |
| 1705 | |
| 1706 | let mut vertices = Vec::with_capacity(positions.len()); |
| 1707 | for i in 0..positions.len() { |
| 1708 | let p = positions[i]; |
| 1709 | for k in 0..3 { |
| 1710 | if p[k] < bbox_min[k] { bbox_min[k] = p[k]; } |
| 1711 | if p[k] > bbox_max[k] { bbox_max[k] = p[k]; } |
| 1712 | } |
no test coverage detected