GltfBlockParser
Parses a loaded GLTF object and extracts all blocks as Snappable instances. Stateless — all methods are static. No DOM dependency.
Warning
Meant to be used with ComponentMgr only.
Getting started
import { GltfBlockParser } from './configurator';
// Always call copyExtrasToUserData first
GltfBlockParser.copyExtrasToUserData(gltf.scene);
const { blocks, blocksData } = await GltfBlockParser.parse(gltf);
Parsing Flow
Blocks with no sockets AND no geometry are excluded from blocks but still appear in blocksData with hasError: true so you can display a warning in the UI.
API
Methods
GltfBlockParser.copyExtrasToUserData(object3d)
Flattens GLTF extras into userData on every node in the scene graph. The GLTFLoader sometimes stores custom properties inside node.userData.extras rather than directly on node.userData — this method normalises that.
Parameters
object3d: The root scene node (typicallygltf.scene)
Note
Skips the keys M3 and MM (Blender-internal metadata)
Call this before parse(). If you skip it, blocks and sockets authored with the standard Blender GLTF exporter may not be found.
GltfBlockParser.parse(gltf) → Promise<{ blocks, blocksData }>
Traverses the GLTF scene, finds all block nodes, and creates a Snappable for each one.
Parameters
gltf: The object returned byGLTFLoader.load()orGLTFLoader.loadAsync()
Returns
Promise resolving to:
{
blocks: Map<string, Snappable>, // keyed by blockId
blocksData: Array<BlockData>, // for UI rendering
}
Return Types
blocks: Map<string, Snappable>
Each entry maps a blockId string to the Snappable template for that block. Use this map to get a Snappable instance when the user picks a block:
const snappable = blocks.get('leg-short');
componentMgr.setCurrent(snappable);
blocksData: BlockData[]
An array of plain objects for driving your UI palette (block list, thumbnails, etc.):
{
blockId: string, // e.g. "leg-short"
category: string | null, // from userData.category on the block node
socketCount: number, // number of Socket instances
sockets: [
{
index: number, // 0-based index in snappable.sockets
name: string, // socket group name from Blender
categories: string[], // parsed category strings
}
],
hasError: boolean, // true if Snappable construction failed
errorMessage: string | null // error details if hasError is true
}
You can extend each BlockData entry with your own UI fields such as:
thumbnailUrl: data URL generated via therenderThumbnailhelperlabel/description: localised text for your palette
Notes
- The parser is
async(returns aPromise) for future-proofing. Currently all work is synchronous, but the signature is async so that thumbnail generation, lazy geometry decoding, or remote asset fetching can be inserted into the pipeline in the future without breaking existing call sites. Alwaysawaitit. For thumbnails, the recommended helper isrenderThumbnail, which can render each block'sSnappabletemplate to a small PNG or data URL. - Multiple blocks with the same
blockIdare de-duplicated. The parser traverses the scene using Three.js'straverse(), which walks the object graph depth-first, parent before children. The first node that matches a givenblockIdwins; any later node with the same ID is skipped and aconsole.logmessage is written. In practice this means the block that appears highest in the Blender outliner hierarchy will win if duplicates exist. console.logstatements at theparselevel are intentional for development visibility. They can be suppressed by overridingconsole.login your build if needed.