World Tracking — Babylon.js
Integration of Monolook World with Babylon.js for surface detection and 3D content placement.
Requirements
- Babylon.js loaded via CDN (
window.BABYLON) or as npm module - Monolook World license key
- HTTPS + Chrome on Android, or Monolook App / AppClip on iOS
HTML setup
html
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<canvas id="scene"></canvas>Setup
js
import { Monolook } from 'monolook/world'
const BABYLON = window.BABYLON
const canvas = document.getElementById('scene')
const engine = new BABYLON.Engine(canvas, true, {
alpha: true,
premultipliedAlpha: false,
preserveDrawingBuffer: false,
stencil: true,
})
const scene = new BABYLON.Scene(engine)
scene.clearColor = new BABYLON.Color4(0.2, 0.2, 0.2, 1)
scene.useRightHandedSystem = true
const camera = new BABYLON.FreeCamera('camera', new BABYLON.Vector3(0, 1.2, 3), scene)
camera.minZ = 0.01
camera.maxZ = 100
camera.setTarget(BABYLON.Vector3.Zero())
const light = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0, 1, 0), scene)
light.intensity = 2.4
const cube = BABYLON.MeshBuilder.CreateBox('cube', { size: 0.35 }, scene)
cube.setEnabled(false)
const monolook = new Monolook({
adapter: 'babylon',
BABYLON,
engine,
scene,
camera,
domOverlayRoot: document.getElementById('dom_overlay'),
})
useRightHandedSystem = trueis required for correct coordinate alignment.
Events and start
js
monolook.on('surfacefound', () => setStatus('Surface found — tap to place'))
monolook.on('select', placeCube)
monolook.on('sessionend', resetAfterSession)
await monolook.start({ mode: 'surface', licenseKey: '<WORLD_LICENSE_KEY>' })
cube.setEnabled(false)
monolook.startTracking()
monolook.setRenderLoop(() => monolook.updateTracking())
await monolook.enterAR()Placement
js
function placeCube() {
if (!monolook.isPresenting() || isPlaced) return
const pose = monolook.getIndicatorPose()
if (!pose?.visible) return
isPlaced = true
cube.position.set(pose.position.x, pose.position.y, pose.position.z)
cube.setEnabled(true)
monolook.pauseTracking()
monolook.setIndicatorVisible(false)
}Complete example
js
import { Monolook } from 'monolook/world'
const BABYLON = window.BABYLON
const canvas = document.getElementById('scene')
const engine = new BABYLON.Engine(canvas, true, { alpha: true, premultipliedAlpha: false, stencil: true })
const scene = new BABYLON.Scene(engine)
scene.clearColor = new BABYLON.Color4(0.2, 0.2, 0.2, 1)
scene.useRightHandedSystem = true
const camera = new BABYLON.FreeCamera('camera', new BABYLON.Vector3(0, 1.2, 3), scene)
camera.minZ = 0.01
camera.setTarget(BABYLON.Vector3.Zero())
new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0, 1, 0), scene).intensity = 2.4
const cube = BABYLON.MeshBuilder.CreateBox('cube', { size: 0.35 }, scene)
cube.setEnabled(false)
const monolook = new Monolook({
adapter: 'babylon',
BABYLON, engine, scene, camera,
domOverlayRoot: document.getElementById('dom_overlay'),
})
let isPlaced = false
monolook.on('surfacefound', () => !isPlaced && setStatus('Surface found — tap to place'))
monolook.on('select', placeCube)
monolook.on('sessionend', () => {
isPlaced = false
cube.setEnabled(true)
scene.render()
})
async function startAR() {
await monolook.start({ mode: 'surface', licenseKey: '<WORLD_LICENSE_KEY>' })
isPlaced = false
cube.setEnabled(false)
monolook.startTracking()
monolook.setRenderLoop(() => monolook.updateTracking())
await monolook.enterAR()
}
function placeCube() {
if (!monolook.isPresenting() || isPlaced) return
const pose = monolook.getIndicatorPose()
if (!pose?.visible) return
isPlaced = true
cube.position.set(pose.position.x, pose.position.y, pose.position.z)
cube.setEnabled(true)
monolook.pauseTracking()
monolook.setIndicatorVisible(false)
}
document.getElementById('startButton').addEventListener('click', startAR)
window.addEventListener('pointerup', placeCube)
engine.runRenderLoop(() => { if (!monolook.isPresenting()) scene.render() })