@pmndrs/viverse 0.1.20 → 0.2.0
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.
- package/dist/animation/bvh.d.ts +2 -2
- package/dist/animation/default.d.ts +1 -0
- package/dist/animation/default.js +18 -0
- package/dist/animation/fbx.d.ts +2 -2
- package/dist/animation/gltf.d.ts +2 -2
- package/dist/animation/index.d.ts +14 -16
- package/dist/animation/index.js +18 -36
- package/dist/animation/mask.d.ts +3 -0
- package/dist/animation/mask.js +3 -0
- package/dist/camera.d.ts +3 -7
- package/dist/camera.js +16 -24
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/input/index.d.ts +6 -7
- package/dist/input/index.js +5 -4
- package/dist/input/keyboard.d.ts +3 -4
- package/dist/input/keyboard.js +8 -10
- package/dist/input/pointer-capture.d.ts +3 -3
- package/dist/input/pointer-capture.js +11 -12
- package/dist/input/pointer-lock.d.ts +3 -3
- package/dist/input/pointer-lock.js +10 -10
- package/dist/input/screen-joystick.d.ts +6 -10
- package/dist/input/screen-joystick.js +29 -36
- package/dist/input/screen-jump-button.d.ts +1 -1
- package/dist/model/index.d.ts +10 -13
- package/dist/model/index.js +12 -34
- package/dist/physics/index.d.ts +2 -5
- package/dist/physics/index.js +7 -16
- package/dist/simple-character/defaults.d.ts +2 -0
- package/dist/simple-character/defaults.js +2 -0
- package/dist/simple-character/index.d.ts +101 -0
- package/dist/simple-character/index.js +109 -0
- package/dist/simple-character/state/index.d.ts +6 -0
- package/dist/simple-character/state/index.js +6 -0
- package/dist/simple-character/state/jump-down.d.ts +3 -0
- package/dist/simple-character/state/jump-down.js +25 -0
- package/dist/simple-character/state/jump-forward.d.ts +5 -0
- package/dist/simple-character/state/jump-forward.js +39 -0
- package/dist/simple-character/state/jump-loop.d.ts +3 -0
- package/dist/simple-character/state/jump-loop.js +23 -0
- package/dist/simple-character/state/jump-start.d.ts +4 -0
- package/dist/simple-character/state/jump-start.js +30 -0
- package/dist/simple-character/state/jump-up.d.ts +5 -0
- package/dist/simple-character/state/jump-up.js +38 -0
- package/dist/simple-character/state/movement.d.ts +3 -0
- package/dist/simple-character/state/movement.js +59 -0
- package/dist/simple-character/update-input-velocity.d.ts +5 -0
- package/dist/simple-character/update-input-velocity.js +25 -0
- package/dist/simple-character/update-rotation.d.ts +6 -0
- package/dist/simple-character/update-rotation.js +40 -0
- package/dist/utils.d.ts +12 -5
- package/dist/utils.js +28 -39
- package/package.json +2 -2
- package/dist/simple-character.d.ts +0 -107
- package/dist/simple-character.js +0 -344
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export async function loadDefaultCharacterAnimationUrl(type) {
|
|
2
|
+
switch (type) {
|
|
3
|
+
case 'idle':
|
|
4
|
+
return (await import('../assets/idle.js')).url;
|
|
5
|
+
case 'jumpDown':
|
|
6
|
+
return (await import('../assets/jump-down.js')).url;
|
|
7
|
+
case 'jumpForward':
|
|
8
|
+
return (await import('../assets/jump-forward.js')).url;
|
|
9
|
+
case 'jumpLoop':
|
|
10
|
+
return (await import('../assets/jump-loop.js')).url;
|
|
11
|
+
case 'jumpUp':
|
|
12
|
+
return (await import('../assets/jump-up.js')).url;
|
|
13
|
+
case 'run':
|
|
14
|
+
return (await import('../assets/run.js')).url;
|
|
15
|
+
case 'walk':
|
|
16
|
+
return (await import('../assets/walk.js')).url;
|
|
17
|
+
}
|
|
18
|
+
}
|
package/dist/animation/fbx.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { AnimationClip } from 'three';
|
|
2
|
-
import {
|
|
2
|
+
import type { CharacterModel } from '../model/index.js';
|
|
3
3
|
import type { VRMHumanBoneName } from '@pixiv/three-vrm';
|
|
4
|
-
export declare function loadVrmModelFbxAnimations(model:
|
|
4
|
+
export declare function loadVrmModelFbxAnimations(model: CharacterModel, url: string, removeXZMovement: boolean, boneMap?: Record<string, VRMHumanBoneName>): Promise<Array<AnimationClip>>;
|
package/dist/animation/gltf.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { AnimationClip } from 'three';
|
|
2
|
-
import {
|
|
3
|
-
export declare function loadVrmModelGltfAnimations(model:
|
|
2
|
+
import type { CharacterModel, VRMHumanBoneName } from '../model/index.js';
|
|
3
|
+
export declare function loadVrmModelGltfAnimations(model: CharacterModel, url: string, removeXZMovement: boolean, boneMap?: Record<string, VRMHumanBoneName>): Promise<Array<AnimationClip>>;
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { VRMHumanBoneName } from '@pixiv/three-vrm';
|
|
2
2
|
import { AnimationClip, Object3D } from 'three';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { loadDefaultCharacterAnimationUrl } from './default.js';
|
|
4
|
+
import type { CharacterModel } from '../model/index.js';
|
|
5
|
+
export declare function fixModelAnimationClip(model: CharacterModel, clip: AnimationClip, clipScene: Object3D | undefined, removeXZMovement: boolean, boneMap?: Record<string, VRMHumanBoneName>): void;
|
|
5
6
|
export * from './gltf.js';
|
|
6
7
|
export * from './fbx.js';
|
|
7
8
|
export * from './vrma.js';
|
|
8
9
|
export * from './utils.js';
|
|
9
|
-
export type
|
|
10
|
+
export type CharacterAnimationMask = (boneName: VRMHumanBoneName) => boolean;
|
|
11
|
+
export type CharacterAnimationOptions = {
|
|
12
|
+
url: string | {
|
|
13
|
+
default: Parameters<typeof loadDefaultCharacterAnimationUrl>[0];
|
|
14
|
+
};
|
|
10
15
|
type?: 'mixamo' | 'gltf' | 'vrma' | 'fbx' | 'bvh';
|
|
11
|
-
url: string;
|
|
12
16
|
removeXZMovement?: boolean;
|
|
13
17
|
trimTime?: {
|
|
14
18
|
start?: number;
|
|
@@ -16,18 +20,12 @@ export type ModelAnimationOptions = {
|
|
|
16
20
|
};
|
|
17
21
|
boneMap?: Record<string, VRMHumanBoneName>;
|
|
18
22
|
scaleTime?: number;
|
|
23
|
+
mask?: CharacterAnimationMask;
|
|
19
24
|
};
|
|
20
|
-
export
|
|
21
|
-
declare
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
jumpUp: () => Promise<typeof import("../assets/jump-up.js")>;
|
|
26
|
-
jumpLoop: () => Promise<typeof import("../assets/jump-loop.js")>;
|
|
27
|
-
jumpDown: () => Promise<typeof import("../assets/jump-down.js")>;
|
|
28
|
-
jumpForward: () => Promise<typeof import("../assets/jump-forward.js")>;
|
|
29
|
-
};
|
|
30
|
-
export declare const simpleCharacterAnimationNames: Array<keyof typeof simpleCharacterAnimationUrls>;
|
|
31
|
-
export declare function getSimpleCharacterModelAnimationOptions(animationName: keyof typeof simpleCharacterAnimationUrls): Promise<ModelAnimationOptions>;
|
|
25
|
+
export type Tail<T extends any[]> = T extends [any, ...infer Rest] ? Rest : never;
|
|
26
|
+
export declare function flattenCharacterAnimationOptions(options: Exclude<CharacterAnimationOptions, false>): Tail<Parameters<typeof loadCharacterAnimation>>;
|
|
27
|
+
export declare function loadCharacterAnimation(model: CharacterModel, url: string | {
|
|
28
|
+
default: Parameters<typeof loadDefaultCharacterAnimationUrl>[0];
|
|
29
|
+
}, type?: CharacterAnimationOptions['type'], removeXZMovement?: boolean, trimStartTime?: number | undefined, trimEndTime?: number | undefined, boneMap?: Record<string, VRMHumanBoneName> | undefined, scaleTime?: number | undefined, mask?: CharacterAnimationMask): Promise<AnimationClip>;
|
|
32
30
|
export declare const mixamoBoneMap: Record<string, VRMHumanBoneName>;
|
|
33
31
|
export declare const bvhBoneMap: Record<string, VRMHumanBoneName>;
|
package/dist/animation/index.js
CHANGED
|
@@ -2,12 +2,12 @@ import { VRM } from '@pixiv/three-vrm';
|
|
|
2
2
|
import { Euler, Quaternion, QuaternionKeyframeTrack, Vector3, VectorKeyframeTrack, } from 'three';
|
|
3
3
|
import _bvhBoneMap from './bvh-bone-map.json';
|
|
4
4
|
import { loadVrmModelBvhAnimations } from './bvh.js';
|
|
5
|
+
import { loadDefaultCharacterAnimationUrl } from './default.js';
|
|
5
6
|
import { loadVrmModelFbxAnimations } from './fbx.js';
|
|
6
7
|
import { loadVrmModelGltfAnimations } from './gltf.js';
|
|
7
8
|
import _mixamoBoneMap from './mixamo-bone-map.json';
|
|
8
9
|
import { scaleAnimationClipTime, trimAnimationClip } from './utils.js';
|
|
9
10
|
import { loadVrmModelVrmaAnimations } from './vrma.js';
|
|
10
|
-
import { cached } from '../utils.js';
|
|
11
11
|
//helper variables for the quaternion retargeting
|
|
12
12
|
const baseThisLocalRestRotation_inverse = new Quaternion();
|
|
13
13
|
const baseThisLocalCurrentRotation = new Quaternion();
|
|
@@ -174,7 +174,23 @@ export * from './gltf.js';
|
|
|
174
174
|
export * from './fbx.js';
|
|
175
175
|
export * from './vrma.js';
|
|
176
176
|
export * from './utils.js';
|
|
177
|
-
|
|
177
|
+
export function flattenCharacterAnimationOptions(options) {
|
|
178
|
+
return [
|
|
179
|
+
options.url,
|
|
180
|
+
options.type,
|
|
181
|
+
options.removeXZMovement,
|
|
182
|
+
options.trimTime?.start,
|
|
183
|
+
options.trimTime?.end,
|
|
184
|
+
options.boneMap,
|
|
185
|
+
options.scaleTime,
|
|
186
|
+
options.mask,
|
|
187
|
+
];
|
|
188
|
+
}
|
|
189
|
+
export async function loadCharacterAnimation(model, url, type, removeXZMovement = false, trimStartTime, trimEndTime, boneMap, scaleTime, mask) {
|
|
190
|
+
if (typeof url === 'object') {
|
|
191
|
+
url = await loadDefaultCharacterAnimationUrl(url.default);
|
|
192
|
+
type = 'gltf';
|
|
193
|
+
}
|
|
178
194
|
let clips;
|
|
179
195
|
if (type == null) {
|
|
180
196
|
const lowerCaseUrl = url.toLocaleLowerCase();
|
|
@@ -226,39 +242,5 @@ async function uncachedLoadModelAnimation(model, type, url, removeXZMovement, tr
|
|
|
226
242
|
}
|
|
227
243
|
return clip;
|
|
228
244
|
}
|
|
229
|
-
export function loadCharacterModelAnimation(model, options) {
|
|
230
|
-
return cached(uncachedLoadModelAnimation, [
|
|
231
|
-
model,
|
|
232
|
-
options.type,
|
|
233
|
-
options.url,
|
|
234
|
-
options.removeXZMovement ?? false,
|
|
235
|
-
options.trimTime?.start,
|
|
236
|
-
options.trimTime?.end,
|
|
237
|
-
options.boneMap,
|
|
238
|
-
options.scaleTime,
|
|
239
|
-
]);
|
|
240
|
-
}
|
|
241
|
-
const extraOptions = {
|
|
242
|
-
walk: { scaleTime: 0.5 },
|
|
243
|
-
run: { scaleTime: 0.8 },
|
|
244
|
-
jumpForward: { scaleTime: 0.9 },
|
|
245
|
-
};
|
|
246
|
-
const simpleCharacterAnimationUrls = {
|
|
247
|
-
walk: () => import('../assets/walk.js'),
|
|
248
|
-
run: () => import('../assets/run.js'),
|
|
249
|
-
idle: () => import('../assets/idle.js'),
|
|
250
|
-
jumpUp: () => import('../assets/jump-up.js'),
|
|
251
|
-
jumpLoop: () => import('../assets/jump-loop.js'),
|
|
252
|
-
jumpDown: () => import('../assets/jump-down.js'),
|
|
253
|
-
jumpForward: () => import('../assets/jump-forward.js'),
|
|
254
|
-
};
|
|
255
|
-
export const simpleCharacterAnimationNames = Object.keys(simpleCharacterAnimationUrls);
|
|
256
|
-
export async function getSimpleCharacterModelAnimationOptions(animationName) {
|
|
257
|
-
return {
|
|
258
|
-
type: 'gltf',
|
|
259
|
-
...extraOptions[animationName],
|
|
260
|
-
url: (await simpleCharacterAnimationUrls[animationName]()).url,
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
245
|
export const mixamoBoneMap = _mixamoBoneMap;
|
|
264
246
|
export const bvhBoneMap = _bvhBoneMap;
|
package/dist/camera.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Object3D, Vector3, Vector3Tuple, Ray } from 'three';
|
|
2
|
-
import {
|
|
2
|
+
import { InputSystem } from './input/index.js';
|
|
3
3
|
export declare const FirstPersonCharacterCameraBehavior: SimpleCharacterCameraBehaviorOptions;
|
|
4
4
|
export type SimpleCharacterCameraBehaviorOptions = {
|
|
5
5
|
/**
|
|
@@ -55,16 +55,12 @@ export type SimpleCharacterCameraBehaviorOptions = {
|
|
|
55
55
|
maxDistance?: number;
|
|
56
56
|
} | boolean;
|
|
57
57
|
} | boolean;
|
|
58
|
-
export declare class
|
|
59
|
-
getCamera: () => Object3D;
|
|
60
|
-
character: SimpleCharacter;
|
|
61
|
-
private readonly raycast?;
|
|
58
|
+
export declare class CharacterCameraBehavior {
|
|
62
59
|
rotationPitch: number;
|
|
63
60
|
rotationYaw: number;
|
|
64
61
|
zoomDistance: number;
|
|
65
62
|
private collisionFreeZoomDistance;
|
|
66
63
|
private firstUpdate;
|
|
67
|
-
constructor(getCamera: () => Object3D, character: SimpleCharacter, raycast?: ((ray: Ray, far: number) => number | undefined) | undefined);
|
|
68
64
|
private setRotationFromDelta;
|
|
69
65
|
private setDistanceFromDelta;
|
|
70
66
|
private computeCharacterBaseOffset;
|
|
@@ -74,5 +70,5 @@ export declare class SimpleCharacterCameraBehavior {
|
|
|
74
70
|
/**
|
|
75
71
|
* @param delta in seconds
|
|
76
72
|
*/
|
|
77
|
-
update(deltaTime: number, options?: SimpleCharacterCameraBehaviorOptions): void;
|
|
73
|
+
update(camera: Object3D, target: Object3D, inputSystem: InputSystem, deltaTime: number, raycast?: (ray: Ray, far: number) => number | undefined, options?: SimpleCharacterCameraBehaviorOptions): void;
|
|
78
74
|
}
|
package/dist/camera.js
CHANGED
|
@@ -11,25 +11,17 @@ const sphericalOffset = new Vector3();
|
|
|
11
11
|
const characterWorldPosition = new Vector3();
|
|
12
12
|
const euler = new Euler();
|
|
13
13
|
const rayHelper = new Ray();
|
|
14
|
-
export class
|
|
15
|
-
getCamera;
|
|
16
|
-
character;
|
|
17
|
-
raycast;
|
|
14
|
+
export class CharacterCameraBehavior {
|
|
18
15
|
rotationPitch = (-20 * Math.PI) / 180;
|
|
19
16
|
rotationYaw = 0;
|
|
20
17
|
zoomDistance = 4; // Changed from zoom to distance for clearer semantics
|
|
21
18
|
//internal state
|
|
22
19
|
collisionFreeZoomDistance = this.zoomDistance;
|
|
23
20
|
firstUpdate = true;
|
|
24
|
-
|
|
25
|
-
this.getCamera = getCamera;
|
|
26
|
-
this.character = character;
|
|
27
|
-
this.raycast = raycast;
|
|
28
|
-
}
|
|
29
|
-
setRotationFromDelta(delta, rotationOptions) {
|
|
21
|
+
setRotationFromDelta(camera, delta, rotationOptions) {
|
|
30
22
|
if (delta.lengthSq() < 0.0001) {
|
|
31
23
|
// use current camera rotation if very close to target
|
|
32
|
-
euler.setFromQuaternion(
|
|
24
|
+
euler.setFromQuaternion(camera.quaternion, 'YXZ');
|
|
33
25
|
this.rotationPitch = euler.x;
|
|
34
26
|
this.rotationYaw = euler.y;
|
|
35
27
|
return;
|
|
@@ -63,7 +55,7 @@ export class SimpleCharacterCameraBehavior {
|
|
|
63
55
|
/**
|
|
64
56
|
* @param delta in seconds
|
|
65
57
|
*/
|
|
66
|
-
update(deltaTime, options = true) {
|
|
58
|
+
update(camera, target, inputSystem, deltaTime, raycast, options = true) {
|
|
67
59
|
if (options === false) {
|
|
68
60
|
this.firstUpdate = true;
|
|
69
61
|
return;
|
|
@@ -74,33 +66,33 @@ export class SimpleCharacterCameraBehavior {
|
|
|
74
66
|
}
|
|
75
67
|
//compute character->camera delta through offset
|
|
76
68
|
this.computeCharacterBaseOffset(chracterBaseOffsetHelper, options.characterBaseOffset);
|
|
77
|
-
|
|
69
|
+
target.getWorldPosition(characterWorldPosition);
|
|
78
70
|
characterWorldPosition.add(chracterBaseOffsetHelper);
|
|
79
|
-
|
|
71
|
+
camera.getWorldPosition(deltaHelper);
|
|
80
72
|
deltaHelper.sub(characterWorldPosition);
|
|
81
73
|
// apply rotation input to rotationYaw and rotationPitch if not disabled or first update
|
|
82
74
|
let rotationOptions = options.rotation ?? true;
|
|
83
75
|
if (!this.firstUpdate && rotationOptions !== false) {
|
|
84
76
|
rotationOptions = rotationOptions === true ? {} : rotationOptions;
|
|
85
77
|
const rotationSpeed = rotationOptions.speed ?? 1000.0;
|
|
86
|
-
const deltaYaw =
|
|
87
|
-
const deltaPitch =
|
|
78
|
+
const deltaYaw = inputSystem.get(DeltaYawField);
|
|
79
|
+
const deltaPitch = inputSystem.get(DeltaPitchField);
|
|
88
80
|
this.rotationYaw = this.clampYaw(this.rotationYaw + deltaYaw * rotationSpeed * deltaTime, rotationOptions);
|
|
89
81
|
this.rotationPitch = this.clampPitch(this.rotationPitch + deltaPitch * rotationSpeed * deltaTime, rotationOptions);
|
|
90
82
|
}
|
|
91
83
|
else {
|
|
92
|
-
this.setRotationFromDelta(deltaHelper, typeof rotationOptions === 'boolean' ? {} : rotationOptions);
|
|
84
|
+
this.setRotationFromDelta(camera, deltaHelper, typeof rotationOptions === 'boolean' ? {} : rotationOptions);
|
|
93
85
|
}
|
|
94
86
|
// apply yaw and pitch to camera rotation
|
|
95
|
-
|
|
96
|
-
rayHelper.direction.set(0, 0, 1).applyEuler(
|
|
87
|
+
camera.rotation.set(this.rotationPitch, this.rotationYaw, 0, 'YXZ');
|
|
88
|
+
rayHelper.direction.set(0, 0, 1).applyEuler(camera.rotation);
|
|
97
89
|
rayHelper.origin.copy(characterWorldPosition);
|
|
98
90
|
// apply zoom input to zoomDistance if not disabled or first update
|
|
99
91
|
let zoomOptions = options.zoom ?? true;
|
|
100
92
|
if (!this.firstUpdate && zoomOptions !== false) {
|
|
101
93
|
zoomOptions = zoomOptions === true ? {} : zoomOptions;
|
|
102
94
|
const zoomSpeed = zoomOptions.speed ?? 1000.0;
|
|
103
|
-
const deltaZoom =
|
|
95
|
+
const deltaZoom = inputSystem.get(DeltaZoomField);
|
|
104
96
|
const zoomFactor = 1 + deltaZoom * zoomSpeed * deltaTime;
|
|
105
97
|
if (deltaZoom >= 0) {
|
|
106
98
|
this.zoomDistance *= zoomFactor;
|
|
@@ -119,19 +111,19 @@ export class SimpleCharacterCameraBehavior {
|
|
|
119
111
|
if (collisionOptions === true) {
|
|
120
112
|
collisionOptions = {};
|
|
121
113
|
}
|
|
122
|
-
let distance =
|
|
114
|
+
let distance = raycast?.(rayHelper, this.zoomDistance);
|
|
123
115
|
if (distance != null) {
|
|
124
116
|
this.collisionFreeZoomDistance = distance - (collisionOptions?.offset ?? 0.2);
|
|
125
117
|
}
|
|
126
118
|
}
|
|
127
119
|
// Calculate camera position using spherical coordinates from euler
|
|
128
120
|
sphericalOffset.set(0, 0, this.collisionFreeZoomDistance);
|
|
129
|
-
sphericalOffset.applyEuler(
|
|
121
|
+
sphericalOffset.applyEuler(camera.rotation);
|
|
130
122
|
// Get target position with offset (reuse helper vector)
|
|
131
|
-
|
|
123
|
+
target.getWorldPosition(characterWorldPosition);
|
|
132
124
|
this.computeCharacterBaseOffset(chracterBaseOffsetHelper, options.characterBaseOffset);
|
|
133
125
|
characterWorldPosition.add(chracterBaseOffsetHelper);
|
|
134
126
|
// Set camera position relative to target
|
|
135
|
-
|
|
127
|
+
camera.position.copy(characterWorldPosition).add(sphericalOffset);
|
|
136
128
|
}
|
|
137
129
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from './utils.js';
|
|
2
2
|
export * from './input/index.js';
|
|
3
|
+
export * from './utils.js';
|
|
3
4
|
export * from './camera.js';
|
|
4
5
|
export * from './physics/index.js';
|
|
5
6
|
export * from './animation/index.js';
|
|
6
7
|
export * from './material.js';
|
|
7
|
-
export * from './simple-character.js';
|
|
8
|
+
export * from './simple-character/index.js';
|
|
8
9
|
export * from './model/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from './utils.js';
|
|
2
2
|
export * from './input/index.js';
|
|
3
|
+
export * from './utils.js';
|
|
3
4
|
export * from './camera.js';
|
|
4
5
|
export * from './physics/index.js';
|
|
5
6
|
export * from './animation/index.js';
|
|
6
7
|
export * from './material.js';
|
|
7
|
-
export * from './simple-character.js';
|
|
8
|
+
export * from './simple-character/index.js';
|
|
8
9
|
export * from './model/index.js';
|
|
9
10
|
(function injectMobileClassStyle() {
|
|
10
11
|
if (typeof document === 'undefined') {
|
package/dist/input/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
export declare class InputSystem {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}>, options?: {});
|
|
1
|
+
export declare class InputSystem<T extends {} = {}> {
|
|
2
|
+
options: T;
|
|
3
|
+
readonly inputs: Array<Input>;
|
|
4
|
+
constructor(options?: T);
|
|
6
5
|
add(input: Input): void;
|
|
7
6
|
remove(input: Input): void;
|
|
8
7
|
dispose(): void;
|
|
@@ -21,8 +20,8 @@ export declare const RunField: InputField<boolean>;
|
|
|
21
20
|
export declare const DeltaZoomField: InputField<number>;
|
|
22
21
|
export declare const DeltaYawField: InputField<number>;
|
|
23
22
|
export declare const DeltaPitchField: InputField<number>;
|
|
24
|
-
export interface Input {
|
|
25
|
-
get<T>(field: InputField<T
|
|
23
|
+
export interface Input<O = {}> {
|
|
24
|
+
get<T>(field: InputField<T>, options: O): T | undefined;
|
|
26
25
|
dispose?(): void;
|
|
27
26
|
}
|
|
28
27
|
export * from './pointer-lock.js';
|
package/dist/input/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export class InputSystem {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
options;
|
|
3
|
+
inputs = [];
|
|
4
|
+
constructor(options = {}) {
|
|
5
|
+
this.options = options;
|
|
5
6
|
}
|
|
6
7
|
add(input) {
|
|
7
8
|
this.inputs.push(input);
|
|
@@ -20,7 +21,7 @@ export class InputSystem {
|
|
|
20
21
|
get(field) {
|
|
21
22
|
let current;
|
|
22
23
|
for (const input of this.inputs) {
|
|
23
|
-
const result = input.get(field);
|
|
24
|
+
const result = input.get(field, this.options);
|
|
24
25
|
if (result == null) {
|
|
25
26
|
continue;
|
|
26
27
|
}
|
package/dist/input/keyboard.d.ts
CHANGED
|
@@ -7,11 +7,10 @@ export type LocomotionKeyboardInputOptions = {
|
|
|
7
7
|
keyboardRunKeys?: Array<string>;
|
|
8
8
|
keyboardJumpKeys?: Array<string>;
|
|
9
9
|
};
|
|
10
|
-
export declare class LocomotionKeyboardInput implements Input {
|
|
11
|
-
private readonly options;
|
|
10
|
+
export declare class LocomotionKeyboardInput implements Input<LocomotionKeyboardInputOptions> {
|
|
12
11
|
private readonly abortController;
|
|
13
12
|
private readonly keyState;
|
|
14
|
-
constructor(domElement: HTMLElement
|
|
15
|
-
get<T>(field: InputField<T
|
|
13
|
+
constructor(domElement: HTMLElement);
|
|
14
|
+
get<T>(field: InputField<T>, options: LocomotionKeyboardInputOptions): T | undefined;
|
|
16
15
|
dispose(): void;
|
|
17
16
|
}
|
package/dist/input/keyboard.js
CHANGED
|
@@ -6,11 +6,9 @@ const DefaultMoveRightKeys = ['KeyD'];
|
|
|
6
6
|
const DefaultRunKeys = ['ShiftRight', 'ShiftLeft'];
|
|
7
7
|
const DefaultJumpKeys = ['Space'];
|
|
8
8
|
export class LocomotionKeyboardInput {
|
|
9
|
-
options;
|
|
10
9
|
abortController = new AbortController();
|
|
11
10
|
keyState = new Map();
|
|
12
|
-
constructor(domElement
|
|
13
|
-
this.options = options;
|
|
11
|
+
constructor(domElement) {
|
|
14
12
|
domElement.tabIndex = 0;
|
|
15
13
|
domElement.addEventListener('keydown', (event) => {
|
|
16
14
|
let state = this.keyState.get(event.code);
|
|
@@ -41,9 +39,9 @@ export class LocomotionKeyboardInput {
|
|
|
41
39
|
signal: this.abortController.signal,
|
|
42
40
|
});
|
|
43
41
|
}
|
|
44
|
-
get(field) {
|
|
42
|
+
get(field, options) {
|
|
45
43
|
if (field === LastTimeJumpPressedField) {
|
|
46
|
-
const jumpKeys =
|
|
44
|
+
const jumpKeys = options.keyboardJumpKeys ?? DefaultJumpKeys;
|
|
47
45
|
const pressed = jumpKeys
|
|
48
46
|
.map((key) => this.keyState.get(key)?.pressTime ?? null)
|
|
49
47
|
.filter((t) => t != null);
|
|
@@ -52,19 +50,19 @@ export class LocomotionKeyboardInput {
|
|
|
52
50
|
let keys;
|
|
53
51
|
switch (field) {
|
|
54
52
|
case MoveForwardField:
|
|
55
|
-
keys =
|
|
53
|
+
keys = options.keyboardMoveForwardKeys ?? DefaultMoveForwardKeys;
|
|
56
54
|
break;
|
|
57
55
|
case MoveBackwardField:
|
|
58
|
-
keys =
|
|
56
|
+
keys = options.keyboardMoveBackwardKeys ?? DefaultMoveBackwardKeys;
|
|
59
57
|
break;
|
|
60
58
|
case MoveLeftField:
|
|
61
|
-
keys =
|
|
59
|
+
keys = options.keyboardMoveLeftKeys ?? DefaultMoveLeftKeys;
|
|
62
60
|
break;
|
|
63
61
|
case MoveRightField:
|
|
64
|
-
keys =
|
|
62
|
+
keys = options.keyboardMoveRightKeys ?? DefaultMoveRightKeys;
|
|
65
63
|
break;
|
|
66
64
|
case RunField:
|
|
67
|
-
keys =
|
|
65
|
+
keys = options.keyboardRunKeys ?? DefaultRunKeys;
|
|
68
66
|
break;
|
|
69
67
|
}
|
|
70
68
|
if (keys == null) {
|
|
@@ -6,7 +6,7 @@ export type PointerCaptureInputOptions = {
|
|
|
6
6
|
/**
|
|
7
7
|
* @requires to manually execute `domElement.setPointerCapture(pointerId)` on pointerdown
|
|
8
8
|
*/
|
|
9
|
-
export declare class PointerCaptureInput implements Input {
|
|
9
|
+
export declare class PointerCaptureInput implements Input<PointerCaptureInputOptions> {
|
|
10
10
|
private readonly domElement;
|
|
11
11
|
private readonly abortController;
|
|
12
12
|
private deltaZoom;
|
|
@@ -14,7 +14,7 @@ export declare class PointerCaptureInput implements Input {
|
|
|
14
14
|
private deltaPitch;
|
|
15
15
|
private activePointers;
|
|
16
16
|
private lastPinchDist;
|
|
17
|
-
constructor(domElement: HTMLElement
|
|
18
|
-
get<T>(field: InputField<T
|
|
17
|
+
constructor(domElement: HTMLElement);
|
|
18
|
+
get<T>(field: InputField<T>, options: PointerCaptureInputOptions): T | undefined;
|
|
19
19
|
dispose(): void;
|
|
20
20
|
}
|
|
@@ -10,7 +10,7 @@ export class PointerCaptureInput {
|
|
|
10
10
|
deltaPitch = 0;
|
|
11
11
|
activePointers = new Map();
|
|
12
12
|
lastPinchDist = null;
|
|
13
|
-
constructor(domElement
|
|
13
|
+
constructor(domElement) {
|
|
14
14
|
this.domElement = domElement;
|
|
15
15
|
domElement.addEventListener('pointerdown', (event) => {
|
|
16
16
|
this.domElement.setPointerCapture(event.pointerId);
|
|
@@ -31,16 +31,14 @@ export class PointerCaptureInput {
|
|
|
31
31
|
const pts = Array.from(this.activePointers.values());
|
|
32
32
|
if (this.lastPinchDist != null) {
|
|
33
33
|
const d = Math.hypot(pts[0].x - pts[1].x, pts[0].y - pts[1].y);
|
|
34
|
-
|
|
35
|
-
this.deltaZoom += (this.lastPinchDist - d) * zoomSpeed;
|
|
34
|
+
this.deltaZoom += this.lastPinchDist - d;
|
|
36
35
|
this.lastPinchDist = d;
|
|
37
36
|
}
|
|
38
37
|
event.preventDefault();
|
|
39
38
|
return;
|
|
40
39
|
}
|
|
41
|
-
|
|
42
|
-
this.
|
|
43
|
-
this.deltaPitch -= (rotationSpeed * event.movementY) / window.innerHeight;
|
|
40
|
+
this.deltaYaw -= event.movementX / window.innerHeight;
|
|
41
|
+
this.deltaPitch -= event.movementY / window.innerHeight;
|
|
44
42
|
}, {
|
|
45
43
|
signal: this.abortController.signal,
|
|
46
44
|
});
|
|
@@ -64,25 +62,26 @@ export class PointerCaptureInput {
|
|
|
64
62
|
});
|
|
65
63
|
domElement.addEventListener('wheel', (event) => {
|
|
66
64
|
event.preventDefault();
|
|
67
|
-
|
|
68
|
-
this.deltaZoom += event.deltaY * zoomSpeed;
|
|
65
|
+
this.deltaZoom += event.deltaY;
|
|
69
66
|
}, {
|
|
70
67
|
signal: this.abortController.signal,
|
|
71
68
|
});
|
|
72
69
|
}
|
|
73
|
-
get(field) {
|
|
70
|
+
get(field, options) {
|
|
71
|
+
const rotationSpeed = options.pointerCaptureRotationSpeed ?? 0.4;
|
|
72
|
+
const zoomSpeed = options.pointerCaptureZoomSpeed ?? 0.0001;
|
|
74
73
|
let result;
|
|
75
74
|
switch (field) {
|
|
76
75
|
case DeltaPitchField:
|
|
77
|
-
result = this.deltaPitch;
|
|
76
|
+
result = (this.deltaPitch * rotationSpeed);
|
|
78
77
|
this.deltaPitch = 0;
|
|
79
78
|
break;
|
|
80
79
|
case DeltaYawField:
|
|
81
|
-
result = this.deltaYaw;
|
|
80
|
+
result = (this.deltaYaw * rotationSpeed);
|
|
82
81
|
this.deltaYaw = 0;
|
|
83
82
|
break;
|
|
84
83
|
case DeltaZoomField:
|
|
85
|
-
result = this.deltaZoom;
|
|
84
|
+
result = (this.deltaZoom * zoomSpeed);
|
|
86
85
|
this.deltaZoom = 0;
|
|
87
86
|
break;
|
|
88
87
|
}
|
|
@@ -6,12 +6,12 @@ export type PointerLockInputOptions = {
|
|
|
6
6
|
/**
|
|
7
7
|
* @requires to manually execute `domElement.requestPointerLock()`
|
|
8
8
|
*/
|
|
9
|
-
export declare class PointerLockInput implements Input {
|
|
9
|
+
export declare class PointerLockInput implements Input<PointerLockInputOptions> {
|
|
10
10
|
private readonly abortController;
|
|
11
11
|
private deltaZoom;
|
|
12
12
|
private deltaYaw;
|
|
13
13
|
private deltaPitch;
|
|
14
|
-
constructor(domElement: HTMLElement
|
|
15
|
-
get<T>(field: InputField<T
|
|
14
|
+
constructor(domElement: HTMLElement);
|
|
15
|
+
get<T>(field: InputField<T>, options: PointerLockInputOptions): T | undefined;
|
|
16
16
|
dispose(): void;
|
|
17
17
|
}
|
|
@@ -7,16 +7,15 @@ export class PointerLockInput {
|
|
|
7
7
|
deltaZoom = 0;
|
|
8
8
|
deltaYaw = 0;
|
|
9
9
|
deltaPitch = 0;
|
|
10
|
-
constructor(domElement
|
|
10
|
+
constructor(domElement) {
|
|
11
11
|
domElement.addEventListener('pointermove', (event) => {
|
|
12
12
|
if (document.pointerLockElement != domElement) {
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
|
-
const rotationSpeed = options.pointerLockRotationSpeed ?? 0.4;
|
|
16
15
|
// Compute based on domElement bounds instead of window.innerHeight
|
|
17
16
|
const rect = domElement.getBoundingClientRect();
|
|
18
|
-
this.deltaYaw -=
|
|
19
|
-
this.deltaPitch -=
|
|
17
|
+
this.deltaYaw -= event.movementX / rect.height;
|
|
18
|
+
this.deltaPitch -= event.movementY / rect.height;
|
|
20
19
|
}, {
|
|
21
20
|
signal: this.abortController.signal,
|
|
22
21
|
});
|
|
@@ -24,26 +23,27 @@ export class PointerLockInput {
|
|
|
24
23
|
if (document.pointerLockElement != domElement) {
|
|
25
24
|
return;
|
|
26
25
|
}
|
|
27
|
-
|
|
28
|
-
this.deltaZoom += event.deltaY * zoomSpeed;
|
|
26
|
+
this.deltaZoom += event.deltaY;
|
|
29
27
|
event.preventDefault();
|
|
30
28
|
}, {
|
|
31
29
|
signal: this.abortController.signal,
|
|
32
30
|
});
|
|
33
31
|
}
|
|
34
|
-
get(field) {
|
|
32
|
+
get(field, options) {
|
|
33
|
+
const rotationSpeed = options.pointerLockRotationSpeed ?? 0.4;
|
|
34
|
+
const zoomSpeed = options.pointerLockZoomSpeed ?? 0.0001;
|
|
35
35
|
let result;
|
|
36
36
|
switch (field) {
|
|
37
37
|
case DeltaPitchField:
|
|
38
|
-
result = this.deltaPitch;
|
|
38
|
+
result = (this.deltaPitch * rotationSpeed);
|
|
39
39
|
this.deltaPitch = 0;
|
|
40
40
|
break;
|
|
41
41
|
case DeltaYawField:
|
|
42
|
-
result = this.deltaYaw;
|
|
42
|
+
result = (this.deltaYaw * rotationSpeed);
|
|
43
43
|
this.deltaYaw = 0;
|
|
44
44
|
break;
|
|
45
45
|
case DeltaZoomField:
|
|
46
|
-
result = this.deltaZoom;
|
|
46
|
+
result = (this.deltaZoom * zoomSpeed);
|
|
47
47
|
this.deltaZoom = 0;
|
|
48
48
|
break;
|
|
49
49
|
}
|
|
@@ -3,19 +3,15 @@ export type ScreenJoystickInputOptions = {
|
|
|
3
3
|
screenJoystickRunDistancePx?: number;
|
|
4
4
|
screenJoystickDeadZonePx?: number;
|
|
5
5
|
};
|
|
6
|
-
export declare class ScreenJoystickInput implements Input {
|
|
7
|
-
private readonly options;
|
|
6
|
+
export declare class ScreenJoystickInput implements Input<ScreenJoystickInputOptions> {
|
|
8
7
|
readonly root: HTMLDivElement;
|
|
9
8
|
private readonly handle;
|
|
10
|
-
private moveX;
|
|
11
|
-
private moveY;
|
|
12
|
-
private running;
|
|
13
|
-
private readonly joystickRadius;
|
|
14
|
-
private joyCenterX;
|
|
15
|
-
private joyCenterY;
|
|
16
9
|
private pointerId;
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
private distanceToCenter;
|
|
11
|
+
private clampedX;
|
|
12
|
+
private clampedY;
|
|
13
|
+
constructor(domElement: HTMLElement);
|
|
14
|
+
get<T>(field: InputField<T>, options: ScreenJoystickInputOptions): T | undefined;
|
|
19
15
|
dispose(): void;
|
|
20
16
|
private updateHandle;
|
|
21
17
|
private resetHandle;
|