Permalink
Fetching contributors…
Cannot retrieve contributors at this time
162 lines (146 sloc) 5.13 KB
<html>
<head>
<title>Light 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="../common.js"></script>
</head>
<body>
<div id="target" />
<div onclick="hideMe(this)" id="description">
<h2>Light</h2>
<h5>(click to dismiss)</h5>
<p>Place a reticle on surfaces with light (only works with iOS viewer).</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.RingGeometry(0.04, 0.05, 36, 64),
new THREE.MeshStandardMaterial({ color: '#ffcc00' })
)
this.reticle.geometry.applyMatrix(new THREE.Matrix4().makeRotationX(THREE.Math.degToRad(-90)))
this.reticle.visible = false
this.scene.add(this.reticle)
// Add a few lights
this.ambientLight = new THREE.AmbientLight('#f8f8f8', 1);
this.scene.add(this.ambientLight);
this.directionalLight = new THREE.DirectionalLight('#f8f8f8', 0.5);
this.directionalLight.position.set(0, 10, 0);
this.scene.add(this.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)
}
if(frame.hasLightEstimate){
this.ambientLight.intensity = frame.lightEstimate;
this.directionalLight.intensity = frame.lightEstimate * 0.5;
}
}
// 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>