text: import { Group } from '../../objects/Group.js';
  
  /**
   * @author Mugen87 / https://github.com/Mugen87
   */
  
  function WebXRController() {
  
  	this._targetRay = null;
  	this._grip = null;
  	this._hand = null;
  
  }
  
  Object.assign( WebXRController.prototype, {
  
  	constructor: WebXRController,
  
  	getHandSpace: function () {
  
  		if ( this._hand === null ) {
  
  			this._hand = new Group();
  			this._hand.matrixAutoUpdate = false;
  			this._hand.visible = false;
  
  			this._hand.joints = [];
  			this._hand.inputState = { pinching: false };
  
  			if ( window.XRHand ) {
  
  				for ( let i = 0; i <= XRHand.LITTLE_PHALANX_TIP; i ++ ) {
  
  					// The transform of this joint will be updated with the joint pose on each frame
  					let joint = new Group();
  					joint.matrixAutoUpdate = false;
  					joint.visible = false;
  					this._hand.joints.push( joint );
  					// ??
  					this._hand.add( joint );
  
  				}
  
  			}
  
  		}
  
  		return this._hand;
  
  	},
  
  	getTargetRaySpace: function () {
  
  		if ( this._targetRay === null ) {
  
  			this._targetRay = new Group();
  			this._targetRay.matrixAutoUpdate = false;
  			this._targetRay.visible = false;
  
  		}
  
  		return this._targetRay;
  
  	},
  
  	getGripSpace: function () {
  
  		if ( this._grip === null ) {
  
  			this._grip = new Group();
  			this._grip.matrixAutoUpdate = false;
  			this._grip.visible = false;
  
  		}
  
  		return this._grip;
  
  	},
  
  	dispatchEvent: function ( event ) {
  
  		if ( this._targetRay !== null ) {
  
  			this._targetRay.dispatchEvent( event );
  
  		}
  
  		if ( this._grip !== null ) {
  
  			this._grip.dispatchEvent( event );
  
  		}
  
  		if ( this._hand !== null ) {
  
  			this._hand.dispatchEvent( event );
  
  		}
  
  		return this;
  
  	},
  
  	disconnect: function ( inputSource ) {
  
  		this.dispatchEvent( { type: 'disconnected', data: inputSource } );
  
  		if ( this._targetRay !== null ) {
  
  			this._targetRay.visible = false;
  
  		}
  
  		if ( this._grip !== null ) {
  
  			this._grip.visible = false;
  
  		}
  
  		if ( this._hand !== null ) {
  
  			this._hand.visible = false;
  
  		}
  
  		return this;
  
  	},
  
  	update: function ( inputSource, frame, referenceSpace ) {
  
  		let inputPose = null;
  		let gripPose = null;
  		let handPose = null;
  
  		const targetRay = this._targetRay;
  		const grip = this._grip;
  		const hand = this._hand;
  
  		if ( inputSource ) {
  
  			if ( inputSource.hand ) {
  
  				handPose = true;
  				for ( let i = 0; i <= XRHand.LITTLE_PHALANX_TIP; i ++ ) {
  
  					if ( inputSource.hand[ i ] ) {
  
  						// Update the joints groups with the XRJoint poses
  						let jointPose = frame.getJointPose( inputSource.hand[ i ], referenceSpace );
  						const joint = hand.joints[ i ];
  
  						if ( jointPose !== null ) {
  
  							joint.matrix.fromArray( jointPose.transform.matrix );
  							joint.matrix.decompose( joint.position, joint.rotation, joint.scale );
  							joint.jointRadius = jointPose.radius;
  
  						}
  
  						joint.visible = jointPose !== null;
  
  						// Custom events
  
  						// Check pinch
  						const indexTip = hand.joints[ XRHand.INDEX_PHALANX_TIP ];
  						const thumbTip = hand.joints[ XRHand.THUMB_PHALANX_TIP ];
  						const distance = indexTip.position.distanceTo( thumbTip.position );
  
  						const distanceToPinch = 0.02;
  						const threshold = 0.005;
  						if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) {
  
  							hand.inputState.pinching = false;
  							this.dispatchEvent( {
  								type: "pinchend",
  								target: this
  							} );
  
  						} else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) {
  
  							hand.inputState.pinching = true;
  							this.dispatchEvent( {
  								type: "pinchstart",
  								target: this
  							} );
  
  						}
  
  					}
  
  				}
  
  			} else {
  
  				if ( targetRay !== null ) {
  
  					inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace );
  
  					if ( inputPose !== null ) {
  
  						targetRay.matrix.fromArray( inputPose.transform.matrix );
  						targetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale );
  
  					}
  
  				}
  
  				if ( grip !== null && inputSource.gripSpace ) {
  
  					gripPose = frame.getPose( inputSource.gripSpace, referenceSpace );
  
  					if ( gripPose !== null ) {
  
  						grip.matrix.fromArray( gripPose.transform.matrix );
  						grip.matrix.decompose( grip.position, grip.rotation, grip.scale );
  
  					}
  
  				}
  
  			}
  
  		}
  
  		if ( targetRay !== null ) {
  
  			targetRay.visible = ( inputPose !== null );
  
  		}
  
  		if ( grip !== null ) {
  
  			grip.visible = ( gripPose !== null );
  
  		}
  
  		if ( hand !== null ) {
  
  			hand.visible = ( handPose !== null );
  
  		}
  
  		return this;
  
  	}
  
  } );
  
  
  export { WebXRController };
  