Files
MetaCrate/crates/libremetaverse-prim-mesher/tests/rendering_contract.rs
Chili Palmer 9a62922afa
Some checks failed
Imaging and meshing gate / native (macos-latest) (push) Has been cancelled
Imaging and meshing gate / native (ubuntu-latest) (push) Has been cancelled
Imaging and meshing gate / native (windows-latest) (push) Has been cancelled
JPEG 2000 feature / linux (push) Has been cancelled
JPEG 2000 feature / macos (push) Has been cancelled
JPEG 2000 feature / windows (push) Has been cancelled
Skia feature / linux (push) Has been cancelled
Skia feature / macos (push) Has been cancelled
Skia feature / windows (push) Has been cancelled
Complete imaging and meshing integration gate (#44)
2026-08-09 05:12:19 +00:00

112 lines
4.4 KiB
Rust

//! Integration contracts for the data consumed by the future rendering pipeline.
use libremetaverse_imaging::{ManagedImage, ManagedImageImageChannels};
use libremetaverse_prim_mesher::{
PathType, PrimMesh, SculptMesh, SculptMeshSculptType, ViewerPolygon, ViewerVertex,
};
fn assert_rendering_vertices(vertices: &[ViewerVertex], polygons: &[ViewerPolygon]) {
assert!(vertices.len() <= usize::from(u16::MAX) + 1);
for vertex in vertices {
assert!(vertex.v.x.is_finite() && vertex.v.y.is_finite() && vertex.v.z.is_finite());
assert!(vertex.n.x.is_finite() && vertex.n.y.is_finite() && vertex.n.z.is_finite());
assert!(vertex.uv.u.is_finite() && vertex.uv.v.is_finite());
}
for polygon in polygons {
for index in [polygon.v1, polygon.v2, polygon.v3] {
let index = usize::try_from(index).expect("non-negative viewer index");
assert!(index < vertices.len());
u16::try_from(index).expect("MeshFoundry-facing index fits u16");
}
}
}
#[test]
fn prim_mesh_viewer_groups_are_rendering_ready() {
let mut mesh = PrimMesh::new(24, 0.05, 0.95, 0.25, 12).expect("checked profile");
mesh.viewer_mode = true;
mesh.calc_vertex_normals = true;
mesh.path_cut_begin = 0.03;
mesh.path_cut_end = 0.96;
mesh.twist_begin = -30;
mesh.twist_end = 120;
mesh.taper_x = 0.1;
mesh.skew = 0.15;
mesh.revolutions = 1.25;
mesh.steps_per_revolution = 48;
mesh.extrude(PathType::Circular)
.expect("checked viewer extrusion");
let indexer = mesh
.get_vertex_indexer()
.expect("checked viewer indexing")
.expect("viewer mode produces an indexer");
assert_eq!(indexer.num_prim_faces, mesh.num_prim_faces);
assert_eq!(indexer.viewer_vertices.len(), indexer.viewer_polygons.len());
for (vertices, polygons) in indexer
.viewer_vertices
.iter()
.zip(indexer.viewer_polygons.iter())
{
assert_rendering_vertices(
vertices,
polygons
.as_deref()
.expect("allocated prim-face polygon group"),
);
}
}
#[test]
fn sculpt_lods_and_topologies_keep_rendering_indices_and_attributes_aligned() {
let mut image = ManagedImage::new(128, 128, ManagedImageImageChannels::COLOR)
.expect("bounded sculpt fixture");
for index in 0..image.red.len() {
image.red[index] = u8::try_from(index & 0xff).expect("masked sample");
image.green[index] = u8::try_from((index / 128) & 0xff).expect("masked sample");
image.blue[index] = u8::try_from((index * 17) & 0xff).expect("masked sample");
}
for lod in [8, 16, 32] {
for topology in [
SculptMeshSculptType::Plane,
SculptMeshSculptType::Sphere,
SculptMeshSculptType::Torus,
SculptMeshSculptType::Cylinder,
] {
let mesh =
SculptMesh::new_with_managed_image_sculpt_type_int32_boolean_boolean_boolean(
image.clone().expect("independent image fixture"),
topology,
lod,
true,
true,
false,
)
.expect("checked sculpt mesh");
assert_eq!(mesh.coords.len(), mesh.normals.len());
assert_eq!(mesh.coords.len(), mesh.uvs.len());
assert_eq!(mesh.faces.len(), mesh.viewer_faces.len());
assert!(mesh.coords.len() <= usize::from(u16::MAX) + 1);
for face in &mesh.faces {
for index in [face.v1, face.v2, face.v3] {
let index = usize::try_from(index).expect("non-negative sculpt index");
assert!(index < mesh.coords.len());
u16::try_from(index).expect("MeshFoundry-facing sculpt index fits u16");
}
}
for viewer in &mesh.viewer_faces {
for coord in [viewer.v1, viewer.v2, viewer.v3] {
assert!(coord.x.is_finite() && coord.y.is_finite() && coord.z.is_finite());
}
for normal in [viewer.n1, viewer.n2, viewer.n3] {
assert!(normal.x.is_finite() && normal.y.is_finite() && normal.z.is_finite());
}
for uv in [viewer.uv1, viewer.uv2, viewer.uv3] {
assert!(uv.u.is_finite() && uv.v.is_finite());
}
}
}
}
}