Buckets:
ktongue/docker_container / simsite /frontend /node_modules /three /src /renderers /webxr /WebXRController.js
| import { Vector3 } from '../../math/Vector3.js'; | |
| import { Group } from '../../objects/Group.js'; | |
| const _moveEvent = { type: 'move' }; | |
| class WebXRController { | |
| constructor() { | |
| this._targetRay = null; | |
| this._grip = null; | |
| this._hand = null; | |
| } | |
| getHandSpace() { | |
| if ( this._hand === null ) { | |
| this._hand = new Group(); | |
| this._hand.matrixAutoUpdate = false; | |
| this._hand.visible = false; | |
| this._hand.joints = {}; | |
| this._hand.inputState = { pinching: false }; | |
| } | |
| return this._hand; | |
| } | |
| getTargetRaySpace() { | |
| if ( this._targetRay === null ) { | |
| this._targetRay = new Group(); | |
| this._targetRay.matrixAutoUpdate = false; | |
| this._targetRay.visible = false; | |
| this._targetRay.hasLinearVelocity = false; | |
| this._targetRay.linearVelocity = new Vector3(); | |
| this._targetRay.hasAngularVelocity = false; | |
| this._targetRay.angularVelocity = new Vector3(); | |
| } | |
| return this._targetRay; | |
| } | |
| getGripSpace() { | |
| if ( this._grip === null ) { | |
| this._grip = new Group(); | |
| this._grip.matrixAutoUpdate = false; | |
| this._grip.visible = false; | |
| this._grip.hasLinearVelocity = false; | |
| this._grip.linearVelocity = new Vector3(); | |
| this._grip.hasAngularVelocity = false; | |
| this._grip.angularVelocity = new Vector3(); | |
| } | |
| return this._grip; | |
| } | |
| dispatchEvent( 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; | |
| } | |
| connect( inputSource ) { | |
| if ( inputSource && inputSource.hand ) { | |
| const hand = this._hand; | |
| if ( hand ) { | |
| for ( const inputjoint of inputSource.hand.values() ) { | |
| // Initialize hand with joints when connected | |
| this._getHandJoint( hand, inputjoint ); | |
| } | |
| } | |
| } | |
| this.dispatchEvent( { type: 'connected', data: inputSource } ); | |
| return this; | |
| } | |
| disconnect( 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( 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 && frame.session.visibilityState !== 'visible-blurred' ) { | |
| if ( hand && inputSource.hand ) { | |
| handPose = true; | |
| for ( const inputjoint of inputSource.hand.values() ) { | |
| // Update the joints groups with the XRJoint poses | |
| const jointPose = frame.getJointPose( inputjoint, referenceSpace ); | |
| // The transform of this joint will be updated with the joint pose on each frame | |
| const joint = this._getHandJoint( hand, inputjoint ); | |
| if ( jointPose !== null ) { | |
| joint.matrix.fromArray( jointPose.transform.matrix ); | |
| joint.matrix.decompose( joint.position, joint.rotation, joint.scale ); | |
| joint.matrixWorldNeedsUpdate = true; | |
| joint.jointRadius = jointPose.radius; | |
| } | |
| joint.visible = jointPose !== null; | |
| } | |
| // Custom events | |
| // Check pinchz | |
| const indexTip = hand.joints[ 'index-finger-tip' ]; | |
| const thumbTip = hand.joints[ 'thumb-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', | |
| handedness: inputSource.handedness, | |
| target: this | |
| } ); | |
| } else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) { | |
| hand.inputState.pinching = true; | |
| this.dispatchEvent( { | |
| type: 'pinchstart', | |
| handedness: inputSource.handedness, | |
| target: this | |
| } ); | |
| } | |
| } else { | |
| 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 ); | |
| grip.matrixWorldNeedsUpdate = true; | |
| if ( gripPose.linearVelocity ) { | |
| grip.hasLinearVelocity = true; | |
| grip.linearVelocity.copy( gripPose.linearVelocity ); | |
| } else { | |
| grip.hasLinearVelocity = false; | |
| } | |
| if ( gripPose.angularVelocity ) { | |
| grip.hasAngularVelocity = true; | |
| grip.angularVelocity.copy( gripPose.angularVelocity ); | |
| } else { | |
| grip.hasAngularVelocity = false; | |
| } | |
| } | |
| } | |
| } | |
| if ( targetRay !== null ) { | |
| inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace ); | |
| // Some runtimes (namely Vive Cosmos with Vive OpenXR Runtime) have only grip space and ray space is equal to it | |
| if ( inputPose === null && gripPose !== null ) { | |
| inputPose = gripPose; | |
| } | |
| if ( inputPose !== null ) { | |
| targetRay.matrix.fromArray( inputPose.transform.matrix ); | |
| targetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale ); | |
| targetRay.matrixWorldNeedsUpdate = true; | |
| if ( inputPose.linearVelocity ) { | |
| targetRay.hasLinearVelocity = true; | |
| targetRay.linearVelocity.copy( inputPose.linearVelocity ); | |
| } else { | |
| targetRay.hasLinearVelocity = false; | |
| } | |
| if ( inputPose.angularVelocity ) { | |
| targetRay.hasAngularVelocity = true; | |
| targetRay.angularVelocity.copy( inputPose.angularVelocity ); | |
| } else { | |
| targetRay.hasAngularVelocity = false; | |
| } | |
| this.dispatchEvent( _moveEvent ); | |
| } | |
| } | |
| } | |
| if ( targetRay !== null ) { | |
| targetRay.visible = ( inputPose !== null ); | |
| } | |
| if ( grip !== null ) { | |
| grip.visible = ( gripPose !== null ); | |
| } | |
| if ( hand !== null ) { | |
| hand.visible = ( handPose !== null ); | |
| } | |
| return this; | |
| } | |
| // private method | |
| _getHandJoint( hand, inputjoint ) { | |
| if ( hand.joints[ inputjoint.jointName ] === undefined ) { | |
| const joint = new Group(); | |
| joint.matrixAutoUpdate = false; | |
| joint.visible = false; | |
| hand.joints[ inputjoint.jointName ] = joint; | |
| hand.add( joint ); | |
| } | |
| return hand.joints[ inputjoint.jointName ]; | |
| } | |
| } | |
| export { WebXRController }; | |
Xet Storage Details
- Size:
- 6.52 kB
- Xet hash:
- 2ef0525b46abe81a48ea2d933b3759b0f2a7e746f638ba9016ce34a49a337811
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.