@needle-tools/engine 3.10.1-beta → 3.10.2-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,6 +18,7 @@ import { Rigidbody } from "../RigidBody";
18
18
  import { SyncedTransform } from "../SyncedTransform";
19
19
  import { UIRaycastUtils } from "../ui/RaycastUtils";
20
20
  import { WebXR } from "./WebXR";
21
+ import { XRRig } from "./WebXRRig";
21
22
 
22
23
  const debug = getParam("debugwebxrcontroller");
23
24
 
@@ -165,7 +166,7 @@ export class WebXRController extends Behaviour {
165
166
  public grabbed: AttachedObject | null = null;
166
167
  public input: XRInputSource | null = null;
167
168
  public type: ControllerType = ControllerType.PhysicalDevice;
168
- public showRaycastLine : boolean = true;
169
+ public showRaycastLine: boolean = true;
169
170
 
170
171
  get isUsingHands(): boolean {
171
172
  const r = this.input?.hand;
@@ -353,6 +354,33 @@ export class WebXRController extends Behaviour {
353
354
 
354
355
  rayRotation: Quaternion = new Quaternion();
355
356
 
357
+ private raycastUpdate(raycastLine: Line, wp: Vector3) {
358
+ const allowRaycastLineVisible = this.showRaycastLine && this.type !== ControllerType.Touch;
359
+ if (this.type === ControllerType.Touch) {
360
+ raycastLine.visible = false;
361
+ }
362
+ else if (this.isUsingHands) {
363
+ raycastLine.visible = !this.grabbed && allowRaycastLineVisible;
364
+ setWorldPosition(raycastLine, wp);
365
+ const jnts = this.hand!['joints'];
366
+ if (jnts) {
367
+ const wrist = jnts['wrist'];
368
+ if (wrist && this.grabbed && this.grabbed.isCloseGrab) {
369
+ const wr = this.getWristQuaternion();
370
+ if (wr)
371
+ this.rayRotation.copy(wr);
372
+ // this.rayRotation.slerp(wr, this.useSmoothing ? t * 2 : 1);
373
+ }
374
+ }
375
+ setWorldQuaternion(raycastLine, this.rayRotation);
376
+ }
377
+ else {
378
+ raycastLine.visible = allowRaycastLineVisible;
379
+ setWorldQuaternion(raycastLine, this.rayRotation);
380
+ setWorldPosition(raycastLine, wp);
381
+ }
382
+ }
383
+
356
384
  update(): void {
357
385
 
358
386
  // TODO: we should wait until we actually have models, this is just a workaround
@@ -381,30 +409,7 @@ export class WebXRController extends Behaviour {
381
409
  }
382
410
 
383
411
  if (this.raycastLine) {
384
- const allowRaycastLineVisible = this.showRaycastLine && this.type !== ControllerType.Touch;
385
- if (this.type === ControllerType.Touch) {
386
- this.raycastLine.visible = false;
387
- }
388
- else if (this.isUsingHands) {
389
- this.raycastLine.visible = !this.grabbed && allowRaycastLineVisible;
390
- setWorldPosition(this.raycastLine, wp);
391
- const jnts = this.hand!['joints'];
392
- if (jnts) {
393
- const wrist = jnts['wrist'];
394
- if (wrist && this.grabbed && this.grabbed.isCloseGrab) {
395
- const wr = this.getWristQuaternion();
396
- if (wr)
397
- this.rayRotation.copy(wr);
398
- // this.rayRotation.slerp(wr, this.useSmoothing ? t * 2 : 1);
399
- }
400
- }
401
- setWorldQuaternion(this.raycastLine, this.rayRotation);
402
- }
403
- else {
404
- this.raycastLine.visible = allowRaycastLineVisible;
405
- setWorldQuaternion(this.raycastLine, this.rayRotation);
406
- setWorldPosition(this.raycastLine, wp);
407
- }
412
+ this.raycastUpdate(this.raycastLine, wp);
408
413
  }
409
414
 
410
415
  this.lastHit = this.updateLastHit();
@@ -420,8 +425,6 @@ export class WebXRController extends Behaviour {
420
425
  }
421
426
  }
422
427
 
423
- private _pinchStartTime: number | undefined = undefined;
424
-
425
428
  onUpdate(session: XRSession) {
426
429
  this.lastHit = null;
427
430
 
@@ -446,52 +449,61 @@ export class WebXRController extends Behaviour {
446
449
 
447
450
  switch (this.input.handedness) {
448
451
  case "left":
449
- const speedFactor = 3 * WebXRController.MovementSpeedFactor;
450
- const powFactor = 2;
451
- const speed = Mathf.clamp01(this.joystick.length() * 2);
452
-
453
- const sideDir = this.joystick.x > 0 ? 1 : -1;
454
- let side = Math.pow(this.joystick.x, powFactor);
455
- side *= sideDir;
456
- side *= speed;
457
-
458
-
459
- const forwardDir = this.joystick.y > 0 ? 1 : -1;
460
- let forward = Math.pow(this.joystick.y, powFactor);
461
- forward *= forwardDir;
462
- side *= speed;
463
-
464
- rig.getWorldQuaternion(this.worldRot);
465
- this.movementVector.set(side, 0, forward);
466
- this.movementVector.applyQuaternion(this.webXR.TransformOrientation);
467
- this.movementVector.y = 0;
468
- this.movementVector.applyQuaternion(this.worldRot);
469
- this.movementVector.multiplyScalar(speedFactor * this.context.time.deltaTime);
470
- rig.position.add(this.movementVector);
471
-
472
- if (this.isUsingHands)
473
- this.runTeleport(rig, buttons);
452
+ this.movementUpdate(rig, buttons);
474
453
  break;
475
454
 
476
455
  case "right":
477
- const rotate = this.joystick.x;
478
- const rotAbs = Math.abs(rotate);
479
- if (rotAbs < 0.4) {
480
- this.didRotate = false;
481
- }
482
- else if (rotAbs > .5 && !this.didRotate) {
483
- const dir = rotate > 0 ? -1 : 1;
484
- rig.rotateY(Mathf.toRadians(30 * dir));
485
- this.didRotate = true;
486
- }
456
+ this.rotationUpdate(rig, buttons);
457
+ break;
458
+ }
459
+ }
487
460
 
488
- this.runTeleport(rig, buttons);
489
461
 
490
- break;
462
+ private movementUpdate(rig: Object3D, buttons?: readonly GamepadButton[]) {
463
+ const speedFactor = 3 * WebXRController.MovementSpeedFactor;
464
+ const powFactor = 2;
465
+ const speed = Mathf.clamp01(this.joystick.length() * 2);
466
+
467
+ const sideDir = this.joystick.x > 0 ? 1 : -1;
468
+ let side = Math.pow(this.joystick.x, powFactor);
469
+ side *= sideDir;
470
+ side *= speed;
471
+
472
+
473
+ const forwardDir = this.joystick.y > 0 ? 1 : -1;
474
+ let forward = Math.pow(this.joystick.y, powFactor);
475
+ forward *= forwardDir;
476
+ side *= speed;
477
+
478
+ rig.getWorldQuaternion(this.worldRot);
479
+ this.movementVector.set(side, 0, forward);
480
+ this.movementVector.applyQuaternion(this.webXR.TransformOrientation);
481
+ this.movementVector.y = 0;
482
+ this.movementVector.applyQuaternion(this.worldRot);
483
+ this.movementVector.multiplyScalar(speedFactor * this.context.time.deltaTime);
484
+ rig.position.add(this.movementVector);
485
+
486
+ if (this.isUsingHands)
487
+ this.runTeleport(rig, buttons);
488
+ }
489
+
490
+ private rotationUpdate(rig: Object3D, buttons?: readonly GamepadButton[]) {
491
+ const rotate = this.joystick.x;
492
+ const rotAbs = Math.abs(rotate);
493
+ if (rotAbs < 0.4) {
494
+ this.didRotate = false;
495
+ }
496
+ else if (rotAbs > .5 && !this.didRotate) {
497
+ const dir = rotate > 0 ? -1 : 1;
498
+ rig.rotateY(Mathf.toRadians(30 * dir));
499
+ this.didRotate = true;
491
500
  }
501
+
502
+ this.runTeleport(rig, buttons);
492
503
  }
504
+ private _pinchStartTime: number | undefined = undefined;
493
505
 
494
- private runTeleport(rig, buttons) {
506
+ private runTeleport(rig: Object3D, buttons?: readonly GamepadButton[]) {
495
507
  let teleport = -this.joystick.y;
496
508
  if (this.hand?.visible && !this.grabbed) {
497
509
  const pinched = this.handPointerModel.isPinched();
@@ -526,24 +538,10 @@ export class WebXRController extends Behaviour {
526
538
  this.didChangeScale = true;
527
539
  const rig = this.webXR.Rig;
528
540
  if (rig) {
529
- if (!isInMiniatureMode) {
530
- isInMiniatureMode = true;
531
- doTeleport = true;
532
- newRigScale = .1;
533
- WebXRController.MovementSpeedFactor = newRigScale * 2;
534
- const cam = this.context.mainCamera as PerspectiveCamera;
535
- WebXRController.PreviousCameraFarDistance = cam.far;
536
- cam.far /= newRigScale;
537
- }
538
- else {
539
- isInMiniatureMode = false;
540
- rig.scale.set(1, 1, 1);
541
- newRigScale = 1;
542
- WebXRController.MovementSpeedFactor = 1;
543
- const cam = this.context.mainCamera as PerspectiveCamera;
544
- if (WebXRController.PreviousCameraFarDistance)
545
- cam.far = WebXRController.PreviousCameraFarDistance;
546
- }
541
+ let args = this.switchScale(rig, doTeleport, isInMiniatureMode, newRigScale);
542
+ doTeleport = args.doTeleport;
543
+ isInMiniatureMode = args.isInMiniatureMode;
544
+ newRigScale = args.newRigScale;
547
545
  }
548
546
  }
549
547
  else if (!btn.pressed)
@@ -575,10 +573,33 @@ export class WebXRController extends Behaviour {
575
573
  }
576
574
  }
577
575
 
576
+
578
577
  private isValidTeleportTarget(obj: Object3D): boolean {
579
578
  return GameObject.getComponentInParent(obj, TeleportTarget) != null;
580
579
  }
581
580
 
581
+ private switchScale(rig: Object3D, doTeleport: boolean, isInMiniatureMode: boolean, newRigScale: number | null) {
582
+ if (!isInMiniatureMode) {
583
+ isInMiniatureMode = true;
584
+ doTeleport = true;
585
+ newRigScale = .1;
586
+ WebXRController.MovementSpeedFactor = newRigScale * 2;
587
+ const cam = this.context.mainCamera as PerspectiveCamera;
588
+ WebXRController.PreviousCameraFarDistance = cam.far;
589
+ cam.far /= newRigScale;
590
+ }
591
+ else {
592
+ isInMiniatureMode = false;
593
+ rig.scale.set(1, 1, 1);
594
+ newRigScale = 1;
595
+ WebXRController.MovementSpeedFactor = 1;
596
+ const cam = this.context.mainCamera as PerspectiveCamera;
597
+ if (WebXRController.PreviousCameraFarDistance)
598
+ cam.far = WebXRController.PreviousCameraFarDistance;
599
+ }
600
+ return { doTeleport, isInMiniatureMode, newRigScale }
601
+ }
602
+
582
603
  private updateStick(inputSource: XRInputSource) {
583
604
  if (!inputSource || !inputSource.gamepad || inputSource.gamepad.axes?.length < 4) return;
584
605
  this.joystick.x = inputSource.gamepad.axes[2];