134 lines
4.3 KiB
Rust
134 lines
4.3 KiB
Rust
//! Wall-clock of `parametrize` on remesh-sized meshes. Run:
|
|
//! cargo test -p makepad-xatlas --release --test bench_sizes -- --nocapture --ignored
|
|
|
|
use makepad_xatlas::parametrize;
|
|
use std::time::Instant;
|
|
|
|
fn grid(cols: u32, rows: u32) -> (Vec<[f32; 3]>, Vec<[u32; 3]>) {
|
|
let mut positions = Vec::new();
|
|
for y in 0..=rows {
|
|
for x in 0..=cols {
|
|
positions.push([x as f32, y as f32, 0.0]);
|
|
}
|
|
}
|
|
let mut faces = Vec::new();
|
|
let w = cols + 1;
|
|
for y in 0..rows {
|
|
for x in 0..cols {
|
|
let i = y * w + x;
|
|
faces.push([i, i + 1, i + w + 1]);
|
|
faces.push([i, i + w + 1, i + w]);
|
|
}
|
|
}
|
|
(positions, faces)
|
|
}
|
|
|
|
/// Closed box with per-face verts, then tessellated so xatlas has 6 charts
|
|
/// plus internal splits — closer to a remeshed prop than a flat grid.
|
|
fn tess_cube(div: u32) -> (Vec<[f32; 3]>, Vec<[u32; 3]>) {
|
|
let faces = [
|
|
([1.0f32, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]),
|
|
([-1.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0]),
|
|
([0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0]),
|
|
([0.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]),
|
|
([0.0, 0.0, 1.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]),
|
|
([0.0, 0.0, -1.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0]),
|
|
];
|
|
let mut positions = Vec::new();
|
|
let mut tris = Vec::new();
|
|
for (n, u, v) in faces {
|
|
let base = positions.len() as u32;
|
|
for j in 0..=div {
|
|
for i in 0..=div {
|
|
let su = (i as f32 / div as f32) - 0.5;
|
|
let sv = (j as f32 / div as f32) - 0.5;
|
|
positions.push([
|
|
n[0] * 0.5 + u[0] * su + v[0] * sv,
|
|
n[1] * 0.5 + u[1] * su + v[1] * sv,
|
|
n[2] * 0.5 + u[2] * su + v[2] * sv,
|
|
]);
|
|
}
|
|
}
|
|
let w = div + 1;
|
|
for j in 0..div {
|
|
for i in 0..div {
|
|
let i0 = base + j * w + i;
|
|
tris.push([i0, i0 + 1, i0 + w + 1]);
|
|
tris.push([i0, i0 + w + 1, i0 + w]);
|
|
}
|
|
}
|
|
}
|
|
(positions, tris)
|
|
}
|
|
|
|
/// Heightfield with enough normal variation that xatlas grows many charts.
|
|
fn noisy_terrain(cols: u32, rows: u32) -> (Vec<[f32; 3]>, Vec<[u32; 3]>) {
|
|
let mut positions = Vec::new();
|
|
for y in 0..=rows {
|
|
for x in 0..=cols {
|
|
let xf = x as f32 * 0.08;
|
|
let yf = y as f32 * 0.08;
|
|
let z = (xf * 1.7).sin() * 0.35
|
|
+ (yf * 2.3).cos() * 0.28
|
|
+ ((xf + yf) * 4.1).sin() * 0.12
|
|
+ ((xf * 9.0).sin() * (yf * 8.0).cos()) * 0.08;
|
|
positions.push([xf, yf, z]);
|
|
}
|
|
}
|
|
let mut faces = Vec::new();
|
|
let w = cols + 1;
|
|
for y in 0..rows {
|
|
for x in 0..cols {
|
|
let i = y * w + x;
|
|
faces.push([i, i + 1, i + w + 1]);
|
|
faces.push([i, i + w + 1, i + w]);
|
|
}
|
|
}
|
|
(positions, faces)
|
|
}
|
|
|
|
fn time_one(name: &str, positions: &[[f32; 3]], faces: &[[u32; 3]]) {
|
|
let t0 = Instant::now();
|
|
let out = parametrize(positions, faces).expect(name);
|
|
let dt = t0.elapsed();
|
|
eprintln!(
|
|
"{name:>16} in_v={:<6} in_f={:<6} out_v={:<6} charts={:<4} atlas={}x{} {:>8.3}s",
|
|
positions.len(),
|
|
faces.len(),
|
|
out.vertices.len(),
|
|
out.chart_count,
|
|
out.width,
|
|
out.height,
|
|
dt.as_secs_f64()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn time_remesh_sized_unwraps() {
|
|
// Warm the allocator / caches.
|
|
let (p, f) = tess_cube(4);
|
|
let _ = parametrize(&p, &f);
|
|
|
|
// Flat grid: few charts (optimistic).
|
|
let (p, f) = grid(77, 77); // ~12k tris
|
|
time_one("grid 12k", &p, &f);
|
|
let (p, f) = grid(100, 100); // 20k tris
|
|
time_one("grid 20k", &p, &f);
|
|
|
|
// Tessellated cube: 6 charts, prop/character densities.
|
|
// 6 * 2 * d^2 faces.
|
|
let (p, f) = tess_cube(32); // 6*2*1024 = 12288
|
|
time_one("cube 12k", &p, &f);
|
|
let (p, f) = tess_cube(41); // 6*2*1681 = 20172
|
|
time_one("cube 20k", &p, &f);
|
|
let (p, f) = tess_cube(82); // 6*2*6724 = 80688
|
|
time_one("cube 80k", &p, &f);
|
|
|
|
let (p, f) = noisy_terrain(77, 77);
|
|
time_one("terrain 12k", &p, &f);
|
|
let (p, f) = noisy_terrain(100, 100);
|
|
time_one("terrain 20k", &p, &f);
|
|
let (p, f) = noisy_terrain(200, 200);
|
|
time_one("terrain 80k", &p, &f);
|
|
}
|