diff --git a/example/aframe/sandbox/index.html b/example/aframe/sandbox/index.html
index 25d059d..e699a70 100644
--- a/example/aframe/sandbox/index.html
+++ b/example/aframe/sandbox/index.html
@@ -18,13 +18,13 @@
light="defaultLightsEnabled: false">
-
+
-
+
@@ -73,8 +73,7 @@
-
-
+
diff --git a/src/3rd/js/aframe/index.js b/src/3rd/js/aframe/index.js
index 3120309..5f9e84f 100644
--- a/src/3rd/js/aframe/index.js
+++ b/src/3rd/js/aframe/index.js
@@ -139,14 +139,14 @@ window.AFRAME.registerComponent('xrf', {
let {mesh,clickHandler} = opts;
let createEl = function(c){
let el = document.createElement("a-entity")
- el.setAttribute("xrf-get",c.name ) // turn into AFRAME entity
+ el.setAttribute("xrf-get",c.name ) // turn into AFRAME entity
+ el.setAttribute("pressable", '' ) // detect click via hand-detection
el.setAttribute("class","ray") // expose to raycaster
- el.setAttribute("pressable", '') // detect hand-controller click
// respond to cursor via laser-controls (https://aframe.io/docs/1.4.0/components/laser-controls.html)
el.addEventListener("click", clickHandler )
el.addEventListener("mouseenter", mesh.userData.XRF.href.selected(true) )
el.addEventListener("mouseleave", mesh.userData.XRF.href.selected(false) )
- el.addEventListener("pressedstarted", clickHandler )
+ el.addEventListener("pressedended", clickHandler )
$('a-scene').appendChild(el)
}
createEl(mesh)
diff --git a/src/3rd/js/aframe/pressable.js b/src/3rd/js/aframe/pressable.js
new file mode 100644
index 0000000..15f1555
--- /dev/null
+++ b/src/3rd/js/aframe/pressable.js
@@ -0,0 +1,51 @@
+// this makes WebXR hand controls able to click things (by touching it)
+
+AFRAME.registerComponent('pressable', {
+ schema: {
+ pressDistance: {
+ default: 0.01
+ }
+ },
+ init: function() {
+ this.worldPosition = new THREE.Vector3();
+ this.handWorldPosition = new THREE.Vector3();
+ this.handEls = document.querySelectorAll('[hand-tracking-controls]');
+ this.pressed = false;
+
+ },
+ tick: function() {
+ var handEls = this.handEls;
+ var handEl;
+ var distance;
+ for (var i = 0; i < handEls.length; i++) {
+ handEl = handEls[i];
+ let indexTipPosition = handEl.components['hand-tracking-controls'].indexTipPosition
+ handEl.object3D.localToWorld( this.handWorldPosition )
+ this.handWorldPosition.add( indexTipPosition )
+
+ distance = this.calculateFingerDistance(this.handWorldPosition);
+ if( xrf.debug == 10 && this.el.id == "xrf-button_teleport_me_down_there" ){ debugger }
+
+ if (distance < this.data.pressDistance && distance !== 0.0 ) {
+ if (!this.pressed) {
+ this.el.emit('pressedstarted');
+ }
+ this.pressed = true;
+ return;
+ }
+ }
+ 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);
+ }
+});
diff --git a/src/3rd/js/aframe/xrf-get.js b/src/3rd/js/aframe/xrf-get.js
index 80ed250..e3d2620 100644
--- a/src/3rd/js/aframe/xrf-get.js
+++ b/src/3rd/js/aframe/xrf-get.js
@@ -37,10 +37,11 @@ window.AFRAME.registerComponent('xrf-get', {
mesh.scale.copy(world.scale)
mesh.setRotationFromQuaternion(world.quat);
}else{
- // lets create a dummy add function so that the mesh won't get reparented
+ // lets create a dummy add function so that the mesh won't get reparented during setObject3D
this.el.object3D.add = (a) => a
}
- this.el.setObject3D('mesh',mesh)
+ this.el.object3D = mesh //setObject3D('mesh',mesh)
+
if( !this.el.id ) this.el.setAttribute("id",`xrf-${mesh.name}`)
}else console.warn("xrf-get ignore: "+JSON.stringify(this.data))
}, evt && evt.timeout ? evt.timeout: 500)
diff --git a/src/3rd/js/aframe/xrf-pinchmove.js b/src/3rd/js/aframe/xrf-pinchmove.js
new file mode 100644
index 0000000..7eaf2e6
--- /dev/null
+++ b/src/3rd/js/aframe/xrf-pinchmove.js
@@ -0,0 +1,28 @@
+// poor man's way to move forward using hand gesture pinch
+
+window.AFRAME.registerComponent('xrf-pinchmove', {
+ schema:{
+ rig: {type: "selector"}
+ },
+ init: function(){
+
+ this.el.addEventListener("pinchended", () => {
+ // get the cameras world direction
+ let direction = new THREE.Vector3()
+ this.el.sceneEl.camera.getWorldDirection(direction);
+ // multiply the direction by a "speed" factor
+ direction.multiplyScalar(0.4)
+ // get the current position
+ var pos = player.getAttribute("position")
+ // add the direction vector
+ pos.x += direction.x
+ pos.z += direction.z
+ // set the new position
+ this.data.rig.setAttribute("position", pos);
+ // !!! NOTE - it would be more efficient to do the
+ // position change on the players THREE.Object:
+ // `player.object3D.position.add(direction)`
+ // but it would break "getAttribute("position")
+ })
+ },
+})
diff --git a/src/3rd/js/index.js b/src/3rd/js/index.js
index 068d034..c33dacf 100644
--- a/src/3rd/js/index.js
+++ b/src/3rd/js/index.js
@@ -38,19 +38,6 @@ xrf.detectCameraRig = function(opts){
}
}
-xrf.roundrobin = (frag, store) => {
- if( !frag.args || frag.args.length == 0 ) return 0
- if( !store.rr ) store.rr = {}
- let label = frag.fragment
- if( store.rr[label] ) return store.rr[label].next()
- store.rr[label] = frag.args
- store.rr[label].next = () => {
- store.rr[label].index = (store.rr[label].index + 1) % store.rr[label].length
- return store.rr[label].index
- }
- return store.rr[label].index = 0
-}
-
xrf.stats = () => {
// bookmarklet from https://github.com/zlgenuine/threejs_stats
(function(){
diff --git a/src/3rd/js/three/xrf/href.js b/src/3rd/js/three/xrf/href.js
index 6dcaa30..1119114 100644
--- a/src/3rd/js/three/xrf/href.js
+++ b/src/3rd/js/three/xrf/href.js
@@ -35,7 +35,11 @@ xrf.frag.href = function(v, opts){
let click = mesh.userData.XRF.href.exec = (e) => {
- if( !mesh.material.visible ) return // ignore invisible nodes
+ if( !mesh.material || !mesh.material.visible ) return // ignore invisible nodes
+ if( e.type == "pressedended" && !e.detail ){
+ console.dir(e)
+ return
+ }
// bubble up!
mesh.traverseAncestors( (n) => n.userData && n.userData.href && n.dispatchEvent({type:e.type,data:{}}) )
@@ -59,7 +63,7 @@ xrf.frag.href = function(v, opts){
}
let selected = mesh.userData.XRF.href.selected = (state) => () => {
- if( !mesh.material.visible && !mesh.isSRC ) return // ignore invisible nodes
+ if( (!mesh.material && !mesh.material.visible) && !mesh.isSRC ) return // ignore invisible nodes
if( mesh.selected == state ) return // nothing changed
xrf.interactive.objects.map( (o) => {