@pmndrs/viverse 0.2.0 → 0.2.2

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.
Files changed (64) hide show
  1. package/dist/action/action.d.ts +40 -0
  2. package/dist/action/action.js +114 -0
  3. package/dist/action/index.d.ts +18 -0
  4. package/dist/action/index.js +25 -0
  5. package/dist/action/keyboard.d.ts +26 -0
  6. package/dist/action/keyboard.js +89 -0
  7. package/dist/action/pointer-capture.d.ts +8 -0
  8. package/dist/{input → action}/pointer-capture.js +17 -42
  9. package/dist/action/pointer-lock.d.ts +6 -0
  10. package/dist/action/pointer-lock.js +49 -0
  11. package/dist/action/pointer.d.ts +18 -0
  12. package/dist/action/pointer.js +90 -0
  13. package/dist/action/screen-joystick.d.ts +16 -0
  14. package/dist/action/screen-joystick.js +120 -0
  15. package/dist/action/screen-jump-button.d.ts +6 -0
  16. package/dist/action/screen-jump-button.js +32 -0
  17. package/dist/animation/bone-map.d.ts +4 -0
  18. package/dist/animation/bone-map.js +11 -0
  19. package/dist/animation/default.d.ts +9 -1
  20. package/dist/animation/default.js +16 -9
  21. package/dist/animation/index.d.ts +8 -13
  22. package/dist/animation/index.js +61 -39
  23. package/dist/animation/mask.d.ts +4 -1
  24. package/dist/animation/mask.js +50 -0
  25. package/dist/camera.d.ts +8 -4
  26. package/dist/camera.js +24 -9
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +1 -1
  29. package/dist/model/index.d.ts +1 -2
  30. package/dist/simple-character/apply-input-options.d.ts +2 -0
  31. package/dist/simple-character/apply-input-options.js +34 -0
  32. package/dist/simple-character/index.d.ts +33 -10
  33. package/dist/simple-character/index.js +18 -19
  34. package/dist/simple-character/state/jump-down.js +2 -1
  35. package/dist/simple-character/state/jump-forward.js +4 -2
  36. package/dist/simple-character/state/jump-loop.js +2 -1
  37. package/dist/simple-character/state/jump-start.js +2 -2
  38. package/dist/simple-character/state/jump-up.js +4 -2
  39. package/dist/simple-character/state/movement.js +12 -8
  40. package/dist/simple-character/update-input-velocity.d.ts +1 -2
  41. package/dist/simple-character/update-input-velocity.js +4 -4
  42. package/dist/simple-character/update-rotation.js +1 -1
  43. package/dist/utils.d.ts +5 -5
  44. package/dist/utils.js +15 -6
  45. package/package.json +2 -2
  46. package/dist/animation/bvh.d.ts +0 -4
  47. package/dist/animation/bvh.js +0 -8
  48. package/dist/animation/fbx.d.ts +0 -4
  49. package/dist/animation/fbx.js +0 -8
  50. package/dist/animation/gltf.d.ts +0 -3
  51. package/dist/animation/gltf.js +0 -8
  52. package/dist/animation/vrma.d.ts +0 -3
  53. package/dist/animation/vrma.js +0 -8
  54. package/dist/input/index.d.ts +0 -31
  55. package/dist/input/index.js +0 -77
  56. package/dist/input/keyboard.d.ts +0 -16
  57. package/dist/input/keyboard.js +0 -82
  58. package/dist/input/pointer-capture.d.ts +0 -20
  59. package/dist/input/pointer-lock.d.ts +0 -17
  60. package/dist/input/pointer-lock.js +0 -55
  61. package/dist/input/screen-joystick.d.ts +0 -18
  62. package/dist/input/screen-joystick.js +0 -120
  63. package/dist/input/screen-jump-button.d.ts +0 -8
  64. package/dist/input/screen-jump-button.js +0 -49
@@ -0,0 +1,120 @@
1
+ import { MoveForwardAction, MoveBackwardAction, MoveLeftAction, MoveRightAction, RunAction, } from './index.js';
2
+ const DefaultDeadZonePx = 24;
3
+ const DefaultRunDistancePx = 46;
4
+ const JoystickRadius = 56;
5
+ export class ScreenJoystickLocomotionActionBindings {
6
+ abortSignal;
7
+ root;
8
+ handle;
9
+ pointerId;
10
+ forwardWriter;
11
+ backwardWriter;
12
+ leftWriter;
13
+ rightWriter;
14
+ runWriter;
15
+ //options
16
+ runDistancePx;
17
+ deadZonePx;
18
+ constructor(domElement, abortSignal) {
19
+ this.abortSignal = abortSignal;
20
+ this.forwardWriter = MoveForwardAction.createWriter(this.abortSignal);
21
+ this.backwardWriter = MoveBackwardAction.createWriter(this.abortSignal);
22
+ this.leftWriter = MoveLeftAction.createWriter(this.abortSignal);
23
+ this.rightWriter = MoveRightAction.createWriter(this.abortSignal);
24
+ this.runWriter = RunAction.createWriter(this.abortSignal);
25
+ this.root = document.createElement('div');
26
+ this.root.className = 'viverse-joystick mobile-only';
27
+ this.root.style.position = 'absolute';
28
+ this.root.style.bottom = '24px';
29
+ this.root.style.left = '24px';
30
+ this.root.style.width = '112px';
31
+ this.root.style.height = '112px';
32
+ this.root.style.borderRadius = '9999px';
33
+ this.root.style.background = 'rgba(255,255,255,0.2)';
34
+ this.root.style.pointerEvents = 'auto';
35
+ this.root.style.touchAction = 'none';
36
+ this.root.style.userSelect = 'none';
37
+ this.root.style.setProperty('-webkit-user-select', 'none');
38
+ this.root.style.setProperty('-webkit-touch-callout', 'none');
39
+ const parent = domElement.parentElement ?? domElement;
40
+ parent.appendChild(this.root);
41
+ this.abortSignal.addEventListener('abort', () => this.root.remove(), { once: true });
42
+ this.handle = document.createElement('div');
43
+ this.handle.className = 'viverse-joystick-handle';
44
+ this.root.appendChild(this.handle);
45
+ this.handle.style.position = 'absolute';
46
+ this.handle.style.left = '50%';
47
+ this.handle.style.top = '50%';
48
+ this.handle.style.width = '56px';
49
+ this.handle.style.height = '56px';
50
+ this.handle.style.borderRadius = '9999px';
51
+ this.handle.style.background = 'rgba(0,0,0,0.3)';
52
+ this.handle.style.transform = 'translate(-50%,-50%)';
53
+ this.handle.style.willChange = 'transform';
54
+ this.handle.style.pointerEvents = 'none';
55
+ this.handle.style.touchAction = 'none';
56
+ this.handle.style.userSelect = 'none';
57
+ this.handle.style.setProperty('-webkit-user-select', 'none');
58
+ this.handle.style.setProperty('-webkit-touch-callout', 'none');
59
+ const onPointerDown = (e) => {
60
+ if (this.pointerId != null) {
61
+ return;
62
+ }
63
+ e.preventDefault();
64
+ e.stopPropagation();
65
+ this.root.setPointerCapture(e.pointerId);
66
+ this.pointerId = e.pointerId;
67
+ const rect = this.root.getBoundingClientRect();
68
+ const joyCenterX = rect.left + rect.width / 2;
69
+ const joyCenterY = rect.top + rect.height / 2;
70
+ this.updateHandle(e.clientX - joyCenterX, e.clientY - joyCenterY);
71
+ };
72
+ const onPointerMove = (e) => {
73
+ if (this.pointerId == null) {
74
+ return;
75
+ }
76
+ e.preventDefault();
77
+ e.stopPropagation();
78
+ const rect = this.root.getBoundingClientRect();
79
+ const joyCenterX = rect.left + rect.width / 2;
80
+ const joyCenterY = rect.top + rect.height / 2;
81
+ this.updateHandle(e.clientX - joyCenterX, e.clientY - joyCenterY);
82
+ };
83
+ const onPointerEnd = (e) => {
84
+ if (this.pointerId != e.pointerId) {
85
+ return;
86
+ }
87
+ this.pointerId = undefined;
88
+ this.root.releasePointerCapture(e.pointerId);
89
+ e.preventDefault();
90
+ this.resetHandle();
91
+ };
92
+ this.root.addEventListener('pointerdown', onPointerDown, { signal: this.abortSignal });
93
+ this.root.addEventListener('pointermove', onPointerMove, { signal: this.abortSignal });
94
+ this.root.addEventListener('pointerup', onPointerEnd, { signal: this.abortSignal });
95
+ this.root.addEventListener('pointercancel', onPointerEnd, { signal: this.abortSignal });
96
+ }
97
+ updateHandle(dx, dy) {
98
+ const distanceToCenter = Math.hypot(dx, dy) || 1;
99
+ const clampedX = (dx / distanceToCenter) * Math.min(distanceToCenter, JoystickRadius);
100
+ const clampedY = (dy / distanceToCenter) * Math.min(distanceToCenter, JoystickRadius);
101
+ this.handle.style.transform = `translate(-50%,-50%) translate(${clampedX}px, ${clampedY}px)`;
102
+ const deadZone = this.deadZonePx ?? DefaultDeadZonePx;
103
+ const runDistance = this.runDistancePx ?? DefaultRunDistancePx;
104
+ const moveY = distanceToCenter <= deadZone ? 0 : -clampedY / JoystickRadius;
105
+ const moveX = distanceToCenter <= deadZone ? 0 : clampedX / JoystickRadius;
106
+ this.forwardWriter.write(Math.max(0, moveY));
107
+ this.backwardWriter.write(Math.max(0, -moveY));
108
+ this.leftWriter.write(Math.max(0, -moveX));
109
+ this.rightWriter.write(Math.max(0, moveX));
110
+ this.runWriter.write(distanceToCenter > runDistance);
111
+ }
112
+ resetHandle() {
113
+ this.handle.style.transform = 'translate(-50%,-50%)';
114
+ this.forwardWriter.write(0);
115
+ this.backwardWriter.write(0);
116
+ this.leftWriter.write(0);
117
+ this.rightWriter.write(0);
118
+ this.runWriter.write(false);
119
+ }
120
+ }
@@ -0,0 +1,6 @@
1
+ export declare const defaultScreenButtonStyles: Partial<CSSStyleDeclaration>;
2
+ export declare const jumpButtonImage = "url(\"data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23444%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpolyline%20points=%2218%2015%2012%209%206%2015%22/%3E%3C/svg%3E\")";
3
+ export declare class ScreenButtonJumpActionBindings {
4
+ readonly root: HTMLDivElement;
5
+ constructor(domElement: HTMLElement, abortSignal: AbortSignal);
6
+ }
@@ -0,0 +1,32 @@
1
+ import { JumpAction } from './index.js';
2
+ import { PointerButtonActionBinding } from './pointer.js';
3
+ export const defaultScreenButtonStyles = {
4
+ position: 'absolute',
5
+ bottom: '32px',
6
+ right: '126px',
7
+ minWidth: '64px',
8
+ height: '64px',
9
+ borderRadius: '9999px',
10
+ pointerEvents: 'auto',
11
+ touchAction: 'none',
12
+ userSelect: 'none',
13
+ background: 'rgba(255,255,255,0.3)',
14
+ backgroundRepeat: 'no-repeat',
15
+ backgroundPosition: 'center',
16
+ backgroundSize: '50%',
17
+ };
18
+ Object.assign(defaultScreenButtonStyles, { '-webkit-user-select': 'none' });
19
+ export const jumpButtonImage = 'url("data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22%23444%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpolyline%20points=%2218%2015%2012%209%206%2015%22/%3E%3C/svg%3E")';
20
+ export class ScreenButtonJumpActionBindings {
21
+ root;
22
+ constructor(domElement, abortSignal) {
23
+ const parent = domElement.parentElement ?? domElement;
24
+ this.root = document.createElement('div');
25
+ this.root.className = 'viverse-button viverse-jump mobile-only';
26
+ parent.appendChild(this.root);
27
+ abortSignal.addEventListener('abort', () => this.root.remove(), { once: true });
28
+ Object.assign(this.root.style, defaultScreenButtonStyles);
29
+ new PointerButtonActionBinding(JumpAction, this.root, abortSignal);
30
+ this.root.addEventListener('pointerdown', (e) => e.stopPropagation(), { signal: abortSignal });
31
+ }
32
+ }
@@ -0,0 +1,4 @@
1
+ import { VRMHumanBoneName } from '@pixiv/three-vrm';
2
+ import { AnimationClip, Object3D } from 'three';
3
+ export type BoneMap = Record<string, VRMHumanBoneName>;
4
+ export declare function applyBoneMap(clip: AnimationClip, clipScene: Object3D | undefined, boneMap: BoneMap): void;
@@ -0,0 +1,11 @@
1
+ export function applyBoneMap(clip, clipScene, boneMap) {
2
+ for (const track of clip.tracks) {
3
+ const [clipBoneName, propertyName] = track.name.split('.');
4
+ const clipBone = clipScene?.getObjectByName(clipBoneName);
5
+ const normalizedBoneName = (boneMap?.[clipBoneName] ?? clipBoneName);
6
+ if (clipBone != null) {
7
+ clipBone.name = normalizedBoneName;
8
+ }
9
+ track.name = `${normalizedBoneName}.${propertyName}`;
10
+ }
11
+ }