import { AssetError, type Result, type VertexAttributeMap, type VertexAttributePackDetail } from '@forgeax/engine-types'; declare const ATTRIBUTE_FORMAT_MAP: { readonly position: "float32x3"; readonly normal: "float32x3"; readonly uv: "float32x2"; readonly tangent: "float32x4"; readonly skinIndex: "uint16x4"; readonly skinWeight: "float32x4"; readonly uv1: "float32x2"; readonly uv2: "float32x2"; readonly uv3: "float32x2"; readonly uv4: "float32x2"; readonly uv5: "float32x2"; readonly uv6: "float32x2"; readonly uv7: "float32x2"; readonly color: "float32x4"; }; type AttributeKey = keyof typeof ATTRIBUTE_FORMAT_MAP; export interface GpuVertexBufferLayoutEntry { readonly arrayStride: number; readonly attributes: ReadonlyArray<{ readonly shaderLocation: number; readonly offset: number; readonly format: string; }>; readonly stepMode?: 'vertex' | 'instance' | undefined; } /** Canonical position/normal/uv/tangent map for ordinary interleaved meshes. */ export declare const DEFAULT_VERTEX_ATTRIBUTE_MAP: VertexAttributeMap; /** Canonical six-attribute map for skinned interleaved meshes. */ export declare const SKIN_VERTEX_ATTRIBUTE_MAP: VertexAttributeMap; /** * Build a non-skin `VertexAttributeMap` carrying exactly `uvSetCount` UV sets * (set 0 = `uv`, then `uv1..uv{uvSetCount-1}`). `deriveVertexBufferLayout` * reads only key presence, so the zero-length typed-array values are sentinels. * * feat-20260629-multi-uv-set-support: the forward record stage owns only the * mesh's `uvSetCount` (a scalar threaded through MeshGpuHandles), not the * original `MeshAsset.attributes` map. It synthesizes the map here so the * material PSO's vertex layout includes the real @location(6+) attributes and * its stride matches the interleaved buffer (a mesh with 2 real UV sets has a * 56 B stride; a 48 B PSO layout against it puts every vertex after the first * off-screen). uvSetCount <= 1 yields the canonical 4-attribute single-UV map. */ export declare function buildMeshAttributeMapForUvSets(uvSetCount: number): VertexAttributeMap; export declare function deriveVertexBufferLayout(map: VertexAttributeMap, opts?: { shaderUvSetCount?: number; }): GpuVertexBufferLayoutEntry[]; /** Build the GPU descriptor from an immutable projection, adding only shader UV aliases. */ export declare function deriveVertexBufferLayoutFromProjection(projection: VertexLayoutProjection, opts?: { shaderUvSetCount?: number; }): GpuVertexBufferLayoutEntry[]; export interface VertexLayoutProjectionAttribute { readonly key: AttributeKey; readonly shaderLocation: number; readonly offset: number; readonly format: (typeof ATTRIBUTE_FORMAT_MAP)[AttributeKey]; readonly byteLength: number; } /** Immutable geometry-owned projection consumed by packers and GPU consumers. */ export interface VertexLayoutProjection { readonly schemaVersion: 1; readonly attributes: readonly VertexLayoutProjectionAttribute[]; readonly mask: number; readonly arrayStride: number; readonly digest: string; } /** * Derive a vertex count from the geometry-owned projection. * * Every upload, morph write, and draw range must use this same byte-level * calculation. Returning `undefined` keeps malformed payloads out of GPU * resource construction instead of silently truncating a fractional count. */ export declare function deriveVertexCount(vertices: { readonly byteLength: number; }, projection: VertexLayoutProjection): number | undefined; /** Derive the one canonical immutable layout projection for a vertex map. */ export declare function deriveVertexLayoutProjection(map: VertexAttributeMap): VertexLayoutProjection; export interface PackedVertexAttributes { readonly projection: VertexLayoutProjection; readonly vertices: Float32Array; } export declare class VertexAttributePackError extends AssetError { readonly detail: VertexAttributePackDetail; constructor(detail: VertexAttributePackDetail); } export interface VertexLayoutProjectionMaskError { readonly code: 'vertex-layout-mask-invalid'; readonly expected: string; readonly hint: string; readonly detail: { readonly mask: number; readonly knownMask: number; readonly unknownMask: number; readonly reason: 'empty' | 'unknown-bits'; }; } /** Rebuild the canonical projection from a packed wire mask without a second schema. */ export declare function deriveVertexLayoutProjectionFromMask(mask: number): Result; /** Pack tightly-owned attributes into the projection's canonical interleaved bytes. */ export declare function packInterleavedVertexAttributes(map: VertexAttributeMap, vertexCount: number): Result; /** Copy canonical interleaved bytes to owned attributes; callers validate semantic values. */ export declare function unpackInterleavedVertexAttributes(vertices: Float32Array, projection: VertexLayoutProjection): VertexAttributeMap | undefined; export {}; //# sourceMappingURL=vertex-attribute-layout.d.ts.map