BBC's guide to development
  • General

    • About
    • Tools
    • Git(hub)
    • Showpad
    • Hosting
    • Maintenance
    • Security
    • Go live checklist
  • Front-end development

    • Bundlers
    • CSS/SCSS
    • Javascript
    • Vue
    • PHP
    • Mails
    • Dev Faq
  • Functions
  • Mixins
  • General

    • OOP Structure
  • Component Classes

    • Accordion
    • App
    • Component
    • HighwayApp
    • Popup
    • PNG Sequencer
    • Tab
  • Manager Classes

    • BountListenerMgr
    • Cache
    • Configuration
    • InViewStateMgr
    • Instance Manager
    • Event dispatcher
  • Factories

    • SwiperFactory
  • PDF

    • AssetLoader
    • BasePdfDoc
    • TemplatePdfDoc
    • CustomPdfDoc
  • Utility functions

    • canvas
    • Connection Status
    • css
    • dev
    • placeholder
    • dom
    • fetch
    • json
    • object
    • scroll
    • scrollbar
    • spreadsheets
    • string
    • url
  • General

    • ComponentMgr
    • ThreeJsViewer
  • Components

    • ComponentMgr
    • GltfModel
    • Snappable
    • Socket
    • ThreeJsViewer
    • ThreeJsViewerCamera
  • Loaders

    • ConfigurationSerializer
    • GltfBlockParser
  • Utils

    • CanvasInputAdapter
    • CollisionManager
    • SocketGridExpander
    • blender
    • headless
  • General

    • Troubleshooting
    • Legacy
  • Components

    • AssetBar
    • ConfigGenerator
    • ShowpadApp
  • Managers

    • Assets
    • AppsDb
    • Config
  • Utils

    • Connection Status
    • general
    • showpad-interactive
    • showpad-upload
  • Components

    • Accordion
    • BackButton
    • Breadcrumb
    • ByltButton
    • Hamburger
    • Icon
    • Logo
    • Loader
    • Modal
    • Popup
    • Prompt
    • ProgressBar
    • TextLoader
  • Composables

    • useDebugMode
    • useConnectionStatus
  • Utils

    • dom
    • props
  • General

    • General
    • Tracking
  • Components

    • Accordion
    • ActionButton
    • AssetItem
    • AssetList
    • BackButton
    • ConfigGenButton
    • Logo
    • Media
    • Modal
    • Popup
    • Prompt
    • SPButton
    • SPRouterView
    • SPTrackedRouterLink
    • TextLoader
    • View
  • Composables

    • useConnectionStatus
  • Stores

    • useAppsDbStore
    • useBreadcrumbStore
    • useShowpadAPIStore
    • useShowpadSDKStore
    • useSpConfigStore
    • useSpStore
    • useSpTrackingStore
  • The New Kit

    • General
    • Installation & Usage
    • ACF Blocks
    • PHPCS
    • Functions
    • Vite
    • WP Config
    • Staging Deployment
  • Best Practices

    • Page Structure
    • Fonts/Typography
  • Todo
GitHub
  • General

    • About
    • Tools
    • Git(hub)
    • Showpad
    • Hosting
    • Maintenance
    • Security
    • Go live checklist
  • Front-end development

    • Bundlers
    • CSS/SCSS
    • Javascript
    • Vue
    • PHP
    • Mails
    • Dev Faq
  • Functions
  • Mixins
  • General

    • OOP Structure
  • Component Classes

    • Accordion
    • App
    • Component
    • HighwayApp
    • Popup
    • PNG Sequencer
    • Tab
  • Manager Classes

    • BountListenerMgr
    • Cache
    • Configuration
    • InViewStateMgr
    • Instance Manager
    • Event dispatcher
  • Factories

    • SwiperFactory
  • PDF

    • AssetLoader
    • BasePdfDoc
    • TemplatePdfDoc
    • CustomPdfDoc
  • Utility functions

    • canvas
    • Connection Status
    • css
    • dev
    • placeholder
    • dom
    • fetch
    • json
    • object
    • scroll
    • scrollbar
    • spreadsheets
    • string
    • url
  • General

    • ComponentMgr
    • ThreeJsViewer
  • Components

    • ComponentMgr
    • GltfModel
    • Snappable
    • Socket
    • ThreeJsViewer
    • ThreeJsViewerCamera
  • Loaders

    • ConfigurationSerializer
    • GltfBlockParser
  • Utils

    • CanvasInputAdapter
    • CollisionManager
    • SocketGridExpander
    • blender
    • headless
  • General

    • Troubleshooting
    • Legacy
  • Components

    • AssetBar
    • ConfigGenerator
    • ShowpadApp
  • Managers

    • Assets
    • AppsDb
    • Config
  • Utils

    • Connection Status
    • general
    • showpad-interactive
    • showpad-upload
  • Components

    • Accordion
    • BackButton
    • Breadcrumb
    • ByltButton
    • Hamburger
    • Icon
    • Logo
    • Loader
    • Modal
    • Popup
    • Prompt
    • ProgressBar
    • TextLoader
  • Composables

    • useDebugMode
    • useConnectionStatus
  • Utils

    • dom
    • props
  • General

    • General
    • Tracking
  • Components

    • Accordion
    • ActionButton
    • AssetItem
    • AssetList
    • BackButton
    • ConfigGenButton
    • Logo
    • Media
    • Modal
    • Popup
    • Prompt
    • SPButton
    • SPRouterView
    • SPTrackedRouterLink
    • TextLoader
    • View
  • Composables

    • useConnectionStatus
  • Stores

    • useAppsDbStore
    • useBreadcrumbStore
    • useShowpadAPIStore
    • useShowpadSDKStore
    • useSpConfigStore
    • useSpStore
    • useSpTrackingStore
  • The New Kit

    • General
    • Installation & Usage
    • ACF Blocks
    • PHPCS
    • Functions
    • Vite
    • WP Config
    • Staging Deployment
  • Best Practices

    • Page Structure
    • Fonts/Typography
  • Todo
GitHub
  • GltfBlockParser

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 (typically gltf.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 by GLTFLoader.load() or GLTFLoader.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 the renderThumbnail helper
  • label / description: localised text for your palette

Notes

  • The parser is async (returns a Promise) 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. Always await it. For thumbnails, the recommended helper is renderThumbnail, which can render each block's Snappable template to a small PNG or data URL.
  • Multiple blocks with the same blockId are de-duplicated. The parser traverses the scene using Three.js's traverse(), which walks the object graph depth-first, parent before children. The first node that matches a given blockId wins; any later node with the same ID is skipped and a console.log message is written. In practice this means the block that appears highest in the Blender outliner hierarchy will win if duplicates exist.
  • console.log statements at the parse level are intentional for development visibility. They can be suppressed by overriding console.log in your build if needed.
Edit this page
Last Updated: 4/27/26, 12:56 PM
Contributors: Nicolas Jaenen