@adatechnology/game-test-room 0.27.0 → 0.28.1
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/index.d.ts +22 -2
- package/dist/index.global.js +200 -63
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +86 -5
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createDestruction, JOINT_DEFAULTS, resolveStrings as resolveDestruction
|
|
|
3
3
|
import { createAudioEngine, createAudioSink, loadKitSamples, loadUserSamples } from "@adatechnology/game-audio";
|
|
4
4
|
import { registerFittedSounds } from "@adatechnology/game-audio/fitted";
|
|
5
5
|
import { createDestructionRenderer, createDestructionSound, dragSoundKey, impactKey, impactSoundIds, impactSoundKeys, specFromObject3D } from "@adatechnology/game-destruction-three";
|
|
6
|
-
import { bodyMass, KNOCK_CHEST, KNOCK_DOWN_SPEED, knockOf, surfaceOfMaterial } from "@adatechnology/game-contracts";
|
|
6
|
+
import { bodyMass, FIRST_PERSON_LAYER, KNOCK_CHEST, KNOCK_DOWN_SPEED, knockOf, surfaceOfMaterial } from "@adatechnology/game-contracts";
|
|
7
7
|
|
|
8
8
|
// src/body-sounds.ts
|
|
9
9
|
import { BODY_FOLEY_BANK } from "@adatechnology/game-audio";
|
|
@@ -2154,6 +2154,7 @@ function createNarrator(c) {
|
|
|
2154
2154
|
|
|
2155
2155
|
// src/player.ts
|
|
2156
2156
|
import { stepKnock } from "@adatechnology/game-contracts";
|
|
2157
|
+
var RECOIL_RETURN = { share: 0.7, seconds: 0.25 };
|
|
2157
2158
|
var SLAM_MIN_SPEED = 1.5;
|
|
2158
2159
|
var LANDING_MIN_SPEED = 1;
|
|
2159
2160
|
var EYE = 1.7;
|
|
@@ -2183,6 +2184,18 @@ function createPlayer(THREE, o) {
|
|
|
2183
2184
|
const cam = o.camera;
|
|
2184
2185
|
let yaw = 0;
|
|
2185
2186
|
let pitch = 0;
|
|
2187
|
+
const recoilReturn = o.recoilReturn ?? RECOIL_RETURN;
|
|
2188
|
+
const recoilDebt = { pitch: 0, yaw: 0 };
|
|
2189
|
+
const returnRecoil = (dt) => {
|
|
2190
|
+
if (Math.abs(recoilDebt.pitch) + Math.abs(recoilDebt.yaw) < 1e-6) return;
|
|
2191
|
+
const k = 1 - Math.exp(-3 * dt / Math.max(1e-3, recoilReturn.seconds));
|
|
2192
|
+
const back = { pitch: recoilDebt.pitch * k, yaw: recoilDebt.yaw * k };
|
|
2193
|
+
recoilDebt.pitch -= back.pitch;
|
|
2194
|
+
recoilDebt.yaw -= back.yaw;
|
|
2195
|
+
pitch = Math.max(-1.5, Math.min(1.5, pitch - back.pitch));
|
|
2196
|
+
yaw -= back.yaw;
|
|
2197
|
+
apply();
|
|
2198
|
+
};
|
|
2186
2199
|
let y = 0;
|
|
2187
2200
|
let eye = EYE;
|
|
2188
2201
|
let crouch = 0;
|
|
@@ -2524,6 +2537,7 @@ function createPlayer(THREE, o) {
|
|
|
2524
2537
|
return stunLeft;
|
|
2525
2538
|
},
|
|
2526
2539
|
update(dt) {
|
|
2540
|
+
returnRecoil(dt);
|
|
2527
2541
|
if (stunLeft > 0) {
|
|
2528
2542
|
stunLeft = Math.max(0, stunLeft - dt);
|
|
2529
2543
|
stunPhase += dt * 2.4;
|
|
@@ -2572,6 +2586,8 @@ function createPlayer(THREE, o) {
|
|
|
2572
2586
|
},
|
|
2573
2587
|
setPose(position, yw, pt) {
|
|
2574
2588
|
knocked = null;
|
|
2589
|
+
recoilDebt.pitch = 0;
|
|
2590
|
+
recoilDebt.yaw = 0;
|
|
2575
2591
|
px.x = position[0];
|
|
2576
2592
|
px.z = position[2];
|
|
2577
2593
|
floorLevel = floorHere();
|
|
@@ -2584,6 +2600,8 @@ function createPlayer(THREE, o) {
|
|
|
2584
2600
|
},
|
|
2585
2601
|
look(position, target) {
|
|
2586
2602
|
knocked = null;
|
|
2603
|
+
recoilDebt.pitch = 0;
|
|
2604
|
+
recoilDebt.yaw = 0;
|
|
2587
2605
|
px.x = position[0];
|
|
2588
2606
|
px.z = position[2];
|
|
2589
2607
|
floorLevel = floorHere();
|
|
@@ -2598,8 +2616,11 @@ function createPlayer(THREE, o) {
|
|
|
2598
2616
|
apply();
|
|
2599
2617
|
},
|
|
2600
2618
|
kick(pitchDeg, yawDeg) {
|
|
2619
|
+
const before = pitch;
|
|
2601
2620
|
pitch = Math.max(-1.5, Math.min(1.5, pitch + pitchDeg * Math.PI / 180));
|
|
2602
2621
|
yaw += yawDeg * Math.PI / 180;
|
|
2622
|
+
recoilDebt.pitch += (pitch - before) * recoilReturn.share;
|
|
2623
|
+
recoilDebt.yaw += yawDeg * Math.PI / 180 * recoilReturn.share;
|
|
2603
2624
|
apply();
|
|
2604
2625
|
},
|
|
2605
2626
|
moveBy(dx, dz) {
|
|
@@ -5499,6 +5520,7 @@ function createTestRoom(options) {
|
|
|
5499
5520
|
const scene = options.scene ?? new THREE.Scene();
|
|
5500
5521
|
const camera = options.camera ?? new THREE.PerspectiveCamera(72, width() / height(), 0.05, 140);
|
|
5501
5522
|
if (!options.camera) scene.add(camera);
|
|
5523
|
+
camera.layers.disable(FIRST_PERSON_LAYER);
|
|
5502
5524
|
const resize = () => {
|
|
5503
5525
|
const w = width();
|
|
5504
5526
|
const h = height();
|
|
@@ -5605,7 +5627,9 @@ function createTestRoom(options) {
|
|
|
5605
5627
|
profile: quality,
|
|
5606
5628
|
...options.debris?.particles ? { sprites: { kinds: patchSpriteKinds(SPRITE_KINDS, options.debris.particles) } } : {},
|
|
5607
5629
|
groundAt,
|
|
5608
|
-
marklessAt: (x, z) => terrain.waterAt(x, z) !== null
|
|
5630
|
+
marklessAt: (x, z) => terrain.waterAt(x, z) !== null,
|
|
5631
|
+
// the dirt crater of the effects only where the ground is loose; rock, asphalt and a slab keep the soot and the bowl the terrain itself dug
|
|
5632
|
+
cratersAt: (x, z) => terrain.material(terrain.columnAt(x, z).material).reposeDegrees !== void 0
|
|
5609
5633
|
})
|
|
5610
5634
|
});
|
|
5611
5635
|
const renderer = createDestructionRenderer(THREE, {
|
|
@@ -6590,10 +6614,21 @@ function createTestRoom(options) {
|
|
|
6590
6614
|
return { ...pose, position: pose.at(camDistance), free: camDistance };
|
|
6591
6615
|
};
|
|
6592
6616
|
const thirdActive = () => cameraMode === "third" && avatar !== null;
|
|
6617
|
+
const firstPersonArms = options.firstPersonArms ?? null;
|
|
6618
|
+
if (firstPersonArms) {
|
|
6619
|
+
firstPersonArms.root.visible = cameraMode === "first";
|
|
6620
|
+
scene.add(firstPersonArms.root);
|
|
6621
|
+
}
|
|
6593
6622
|
const syncAvatarVisible = () => {
|
|
6623
|
+
if (firstPersonArms) firstPersonArms.root.visible = cameraMode === "first";
|
|
6594
6624
|
if (!avatar) return;
|
|
6595
6625
|
avatar.root.visible = cameraMode === "third" || !!avatar.eye;
|
|
6596
|
-
avatar.setView?.(cameraMode, camera);
|
|
6626
|
+
avatar.setView?.(cameraMode, camera, { arms: firstPersonArms !== null });
|
|
6627
|
+
};
|
|
6628
|
+
const updateFirstPersonArms = (dt) => {
|
|
6629
|
+
if (!firstPersonArms || cameraMode !== "first") return;
|
|
6630
|
+
firstPersonArms.update(dt, { camera, targets: lastHand.targets, stance: lastHand.stance, speed: player.speed, running: avatarState.running, crouch: avatarState.crouch });
|
|
6631
|
+
firstPersonArms.root.traverse((node) => node.layers.set(FIRST_PERSON_LAYER));
|
|
6597
6632
|
};
|
|
6598
6633
|
const setCameraMode = (mode) => {
|
|
6599
6634
|
if (mode !== "first" && mode !== "third") return;
|
|
@@ -6677,6 +6712,39 @@ function createTestRoom(options) {
|
|
|
6677
6712
|
};
|
|
6678
6713
|
let handSource = null;
|
|
6679
6714
|
let muzzleSource = null;
|
|
6715
|
+
let viewmodelFov = null;
|
|
6716
|
+
const firstPersonCamera = new THREE.PerspectiveCamera(72, 1, 0.01, 30);
|
|
6717
|
+
firstPersonCamera.layers.set(FIRST_PERSON_LAYER);
|
|
6718
|
+
let firstPersonPasses = 0;
|
|
6719
|
+
const drawFirstPersonLayer = () => {
|
|
6720
|
+
if (!firstPersonArms && viewmodelFov === null) return;
|
|
6721
|
+
const renderer2 = gl;
|
|
6722
|
+
if (typeof renderer2.clearDepth !== "function" || typeof renderer2.render !== "function") return;
|
|
6723
|
+
if (firstPersonPasses++ % 60 === 0) {
|
|
6724
|
+
scene.traverse((node) => {
|
|
6725
|
+
if (node.isLight) node.layers.enable(FIRST_PERSON_LAYER);
|
|
6726
|
+
});
|
|
6727
|
+
}
|
|
6728
|
+
firstPersonCamera.position.copy(camera.position);
|
|
6729
|
+
firstPersonCamera.quaternion.copy(camera.quaternion);
|
|
6730
|
+
const fov = viewmodelFov ?? camera.fov;
|
|
6731
|
+
if (firstPersonCamera.fov !== fov || firstPersonCamera.aspect !== camera.aspect) {
|
|
6732
|
+
firstPersonCamera.fov = fov;
|
|
6733
|
+
firstPersonCamera.aspect = camera.aspect;
|
|
6734
|
+
firstPersonCamera.updateProjectionMatrix();
|
|
6735
|
+
}
|
|
6736
|
+
firstPersonCamera.updateMatrixWorld();
|
|
6737
|
+
const { autoClear } = renderer2;
|
|
6738
|
+
const { background, fog } = scene;
|
|
6739
|
+
renderer2.autoClear = false;
|
|
6740
|
+
scene.background = null;
|
|
6741
|
+
scene.fog = null;
|
|
6742
|
+
renderer2.clearDepth();
|
|
6743
|
+
renderer2.render(scene, firstPersonCamera);
|
|
6744
|
+
scene.background = background;
|
|
6745
|
+
scene.fog = fog;
|
|
6746
|
+
renderer2.autoClear = autoClear ?? true;
|
|
6747
|
+
};
|
|
6680
6748
|
let debugView = null;
|
|
6681
6749
|
let lastHand = { stance: "relaxed", triggerFinger: null, targets: null };
|
|
6682
6750
|
const strikeClips = options.strikeClips ?? DEFAULT_STRIKE_CLIPS;
|
|
@@ -6824,7 +6892,7 @@ function createTestRoom(options) {
|
|
|
6824
6892
|
const line = new THREE.Line(g, tracerMat);
|
|
6825
6893
|
line.frustumCulled = false;
|
|
6826
6894
|
scene.add(line);
|
|
6827
|
-
tr = { line, life: 0 };
|
|
6895
|
+
tr = { line, life: 0, follows: false };
|
|
6828
6896
|
tracers.push(tr);
|
|
6829
6897
|
}
|
|
6830
6898
|
const attr = tr.line.geometry.getAttribute("position");
|
|
@@ -6833,6 +6901,7 @@ function createTestRoom(options) {
|
|
|
6833
6901
|
attr.needsUpdate = true;
|
|
6834
6902
|
tr.line.visible = true;
|
|
6835
6903
|
tr.life = 0.07;
|
|
6904
|
+
tr.follows = muzzleSource !== null;
|
|
6836
6905
|
};
|
|
6837
6906
|
const fireZones = [];
|
|
6838
6907
|
const burningStains = [];
|
|
@@ -8148,10 +8217,16 @@ function createTestRoom(options) {
|
|
|
8148
8217
|
}
|
|
8149
8218
|
};
|
|
8150
8219
|
const simulateAfterModules = (dt) => {
|
|
8220
|
+
const drawn = tracers.some((tr) => tr.life > 0 && tr.follows) ? muzzleSource?.() ?? null : null;
|
|
8151
8221
|
for (const tr of tracers) {
|
|
8152
8222
|
if (tr.life > 0) {
|
|
8153
8223
|
tr.life -= dt;
|
|
8154
8224
|
if (tr.life <= 0) tr.line.visible = false;
|
|
8225
|
+
else if (tr.follows && drawn) {
|
|
8226
|
+
const attr = tr.line.geometry.getAttribute("position");
|
|
8227
|
+
attr.setXYZ(0, drawn.position[0], drawn.position[1], drawn.position[2]);
|
|
8228
|
+
attr.needsUpdate = true;
|
|
8229
|
+
}
|
|
8155
8230
|
}
|
|
8156
8231
|
}
|
|
8157
8232
|
flush();
|
|
@@ -8185,6 +8260,7 @@ function createTestRoom(options) {
|
|
|
8185
8260
|
};
|
|
8186
8261
|
const updatePresent = (dt) => {
|
|
8187
8262
|
reachAvatar();
|
|
8263
|
+
updateFirstPersonArms(dt);
|
|
8188
8264
|
if (progress && simTime - progress.at > 0.25) progress = null;
|
|
8189
8265
|
ui?.flushLog();
|
|
8190
8266
|
hudAcc += dt;
|
|
@@ -8534,6 +8610,9 @@ function createTestRoom(options) {
|
|
|
8534
8610
|
if (handSource === source) handSource = null;
|
|
8535
8611
|
};
|
|
8536
8612
|
},
|
|
8613
|
+
setViewmodelFov(degrees) {
|
|
8614
|
+
viewmodelFov = degrees;
|
|
8615
|
+
},
|
|
8537
8616
|
setMuzzleSource(source) {
|
|
8538
8617
|
muzzleSource = source;
|
|
8539
8618
|
return () => {
|
|
@@ -9265,7 +9344,9 @@ function createTestRoom(options) {
|
|
|
9265
9344
|
for (const batcher of batchers.values()) batcher.update();
|
|
9266
9345
|
const restoreCamera = room.applyCamera();
|
|
9267
9346
|
graphics?.beforeRender(camera);
|
|
9268
|
-
|
|
9347
|
+
const view = debugView ?? moduleViews.main(camera);
|
|
9348
|
+
gl.render(scene, view);
|
|
9349
|
+
if (view === camera && cameraMode === "first") drawFirstPersonLayer();
|
|
9269
9350
|
moduleViews.render(scene);
|
|
9270
9351
|
graphics?.afterRender();
|
|
9271
9352
|
restoreCamera();
|