@@ -65,6 +65,7 @@ module.exports.Component = registerComponent('cursor', {
6565 this . intersectedEl = null ;
6666 this . canvasBounds = document . body . getBoundingClientRect ( ) ;
6767 this . isCursorDown = false ;
68+ this . activeXRInput = null ;
6869
6970 // Debounce.
7071 this . updateCanvasBounds = utils . debounce ( function updateCanvasBounds ( ) {
@@ -88,6 +89,19 @@ module.exports.Component = registerComponent('cursor', {
8889 this . updateMouseEventListeners ( ) ;
8990 } ,
9091
92+ tick : function ( ) {
93+ // Update on frame to allow someone to select and mousemove
94+ var frame = this . el . sceneEl . frame ;
95+ var inputSource = this . activeXRInput ;
96+ if ( this . data . rayOrigin === 'xrselect' && frame && inputSource ) {
97+ this . onMouseMove ( {
98+ frame : frame ,
99+ inputSource : inputSource ,
100+ type : 'fakeselectevent'
101+ } ) ;
102+ }
103+ } ,
104+
91105 play : function ( ) {
92106 this . addEventListeners ( ) ;
93107 } ,
@@ -210,6 +224,12 @@ module.exports.Component = registerComponent('cursor', {
210224 var point ;
211225 var top ;
212226
227+ var frame ;
228+ var inputSource ;
229+ var referenceSpace ;
230+ var pose ;
231+ var transform ;
232+
213233 camera . parent . updateMatrixWorld ( ) ;
214234
215235 // Calculate mouse position based on the canvas element
@@ -225,15 +245,18 @@ module.exports.Component = registerComponent('cursor', {
225245 mouse . x = ( left / bounds . width ) * 2 - 1 ;
226246 mouse . y = - ( top / bounds . height ) * 2 + 1 ;
227247
228- if ( this . data . rayOrigin === 'xrselect' && evt . type === 'selectstart' ) {
229- const frame = evt . frame ;
230- const inputSource = evt . inputSource ;
231- const referenceSpace = this . el . renderer . xr . getReferenceSpace ( ) ;
232- const pose = frame . getPose ( inputSource . targetRaySpace , referenceSpace ) ;
233- const transform = pose . transform ;
248+ if ( this . data . rayOrigin === 'xrselect' && ( evt . type === 'selectstart' || evt . type === 'fakeselectevent' ) ) {
249+ frame = evt . frame ;
250+ inputSource = evt . inputSource ;
251+ referenceSpace = this . el . renderer . xr . getReferenceSpace ( ) ;
252+ pose = frame . getPose ( inputSource . targetRaySpace , referenceSpace ) ;
253+ transform = pose . transform ;
234254 direction . set ( 0 , 0 , - 1 ) ;
235255 direction . applyQuaternion ( transform . orientation ) ;
236256 origin . copy ( transform . position ) ;
257+ } else if ( evt . type === 'fakeselectout' ) {
258+ direction . set ( 0 , 1 , 0 ) ;
259+ origin . set ( 0 , 9999 , 0 ) ;
237260 } else if ( camera && camera . isPerspectiveCamera ) {
238261 origin . setFromMatrixPosition ( camera . matrixWorld ) ;
239262 direction . set ( mouse . x , mouse . y , 0.5 ) . unproject ( camera ) . sub ( origin ) . normalize ( ) ;
@@ -262,19 +285,18 @@ module.exports.Component = registerComponent('cursor', {
262285 }
263286
264287 if ( this . data . rayOrigin === 'xrselect' && evt . type === 'selectstart' ) {
288+ this . activeXRInput = evt . inputSource ;
265289 this . onMouseMove ( evt ) ;
266290 this . el . components . raycaster . checkIntersections ( ) ;
267291
268292 // if something was tapped on don't do ar-hit-test things
269293 if (
270294 this . el . components . raycaster . intersectedEls . length &&
271295 this . el . sceneEl . components [ 'ar-hit-test' ] !== undefined &&
272- this . el . sceneEl . components [ 'ar-hit-test' ] . data . enabled
296+ this . el . sceneEl . getAttribute ( 'ar-hit-test' ) . enabled
273297 ) {
274298 // Cancel the ar-hit-test behaviours and disable the ar-hit-test
275- this . el . sceneEl . components [ 'ar-hit-test' ] . data . enabled = false ;
276- this . el . sceneEl . components [ 'ar-hit-test' ] . hitTest = null ;
277- this . el . sceneEl . components [ 'ar-hit-test' ] . bboxMesh . visible = false ;
299+ this . el . sceneEl . setAttribute ( 'ar-hit-test' , 'enabled' , false ) ;
278300 this . reenableARHitTest = true ;
279301 }
280302 }
@@ -299,7 +321,7 @@ module.exports.Component = registerComponent('cursor', {
299321 this . twoWayEmit ( EVENTS . MOUSEUP ) ;
300322
301323 if ( this . reenableARHitTest === true ) {
302- this . el . sceneEl . components [ 'ar-hit-test' ] . data . enabled = true ;
324+ this . el . sceneEl . setAttribute ( 'ar-hit-test' , ' enabled' , true ) ;
303325 this . reenableARHitTest = undefined ;
304326 }
305327
@@ -315,6 +337,14 @@ module.exports.Component = registerComponent('cursor', {
315337 this . twoWayEmit ( EVENTS . CLICK ) ;
316338 }
317339
340+ // if the current xr input stops selecting then make the ray caster point somewhere else
341+ if ( data . rayOrigin === 'xrselect' && this . activeXRInput === evt . inputSource ) {
342+ this . onMouseMove ( {
343+ type : 'fakeselectout'
344+ } ) ;
345+ }
346+
347+ this . activeXRInput = null ;
318348 this . cursorDownEl = null ;
319349 if ( evt . type === 'touchend' ) { evt . preventDefault ( ) ; }
320350 } ,
@@ -397,7 +427,7 @@ module.exports.Component = registerComponent('cursor', {
397427 }
398428
399429 // Begin fuse if necessary.
400- if ( data . fuseTimeout === 0 || ! data . fuse || data . rayOrigin === 'xrselect' ) { return ; }
430+ if ( data . fuseTimeout === 0 || ! data . fuse || data . rayOrigin === 'xrselect' || data . rayOrigin === 'mouse' ) { return ; }
401431 cursorEl . addState ( STATES . FUSING ) ;
402432 this . twoWayEmit ( EVENTS . FUSING ) ;
403433 this . fuseTimeout = setTimeout ( function fuse ( ) {
0 commit comments