فهرست منبع

InteractiveGroup: Add `disconnect()`. (#29975)

* fix: add ability to disconnect event listeners in InteractiveGroup so it can be removed from the scene

* Update InteractiveGroup.js

Refactor code.

* Update InteractiveGroup.js

Clean up.

---------

Co-authored-by: Michael Herzog <michael.herzog@human-interactive.org>
Simon Gaeremynck 1 سال پیش
والد
کامیت
4b2119b8fd
1فایلهای تغییر یافته به همراه108 افزوده شده و 51 حذف شده
  1. 108 51
      examples/jsm/interactive/InteractiveGroup.js

+ 108 - 51
examples/jsm/interactive/InteractiveGroup.js

@@ -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 = [];
 
 
 	}
 	}
 
 

粤ICP备19079148号