Skip to main content

Module mesh_payload

Module mesh_payload 

Source
Expand description

Canonical vertex type and the binary serialisation format shared between the build step (build_mesh.rs writes) and GraphicsSystem (reads).

The layout asserts below stay hand-written. A vertex payload reaches a shader through a vertex descriptor or a raw pointer, never as a declared buffer block, so slangc’s reflection reports it as an attribute index with no byte offset – the reflection-driven check in concinnity-device’s shader_layout has nothing to compare against here.

Format (little-endian): u32 vertex_count vertex_count * 56 bytes float3 pos + float3 normal + float3 tangent + float3 color + float2 uv (14 x f32) u32 index_count // LOD0 indices index_count * 2 bytes u16 indices optional LOD trailer 4 bytes ascii “LODS” magic (absent for legacy / single-LOD payloads) u32 alt_count // number of additional LODs beyond LOD0 alt_count × { f32 switch_distance // camera-distance threshold (LOD i+1 applies at d >= switch_distance) u32 index_count index_count * 2 bytes u16 indices }

deserialise reads only the LOD0 indices and ignores any trailer, so old readers keep working unchanged. deserialise_with_lods reads the trailer when present and returns the additional LODs alongside LOD0.

Structs§

HeightfieldGrid
A baked heightfield collider grid: rows x cols world-space heights in row-major order (row index increases along +Z, column index along +X), matching the vertex order the heightfield mesh generator emits.
MorphDelta
One morph-target vertex delta in dense form: position and normal offsets added to the bind pose before skinning, scaled by the target’s weight.
MorphEntry
One sparse morph entry as the GPU consumes it: the target it belongs to plus the position and normal offsets. Plain tightly packed 4-byte fields; the shader-side struct uses packed types so the 28-byte stride matches.
PayloadJoint
One joint of a skinned mesh’s bind-pose skeleton, as stored in the compiled payload. Mirrors assets::skinned_mesh::SkeletonJoint but lives in gfx so the payload format stays self-contained: the build/runtime boundaries convert between the two. Parents must appear before their children, so the runtime can walk the array once when building the Skeleton.
PayloadMorphs
Morph-target block of a skinned payload: target names plus the sparse vertex-major entries.
SkinnedPayload
A fully deserialised skinned payload, including the optional morph and LOD blocks (empty when the payload carries none).
SkinnedVertex
Vertex layout for skeletally animated meshes. A superset of Vertex: the same 56-byte static attributes plus four joint indices and four blend weights. repr(C), 80 bytes, so it casts directly to a GPU buffer.
Vertex
Vertex layout shared by all mesh producers and both GPU backends. Repr(C) so it can be cast directly to GPU buffer memory.

Constants§

MORPH_DELTA_EPSILON
Deltas whose every component is at or below this magnitude are dropped when a dense target is sparsified: a micron of position or a 1e-6 normal tilt is invisible, and imported targets carry that much float noise.

Functions§

deserialise_heightfield
Decode the baked-heightfield trailer from a static mesh payload, if present. The trailer rides at the very end, so this walks past the vertex, LOD0 index, and optional LOD blocks positionally before reading the "HFLD" block. Returns Ok(None) for any payload without the trailer (i.e. every non-heightfield mesh) so callers can treat absence as “no baked collider”.
deserialise_skinned
Deserialise a packed skinned-mesh payload produced by serialise_skinned. The returned skeleton lives in the payload; the args JSON no longer needs to carry it. The optional LOD trailer is parsed and discarded; callers who need LOD alternates should use deserialise_skinned_with_lods.
deserialise_skinned_with_lods
Deserialise a packed skinned-mesh payload, also returning any optional LOD trailer. Mirrors deserialise_with_lods for static meshes: legacy single-LOD payloads have no trailer and produce an empty alternates vec.
deserialise_with_lods
Deserialise a packed payload, also returning any optional LOD trailer. Legacy single-LOD payloads have no trailer and produce an empty alternates vec; multi-LOD payloads parse the "LODS" block after the LOD0 indices and return one entry per additional level. The order is preserved: alternates[i] is LOD i + 1 and applies at camera distance ≥ alternates[i].0.
serialise
Serialise vertex and index slices into the packed binary payload format. Each vertex tuple is (pos, normal, tangent, color, uv).
serialise_heightfield_trailer
Serialise a baked-heightfield collider trailer: "HFLD" magic, u32 rows, u32 cols, then rows * cols little-endian f32 heights in row-major order. Appended to a heightfield ProceduralMesh payload after the optional LOD trailer.
serialise_skinned_with_lods
Serialise a multi-LOD skinned mesh. Two optional blocks ride after the joint block, each announced by a magic: "MRPS" (u32 target_count, per target u32 name_byte_len + name UTF-8 bytes, then u32 entry_count, (vertex_count + 1) * 4 bytes of u32 entry offsets and entry_count * 28 bytes of sparse MorphEntrys, see PayloadMorphs) and "LODS" (u32 alt_count, then per alternate f32 switch_distance, u32 index_count, index_count * 2 bytes of u16 indices). Empty morphs and alternates match the legacy single-LOD payload byte-for-byte.
serialise_with_lods
Serialise a multi-LOD mesh payload. indices is LOD0; lod_alternates is the list of additional LODs (LOD1..N), each paired with the camera-distance threshold that triggers a switch to it. When lod_alternates is empty this is byte-identical to the single-LOD serialise output, so the build can call this unconditionally.