Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
webxr-polyfill/examples/reticle/index.html
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
168 lines (154 sloc)
5.5 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Reticle 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; | |
overflow: hidden; | |
position: fixed; | |
width: 100%; | |
height: 100vh; | |
-webkit-user-select: none; | |
user-select: none; | |
} | |
#target { | |
width: 100%; | |
height: 100%; | |
position: absolute; | |
} | |
.common-message { | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
font-size: 20px; | |
} | |
</style> | |
<link rel="stylesheet" href="../common.css"/> | |
<script src="../libs/three.min.js"></script> | |
<!-- | |
<script type="module" src="../../polyfill/XRPolyfill.js"></script> | |
<script nomodule src="../../dist/webxr-polyfill.js"></script> | |
--> | |
<script src="../../dist/webxr-polyfill.js"></script> | |
<script src="../common.js"></script> | |
</head> | |
<body> | |
<div id="target" /> | |
<div onclick="hideMe(this)" id="description"> | |
<h2>Reticle</h2> | |
<h5>(click to dismiss)</h5> | |
<p>Place a reticle on surfaces.</p> | |
</div> | |
<script> | |
/* | |
HitTestExample shows how to find surfaces or other features and place content relative to them. | |
In a production application, you would not create a separate anchor for every user action because | |
your application would quickly slow down tracking so many anchors. Instead, find an anchor | |
for groups of content that are positioned relative to some surface or other feature. | |
*/ | |
var model = new THREE.Matrix4(); | |
var tempPos = new THREE.Vector3(); | |
var tempQuat = new THREE.Quaternion(); | |
var tempScale = new THREE.Vector3(); | |
class HitTestExample extends XRExampleBase { | |
constructor(domElement){ | |
super(domElement, false) | |
this._tapEventData = null // Will be filled in on touch start and used in updateScene | |
// A message at the bottom of the screen that shows whether a surface has been found | |
this._messageEl = document.createElement('div') | |
this.el.appendChild(this._messageEl) | |
this._messageEl.style.position = 'absolute' | |
this._messageEl.style.bottom = '10px' | |
this._messageEl.style.left = '10px' | |
this._messageEl.style.color = 'white' | |
this._messageEl.style['font-size'] = '16px' | |
this._tapEventData = [ 0.5, 0.5 ] | |
this._hitAnchorOffset = null; | |
this.el.addEventListener('touchstart', this._onTouchStart.bind(this), false) | |
} | |
// Called during construction to allow the app to populate this.scene | |
initializeScene(){ | |
// Add a reticle at the scene | |
/*this.reticle = new THREE.Mesh( | |
new THREE.CubeGeometry(0.1, 0.1, 0.1, 30, 30, 30), | |
new THREE.MeshBasicMaterial({ color: '#DDFFDD' }) | |
)*/ | |
this.reticleParent = new THREE.Object3D() | |
this.reticle = new THREE.Mesh( | |
new THREE.RingGeometry(0.04, 0.05, 36, 64), | |
new THREE.MeshBasicMaterial({ color: '#DDFFDD' }) | |
) | |
/*this.reticle = new THREE.Mesh( | |
new THREE.SphereGeometry(0.01, 32, 32), | |
new THREE.MeshBasicMaterial({ color: '#DDFFDD' }) | |
)*/ | |
this.reticle.geometry.applyMatrix(new THREE.Matrix4().makeRotationX(THREE.Math.degToRad(-90))) | |
this.reticle.visible = false | |
this.reticleParent.add(this.reticle) | |
this.scene.add(this.reticleParent) | |
// Add a few lights | |
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) | |
} | |
// updated to use session.hitTest, since that's what WebXR looks like it will use | |
newSession() { | |
const x = this._tapEventData[0] | |
const y = this._tapEventData[1] | |
this.session.hitTest(x, y, XRPresentationFrame.HIT_TEST_TYPE_ALL).then(this.handleHit.bind(this)).catch(err => { | |
console.error('Error in hit test', err) | |
}) | |
} | |
handleHit(anchorOffset) { | |
if(anchorOffset === null){ | |
this._messageEl.innerHTML = 'miss' | |
} else { | |
this._messageEl.innerHTML = 'hit' | |
this.reticle.visible = true; | |
this._hitAnchorOffset = anchorOffset; | |
} | |
// keep testing! | |
const x = this._tapEventData[0] | |
const y = this._tapEventData[1] | |
window.setTimeout(() => { | |
this.session.hitTest(x, y, XRPresentationFrame.HIT_TEST_TYPE_ALL).then(this.handleHit.bind(this)).catch(err => { | |
console.error('Error in hit test', err) | |
}) | |
}) | |
} | |
// Called once per frame, before render, to give the app a chance to update this.scene | |
updateScene(frame){ | |
if (this._hitAnchorOffset) { | |
this.updateNodeFromAnchorOffset(frame, this.reticle, this._hitAnchorOffset) | |
} | |
} | |
// Save screen taps as normalized coordinates for use in this.updateScene | |
_onTouchStart(ev){ | |
if (!ev.touches || ev.touches.length === 0) { | |
console.error('No touches on touch event', ev) | |
return | |
} | |
//save screen coordinates normalized to -1..1 (0,0 is at center and 1,1 is at top right) | |
this._tapEventData = [ | |
ev.touches[0].clientX / window.innerWidth, | |
ev.touches[0].clientY / window.innerHeight | |
] | |
} | |
} | |
window.addEventListener('DOMContentLoaded', () => { | |
setTimeout(() => { | |
try { | |
window.pageApp = new HitTestExample(document.getElementById('target')) | |
} catch(e) { | |
console.error('page error', e) | |
} | |
}, 1000) | |
}) | |
</script> | |
</body> | |
</html> |