Implement MeshFoundry pipeline (#77)
Some checks failed
Native code generation / deterministic (push) Failing after 1m58s
Imaging and meshing gate / native (push) Failing after 4m10s
JPEG 2000 feature / linux (push) Successful in 3m0s
Native Rust workspace compile / compile (push) Failing after 6m12s
Skia feature / linux (push) Has been cancelled

This commit is contained in:
2026-08-10 22:37:43 +00:00
parent 611db567a0
commit 88408c9680
17 changed files with 2402 additions and 50 deletions

View File

@@ -0,0 +1,82 @@
#![allow(clippy::cast_precision_loss)] // The benchmark grid is fixed at 240×240.
use std::alloc::System;
use std::hint::black_box;
use std::time::Instant;
use libremetaverse::Primitive;
use libremetaverse::import_export::{ModelFace, ModelPrim};
use libremetaverse::rendering::{DetailLevel, Vertex};
use libremetaverse_rendering_mesh_foundry::MeshFoundry;
use libremetaverse_types::{UUID, Vector2, Vector3};
use stats_alloc::{INSTRUMENTED_SYSTEM, Region, StatsAlloc};
#[global_allocator]
static ALLOCATOR: &StatsAlloc<System> = &INSTRUMENTED_SYSTEM;
fn fixture(side: usize) -> Vec<u8> {
let mut model = ModelPrim::new().expect("model prim");
let mut face = ModelFace::new().expect("model face");
face.vertices.reserve(side * side);
for y in 0..side {
for x in 0..side {
let u = x as f32 / (side - 1) as f32;
let v = y as f32 / (side - 1) as f32;
face.vertices.push(Vertex {
position: Vector3 {
x: u - 0.5,
y: v - 0.5,
z: (u * std::f32::consts::TAU).sin() * 0.05,
},
normal: Vector3::unit_z(),
tex_coord: Vector2 { x: u, y: v },
});
}
}
for y in 0..side - 1 {
for x in 0..side - 1 {
let a = u32::try_from(y * side + x).expect("bounded benchmark index");
let b = a + 1;
let c = a + u32::try_from(side).expect("bounded side");
let d = c + 1;
face.indices.extend_from_slice(&[a, b, c, b, d, c]);
}
}
model.faces.push(face);
model
.create_asset(UUID::zero())
.expect("bounded benchmark mesh asset");
model.asset
}
fn main() {
let asset = fixture(240);
let renderer = MeshFoundry::new().expect("MeshFoundry constructor");
let primitive = Primitive::new_with_constructor().expect("Primitive constructor");
let allocation_region = Region::new(ALLOCATOR);
let started = Instant::now();
let mesh = renderer
.generate_faceted_mesh_mesh_with_primitive_bytes_detail_level(
primitive,
asset.clone(),
DetailLevel::Highest,
)
.expect("large fixture decode")
.expect("large fixture geometry");
let elapsed = started.elapsed();
let allocation_stats = allocation_region.change();
assert_eq!(mesh.faces.len(), 1);
assert_eq!(mesh.faces[0].vertices.len(), 57_600);
assert_eq!(mesh.faces[0].indices.len(), 342_726);
black_box((&asset, &mesh));
println!(
"mesh decode: {} compressed bytes, {} vertices, {} indices in {elapsed:?}, {} allocations, {} reallocations, {} bytes allocated",
asset.len(),
mesh.faces[0].vertices.len(),
mesh.faces[0].indices.len(),
allocation_stats.allocations,
allocation_stats.reallocations,
allocation_stats.bytes_allocated,
);
}