|
@@ -7,97 +7,154 @@ import {
|
|
|
const _pointer = new Vector2();
|
|
const _pointer = new Vector2();
|
|
|
const _event = { type: '', data: _pointer };
|
|
const _event = { type: '', data: _pointer };
|
|
|
|
|
|
|
|
|
|
+// TODO: Dispatch pointerevents too
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * The XR events that are mapped to "standard" pointer events
|
|
|
|
|
+ */
|
|
|
|
|
+const _events = {
|
|
|
|
|
+ 'move': 'mousemove',
|
|
|
|
|
+ 'select': 'click',
|
|
|
|
|
+ 'selectstart': 'mousedown',
|
|
|
|
|
+ 'selectend': 'mouseup'
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
const _raycaster = new Raycaster();
|
|
const _raycaster = new Raycaster();
|
|
|
|
|
|
|
|
class InteractiveGroup extends Group {
|
|
class InteractiveGroup extends Group {
|
|
|
|
|
|
|
|
- listenToPointerEvents( renderer, camera ) {
|
|
|
|
|
|
|
+ constructor() {
|
|
|
|
|
+
|
|
|
|
|
+ super();
|
|
|
|
|
+
|
|
|
|
|
+ this.raycaster = new Raycaster();
|
|
|
|
|
|
|
|
- const scope = this;
|
|
|
|
|
- const raycaster = new Raycaster();
|
|
|
|
|
|
|
+ this.element = null;
|
|
|
|
|
+ this.camera = null;
|
|
|
|
|
|
|
|
- const element = renderer.domElement;
|
|
|
|
|
|
|
+ this.controllers = [];
|
|
|
|
|
|
|
|
- function onPointerEvent( event ) {
|
|
|
|
|
|
|
+ this._onPointerEvent = this.onPointerEvent.bind( this );
|
|
|
|
|
+ this._onXRControllerEvent = this.onXRControllerEvent.bind( this );
|
|
|
|
|
|
|
|
- event.stopPropagation();
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ onPointerEvent( event ) {
|
|
|
|
|
|
|
|
- const rect = renderer.domElement.getBoundingClientRect();
|
|
|
|
|
|
|
+ event.stopPropagation();
|
|
|
|
|
|
|
|
- _pointer.x = ( event.clientX - rect.left ) / rect.width * 2 - 1;
|
|
|
|
|
- _pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1;
|
|
|
|
|
|
|
+ const rect = this.element.getBoundingClientRect();
|
|
|
|
|
|
|
|
- raycaster.setFromCamera( _pointer, camera );
|
|
|
|
|
|
|
+ _pointer.x = ( event.clientX - rect.left ) / rect.width * 2 - 1;
|
|
|
|
|
+ _pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1;
|
|
|
|
|
|
|
|
- const intersects = raycaster.intersectObjects( scope.children, false );
|
|
|
|
|
|
|
+ this.raycaster.setFromCamera( _pointer, this.camera );
|
|
|
|
|
|
|
|
- if ( intersects.length > 0 ) {
|
|
|
|
|
|
|
+ const intersects = this.raycaster.intersectObjects( this.children, false );
|
|
|
|
|
|
|
|
- const intersection = intersects[ 0 ];
|
|
|
|
|
|
|
+ if ( intersects.length > 0 ) {
|
|
|
|
|
|
|
|
- const object = intersection.object;
|
|
|
|
|
- const uv = intersection.uv;
|
|
|
|
|
|
|
+ const intersection = intersects[ 0 ];
|
|
|
|
|
|
|
|
- _event.type = event.type;
|
|
|
|
|
- _event.data.set( uv.x, 1 - uv.y );
|
|
|
|
|
|
|
+ const object = intersection.object;
|
|
|
|
|
+ const uv = intersection.uv;
|
|
|
|
|
|
|
|
- object.dispatchEvent( _event );
|
|
|
|
|
|
|
+ _event.type = event.type;
|
|
|
|
|
+ _event.data.set( uv.x, 1 - uv.y );
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ object.dispatchEvent( _event );
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- element.addEventListener( 'pointerdown', onPointerEvent );
|
|
|
|
|
- element.addEventListener( 'pointerup', onPointerEvent );
|
|
|
|
|
- element.addEventListener( 'pointermove', onPointerEvent );
|
|
|
|
|
- element.addEventListener( 'mousedown', onPointerEvent );
|
|
|
|
|
- element.addEventListener( 'mouseup', onPointerEvent );
|
|
|
|
|
- element.addEventListener( 'mousemove', onPointerEvent );
|
|
|
|
|
- element.addEventListener( 'click', onPointerEvent );
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ onXRControllerEvent( event ) {
|
|
|
|
|
+
|
|
|
|
|
+ const controller = event.target;
|
|
|
|
|
+
|
|
|
|
|
+ _raycaster.setFromXRController( controller );
|
|
|
|
|
+
|
|
|
|
|
+ const intersections = _raycaster.intersectObjects( this.children, false );
|
|
|
|
|
+
|
|
|
|
|
+ if ( intersections.length > 0 ) {
|
|
|
|
|
+
|
|
|
|
|
+ const intersection = intersections[ 0 ];
|
|
|
|
|
+
|
|
|
|
|
+ const object = intersection.object;
|
|
|
|
|
+ const uv = intersection.uv;
|
|
|
|
|
+
|
|
|
|
|
+ _event.type = _events[ event.type ];
|
|
|
|
|
+ _event.data.set( uv.x, 1 - uv.y );
|
|
|
|
|
+
|
|
|
|
|
+ object.dispatchEvent( _event );
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- listenToXRControllerEvents( controller ) {
|
|
|
|
|
|
|
+ listenToPointerEvents( renderer, camera ) {
|
|
|
|
|
|
|
|
- const scope = this;
|
|
|
|
|
|
|
+ this.camera = camera;
|
|
|
|
|
+ this.element = renderer.domElement;
|
|
|
|
|
|
|
|
- // TODO: Dispatch pointerevents too
|
|
|
|
|
|
|
+ this.element.addEventListener( 'pointerdown', this._onPointerEvent );
|
|
|
|
|
+ this.element.addEventListener( 'pointerup', this._onPointerEvent );
|
|
|
|
|
+ this.element.addEventListener( 'pointermove', this._onPointerEvent );
|
|
|
|
|
+ this.element.addEventListener( 'mousedown', this._onPointerEvent );
|
|
|
|
|
+ this.element.addEventListener( 'mouseup', this._onPointerEvent );
|
|
|
|
|
+ this.element.addEventListener( 'mousemove', this._onPointerEvent );
|
|
|
|
|
+ this.element.addEventListener( 'click', this._onPointerEvent );
|
|
|
|
|
|
|
|
- const events = {
|
|
|
|
|
- 'move': 'mousemove',
|
|
|
|
|
- 'select': 'click',
|
|
|
|
|
- 'selectstart': 'mousedown',
|
|
|
|
|
- 'selectend': 'mouseup'
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- function onXRControllerEvent( event ) {
|
|
|
|
|
|
|
+ disconnectionPointerEvents() {
|
|
|
|
|
|
|
|
- const controller = event.target;
|
|
|
|
|
|
|
+ if ( this.element !== null ) {
|
|
|
|
|
|
|
|
- _raycaster.setFromXRController( controller );
|
|
|
|
|
|
|
+ this.element.removeEventListener( 'pointerdown', this._onPointerEvent );
|
|
|
|
|
+ this.element.removeEventListener( 'pointerup', this._onPointerEvent );
|
|
|
|
|
+ this.element.removeEventListener( 'pointermove', this._onPointerEvent );
|
|
|
|
|
+ this.element.removeEventListener( 'mousedown', this._onPointerEvent );
|
|
|
|
|
+ this.element.removeEventListener( 'mouseup', this._onPointerEvent );
|
|
|
|
|
+ this.element.removeEventListener( 'mousemove', this._onPointerEvent );
|
|
|
|
|
+ this.element.removeEventListener( 'click', this._onPointerEvent );
|
|
|
|
|
|
|
|
- const intersections = _raycaster.intersectObjects( scope.children, false );
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if ( intersections.length > 0 ) {
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- const intersection = intersections[ 0 ];
|
|
|
|
|
|
|
+ listenToXRControllerEvents( controller ) {
|
|
|
|
|
|
|
|
- const object = intersection.object;
|
|
|
|
|
- const uv = intersection.uv;
|
|
|
|
|
|
|
+ this.controllers.push( controller );
|
|
|
|
|
+ controller.addEventListener( 'move', this._onXRControllerEvent );
|
|
|
|
|
+ controller.addEventListener( 'select', this._onXRControllerEvent );
|
|
|
|
|
+ controller.addEventListener( 'selectstart', this._onXRControllerEvent );
|
|
|
|
|
+ controller.addEventListener( 'selectend', this._onXRControllerEvent );
|
|
|
|
|
|
|
|
- _event.type = events[ event.type ];
|
|
|
|
|
- _event.data.set( uv.x, 1 - uv.y );
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ disconnectXrControllerEvents() {
|
|
|
|
|
|
|
|
- object.dispatchEvent( _event );
|
|
|
|
|
|
|
+ for ( const controller of this.controllers ) {
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ controller.removeEventListener( 'move', this._onXRControllerEvent );
|
|
|
|
|
+ controller.removeEventListener( 'select', this._onXRControllerEvent );
|
|
|
|
|
+ controller.removeEventListener( 'selectstart', this._onXRControllerEvent );
|
|
|
|
|
+ controller.removeEventListener( 'selectend', this._onXRControllerEvent );
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- controller.addEventListener( 'move', onXRControllerEvent );
|
|
|
|
|
- controller.addEventListener( 'select', onXRControllerEvent );
|
|
|
|
|
- controller.addEventListener( 'selectstart', onXRControllerEvent );
|
|
|
|
|
- controller.addEventListener( 'selectend', onXRControllerEvent );
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ disconnect() {
|
|
|
|
|
+
|
|
|
|
|
+ this.disconnectionPointerEvents();
|
|
|
|
|
+ this.disconnectXrControllerEvents();
|
|
|
|
|
+
|
|
|
|
|
+ this.camera = null;
|
|
|
|
|
+ this.element = null;
|
|
|
|
|
+
|
|
|
|
|
+ this.controllers = [];
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|