Files
MetaCrate/crates/libremetaverse-rendering-mesh-foundry
Chili Palmer dceb394378
Some checks failed
API and SemVer surface / api-surface (push) Failing after 1m28s
Native release artifact audit / audit (push) Failing after 1h6m34s
Native code generation / deterministic (push) Failing after 2m15s
Concurrency and resource soak audit / soak (push) Failing after 6m33s
Documentation / documentation (push) Failing after 2m0s
Imaging and meshing gate / native (push) Failing after 55s
JPEG 2000 feature / linux (push) Successful in 2m46s
performance evidence / audit (push) Failing after 13m45s
Release platform and feature matrix / audit (push) Successful in 1m3s
Native Rust workspace compile / compile (push) Failing after 55s
Skia feature / linux (push) Successful in 31m58s
Dependency and supply-chain audit / audit (push) Failing after 9m34s
Release platform and feature matrix / matrix (false, linux-stable-minimal, x86_64-unknown-linux-gnu, stable) (push) Failing after 10m2s
Release platform and feature matrix / matrix (false, macos-stable-portable, x86_64-apple-darwin, stable) (push) Failing after 2m0s
Release platform and feature matrix / matrix (false, windows-stable-portable, x86_64-pc-windows-gnu, stable) (push) Failing after 1m56s
Release platform and feature matrix / matrix (true, linux-msrv-portable, x86_64-unknown-linux-gnu, 1.96.0) (push) Failing after 6m19s
Release platform and feature matrix / matrix (true, linux-stable-default, x86_64-unknown-linux-gnu, stable) (push) Failing after 6m57s
Release platform and feature matrix / matrix (true, linux-stable-features, x86_64-unknown-linux-gnu, stable) (push) Failing after 7m6s
Release platform and feature matrix / matrix (true, linux-stable-release-surface, x86_64-unknown-linux-gnu, stable) (push) Failing after 8m8s
Prove clean native release artifacts (#106)
2026-08-12 04:57:37 +00:00
..
2026-08-10 22:37:43 +00:00

LibreMetaverse MeshFoundry renderer

libremetaverse-rendering-mesh-foundry is the bounded native renderer for legacy prims, sculpt maps, terrain, and Second Life LLSD mesh assets. It uses the checked SimpleRenderer/PrimMesher path for legacy geometry and the native StructuredData binary codec for mesh containers. It does not wrap, load, or invoke the C# renderer or duplicate the LLSD and image codecs.

Pipelines

The mapped MeshFoundry methods cover:

  • simple and face-grouped legacy prim geometry at every DetailLevel, always retaining finite normals and UVs;
  • plane, cylinder, sphere, and torus sculpt maps;
  • rectangular height-map terrain with generated normals and UVs;
  • packed mesh-asset headers and individually zlib-compressed LLSD sections;
  • requested visual LOD selection (high_lod, medium_lod, low_lod, and lowest_lod) with deterministic highest-to-lowest fallback;
  • single-section simple-mesh extraction and physics convex/bounding hulls; and
  • default or planar texture transforms, repeats, offsets, rotation, and prim scale through the common IRendering contract.

Mesh vertices remain in prim-local coordinates. Quantized positions use each submesh's PositionDomain; normals and tangent components use the format's fixed [-1, 1] domain; UV0 and optional UV1 use their independent domains. Triangle and face order is preserved, while flattened multi-face output rebases indices without reordering vertices. Missing normals and tangents are generated deterministically from triangles and UVs. Degenerate UV gradients receive a stable normal-orthogonal fallback tangent.

The mapped Face type has no tangent field. Mesh tangents are therefore kept without changing the public C# layout in a public MeshFaceAux value stored in Face.user_data; recover it with face.user_data.downcast_ref::<MeshFaceAux>(). Its Vector4.w is the bitangent handedness. UV1 remains in Face.tex_coords1.

Rigged meshes and materials

The skin section decodes bounded joint names, inverse-bind matrices, bind-shape matrix, alternative inverse-bind matrices, pelvis offset, and the joint-position scale lock into the shared MeshSkinData. Per-vertex weight streams accept the protocol's sentinel form and its exactly-four-influence form, validate every joint index, clamp protocol weights, normalize four influences, and bind missing vertices to joint zero. The output is directly consumable by RiggedSkinMath and AnimeshSkinning.

Each submesh retains its original face ID and the effective inherited PrimitiveTextureEntryFace, including texture, legacy material, and render material overrides. NormalizedScale, face bounds, centers, optional UV1, weights, normals, tangents, and winding are kept together. Mesh sculpt mirror and invert flags apply the viewer-compatible reflection, normal inversion, and XOR winding rule to every face and tangent domain.

Bounds and failure contract

Assets and compressed/decompressed sections are capped at 64 MiB. Header sections and submeshes are capped at 256, each face remains within the 16-bit 65,536-vertex index domain, aggregate visual geometry is capped at 1,000,000 vertices and 6,000,000 indices, skins at 512 joints, and convex data at 65,536 hulls and 1,000,000 vertices. All sizes, offsets, index rebasing, buffer strides, and allocation products use checked arithmetic before slicing or allocation.

Malformed LLSD, zlib data, domains, parallel buffers, matrices, weights, offsets, and indices return Error::Rendering with the source primitive UUID and a stable operation context. UnpackMesh has no primitive parameter and uses the zero UUID. This crate performs no asset download, scene traversal, world transform, GPU upload, material shading, texture fetch, or drawing.

Reproducible gates and benchmark

python3 tools/check_milestone_10_issue_77.py
CARGO_BUILD_JOBS=1 cargo test -p libremetaverse-compat-tests --test imaging_meshing_semantics --locked -j1
CARGO_BUILD_JOBS=1 cargo test -p libremetaverse-rendering-mesh-foundry --locked -j1
CARGO_BUILD_JOBS=1 cargo bench -p libremetaverse-rendering-mesh-foundry --bench mesh_decode --profile benchmark --locked -j1

The named benchmark profile uses bounded-memory moderate optimization because full release optimization of the generated core surface can exceed small Gitea-worker memory before the fixture runs. The non-statistical benchmark builds and decodes a deterministic 57,600-vertex, 342,726-index mesh asset and reports elapsed time plus allocation counts. It is diagnostic evidence for regressions; correctness and malformed-input tests remain the release gates.