OculusHandModel.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import { Object3D, Sphere, Box3 } from '../../../build/three.module.js';
  2. import { fetchProfile } from '../libs/motion-controllers.module.js';
  3. import { XRHandMeshModel } from './XRHandMeshModel.js';
  4. const DEFAULT_PROFILES_PATH = 'https://cdn.jsdelivr.net/npm/@webxr-input-profiles/[email protected]/dist/profiles';
  5. const DEFAULT_PROFILE = 'generic-hand';
  6. const POINTING_JOINT = 'index-finger-tip';
  7. class OculusHandModel extends Object3D {
  8. constructor( controller ) {
  9. super();
  10. this.controller = controller;
  11. this.motionController = null;
  12. this.envMap = null;
  13. this.mesh = null;
  14. controller.addEventListener( 'connected', ( event ) => {
  15. const xrInputSource = event.data;
  16. if ( xrInputSource.hand && ! this.motionController ) {
  17. this.visible = true;
  18. this.xrInputSource = xrInputSource;
  19. fetchProfile( xrInputSource, DEFAULT_PROFILES_PATH, DEFAULT_PROFILE ).then( ( { profile, assetPath } ) => {
  20. this.motionController = new XRHandMeshModel(
  21. this,
  22. controller,
  23. assetPath
  24. );
  25. } ).catch( ( err ) => {
  26. console.warn( err );
  27. } );
  28. }
  29. } );
  30. controller.addEventListener( 'disconnected', () => {
  31. this.clear();
  32. this.motionController = null;
  33. } );
  34. }
  35. updateMatrixWorld( force ) {
  36. super.updateMatrixWorld( force );
  37. if ( this.motionController ) {
  38. this.motionController.updateMesh();
  39. }
  40. }
  41. getPointerPosition() {
  42. const indexFingerTip = this.controller.joints[ POINTING_JOINT ];
  43. if ( indexFingerTip ) {
  44. return indexFingerTip.position;
  45. } else {
  46. return null;
  47. }
  48. }
  49. intersectBoxObject( boxObject ) {
  50. const pointerPosition = this.getPointerPosition();
  51. if ( pointerPosition ) {
  52. const indexSphere = new Sphere( pointerPosition, TOUCH_RADIUS );
  53. const box = new Box3().setFromObject( boxObject );
  54. return indexSphere.intersectsBox( box );
  55. } else {
  56. return false;
  57. }
  58. }
  59. checkButton( button ) {
  60. if ( this.intersectBoxObject( button ) ) {
  61. button.onPress();
  62. } else {
  63. button.onClear();
  64. }
  65. if ( button.isPressed() ) {
  66. button.whilePressed();
  67. }
  68. }
  69. }
  70. export { OculusHandModel };