ThreeAdapter
Wires XRSessionManager to a Three.js renderer
import { ThreeAdapter } from '@multisetai/vps/three';Integrates XRSessionManager with a Three.js scene. Runs the XR render loop, synchronizes the camera each frame, downloads the map mesh on successful localization, and provides a worldFromMap matrix for content placement.
Constructor
new ThreeAdapter(options: IThreeAdapterOptions)Options
session
XRSessionManager
Required
Session manager
renderer
THREE.WebGLRenderer
Required
Three.js renderer. The adapter manages renderer.xr itself, so you do not need to enable it.
scene
THREE.Scene
Required
Three.js scene
camera
THREE.PerspectiveCamera
Required
Three.js camera
showMesh
boolean
false
Download and add the map mesh to the scene after localization
showGizmo
boolean
true
Show a transform gizmo at the map origin after localization
showObjectMeshes
boolean
false
Download and display 3D outline meshes for detected objects
useDefaultButton
boolean
true
Mount the built-in START AR / STOP AR button
buttonContainer
HTMLElement
—
Element to append the button to. Defaults to overlayRoot or document.body.
onButtonCreated
(button: HTMLButtonElement) => void
—
Called when the button is created
onXRFrame
(event: IXRFrameEvent) => void
—
Called every XR frame after camera sync, before rendering
onLocalizationSuccess
(result: ILocalizeAndMapDetails, worldFromMap: THREE.Matrix4) => void
—
Called after successful localization
onObjectMeshLoaded
(objectCode: string) => void
—
Called when an object mesh finishes loading. Requires showObjectMeshes: true.
Static Methods
ThreeAdapter.isSupported()
Promise<boolean>
Check if the browser supports immersive-ar
Instance Methods
initialize(buttonContainer?)
HTMLButtonElement | null
Start the preview loop, attach resize handler, and mount the AR button
startSession()
Promise<void>
Start the AR session. Must be called from a user gesture handler.
stopSession()
void
Stop the active session
localizeFrame()
Promise<ILocalizeAndMapDetails | null>
Capture and localize one frame
trackObjects()
Promise<IObjectTrackingResponse | null>
Capture and run object detection
isActive()
boolean
Whether an AR session is running
clearObjectMeshes()
void
Remove all loaded object meshes from the scene
dispose()
void
End session, remove listeners, release resources
Properties
isLocalizing
boolean
Whether localization or tracking is in progress
Events and Scene Access
The onLocalizationSuccess and onXRFrame options are single-slot: setting one replaces it. Use the listeners below when more than one part of your app needs to react. Anything layered on the adapter, including MapSpace and Navigation, uses them, so they compose.
Every add*Listener returns its own unsubscribe function, which is usually easier than keeping a reference for the matching remove*Listener.
addLocalizationListener(fn)
() => void
fn(result, worldFromMap) after every successful localization
removeLocalizationListener(fn)
void
Unsubscribe. Equivalent to calling the returned function.
addSessionStartListener(fn)
() => void
Fires when the AR session starts
removeSessionStartListener(fn)
void
Unsubscribe
addSessionEndListener(fn)
() => void
Fires when the AR session ends
removeSessionEndListener(fn)
void
Unsubscribe
addFrameListener(fn)
() => void
fn(event) every XR frame, after camera matrices are synced and before the scene renders, so anything you move lands in the same frame
removeFrameListener(fn)
void
Unsubscribe
waitForLocalization()
Promise<ILocalizeAndMapDetails>
Resolves immediately if the current session has already localized, otherwise on the next success. Never rejects.
getLastLocalization()
ILocalizationSnapshot | null
The current session's most recent result and its worldFromMap. Cleared when the session ends, so a stale pose can never be replayed into a new session.
getScene()
THREE.Scene
The active scene
getCamera()
THREE.Camera
The XR-driven camera
waitForLocalization() replaces the usual "do this once we are localized" callback plumbing:
Read the camera pose with camera.getWorldPosition(target) or camera.matrixWorld, never camera.position. During a session the adapter writes matrixWorld directly and leaves position and quaternion untouched, so reading position returns a stale value.
IVpsAdapter
Both adapters satisfy the same IVpsAdapter contract, so a feature written against it works on either one and on any future adapter.
They satisfy it structurally, so neither declares implements. A compile-time guard in each entry point fails the build if one drifts from the interface. ILocalizationSnapshot is { result: ILocalizeAndMapDetails; worldFromMap: THREE.Matrix4 }.
The worldFromMap Matrix
onLocalizationSuccess receives a THREE.Matrix4 that converts map-local coordinates to Three.js world space. Use it to place objects at known positions within the map.
Last updated
Was this helpful?

