| 730 | // ============================================================ |
| 731 | |
| 732 | fn read_accessor_f32(_gltf: &gltf::Gltf, buffer_data: &[Vec<u8>], accessor: &gltf::Accessor) -> Vec<f32> { |
| 733 | let view = match accessor.view() { |
| 734 | Some(v) => v, |
| 735 | None => return Vec::new(), |
| 736 | }; |
| 737 | let buf_idx = view.buffer().index(); |
| 738 | if buf_idx >= buffer_data.len() { return Vec::new(); } |
| 739 | let buf = &buffer_data[buf_idx]; |
| 740 | let offset = view.offset() + accessor.offset(); |
| 741 | let count = accessor.count(); |
| 742 | let stride = view.stride().unwrap_or(accessor.size()); |
| 743 | let component_count = match accessor.dimensions() { |
| 744 | gltf::accessor::Dimensions::Scalar => 1, |
| 745 | gltf::accessor::Dimensions::Vec2 => 2, |
| 746 | gltf::accessor::Dimensions::Vec3 => 3, |
| 747 | gltf::accessor::Dimensions::Vec4 => 4, |
| 748 | gltf::accessor::Dimensions::Mat4 => 16, |
| 749 | _ => 1, |
| 750 | }; |
| 751 | |
| 752 | let mut result = Vec::with_capacity(count * component_count); |
| 753 | for i in 0..count { |
| 754 | let base = offset + i * stride; |
| 755 | for c in 0..component_count { |
| 756 | let byte_offset = base + c * 4; |
| 757 | if byte_offset + 4 <= buf.len() { |
| 758 | let val = f32::from_le_bytes([buf[byte_offset], buf[byte_offset+1], buf[byte_offset+2], buf[byte_offset+3]]); |
| 759 | result.push(val); |
| 760 | } else { |
| 761 | result.push(0.0); |
| 762 | } |
| 763 | } |
| 764 | } |
| 765 | result |
| 766 | } |
| 767 | |
| 768 | fn load_gltf_animation(data: &[u8]) -> Option<ModelAnimation> { |
| 769 | let gltf = gltf::Gltf::from_slice(data).ok()?; |