throttle raycaster by distance for clickable objects + teleport with right hand

This commit is contained in:
Leon van Kammen 2024-03-06 10:31:40 +00:00
parent 9f14ed017d
commit 7e0d7ca7c1
5 changed files with 33 additions and 23 deletions

View File

@ -18,13 +18,13 @@
light="defaultLightsEnabled: false">
<a-entity id="player" movement-controls touch-controls wasd-controls="fly:false" look-controls>
<a-entity camera="fov:90" position="0 1.6 0" id="camera"></a-entity>
<a-entity id="left-hand" hand-tracking-controls="hand:left" laser-controls="hand: left" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: .floor" xrf-pinchmove="rig: #player">
<a-entity id="left-hand" hand-tracking-controls="hand:left" laser-controls="hand: left" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: .floor">
<a-entity rotation="-35 0 0" position="0 0.1 0" id="navigator">
<a-entity id="back" xrf-button="label: <; width:0.05; action: history.back()" position="-0.025 0 0" class="ray"></a-entity>
<a-entity id="next" xrf-button="label: >; width:0.05; action: history.forward()" position=" 0.025 0 0" class="ray"></a-entity>
</a-entity>
</a-entity>
<a-entity id="right-hand" hand-tracking-controls="hand:right" laser-controls="hand: right" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: .floor"></a-entity>
<a-entity id="right-hand" hand-tracking-controls="hand:right" laser-controls="hand: right" raycaster="objects:.ray" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: .floor" xrf-pinchmove="rig: #player"></a-entity>
</a-entity>
<a-entity id="home" xrf="index.glb" xrf-menu></a-entity>

Binary file not shown.

View File

@ -12,11 +12,27 @@ AFRAME.registerComponent('pressable', {
this.raycaster = new THREE.Raycaster()
this.handEls = document.querySelectorAll('[hand-tracking-controls]');
this.pressed = false;
this.distance = -1
// we throttle by distance, to support scenes with loads of clickable objects (far away)
this.tick = this.throttleByDistance( () => this.detectPress() )
},
tick: function() {
throttleByDistance: function(f){
return function(){
if( this.distance < 0 ) return f() // first call
if( !f.tid ){
let x = this.distance
let y = x*(x*0.05)*1000 // parabolic curve
f.tid = setTimeout( function(){
f.tid = null
f()
}, y )
}
}
},
detectPress: function(){
var handEls = this.handEls;
var handEl;
var distance;
let minDistance = 5
// compensate for xrf-get AFRAME component (which references non-reparented buffergeometries from the 3D model)
let object3D = this.el.object3D.child || this.el.object3D
@ -37,25 +53,19 @@ AFRAME.registerComponent('pressable', {
object3D.getWorldPosition(this.worldPosition)
this.distance = this.fingerWorldPosition.distanceTo(this.worldPosition)
distance = this.fingerWorldPosition.distanceTo(this.worldPosition)
minDistance = distance < minDistance ? distance : minDistance
if (intersects.length ){
this.pressed = true
this.el.emit('pressedstarted');
if( !this.pressed ){
this.el.emit('pressedstarted');
this.pressed = setTimeout( () => {
this.el.emit('pressedended');
this.pressed = null
},300)
}
}
}
if (this.pressed) {
this.el.emit('pressedended');
}
this.pressed = false;
},
calculateFingerDistance: function(fingerPosition) {
var el = this.el;
//worldPosition.copy(el.object3D.position);
el.object3D.updateMatrixWorld();
el.object3D.localToWorld(this.worldPosition);
if( xrf.debug == 10 && this.el.id == "xrf-button_teleport_me_down_there" ){ debugger }
return this.worldPosition.distanceTo(fingerPosition);
this.distance = minDistance
}
});

View File

@ -3,7 +3,7 @@ AFRAME.registerComponent('vconsole', {
//AFRAME.XRF.navigator.to("https://coderofsalvation.github.io/xrsh-media/assets/background.glb")
let aScene = AFRAME.scenes[0]
return
// return
document.head.innerHTML += `
<style type="text/css">
.vc-panel {

View File

@ -42,8 +42,8 @@ window.AFRAME.registerComponent('xrf-get', {
this.el.object3D.add = (a) => a
}
this.el.setObject3D('mesh',mesh)
this.el.object3D.child = mesh // keep reference (because .children will be empty)
this.el.setObject3D('mesh',mesh) // (doing this.el.object3D = mesh causes AFRAME to crash when resetting scene)
this.el.object3D.child = mesh // keep reference (because .children will be empty)
if( !this.el.id ) this.el.setAttribute("id",`xrf-${mesh.name}`)
}else console.warn("xrf-get ignore: "+JSON.stringify(this.data))