Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
use std::error::Error as StdError;
use std::{fs, path};
const SAMPLE_MODELS_DIRECTORY_PATH: &str = "glTF-Sample-Assets/Models";
fn check_import_result(
result: gltf::Result<(
gltf::Document,
Vec<gltf::buffer::Data>,
Vec<gltf::image::Data>,
)>,
) {
use gltf::json::validation::Error;
match result {
Err(gltf::Error::Validation(errors)) => {
assert!(errors
.iter()
.all(|(_path, error)| *error == Error::Unsupported));
println!("skipped");
}
Err(otherwise) => {
panic!("{otherwise:#?}");
}
Ok((document, buffer_data, image_data)) => {
// Check buffers.
assert_eq!(document.buffers().len(), buffer_data.len());
for (buf, data) in document.buffers().zip(buffer_data.iter()) {
assert!((buf.length() + 3) & !3 <= data.0.len())
}
// Check images.
assert_eq!(document.images().len(), image_data.len());
println!("ok");
}
}
}
fn run() -> Result<(), Box<dyn StdError>> {
let sample_dir_path = path::Path::new(SAMPLE_MODELS_DIRECTORY_PATH);
for entry in fs::read_dir(sample_dir_path)? {
let entry = entry?;
let metadata = entry.metadata()?;
if metadata.is_dir() {
let entry_path = entry.path();
if let Some(file_name) = entry_path.file_name() {
// Import standard glTF.
let mut gltf_path = entry_path.join("glTF").join(file_name);
gltf_path.set_extension("gltf");
if gltf_path.exists() {
print!("{}: ", gltf_path.display());
check_import_result(gltf::import(&gltf_path));
}
// Import standard glTF with embedded buffer and image data.
let mut gle_path = entry_path.join("glTF-Embedded").join(file_name);
gle_path.set_extension("gltf");
if gle_path.exists() {
print!("{}: ", gle_path.display());
check_import_result(gltf::import(&gle_path));
}
// Import binary glTF.
let mut glb_path = entry_path.join("glTF-Binary").join(file_name);
glb_path.set_extension("glb");
if glb_path.exists() {
print!("{}: ", glb_path.display());
check_import_result(gltf::import(&glb_path));
}
}
}
}
sparse_accessor_without_buffer_view_test()
}
/// Test a file with a sparse accessor with no buffer view
fn sparse_accessor_without_buffer_view_test() -> Result<(), Box<dyn StdError>> {
let glb_path = path::Path::new("tests/box_sparse.glb");
print!("{}: ", glb_path.display());
check_import_result(gltf::import(glb_path));
let gltf_path = path::Path::new("tests/box_sparse.gltf");
print!("{}: ", gltf_path.display());
check_import_result(gltf::import(gltf_path));
Ok(())
}
#[test]
fn import_sample_models() {
if let Err(error) = run() {
panic!("import failed: {:?}", error);
}
}

View File

@@ -0,0 +1,89 @@
//! Roundtrip test.
//!
//! Read some binary glTF, write it to disk, and compare to the original.
//! The test will succeed if the output is the same as the original.
use std::io::Read;
use std::{boxed, error, fs, io, path};
const SAMPLE_MODELS_DIRECTORY_PATH: &str = "glTF-Sample-Assets/Models";
fn run() -> Result<(), boxed::Box<dyn error::Error>> {
let mut all_tests_passed = true;
let mut nr_test_cases = 0;
for entry in fs::read_dir(SAMPLE_MODELS_DIRECTORY_PATH)? {
let entry = entry?;
let metadata = entry.metadata()?;
if metadata.is_dir() {
let entry_path = entry.path();
if let Some(file_name) = entry_path.file_name() {
let mut path = entry_path.join("glTF-Binary").join(file_name);
path.set_extension("glb");
if path.exists() {
// not all models have binary versions
if let Err(err) = test(&path) {
println!("{:?}: error: {:?}", path, err);
all_tests_passed = false;
} else {
println!("{:?}: ok", path);
nr_test_cases += 1;
}
}
}
}
}
if sparse_accessor_without_buffer_view_test() {
nr_test_cases += 1;
} else {
all_tests_passed = false;
}
assert!(all_tests_passed);
assert!(nr_test_cases >= 25);
Ok(())
}
fn test(path: &path::Path) -> Result<(), boxed::Box<dyn error::Error>> {
let file = fs::File::open(path)?;
let length = file.metadata()?.len() as usize;
let mut reader = io::BufReader::new(file);
let mut original = Vec::with_capacity(length);
reader.read_to_end(&mut original)?;
// Check from_reader/to_vec implementation.
{
let glb = gltf::binary::Glb::from_reader(io::Cursor::new(&original))?;
let output = glb.to_vec()?;
assert_eq!(&original, &output);
}
// Check from_slice/to_writer implementation.
{
let glb = gltf::binary::Glb::from_slice(&original)?;
let mut output = Vec::with_capacity(length);
glb.to_writer(&mut output as &mut dyn io::Write)?;
assert_eq!(&original, &output);
}
Ok(())
}
/// Test a file with a sparse accessor with no buffer view.
///
/// Return true if the test passes, and false otherwise.
fn sparse_accessor_without_buffer_view_test() -> bool {
let path = path::Path::new("tests/box_sparse.glb");
if let Err(err) = test(path) {
println!("{:?}: error: {:?}", path, err);
false
} else {
println!("{:?}: ok", path);
true
}
}
#[test]
fn roundtrip_binary_gltf() {
run().expect("test failure");
}

128
vendor/gltf/tests/test_wrapper.rs vendored Normal file
View File

@@ -0,0 +1,128 @@
use std::io::Read;
use std::{fs, io};
use gltf::mesh::Bounds;
#[test]
fn test_accessor_bounds() {
// file derived from minimal.gltf with changed min/max values
let file = fs::File::open("tests/minimal_accessor_min_max.gltf").unwrap();
let mut reader = io::BufReader::new(file);
let mut buffer = vec![];
reader.read_to_end(&mut buffer).unwrap();
let gltf = gltf::Gltf::from_slice(&buffer).unwrap();
let mesh = &gltf.meshes().next().unwrap();
let prim = mesh.primitives().next().unwrap();
let bounds = prim.bounding_box();
assert_eq!(
bounds,
Bounds {
min: [-0.03, -0.04, -0.05],
max: [1.0, 1.01, 0.02]
}
);
}
/// "SimpleSparseAccessor.gltf" contains positions specified with a sparse accessor.
/// The accessor use a base `bufferView` that contains 14 `Vec3`s and the sparse
/// section overwrites 3 of these with other values when read.
const SIMPLE_SPARSE_ACCESSOR_GLTF: &str =
"glTF-Sample-Assets/Models/SimpleSparseAccessor/glTF-Embedded/SimpleSparseAccessor.gltf";
#[test]
fn test_sparse_accessor_with_base_buffer_view_yield_exact_size_hints() {
let (document, buffers, _) = gltf::import(SIMPLE_SPARSE_ACCESSOR_GLTF).unwrap();
let mesh = document.meshes().next().unwrap();
let primitive = mesh.primitives().next().unwrap();
let reader = primitive
.reader(|buffer: gltf::Buffer| buffers.get(buffer.index()).map(|data| &data.0[..]));
let mut positions = reader.read_positions().unwrap();
const EXPECTED_POSITION_COUNT: usize = 14;
for i in (0..=EXPECTED_POSITION_COUNT).rev() {
assert_eq!(positions.size_hint(), (i, Some(i)));
positions.next();
}
}
#[test]
fn test_sparse_accessor_with_base_buffer_view_yield_all_values() {
let (document, buffers, _) = gltf::import(SIMPLE_SPARSE_ACCESSOR_GLTF).unwrap();
let mesh = document.meshes().next().unwrap();
let primitive = mesh.primitives().next().unwrap();
let reader = primitive
.reader(|buffer: gltf::Buffer| buffers.get(buffer.index()).map(|data| &data.0[..]));
let positions: Vec<[f32; 3]> = reader.read_positions().unwrap().collect::<Vec<_>>();
const EXPECTED_POSITIONS: [[f32; 3]; 14] = [
[0.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[2.0, 0.0, 0.0],
[3.0, 0.0, 0.0],
[4.0, 0.0, 0.0],
[5.0, 0.0, 0.0],
[6.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[1.0, 2.0, 0.0], // Sparse value #1
[2.0, 1.0, 0.0],
[3.0, 3.0, 0.0], // Sparse value #2
[4.0, 1.0, 0.0],
[5.0, 4.0, 0.0], // Sparse value #3
[6.0, 1.0, 0.0],
];
assert_eq!(positions.len(), EXPECTED_POSITIONS.len());
for (i, p) in positions.iter().enumerate() {
for (j, q) in p.iter().enumerate() {
assert_eq!(q - EXPECTED_POSITIONS[i][j], 0.0);
}
}
}
/// "box_sparse.gltf" contains an animation with a sampler with output of two values.
/// The values are specified with a sparse accessor that is missing a base `bufferView` field.
/// Which means that each value in it will be 0.0, except the values contained in the sparse
/// buffer view itself. In this case the second value is read from the sparse accessor (1.0),
/// while the first is left at the default zero.
const BOX_SPARSE_GLTF: &str = "tests/box_sparse.gltf";
#[test]
fn test_sparse_accessor_without_base_buffer_view_yield_exact_size_hints() {
let (document, buffers, _) = gltf::import(BOX_SPARSE_GLTF).unwrap();
let animation = document.animations().next().unwrap();
let sampler = animation.samplers().next().unwrap();
let output_accessor = sampler.output();
let mut outputs_iter =
gltf::accessor::Iter::<f32>::new(output_accessor, |buffer: gltf::Buffer| {
buffers.get(buffer.index()).map(|data| &data.0[..])
})
.unwrap();
const EXPECTED_OUTPUT_COUNT: usize = 2;
for i in (0..=EXPECTED_OUTPUT_COUNT).rev() {
assert_eq!(outputs_iter.size_hint(), (i, Some(i)));
outputs_iter.next();
}
}
#[test]
fn test_sparse_accessor_without_base_buffer_view_yield_all_values() {
let (document, buffers, _) = gltf::import(BOX_SPARSE_GLTF).unwrap();
let animation = document.animations().next().unwrap();
let sampler = animation.samplers().next().unwrap();
let output_accessor = sampler.output();
let output_iter = gltf::accessor::Iter::<f32>::new(output_accessor, |buffer: gltf::Buffer| {
buffers.get(buffer.index()).map(|data| &data.0[..])
})
.unwrap();
let outputs = output_iter.collect::<Vec<_>>();
const EXPECTED_OUTPUTS: [f32; 2] = [0.0, 1.0];
assert_eq!(outputs.len(), EXPECTED_OUTPUTS.len());
for (i, o) in outputs.iter().enumerate() {
assert_eq!(o - EXPECTED_OUTPUTS[i], 0.0);
}
}