(
node: &gltf::Node,
parent_transform: Mat4,
buffers: &[gltf::buffer::Data],
materials: &[Material],
default_material_index: u32,
triangles: &mut Vec<Triangle>,
bbox_min: &
| 534 | } |
| 535 | |
| 536 | fn walk_node( |
| 537 | node: &gltf::Node, |
| 538 | parent_transform: Mat4, |
| 539 | buffers: &[gltf::buffer::Data], |
| 540 | materials: &[Material], |
| 541 | default_material_index: u32, |
| 542 | triangles: &mut Vec<Triangle>, |
| 543 | bbox_min: &mut Vec3, |
| 544 | bbox_max: &mut Vec3, |
| 545 | ) { |
| 546 | let local = Mat4::from_cols_array_2d(&node.transform().matrix()); |
| 547 | let world = parent_transform * local; |
| 548 | let world_normal = world.inverse().transpose(); |
| 549 | |
| 550 | if let Some(mesh) = node.mesh() { |
| 551 | for primitive in mesh.primitives() { |
| 552 | let reader = primitive.reader(|buffer| Some(&buffers[buffer.index()])); |
| 553 | |
| 554 | let positions: Vec<[f32; 3]> = match reader.read_positions() { |
| 555 | Some(iter) => iter.collect(), |
| 556 | None => continue, |
| 557 | }; |
| 558 | let normals: Vec<[f32; 3]> = reader |
| 559 | .read_normals() |
| 560 | .map(|iter| iter.collect()) |
| 561 | .unwrap_or_else(|| vec![[0.0, 1.0, 0.0]; positions.len()]); |
| 562 | let texcoords: Vec<[f32; 2]> = reader |
| 563 | .read_tex_coords(0) |
| 564 | .map(|iter| iter.into_f32().collect()) |
| 565 | .unwrap_or_else(|| vec![[0.0, 0.0]; positions.len()]); |
| 566 | // glTF tangents: Vec4 (xyz = tangent, w = ±1 bitangent sign). |
| 567 | // Required for normal mapping; we zero them out for meshes |
| 568 | // without tangents, and the shader falls back to geometric |
| 569 | // normals when the length is zero. |
| 570 | let tangents: Vec<[f32; 4]> = reader |
| 571 | .read_tangents() |
| 572 | .map(|iter| iter.collect()) |
| 573 | .unwrap_or_else(|| vec![[0.0, 0.0, 0.0, 0.0]; positions.len()]); |
| 574 | let indices: Vec<u32> = match reader.read_indices() { |
| 575 | Some(i) => i.into_u32().collect(), |
| 576 | None => (0..positions.len() as u32).collect(), |
| 577 | }; |
| 578 | |
| 579 | let material_index = primitive |
| 580 | .material() |
| 581 | .index() |
| 582 | .map(|i| i as u32) |
| 583 | .unwrap_or(default_material_index); |
| 584 | if material_index as usize >= materials.len() { |
| 585 | continue; |
| 586 | } |
| 587 | |
| 588 | for tri in indices.chunks_exact(3) { |
| 589 | let (i0, i1, i2) = (tri[0] as usize, tri[1] as usize, tri[2] as usize); |
| 590 | if i0.max(i1).max(i2) >= positions.len() { |
| 591 | continue; |
| 592 | } |
| 593 |
no test coverage detected