From c7e76c8efc0e9705adfca4a3b99b8a4cc20f6a9c Mon Sep 17 00:00:00 2001 From: Fabien Benetou Date: Mon, 6 May 2024 14:08:59 +0200 Subject: [PATCH] events based princh primary (rather than .addEventListener() --- index.html | 2 +- jxr-core.js | 141 ++++++++++++++++++++-------------------------------- 2 files changed, 55 insertions(+), 88 deletions(-) diff --git a/index.html b/index.html index 2bc6fc9..4bbe10e 100644 --- a/index.html +++ b/index.html @@ -8,7 +8,7 @@ - + diff --git a/jxr-core.js b/jxr-core.js index 58adfe1..c9c64fc 100644 --- a/jxr-core.js +++ b/jxr-core.js @@ -149,95 +149,62 @@ AFRAME.registerComponent('pinchsecondary', { } }); +// grouping and distance between last two pinches should be rewritten, simplified and more reliable AFRAME.registerComponent('pinchprimary', { // currently only 1 hand, the right one, should be switchable - -// consider instead https://github.com/AdaRoseCannon/handy-work/blob/main/README-AFRAME.md for specific poses -// or https://aframe.io/aframe/examples/showcase/hand-tracking/pinchable.js - - init: function () { - var el = this.el - this.el.addEventListener('pinchended', function (event) { - // if positioned close enough to a target zone, trigger action - // see own trigger-box component. Could use dedicated threejs helpers instead. - // https://github.com/Utopiah/aframe-triggerbox-component/blob/master/aframe-triggerbox-component.js#L66 - // could make trigger zones visible as debug mode - var closests = getClosestTargetElements( event.detail.position ) - //if (closests && closests.length > 0) // avoiding self reference - // setFeedbackHUD("close enough, could stack with "+ closests[1].el.getAttribute("value") ) - /* - somehow #box MUST exist, otherwise craches?! - */ - let dist = 100 - if ( document.querySelector("#box") ) - dist = event.detail.position.distanceTo( document.querySelector("#box").object3D.position ) - if (dist < .1){ - setFeedbackHUD("close enough, replaced shortcut with "+ selectedElement.getAttribute("value") ) - wristShortcut = selectedElement.getAttribute("value") - } - if (selectedElement){ - let content = selectedElement.getAttribute("value") - selectedElement.emit('released', {element:selectedElement, timestamp:Date.now(), primary:true}) - } - // unselect current target if any - selectedElement = null; - if ( groupingMode ) addToGroup( event.detail.position ) - selectionPinchMode = false - /* - setHUD( AFRAME.utils.coordinates.stringify( bbox.min ), - AFRAME.utils.coordinates.stringify( bbox.max ) ) - bbox.min.copy( zeroVector3 ) - bbox.man.copy( zeroVector3 ) - */ - setTimeout( _ => primaryPinchStarted = false, 200) // delay otherwise still activate on release - - var newPinchPos = new THREE.Vector3() - newPinchPos.copy(event.detail.position ) - pinches.push({position:newPinchPos, timestamp:Date.now(), primary:true}) - dl2p = distanceLastTwoPinches() - - }); - this.el.addEventListener('pinchmoved', function (event) { - // move current target if any - if (selectionPinchMode){ - bbox.max.copy( event.detail.position ) - if (!bbox.min.equal(zeroVector3)) - selectionBox.update(); - } - if (selectedElement && !groupingMode) { - selectedElement.setAttribute("position", event.detail.position) - document.querySelector("#rightHand").object3D.traverse( e => { - if (e.name == "ring-finger-tip"){ - selectedElement.object3D.rotation.copy( e.rotation ) - } - }) - // rotation isn't ideal with the wrist as tend not have wrist flat as we pinch - } - if (selectedElement) selectedElement.emit("moved") - }); - this.el.addEventListener('pinchstarted', function (event) { - primaryPinchStarted = true - if (!selectionPinchMode) bbox.max.copy( zeroVector3 ) - - //var clone = getClosestTargetElement( event.detail.position ).cloneNode() - // might want to limit cloning to unmoved element and otherwise move the cloned one - //AFRAME.scenes[0].appendChild( clone ) - //targets.push( clone ) - //selectedElement = clone - - selectedElement = getClosestTargetElement( event.detail.position ) - if (selectedElement) { - selectedElements.push({element:selectedElement, timestamp:Date.now(), primary:true}) - selectedElement.emit("picked") + events: { + pinchended: function (event) { + let closests = getClosestTargetElements( event.detail.position ) + let dist = 100 + if ( document.querySelector("#box") ) + dist = event.detail.position.distanceTo( document.querySelector("#box").object3D.position ) + if (dist < .1){ + setFeedbackHUD("close enough, replaced shortcut with "+ selectedElement.getAttribute("value") ) + wristShortcut = selectedElement.getAttribute("value") + } + if (selectedElement){ + let content = selectedElement.getAttribute("value") + selectedElement.emit('released', {element:selectedElement, timestamp:Date.now(), primary:true}) + } + // unselect current target if any + selectedElement = null; + if ( groupingMode ) addToGroup( event.detail.position ) + selectionPinchMode = false + setTimeout( _ => primaryPinchStarted = false, 200) // delay otherwise still activate on release + var newPinchPos = new THREE.Vector3() + newPinchPos.copy(event.detail.position ) + pinches.push({position:newPinchPos, timestamp:Date.now(), primary:true}) + dl2p = distanceLastTwoPinches() + }, + pinchmoved: function (event) { + if (selectionPinchMode){ + bbox.max.copy( event.detail.position ) + if (!bbox.min.equal(zeroVector3)) + selectionBox.update(); + } + if (selectedElement && !groupingMode) { + selectedElement.setAttribute("position", event.detail.position) + document.querySelector("#rightHand").object3D.traverse( e => { + if (e.name == "ring-finger-tip"){ + selectedElement.object3D.rotation.copy( e.rotation ) + } + }) + // rotation isn't ideal with the wrist as tend not have wrist flat as we pinch + } + if (selectedElement) selectedElement.emit("moved") // consider adding as data selectedElement + }, + pinchstarted: function (event) { + primaryPinchStarted = true + if (!selectionPinchMode) bbox.max.copy( zeroVector3 ) + + selectedElement = getClosestTargetElement( event.detail.position ) + if (selectedElement) { + selectedElements.push({element:selectedElement, timestamp:Date.now(), primary:true}) + selectedElement.emit("picked") + } } - // is it truly world position? See https://github.com/aframevr/aframe/issues/5182 - // setFeedbackHUD( AFRAME.utils.coordinates.stringify( event.detail.position ) ) - // if close enough to a target among a list of potential targets, unselect previous target then select new - }); - }, - remove: function() { - // should remove event listeners here. Requires naming them. - } -}); + } + // should remove event listeners +}) // avoiding setOnDropFromAttribute() as it is not idiosyncratic and creates timing issues AFRAME.registerComponent('onreleased', { // changed from ondrop to be coherent with event name