Revision control

Copy as Markdown

<html>
<head>
<title>AR anchor example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body, html {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
-webkit-user-select: none;
user-select: none;
}
#target {
width: 100%;
height: 100%;
position: absolute;
}
.add-object-button {
position: absolute;
bottom: 20px;
left: 50%;
transform: translate(-50%, -50%);
font-size: 2em;
padding: 10px;
}
.common-message {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 20px;
}
</style>
<script src="../libs/three.js"></script>
<script type="module" src="../../polyfill/XRPolyfill.js"></script>
<script nomodule src="../../dist/webxr-polyfill.js"></script>
<script src="../common.js"></script>
</head>
<body>
<div id="target" />
<script>
class ARAnchorExample extends XRExampleBase {
constructor(domElement){
super(domElement, false)
this.anchorsToAdd = [] // { node, x, y, z }
this.addObjectButton = document.createElement('button')
this.addObjectButton.setAttribute('class', 'add-object-button')
this.addObjectButton.innerText = 'Add anchor'
this.el.appendChild(this.addObjectButton)
this.addObjectButton.addEventListener('click', ev => {
this.addAnchoredModel(this.createSceneGraphNode(), 0, 0, -0.75)
})
}
// Called during construction
initializeScene(){
this.scene.add(new THREE.AmbientLight('#FFF', 0.2))
let directionalLight = new THREE.DirectionalLight('#FFF', 0.6)
directionalLight.position.set(0, 10, 0)
this.scene.add(directionalLight)
}
createSceneGraphNode(){
let geometry = new THREE.BoxBufferGeometry(0.1, 0.1, 0.1)
let material = new THREE.MeshPhongMaterial({ color: '#FF9999' })
return new THREE.Mesh(geometry, material)
}
/*
addAnchoredModel creates an anchor at (x,y,z) relative to the camera and positions the sceneGraphNode on the anchor from that point on
*/
addAnchoredModel(sceneGraphNode, x, y, z){
// Save this info for use during the next render frame
this.anchorsToAdd.push({
node: sceneGraphNode,
x: x, y: y, z: z
})
}
// Called once per frame
updateScene(frame){
const headCoordinateSystem = frame.getCoordinateSystem(XRCoordinateSystem.HEAD_MODEL)
const trackerCoordinateSystem = frame.getCoordinateSystem(XRCoordinateSystem.TRACKER)
// Create anchors and start tracking them
for(let anchorToAdd of this.anchorsToAdd){
// Create an anchor that we'd like to add, relative to the current head position
const anchorCoordinates = new XRCoordinates(
this.session.display,
headCoordinateSystem,
[anchorToAdd.x, anchorToAdd.y, anchorToAdd.z]
)
const anchor = new XRAnchor(anchorCoordinates)
// Create the anchor and tell the base class to update the node with its position
const anchorUID = frame.addAnchor(anchor)
this.addAnchoredNode(new XRAnchorOffset(anchorUID), anchorToAdd.node)
}
this.anchorsToAdd = []
}
}
window.addEventListener('DOMContentLoaded', () => {
setTimeout(() => {
try {
window.pageApp = new ARAnchorExample(document.getElementById('target'))
} catch(e) {
console.error('page error', e)
}
}, 1000)
})
</script>
</body>
</html>