SwitchNodeBasePlugin
Example — Source Code — API Reference
Base plugin for creating object/node configurators. A switch node is a parent Object3D whose direct children represent swappable variants — only one child is visible at a time. This enables product configurators with interchangeable parts (e.g., watch straps, phone cases, shoe soles).
This is the base class included in the core threepipe package. For a ready-made UI with visual thumbnail grids, use SwitchNodePlugin from @threepipe/plugin-configurator.
Basic Setup
import {ThreeViewer, SwitchNodeBasePlugin} from 'threepipe'
const viewer = new ThreeViewer({canvas: document.getElementById('canvas')})
const switcher = viewer.addPluginSync(new SwitchNodeBasePlugin())
// Load a model with switch node groups
await viewer.load('product_configurator.glb')Defining Switch Nodes
A switch node maps a parent object name to a set of child variants:
// Add a switch node — 'strap_variants' is the name of a parent Object3D in the scene
// whose children are the individual strap options
switcher.addNode({
name: 'strap_variants', // Parent object name in scene
title: 'Watch Strap', // Display title in UI
selected: '', // Currently selected child (name or UUID)
camView: 'front', // Camera angle for preview thumbnails
camDistance: 1, // Camera distance multiplier for previews
})ObjectSwitchNode Interface
interface ObjectSwitchNode {
name: string // Name of the parent Object3D in the scene
title: string // Display title for UI
selected: string // Name or UUID of the currently selected child
camView: 'top' | 'bottom' | 'front' | 'back' | 'left' | 'right' | string
camDistance: number // Camera distance multiplier for preview snapshots
}Selecting Variants
// Select by child name
switcher.selectNode(variation, 'leather_strap')
// Select by child UUID
switcher.selectNode(variation, 'some-uuid-string')
// Select by index (0-based)
switcher.selectNode(variation, 0)
// Select without marking scene dirty
switcher.selectNode(variation, 1, false)When a child is selected:
- All sibling children are hidden (
visible = false) - The selected child is shown (
visible = true) - The scene is marked dirty with
frameFade: truefor smooth transitions (if FrameFadePlugin is active)
Reapply All
Reapply all currently selected variations (useful after scene changes):
switcher.reapplyAll()This iterates all variations and calls selectNode for each, using the stored selected value or index 0 as fallback.
Preview Thumbnails
Generate preview images of individual child variants:
// Get a base64 PNG data URL of a child object
const preview = switcher.getPreview(variation, childObject)
// Auto-generate and cache icons for all children
switcher.snapIcons()
// Enable automatic icon generation on UI refresh
switcher.autoSnapIcons = trueThe preview uses the variation's camView and camDistance to position the camera, rendering via snapObject().
Serialization
The plugin serializes its variations array and refreshScene setting (both via @serialize()). The applyOnLoad property controls deserialization behavior but is not itself serialized. The fromJSON method uses this.applyOnLoad to decide whether to call reapplyAll() after deserialization:
// Controls whether fromJSON reapplies variations (default: true, not serialized)
switcher.applyOnLoad = true
// Whether to call refreshScene when a node is selected (default: true, serialized)
// Disable if geometry changes are insignificant (e.g., color-only swaps)
switcher.refreshScene = trueWhen loading from JSON (e.g., embedded in a glTF config), all stored selections are automatically reapplied if applyOnLoad is true.
Plugin Integration
- PickingPlugin — Used for selection awareness. When a user picks an object that belongs to a switch node group, the UI shows editing options for that group.
- FrameFadePlugin — Provides smooth visual transitions when switching between variants.
UI Integration
The plugin exposes a uiConfig for use with TweakpaneUiPlugin or other UI renderers:
import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'
const ui = viewer.addPluginSync(new TweakpaneUiPlugin(true))
ui.setupPluginUi(SwitchNodeBasePlugin)The UI shows:
- List of all registered switch nodes with editable names
- "Add Node" button to create new switch node entries
- When a switch node child is selected via PickingPlugin: title editor, camera view dropdown, camera distance slider
Extended Plugin
For a complete visual configurator with clickable thumbnail grids overlaid on the viewer, use SwitchNodePlugin from @threepipe/plugin-configurator:
import {SwitchNodePlugin} from '@threepipe/plugin-configurator'
const switcher = viewer.addPluginSync(new SwitchNodePlugin())
switcher.enableEditContextMenus = true // Right-click to rename/remove switch nodesINFO
Both SwitchNodeBasePlugin and SwitchNodePlugin share PluginType = 'SwitchNodePlugin'. Only one can be active in a viewer at a time.
How It Works
- Each
ObjectSwitchNodeentry stores a parent objectnamethat is looked up in the scene selectNode()finds the parent, iterates its direct children, and toggles visibility so only the selected child is shown- Scene is marked dirty with
refreshSceneandframeFadeflags to notify other plugins (shadow baking, progressive rendering, etc.) - Preview generation computes a camera offset from the variation's
camView/camDistanceand delegates tosnapObject(), which renders the child within the scene - UI refresh is deferred to
postFrameto batch updates
Related Plugins
- MaterialConfiguratorBasePlugin — Sibling plugin for material property swapping
- GLTFKHRMaterialVariantsPlugin — Standard glTF material variants extension
