From 7e0d7ca7c1c6ea7d0d8acd10c43fde02af79b9c3 Mon Sep 17 00:00:00 2001 From: Leon van Kammen Date: Wed, 6 Mar 2024 10:31:40 +0000 Subject: [PATCH] throttle raycaster by distance for clickable objects + teleport with right hand --- example/aframe/sandbox/index.html | 4 +-- example/assets/index.glb | Bin 8657288 -> 8657308 bytes src/3rd/js/aframe/pressable.js | 46 ++++++++++++++++++------------ src/3rd/js/aframe/xrf-console.js | 2 +- src/3rd/js/aframe/xrf-get.js | 4 +-- 5 files changed, 33 insertions(+), 23 deletions(-) diff --git a/example/aframe/sandbox/index.html b/example/aframe/sandbox/index.html index e699a70..9b7556a 100644 --- a/example/aframe/sandbox/index.html +++ b/example/aframe/sandbox/index.html @@ -18,13 +18,13 @@ light="defaultLightsEnabled: false"> - + - + diff --git a/example/assets/index.glb b/example/assets/index.glb index 7254c3836171f289b2bd1e6a52bfec078bc060dd..12efcc56877c4cb9cb2f5f8e408bfa64a6cd821f 100644 GIT binary patch delta 3831 zcmbuBd#u-W8OQma!{Krc2Y%-qxrGQqfWSFFKlcj)f`GgbD{nI~fZRgE7e7>K{ zb9q1S=lM$Y#OTAI^RE4ySGSBBHR|y6FOE8MwDZuoLRU|YyQ9sgV3f;RnV78URZVT9 zw>tW0y^A(j%bGF9rEGGvDd*(0trkptt>BLkY;;Bi@Az0Bb|yGuRWwPv>~wFRYAUNz zP&xa=d6iNqS2d0Y6SyE0#<$^aM@Z0-b4R&8KvCA~Q4?0^iXu_n4XZiHPk>wVnC2=7Ky!rQwF=DCpSfAx!{j_6^$nJW$ z_rW>$>^ZP^&Jq*K7Z*<{Pb~VWg%wI$i-!TjYKJY)_~eqrp}xfs9g7qASKIx|#iyJ# z&RSAP?0L{hd~@KoJPgW6;qbnDdjsABV#<}3?FRXjz`7pQq z*#oo6t*ibxiR8oioGfLWy(yOuTx{sb1J;r#PXT*Zu3LS9jUgoqA8bgNUv6Dh*T{H#u*-nasr9?#uJy7 zXC5Do-WUbh&m*0r~GaXCqVQ88kQNv8b8 z#!C%$q?pAsnbr_N0XIhJ5St&6_T;niRYs z+tflvb*i&Bw-gOaO_M?sVG_#V%8tz!I|(Ngc2;E)eq{2NqQMq41F_Nwu(z(9xAg)R z>tLNG^4U_|E|qrM2VJCx>Q~01(QqTjBg?l#!GyV*^6*Y!Zz?z5dWl6XG-bvjaeR9xh}K*UAjDK@PYDvG5f z)O!iI$3QZhs9m~(!pnui7@ly%C?#5n_8|&kXhDWb zCM#&SiZ)i?-gT&#idHxw0g{)Ms}_H?dEEq);U7#3vTygX0g9=KM$yAi(mJK496UaK zXzG-rt9tb}W8^!0O)!Zhic*K_+zYvAC@BY|2i+58w`KotFO&nvdS;90z-NMpbYPx^ zXZ+AxXi4Z=b>PJ%9EV(q$O=OhX)JF)KCOO~GVZ9}{@q|pJ2C@zM02s|SBN%tClMqr zrE$@Yt@DxWp&_z{-tuFFmYEp2YWs;rMGxvp!ws~eTD|x5LE7T=snt_|_-oOvn^IJw zStQiS$!h4O&Z6CsjZ9lLvHao5)9s{$haA>d-#K-um_-d!@8Uc%tDE9RkN_e%(JuWQu@WIy+gb3o%NQmLY*S(_mBe&MRMPr3~o$ z(1amGv_PSmTElsnF(P8X8fpf4ARhAu;#TU@J=M=&3q=RrNV*^{`l@)ntC&C~%Ctc7 zxme9Q-6rW}u80YFAlfoql+V63w>;R>Rt~=L@=WRwgX+#N0}$ndIEy(4jL@=k&Kw7>dgDGkV}LVq)D0y5zJ*ecb4TW-4`LDDFjMFm;E2S&wK>04JFD{K%x=2 z_2E3yO*nhNebu)qdz;QOFS{8@LvjE?^cBmi5^~KWHgVbn`edMBf?P z&^>3xAM?`Y1yqUT`y`1|visexb9tTNo>3r#;i0Gy{eiUNfnf*4ju- zB8%fOF_}>R!}oRN&bLg`v?wX(7^$Y9hu+Y|xo+DeDJTm=8AN9a@Wbzz;`xT?JhcQbpfF>D z6&d`W)`s+oVqoaeZABX1zpC(K|G%5I{CI6KrTFr|20;sG1*1V57z4(FabP@X2OVGn z=mZnNB+vj|pd0jn%fMtX1xy9gz;y5-Faul;W`ZlgEHE2f3Fd&g;KN`Zm=6|!tH46A z2rLG@pbs>`)j$Ca46wif4+4lFfee;_Yrs;l3@iuNf)!vTxDND#RbT+D25Z1ta6PyI ztOM)82Cxy_2sVM6z|G(muo-LtTfsK49o!0bfZM=MunP==+rdY`9pIzjV_-Mf1MUQO zfxX~vun&A3><9ONPk>K?d%=C+Q{VvjH24g-AAA;k4tyRw03HMnfrr5(;8Ac8d;vT* LJh0(V|FM4p$qd+k delta 3820 zcmb`JS&Wru9me@)7=~?T&KW?!QkJ4@ojJVw!XhmU0|i-HCv_+6aTw2kRiW6-oss21w9HmR*NjY}-FY~$~L^sbnAA>>KmJ>U1e z@BjHf&+~u3TRk%NVbF8S?c0Yt#*7*B@XW7{dHHD1;qis79vy#Em)F_oluR($X6FY~ zLwg-fjM)dJQr4O!V^dPeM`NMt3k zO-MG$FUiRHroNpJd?Pr6@p1lr}CSN zMtn$8Pt00rAB;3C!Aneh3l89y9eqPN!>2e?3@~rX?=2qjCM6qv^3Jte{$I9q#zxq7 z(bDt~%bzY8u{NlzIc^O9?#laXY|Pndkr!PL zuKLl6RMevEqNEr{iP2Q2R<5|z!(r8>9zJx{tfB^`I>TB>Vk;BNS5_}Bm(Cwo{^9D= zb+KilTx3JzAftL^_3WZA`aolhqiUAt#O2 zye@}^FZ2d+XK=X0xfIH+>n`%HN8%#K5Hg&Wd)J?@(>9%ATSG1)9)0B2YYJHn5d$Il ztO7zR4{jLVq+$vItyyi+J=$p-A4gFfy;sg#l0j4+oW-`15jjTJP7Q)0y9^P?AEW2; z`Qd5h6&t6{#tWWE@T%=`wCwQ^{YRnNnDW8RQ$w&h)2xJsuul@Dpdr?ftk1%rlNiCS z1RZUpOdDPGgN+kA>uuQ?F_L&VS}&fdLS1i~?44+9V@zC3W_`5Kw89U+%9Vq*XDo;_U?su6U(O;Pz#2sc&jH~A^SVk8N zME1)Zi-Ba7VNwvxHZyhP{3wI*fb{T|!h+S^&o3h;9ERlq1|Nf!M0)y#Z+Fxn4P_cJ zZPJj>!Df_q9sh-K!ILW9WRWtyp%b__pe@L;LMZ%WGNIXHq?D^|FD@wxRXy_i&JIdq ztTH{Qm2lvZ>amx4iV1`*2Id3hlPBJsC}BgMFnOz=pBydb@GR}&pqYWK8;G2PktIAJ zqrE)#$Kw;3!JGo2gzE8;1)YSqqWSW-ZFQ)TD6@ucDgu#nYHA><#q1KXp&I+z*E;DU z69K6P@<*-=3gRVc4DHNNE@jIok!u9Z5?VS`Prbgrm_*S3=aOQp+8gzv2kqsYC3~?* zHTY&%(NFmz0n}z$a}2-o*|+DH_fP36Z~M!uvl5O&tJER8&?^FgZ(?j4s{N6<#I8=_DQZb*;n8H$NH{5_~3txYZ}chsXTq= zj7XYW54r1zEezzU(RU-UOyT^&Ux-ld1?Bp)@9|-zMBk&63lynn%5CS~t#btmiP<9} zXF>#5?m2&!FViV$Sg<$?tCssOoW8`fcV0XT&sdZ@ADyDja&asVj=sk-351;~ST0jM z!1A2$JXW0GC=qXCbjCWjMs9q~M~gyUVKR^)?THk*C|X&c+kCR4cv0?ZGF%}A`ysbv zn?LR>-jSEcOCsNpaunfQ^YO98JFtMX@CP>{oCe{|Uv{yKDwu2V%}*H4$L15`ir$)RkK|CqH9&%#S^46HvujzDUiloPh9K13B?KNB4x=f zjN6#ZG84wo@ox zIBq@EUmP9V%Se)h6O~03TdSuRhdOGhA(dHf=$?qls`cE=qBgCLyv1R}ROI+D-}-x_ zIN#C7s)I!gN3`Yq&wH$)_7YyQ(G?Gl5v-f97S=R7jOPAYr6Tv zb;Z=?s-4A*=Ir5Odh^#iiqs-_efR(8t1Z5|viSP0O@a>43C4mhFb;Hs@n8a&2quBa zpa=AVK2QU7&=017sbCuT0GJMDfSKTf;4&}^Tn=V~IbbfB2d)6~!H2+y!2+-lECP$c z5^yCL0E3_bmI4JdFu(!_JP06y1Tt6#mV*^wCHM$f1+D^DgVkUS7y@g-FjxoHgKNMB zun~L|Yyz9X7O)ju3$6p(z;j;N##E;3n`%@F{RJ_%zrD zZUOtj0dOn04crdy0G|POg3p4_fzN}xz}?^;@CEQi@FnnNa4$Fr?gL)|hrs>d0q`Jr MsI_a;;Wfwp1rOWbNdN!< diff --git a/src/3rd/js/aframe/pressable.js b/src/3rd/js/aframe/pressable.js index 9d15048..aed7825 100644 --- a/src/3rd/js/aframe/pressable.js +++ b/src/3rd/js/aframe/pressable.js @@ -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 } }); diff --git a/src/3rd/js/aframe/xrf-console.js b/src/3rd/js/aframe/xrf-console.js index 09d52ab..e68aa57 100644 --- a/src/3rd/js/aframe/xrf-console.js +++ b/src/3rd/js/aframe/xrf-console.js @@ -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 += `