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
112 lines
4.4 KiB
Rust
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());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|