type Endianness = 'little' | 'big'; type PointerSize = 4 | 8; interface BlendHeader { /** ASCII version string straight from the file header (e.g. "0501"). */ versionString: string; /** Numeric Blender version with one decimal, derived from versionString. */ version: number; pointerSize: PointerSize; endianness: Endianness; /** True if the file uses the large 17-byte / 32-byte block header layout. */ largeFormat: boolean; /** Total size of the file header. */ size: number; } interface BlendBlock { /** 4-char code, trailing nulls stripped (e.g. "ME", "MA", "DATA"). */ code: string; /** Index into the SDNA struct table. */ sdnaIndex: number; /** Original memory address from the writing Blender process. Used to resolve pointers. */ oldPtr: bigint; /** Size of the data payload in bytes. */ size: number; /** Number of consecutive structs in the payload. */ count: number; /** Absolute byte offset of the payload in the file. */ dataOffset: number; } interface SDNAField { typeIndex: number; nameIndex: number; } interface SDNAStruct { typeIndex: number; fields: SDNAField[]; } interface ParsedFieldName { /** The bare identifier, with any `*` and `[N]` suffixes stripped. */ baseName: string; /** Original name as it appears in the SDNA. */ rawName: string; /** Number of `*` characters in front of the identifier. */ pointerDepth: number; /** Whether the name describes a function pointer like `(*foo)()`. */ isFunctionPointer: boolean; /** Array dimensions, outermost first. Empty for scalars. */ arrayDims: number[]; } interface FieldLayout { field: SDNAField; name: ParsedFieldName; typeName: string; /** Total size of this field in bytes. */ size: number; /** Offset within the parent struct. */ offset: number; } interface SDNAStructLayout { index: number; typeName: string; size: number; fields: FieldLayout[]; /** Quick lookup from base field name to its layout. */ fieldByName: Map; } interface SDNA { names: string[]; parsedNames: ParsedFieldName[]; types: string[]; typeSizes: number[]; structs: SDNAStruct[]; /** Per-struct precomputed layout, indexed by SDNA struct index. */ layouts: SDNAStructLayout[]; /** Type name -> SDNA struct index. */ structIndexByType: Map; } /** * Low-level cursor that reads typed values out of a .blend buffer, indexed by * SDNA struct layouts. One reader is shared across all extractors. */ declare class StructReader { readonly buf: Uint8Array; readonly view: DataView; readonly header: BlendHeader; readonly sdna: SDNA; readonly little: boolean; readonly textDecoder: TextDecoder; /** First (or only) block for a given oldPtr. */ readonly blockByPtr: Map; /** Extra blocks when an oldPtr is reused across multiple writes (Blender 5+ * reuses temporary writer buffers, producing duplicates that share an oldPtr). * Sorted by dataOffset. */ readonly duplicatesByPtr: Map; constructor(buf: Uint8Array, header: BlendHeader, sdna: SDNA, blocks: BlendBlock[]); layoutOf(typeName: string): SDNAStructLayout; fieldOf(layout: SDNAStructLayout, name: string): FieldLayout; readPointer(offset: number): bigint; /** * Resolves a pointer to a block. When several blocks were written with the * same `oldPtr` (Blender's writer reuses temporary buffer addresses across * ID datablocks), pass `anchor` — the dataOffset of the block doing the * dereference — and the resolver returns the matching block whose payload * is nearest to (and at or after) the anchor in file order. */ blockAt(ptr: bigint, anchor?: number): BlendBlock | undefined; readInt8(offset: number): number; readUint8(offset: number): number; readInt16(offset: number): number; readUint16(offset: number): number; readInt32(offset: number): number; readUint32(offset: number): number; readFloat32(offset: number): number; readFloat64(offset: number): number; readInt64(offset: number): bigint; readUint64(offset: number): bigint; /** Reads a null-terminated ASCII string out of a fixed-size char array. */ readCString(offset: number, maxLen: number): string; /** Reads an arbitrary scalar primitive by its SDNA type name. Returns 0 for unknown types. */ readPrimitive(typeName: string, offset: number): number | bigint; /** * Reads a field that holds a pointer, returning the destination block (if any). * The `anchor` is used as a tie-breaker when several blocks share an oldPtr. */ followPointer(offset: number, anchor: number): BlendBlock | undefined; /** * Reads an N-element float array starting at `offset` into a fresh Float32Array. */ readFloatArray(offset: number, count: number): Float32Array; /** * Reads an N-element int32 array starting at `offset` into a fresh Int32Array. */ readInt32Array(offset: number, count: number): Int32Array; } interface BlendFileData { header: BlendHeader; sdna: SDNA; blocks: BlendBlock[]; reader: StructReader; } /** * Decompresses (if needed), validates, and indexes a .blend file. The returned * object is the foundation every extractor reads from. */ declare const parseBlend: (raw: Uint8Array | ArrayBuffer) => BlendFileData; /** * `bke::AttrType` values used by Blender 5.x AttributeStorage. This enum was * renumbered from the older CD_PROP_* values; the new mapping is what is * written into `Attribute.data_type` in modern files. */ declare const ATTR_TYPE: { readonly BOOL: 0; readonly INT8: 1; readonly INT16: 2; readonly INT32: 3; readonly INT32_2D: 4; readonly FLOAT: 5; readonly FLOAT2: 6; readonly FLOAT3: 7; readonly BYTE_COLOR: 8; readonly COLOR: 9; readonly QUATERNION: 10; readonly FLOAT4X4: 11; readonly STRING: 12; }; type AttrTypeName = keyof typeof ATTR_TYPE; type AttrTypeValue = (typeof ATTR_TYPE)[AttrTypeName]; /** AttrDomain enum values. */ declare const ATTR_DOMAIN: { readonly POINT: 0; readonly EDGE: 1; readonly FACE: 2; readonly CORNER: 3; readonly CURVE: 4; readonly INSTANCE: 5; readonly LAYER: 6; }; type AttrDomainName = keyof typeof ATTR_DOMAIN; type AttrDomainValue = (typeof ATTR_DOMAIN)[AttrDomainName]; interface MeshAttributeRaw { name: string; dataType: number; domain: number; storageType: number; /** Number of elements (length of array). */ length: number; /** Element size in bytes, derived from dataType. */ elementSize: number; /** Absolute byte offset of the first element in the file buffer. */ dataOffset: number; } /** Returns the byte width of a single element for a given AttrType. 0 if unknown. */ declare const attributeElementSize: (dataType: number) => number; /** * Reads the `AttributeStorage` embedded inside a Mesh struct and returns every * resolved attribute. The mesh layout and the storage-field layout are passed * in so the caller does not have to compute them twice. */ declare const readAttributeStorage: (reader: StructReader, parentOffset: number, storageField: FieldLayout) => MeshAttributeRaw[]; /** * Returns the attribute's payload as a typed array sized for `length * channels`. * Returns `undefined` for unsupported types. */ declare const readAttributeAsFloats: (reader: StructReader, attr: MeshAttributeRaw) => Float32Array | undefined; declare const readAttributeAsInt32: (reader: StructReader, attr: MeshAttributeRaw) => Int32Array | undefined; declare const readAttributeAsUint8: (reader: StructReader, attr: MeshAttributeRaw) => Uint8Array | undefined; /** Values of `IDProperty.type` for Blender 5+. */ declare const IDP_TYPE: { readonly STRING: 0; readonly INT: 1; readonly FLOAT: 2; readonly ARRAY: 5; readonly GROUP: 6; readonly ID: 7; readonly DOUBLE: 8; readonly IDPARRAY: 9; readonly BOOLEAN: 10; }; /** String form of the IDProperty type, mirroring the `IDP_TYPE` keys. */ type IDPropertyTypeName = keyof typeof IDP_TYPE; type IDPropertyValue = string | number | boolean | number[] | boolean[] | { [key: string]: IDPropertyValue; } | { __idRef: string | null; } | IDPropertyValue[]; /** * Reads the `ID.properties` group attached to an ID datablock and returns its * children as a plain object. Returns `{}` when the ID has no custom properties. */ declare const readCustomProperties: (reader: StructReader, idOffset: number) => Record; /** * Companion to `readCustomProperties`: for each top-level key, returns the * original `IDP_TYPE` (as a string name). Lets callers distinguish e.g. an * INT `5` from a FLOAT `5.0` — both collapse to the same JS number in the * value map. Nested groups appear as `'GROUP'` without their inner types. */ declare const readCustomPropertyTypes: (reader: StructReader, idOffset: number) => Record; /** * Internal-use raw decoder, exposed for callers that already have an * IDProperty offset (e.g. inspecting bNodeTree.layer_properties). */ declare const decodeIDPropertyAt: (reader: StructReader, offset: number, anchor: number) => IDPropertyValue; interface DeformWeight { groupIndex: number; weight: number; } interface DeformVertex { totalWeight: number; weights: DeformWeight[]; } interface Mesh { /** Blender datablock name with the leading "ME" prefix stripped. */ name: string; vertexCount: number; edgeCount: number; faceCount: number; cornerCount: number; /** Flat XYZ vertex positions (length = vertexCount * 3). */ vertices: Float32Array; /** Per-vertex normals derived from connected face normals (length = vertexCount * 3). */ vertexNormals: Float32Array; /** Per-face flat normals (length = faceCount * 3). */ faceNormals: Float32Array; /** Offset table for faces; offsets[i] is the first corner of face i, offsets[faceCount] is total corners. */ faceOffsets: Uint32Array; /** Per-corner vertex index. */ cornerVertices: Uint32Array; /** Per-corner edge index, when present. */ cornerEdges?: Uint32Array; /** Per-face material index (length = faceCount). All zero if absent. */ materialIndices: Uint32Array; /** Names of the materials slots, in order. */ materialSlotNames: string[]; /** UV maps, keyed by attribute name (CD_PROP_FLOAT2 on CORNER domain). */ uvMaps: Record; /** Float vertex colour layers (CD_PROP_COLOR on POINT or CORNER domain). */ vertexColors: Record; /** Byte (sRGB-encoded) vertex colour layers (CD_PROP_BYTE_COLOR). */ vertexByteColors: Record; /** Triangulated face indices (length = trianglesCount * 3). */ triangles: Uint32Array; /** All extra attributes by name; same MeshAttributeRaw entries as in extra. */ attributes: Record; /** Vertex group names from `vertex_group_names`. */ vertexGroupNames: string[]; /** Per-vertex weights, when the mesh has any. */ dvert?: DeformVertex[]; /** User-defined custom properties on this datablock. */ customProperties: Record; /** Original `IDP_TYPE` for each top-level custom property (parallel to `customProperties`). */ customPropertyTypes: Record; } /** * Pulls every `Mesh` datablock out of the parsed file and returns a clean, * triangulated, typed-array view of each. */ declare const extractMeshes: (data: BlendFileData) => Mesh[]; interface ShaderSocket { name: string; identifier: string; /** Decoded socket default value (number, [r,g,b,a], etc.). `undefined` when not stored. */ defaultValue?: number | number[] | string | boolean; /** When connected, the upstream node + socket. */ linkedFrom?: { nodeName: string; socketName: string; }; } interface ShaderNode { name: string; /** Blender's idname, e.g. `ShaderNodeBsdfPrincipled`, `ShaderNodeTexImage`. */ idname: string; type: number; inputs: ShaderSocket[]; outputs: ShaderSocket[]; /** When the node has an `ID *id` linked (e.g. an Image Texture's image), this is its name. */ linkedDataName?: string; } interface ShaderGraph { nodes: ShaderNode[]; /** Convenience: the first Principled BSDF found, with its inputs distilled. */ principled?: PrincipledBSDF; } interface PrincipledBSDF { nodeName: string; baseColor: [number, number, number, number]; metallic: number; roughness: number; ior: number; alpha: number; emissionColor: [number, number, number, number]; emissionStrength: number; normalStrength?: number; /** Image name connected to Base Color, if any. */ baseColorImage?: string; /** Image name connected to Normal (via a Normal Map node), if any. */ normalImage?: string; /** Image name connected to Roughness, if any. */ roughnessImage?: string; /** Image name connected to Metallic, if any. */ metallicImage?: string; } /** * Reads a Material's node tree (if any) and returns the flat node list plus a * distilled Principled BSDF view. */ declare const readMaterialShaderGraph: (data: BlendFileData, materialBlockOffset: number) => ShaderGraph | undefined; interface Material { name: string; diffuse: [number, number, number, number]; specular: [number, number, number]; metallic: number; roughness: number; /** True when this material uses a node tree (modern Blender always does). */ hasNodeTree: boolean; /** Parsed shader graph, when the material has a node tree. */ shader?: ShaderGraph; customProperties: Record; /** Original `IDP_TYPE` for each top-level custom property (parallel to `customProperties`). */ customPropertyTypes: Record; } declare const extractMaterials: (data: BlendFileData) => Material[]; interface SceneObject { name: string; /** Object type code (OB_MESH=1, OB_CURVE=2, OB_ARMATURE=25, …). */ type: number; location: [number, number, number]; /** XYZ Euler rotation in radians (only meaningful when rotationMode is 1..6). */ rotation: [number, number, number]; scale: [number, number, number]; /** Local-to-world matrix as a float[16], column-major. Composed from * loc/rot/scale + parent chain — Blender 5 no longer caches `obmat` to disk. */ worldMatrix: Float32Array; /** * Blender's `rotmode`. 0 = quaternion, 1..6 = Euler (XYZ, XZY, YXZ, YZX, * ZXY, ZYX), -1 = axis-angle. */ rotationMode: number; /** Name of the linked ID datablock, e.g. the mesh that backs this object. */ dataName?: string; /** Parent object name, when set. */ parentName?: string; customProperties: Record; /** Original `IDP_TYPE` for each top-level custom property (parallel to `customProperties`). */ customPropertyTypes: Record; } declare const OB_TYPE: { readonly EMPTY: 0; readonly MESH: 1; readonly CURVE: 2; readonly SURF: 3; readonly FONT: 4; readonly MBALL: 5; readonly LAMP: 10; readonly CAMERA: 11; readonly SPEAKER: 12; readonly LIGHTPROBE: 13; readonly LATTICE: 22; readonly ARMATURE: 25; readonly GPENCIL: 26; }; declare const extractObjects: (data: BlendFileData) => SceneObject[]; interface Bone { name: string; /** Head position in armature space. */ head: [number, number, number]; /** Tail position in armature space. */ tail: [number, number, number]; /** Roll angle (radians). */ roll: number; /** 4x4 rest-pose matrix in armature space (row-major float[16]). */ armatureMatrix: Float32Array; /** Length value computed by Blender. */ length: number; children: Bone[]; } interface Armature { name: string; bones: Bone[]; customProperties: Record; /** Original `IDP_TYPE` for each top-level custom property (parallel to `customProperties`). */ customPropertyTypes: Record; } declare const extractArmatures: (data: BlendFileData) => Armature[]; declare const LIGHT_TYPE: { readonly POINT: 0; readonly SUN: 1; readonly SPOT: 2; readonly AREA: 4; }; declare const AREA_SHAPE: { readonly SQUARE: 0; readonly RECTANGLE: 1; readonly DISK: 4; readonly ELLIPSE: 5; }; type LightTypeName = 'point' | 'sun' | 'spot' | 'area' | 'unknown'; type AreaShapeName = 'square' | 'rectangle' | 'disk' | 'ellipse' | 'unknown'; interface Light { name: string; type: LightTypeName; /** Linear RGB triple. */ color: [number, number, number]; /** Energy / strength. */ energy: number; /** Soft-shadow radius. */ radius: number; spotSize?: number; spotBlend?: number; sunAngle?: number; areaShape?: AreaShapeName; /** Area X size, or X and Y for rectangle/ellipse. */ areaSize?: [number] | [number, number]; useNodes: boolean; customProperties: Record; /** Original `IDP_TYPE` for each top-level custom property (parallel to `customProperties`). */ customPropertyTypes: Record; } declare const extractLights: (data: BlendFileData) => Light[]; declare const CAMERA_TYPE: { readonly PERSPECTIVE: 0; readonly ORTHOGRAPHIC: 1; readonly PANORAMIC: 2; }; declare const SENSOR_FIT: { readonly AUTO: 0; readonly HORIZONTAL: 1; readonly VERTICAL: 2; }; type CameraTypeName = 'perspective' | 'orthographic' | 'panoramic' | 'unknown'; type SensorFitName = 'auto' | 'horizontal' | 'vertical' | 'unknown'; interface Camera { name: string; type: CameraTypeName; /** Focal length in mm (perspective). */ lens: number; sensorWidth: number; sensorHeight: number; sensorFit: SensorFitName; /** Half-size of the orthographic view (orthographic only). */ orthoScale: number; clipStart: number; clipEnd: number; shiftX: number; shiftY: number; customProperties: Record; /** Original `IDP_TYPE` for each top-level custom property (parallel to `customProperties`). */ customPropertyTypes: Record; } declare const extractCameras: (data: BlendFileData) => Camera[]; declare const IMAGE_SOURCE: { readonly FILE: 0; readonly SEQUENCE: 1; readonly MOVIE: 2; readonly GENERATED: 3; readonly VIEWER: 4; readonly TILED: 5; }; type ImageSourceName = 'file' | 'sequence' | 'movie' | 'generated' | 'viewer' | 'tiled' | 'unknown'; interface Image { name: string; /** Filepath as written in the blend; may be relative (e.g. `//tex.png`). */ filepath: string; source: ImageSourceName; /** Generated image type / size (only meaningful when source === 'generated'). */ generatedWidth: number; generatedHeight: number; /** Raw bytes of the embedded file (when image data is packed into the blend). */ packed?: Uint8Array; customProperties: Record; /** Original `IDP_TYPE` for each top-level custom property (parallel to `customProperties`). */ customPropertyTypes: Record; } declare const extractImages: (data: BlendFileData) => Image[]; interface Collection { name: string; /** Names of objects directly placed in this collection. */ objectNames: string[]; /** Sub-collections (recursive). */ children: Collection[]; customProperties: Record; /** Original `IDP_TYPE` for each top-level custom property (parallel to `customProperties`). */ customPropertyTypes: Record; } interface Scene { name: string; /** Linked active-camera object name, if set. */ cameraObject?: string; frameStart: number; frameEnd: number; frameCurrent: number; /** Effective FPS: `fpsNumerator / fpsDenominator`. */ fps: number; resolutionX: number; resolutionY: number; /** Render-resolution percentage (100 = full). */ resolutionPercentage: number; /** Master scene collection — the root of the scene's collection tree. */ rootCollection?: Collection; customProperties: Record; /** Original `IDP_TYPE` for each top-level custom property (parallel to `customProperties`). */ customPropertyTypes: Record; } declare const extractScenes: (data: BlendFileData) => Scene[]; /** Flat list of every top-level Collection (`GR`) datablock. */ declare const extractCollections: (data: BlendFileData) => Collection[]; /** * Blender modifier type codes (from `DNA_modifier_types.h`). * Only the ones jsblender can evaluate are listed; the rest go through as * `{ type: 'unknown' }`. */ declare const MOD_TYPE: { readonly SUBSURF: 1; readonly LATTICE: 2; readonly CURVE: 3; readonly BUILD: 4; readonly MIRROR: 5; readonly DECIMATE: 6; readonly WAVE: 7; readonly ARMATURE: 8; readonly HOOK: 9; readonly SOFTBODY: 10; readonly BOOLEAN: 11; readonly ARRAY: 12; }; interface MirrorModifier { type: 'mirror'; name: string; axisX: boolean; axisY: boolean; axisZ: boolean; merge: boolean; tolerance: number; /** Name of an Object the mirror plane uses as its frame. Falls back to local origin. */ mirrorObjectName?: string; } interface ArrayModifier { type: 'array'; name: string; fitType: 'fixed' | 'length' | 'curve'; count: number; fitLength: number; useConstantOffset: boolean; useRelativeOffset: boolean; useObjectOffset: boolean; constantOffset: [number, number, number]; relativeOffset: [number, number, number]; /** Name of the offset object, when `useObjectOffset`. */ offsetObjectName?: string; } interface UnknownModifier { type: 'unknown'; name: string; typeCode: number; } type Modifier = MirrorModifier | ArrayModifier | UnknownModifier; /** * Walks `Object.modifiers` for every object in the file and returns a map * keyed by object name. Each entry is the modifier stack in evaluation order. */ declare const extractObjectModifiers: (data: BlendFileData) => Map; /** * Returns the modifier-evaluated mesh for an object — applying its Mirror and * Array modifiers in stack order. Unknown modifiers are skipped (the mesh * passes through unchanged). Returns `undefined` when the object isn't a mesh * or has no backing mesh datablock. */ declare const evaluateMesh: (data: BlendFileData, object: SceneObject, baseMeshes?: Mesh[]) => Mesh | undefined; /** Convenience: evaluate every mesh object in the file. Returns object-name → evaluated Mesh. */ declare const evaluateAllMeshes: (data: BlendFileData) => Map; /** * Parses a Blender SDNA field name like `*foo`, `(*bar)()`, or `baz[3][4]` * into its structural pieces. */ declare const parseFieldName: (raw: string) => ParsedFieldName; /** * Returns the size in bytes of a parsed field given the pointer size used by * the file and the size of its base type. */ declare const fieldSize: (parsed: ParsedFieldName, typeSize: number, pointerSize: number) => number; /** * Tiny matrix math used to compose Blender object world matrices. * * Conventions: * - All 4x4 matrices are column-major Float32Array(16), matching Blender's * internal `float mat[4][4]` layout. mat[0..3] = first column, mat[12..14] = * translation. * - All 3x3 matrices are column-major number[9]. * - All rotations use the right-hand rule (Blender's convention). */ type Mat4 = Float32Array; type Mat3 = number[]; type Vec3 = [number, number, number]; type Vec4 = [number, number, number, number]; declare const mat4Identity: () => Mat4; /** out = a * b (column-major: applies b first to a column vector, then a). */ declare const mat4Multiply: (a: Mat4, b: Mat4) => Mat4; /** Transform a 3D point by a column-major 4x4 (treating it as homogeneous w=1). */ declare const mat4TransformPoint: (m: Mat4, v: Vec3) => Vec3; /** Transform a direction vector (no translation, no normalisation). */ declare const mat4TransformDirection: (m: Mat4, v: Vec3) => Vec3; /** General 4x4 inverse (cofactor expansion). Returns identity if singular. */ declare const mat4Invert: (m: Mat4) => Mat4; interface ObjectTransformInputs { loc: Vec3; rot: Vec3; quat: Vec4; rotAxis: Vec3; rotAngle: number; size: Vec3; /** * Blender's `rotmode`: * 0 = quaternion * 1..6 = Euler (XYZ, XZY, YXZ, YZX, ZXY, ZYX) * -1 = axis-angle */ rotmode: number; } /** * Composes a local-to-parent transform matrix from a Blender object's stored * loc/rot/size + rotmode. Mirrors `loc_eulO_size_to_mat4` / * `loc_quat_size_to_mat4` / `loc_axisangle_size_to_mat4` from Blender's source. */ declare const composeObjectMatrix: (t: ObjectTransformInputs) => Mat4; /** Returns the upper-left 3x3 of a 4x4 (column-major). */ declare const mat4ToMat3: (m: Mat4) => Mat3; /** Transposes a column-major 3x3. */ declare const mat3Transpose: (m: Mat3) => Mat3; /** Inverts a column-major 3x3 (cofactor / det). Returns identity if singular. */ declare const mat3Invert: (m: Mat3) => Mat3; /** Applies a column-major 3x3 to a Vec3. */ declare const mat3TransformDirection: (m: Mat3, v: Vec3) => Vec3; export { AREA_SHAPE, ATTR_DOMAIN, ATTR_TYPE, type AreaShapeName, type Armature, type ArrayModifier, type AttrDomainName, type AttrDomainValue, type AttrTypeName, type AttrTypeValue, type BlendBlock, type BlendFileData, type BlendHeader, type Bone, CAMERA_TYPE, type Camera, type CameraTypeName, type Collection, type DeformVertex, type DeformWeight, type Endianness, type FieldLayout, IDP_TYPE, type IDPropertyTypeName, type IDPropertyValue, IMAGE_SOURCE, type Image, type ImageSourceName, LIGHT_TYPE, type Light, type LightTypeName, MOD_TYPE, type Mat3, type Mat4, type Material, type Mesh, type MeshAttributeRaw, type MirrorModifier, type Modifier, OB_TYPE, type ObjectTransformInputs, type ParsedFieldName, type PointerSize, type PrincipledBSDF, type SDNA, type SDNAField, type SDNAStruct, type SDNAStructLayout, SENSOR_FIT, type Scene, type SceneObject, type SensorFitName, type ShaderGraph, type ShaderNode, type ShaderSocket, type UnknownModifier, type Vec3, type Vec4, attributeElementSize, composeObjectMatrix, decodeIDPropertyAt, evaluateAllMeshes, evaluateMesh, extractArmatures, extractCameras, extractCollections, extractImages, extractLights, extractMaterials, extractMeshes, extractObjectModifiers, extractObjects, extractScenes, fieldSize, mat3Invert, mat3TransformDirection, mat3Transpose, mat4Identity, mat4Invert, mat4Multiply, mat4ToMat3, mat4TransformDirection, mat4TransformPoint, parseBlend, parseFieldName, readAttributeAsFloats, readAttributeAsInt32, readAttributeAsUint8, readAttributeStorage, readCustomProperties, readCustomPropertyTypes, readMaterialShaderGraph };