@adatechnology/game-characters-three 0.6.0 → 0.7.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/index.d.ts +87 -21
- package/dist/index.global.js +293 -101
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +294 -101
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -993,7 +993,7 @@ var createBestBuilder = (host, { types, random = Math.random }) => {
|
|
|
993
993
|
});
|
|
994
994
|
}
|
|
995
995
|
const neckLen = 0.14 + Math.max(0, P.neck);
|
|
996
|
-
|
|
996
|
+
const neck = cut.head ? void 0 : add(U, CYL(0.058, 0.068, neckLen, SEG), skinM, 0, 1.63 + Math.max(0, P.neck) / 2, 0);
|
|
997
997
|
const headG = new THREE.Group();
|
|
998
998
|
headG.position.set(0, 1.64 + P.neck, P.headFwd || 0);
|
|
999
999
|
headG.rotation.x = P.headX;
|
|
@@ -1200,6 +1200,7 @@ var createBestBuilder = (host, { types, random = Math.random }) => {
|
|
|
1200
1200
|
if (o.userData.flap) flaps.push(o);
|
|
1201
1201
|
});
|
|
1202
1202
|
const rig = { flaps, dangles: arms.filter((a) => a.el.userData.dangle), type: spec.type || "Lento", fig, upper, headG, arms, legs, P, ph: spec.phase ?? options.random() * 6, dropBase: fig.position.y, leanBase: P.lean, hxBase: P.headX };
|
|
1203
|
+
if (neck) Object.defineProperty(rig, "neck", { value: neck });
|
|
1203
1204
|
if (spec.lying) {
|
|
1204
1205
|
root.rotation.x = -PI / 2;
|
|
1205
1206
|
root.position.set(0, 0.16 * P.s, 0.9 * P.s);
|
|
@@ -3751,7 +3752,8 @@ function createCharactersTestModule(options = {}) {
|
|
|
3751
3752
|
const makeKit = () => options.createKit ? options.createKit({ penetration: settings.penetration, deathRule: settings.deathRule }) : createCharacters({ ...options.packs ? { packs: options.packs } : {}, penetration: settings.penetration, damage: { deathRule: settings.deathRule } });
|
|
3752
3753
|
let kit = makeKit();
|
|
3753
3754
|
let undead = options.createUndead ? options.createUndead(kit) : null;
|
|
3754
|
-
|
|
3755
|
+
let stream = createRng3(options.seed ?? 1);
|
|
3756
|
+
const random = () => stream();
|
|
3755
3757
|
let seedCounter = 100;
|
|
3756
3758
|
let host = null;
|
|
3757
3759
|
let three = null;
|
|
@@ -4131,6 +4133,14 @@ function createCharactersTestModule(options = {}) {
|
|
|
4131
4133
|
wounds = createWounds(lent.THREE, { random, scene: scene2, groundAt: (x, z) => lent.groundAt(x, z), ...bridge ? { bridge } : {}, ...sound ? { sound } : {} });
|
|
4132
4134
|
for (const entry of entries.values()) trackEntry(entry);
|
|
4133
4135
|
const stopChange = lent.bench?.onChange(onChange);
|
|
4136
|
+
const stopReset = lent.onReset?.(() => {
|
|
4137
|
+
stream = createRng3(options.seed ?? 1);
|
|
4138
|
+
seedCounter = 100;
|
|
4139
|
+
time = 0;
|
|
4140
|
+
selected = null;
|
|
4141
|
+
lastCrossed = 0;
|
|
4142
|
+
lastEnergy = 1;
|
|
4143
|
+
});
|
|
4134
4144
|
const stopEvents = lent.on((event) => {
|
|
4135
4145
|
if (event.type !== "explosion") return;
|
|
4136
4146
|
for (const entry of entries.values()) {
|
|
@@ -4155,6 +4165,7 @@ function createCharactersTestModule(options = {}) {
|
|
|
4155
4165
|
});
|
|
4156
4166
|
return () => {
|
|
4157
4167
|
stopChange?.();
|
|
4168
|
+
stopReset?.();
|
|
4158
4169
|
stopEvents();
|
|
4159
4170
|
stopFrame();
|
|
4160
4171
|
clearOverlays();
|
|
@@ -4201,6 +4212,7 @@ import {
|
|
|
4201
4212
|
filterPoseChannels,
|
|
4202
4213
|
samplePoseClip,
|
|
4203
4214
|
walkCadence,
|
|
4215
|
+
stepCascade as stepCascade2,
|
|
4204
4216
|
walkGait
|
|
4205
4217
|
} from "@adatechnology/game-characters";
|
|
4206
4218
|
|
|
@@ -4276,8 +4288,22 @@ var ARM_REACH = {
|
|
|
4276
4288
|
slack: 0.96,
|
|
4277
4289
|
/** Where the elbow points: down and out from the body, a little back (body space, x outward). */
|
|
4278
4290
|
elbowPole: [0.55, -1, -0.25],
|
|
4291
|
+
/** The support arm's elbow: under the gun, hardly out of the body (the first-person arms' `elbowPoleLeft`), so the forearm meets the handguard nearer the aim's line. */
|
|
4292
|
+
elbowPoleSupport: [0.1, -1, -0.2],
|
|
4279
4293
|
/** From the wrist joint to the middle of the palm, metres of the body. */
|
|
4280
|
-
palm: 0.042
|
|
4294
|
+
palm: 0.042,
|
|
4295
|
+
/** In a view the elbow keeps at least this interior bend where a hand is out of reach, right then left (the first-person arms' numbers). */
|
|
4296
|
+
viewBend: [1.35, 0.95],
|
|
4297
|
+
/** In a view a hand stays this far before a surface, metres. */
|
|
4298
|
+
contactMargin: 5e-3,
|
|
4299
|
+
/** In a view a hand is never nearer than this to the eye, metres. */
|
|
4300
|
+
contactNearest: 0.12,
|
|
4301
|
+
/** How far in front of the eye a surface is looked for, metres. */
|
|
4302
|
+
contactProbe: 1.4,
|
|
4303
|
+
/** How far a hand reaches forward of its middle at least (the thickness of the palm), and per metre of fingers pointing ahead. */
|
|
4304
|
+
contactPalm: 0.03,
|
|
4305
|
+
/** From the middle of the palm to the fingertips. */
|
|
4306
|
+
contactFingers: 0.085
|
|
4281
4307
|
};
|
|
4282
4308
|
var createArmReach = (THREE, rig, hands) => {
|
|
4283
4309
|
const arms = {
|
|
@@ -4298,11 +4324,17 @@ var createArmReach = (THREE, rig, hands) => {
|
|
|
4298
4324
|
const v = { shoulder: new THREE.Vector3(), elbow: new THREE.Vector3(), wrist: new THREE.Vector3(), palm: new THREE.Vector3(), target: new THREE.Vector3(), pole: new THREE.Vector3(), a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3() };
|
|
4299
4325
|
const q = { hand: new THREE.Quaternion(), parent: new THREE.Quaternion(), body: new THREE.Quaternion(), local: new THREE.Quaternion(), swing: new THREE.Quaternion(), twist: new THREE.Quaternion(), rest: new THREE.Quaternion() };
|
|
4300
4326
|
const basis = new THREE.Matrix4();
|
|
4327
|
+
const camera = { position: new THREE.Vector3(), quaternion: new THREE.Quaternion(), inverse: new THREE.Quaternion(), probe: new THREE.Vector3(), forward: new THREE.Vector3(), fingers: new THREE.Vector3(), hand: new THREE.Quaternion() };
|
|
4328
|
+
let bendLimit = null;
|
|
4301
4329
|
const yAxis = new THREE.Vector3(0, 1, 0);
|
|
4302
4330
|
const lengthsOf = (arm) => {
|
|
4303
4331
|
const scale = arm.g.getWorldScale(v.a).y;
|
|
4304
4332
|
return { upper: arm.el.position.length() * scale, fore: arm.hand.position.length() * scale, palm: ARM_REACH.palm * scale };
|
|
4305
4333
|
};
|
|
4334
|
+
const limitOf = (side, upperLength, fore) => {
|
|
4335
|
+
if (!bendLimit) return (upperLength + fore) * ARM_REACH.slack;
|
|
4336
|
+
return Math.sqrt(upperLength * upperLength + fore * fore + 2 * upperLength * fore * Math.cos(bendLimit[side === "R" ? 0 : 1]));
|
|
4337
|
+
};
|
|
4306
4338
|
const wristOf = (side, pose, palm) => {
|
|
4307
4339
|
q.hand.set(...pose.quaternion).multiply(handBasis[side]);
|
|
4308
4340
|
v.palm.set(...pose.position);
|
|
@@ -4311,14 +4343,14 @@ var createArmReach = (THREE, rig, hands) => {
|
|
|
4311
4343
|
const turnChest = (pose) => {
|
|
4312
4344
|
const { upper: up, fore, palm } = lengthsOf(arms.L);
|
|
4313
4345
|
wristOf("L", pose, palm);
|
|
4314
|
-
const excess = arms.L.g.getWorldPosition(v.shoulder).distanceTo(v.wrist) - (up
|
|
4346
|
+
const excess = arms.L.g.getWorldPosition(v.shoulder).distanceTo(v.wrist) - limitOf("L", up, fore);
|
|
4315
4347
|
if (excess <= 0) return;
|
|
4316
4348
|
const chestRadius = Math.hypot(arms.L.g.position.x, arms.L.g.position.z) * arms.L.g.getWorldScale(v.a).y;
|
|
4317
4349
|
upper.rotation.y -= Math.min(ARM_REACH.chestTurn, excess / Math.max(0.05, chestRadius));
|
|
4318
4350
|
upper.updateMatrixWorld(true);
|
|
4319
4351
|
};
|
|
4320
|
-
const protract = (arm,
|
|
4321
|
-
const excess = arm.g.getWorldPosition(v.shoulder).distanceTo(v.wrist) -
|
|
4352
|
+
const protract = (arm, limit) => {
|
|
4353
|
+
const excess = arm.g.getWorldPosition(v.shoulder).distanceTo(v.wrist) - limit;
|
|
4322
4354
|
if (excess <= 0) return;
|
|
4323
4355
|
const parent = arm.g.parent;
|
|
4324
4356
|
v.b.copy(v.wrist).sub(v.shoulder).normalize().multiplyScalar(Math.min(excess, ARM_REACH.protraction)).add(v.shoulder);
|
|
@@ -4339,11 +4371,13 @@ var createArmReach = (THREE, rig, hands) => {
|
|
|
4339
4371
|
const arm = arms[side];
|
|
4340
4372
|
const { upper: up, fore, palm } = lengthsOf(arm);
|
|
4341
4373
|
wristOf(side, pose, palm);
|
|
4342
|
-
protract(arm, up
|
|
4374
|
+
protract(arm, limitOf(side, up, fore));
|
|
4343
4375
|
arm.g.getWorldPosition(v.shoulder);
|
|
4344
4376
|
upper.getWorldQuaternion(q.body);
|
|
4345
|
-
|
|
4346
|
-
|
|
4377
|
+
const pole = side === "L" ? ARM_REACH.elbowPoleSupport : ARM_REACH.elbowPole;
|
|
4378
|
+
v.pole.set(pole[0] * arm.outward, pole[1], pole[2]).applyQuaternion(q.body);
|
|
4379
|
+
const lockLimit = Math.sqrt(up * up + fore * fore + 2 * up * fore * Math.cos(ARM_REACH.elbowMin));
|
|
4380
|
+
const most = bendLimit ? Math.min(lockLimit, limitOf(side, up, fore)) : lockLimit;
|
|
4347
4381
|
const least = Math.sqrt(up * up + fore * fore + 2 * up * fore * Math.cos(ARM_REACH.elbowMax));
|
|
4348
4382
|
const line = v.c.copy(v.wrist).sub(v.shoulder);
|
|
4349
4383
|
const distance2 = Math.min(most, Math.max(least, line.length()));
|
|
@@ -4368,6 +4402,20 @@ var createArmReach = (THREE, rig, hands) => {
|
|
|
4368
4402
|
arm.el.getWorldQuaternion(q.parent);
|
|
4369
4403
|
arm.hand.quaternion.copy(limitWrist(q.local.copy(q.parent.invert()).multiply(q.hand)));
|
|
4370
4404
|
};
|
|
4405
|
+
const keepOutside = (pose, outside) => {
|
|
4406
|
+
const place = v.a.set(...pose.position).sub(camera.position).applyQuaternion(camera.inverse);
|
|
4407
|
+
camera.probe.set(place.x, place.y, 0).applyQuaternion(camera.quaternion).add(camera.position);
|
|
4408
|
+
camera.forward.set(0, 0, -1).applyQuaternion(camera.quaternion);
|
|
4409
|
+
const distance2 = outside.contact([camera.probe.x, camera.probe.y, camera.probe.z], [camera.forward.x, camera.forward.y, camera.forward.z], ARM_REACH.contactProbe);
|
|
4410
|
+
if (distance2 === null) return pose;
|
|
4411
|
+
camera.hand.set(...pose.quaternion).premultiply(camera.inverse);
|
|
4412
|
+
const ahead = Math.max(ARM_REACH.contactPalm, -camera.fingers.set(1, 0, 0).applyQuaternion(camera.hand).z * ARM_REACH.contactFingers);
|
|
4413
|
+
const limit = Math.max(outside.nearest ?? ARM_REACH.contactNearest, distance2 - ahead - (outside.margin ?? ARM_REACH.contactMargin));
|
|
4414
|
+
if (-place.z <= limit) return pose;
|
|
4415
|
+
place.z = -limit;
|
|
4416
|
+
place.applyQuaternion(camera.quaternion).add(camera.position);
|
|
4417
|
+
return { ...pose, position: [place.x, place.y, place.z] };
|
|
4418
|
+
};
|
|
4371
4419
|
const save = () => {
|
|
4372
4420
|
saved.twist = upper.rotation.y;
|
|
4373
4421
|
for (const side of ["R", "L"]) {
|
|
@@ -4380,14 +4428,24 @@ var createArmReach = (THREE, rig, hands) => {
|
|
|
4380
4428
|
}
|
|
4381
4429
|
};
|
|
4382
4430
|
return {
|
|
4383
|
-
apply(targets) {
|
|
4431
|
+
apply(targets, view) {
|
|
4384
4432
|
if (!targets || !targets.R && !targets.L) return;
|
|
4385
4433
|
save();
|
|
4386
4434
|
applied = true;
|
|
4387
4435
|
upper.updateWorldMatrix(true, true);
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
if (
|
|
4436
|
+
let { R, L } = targets;
|
|
4437
|
+
bendLimit = view ? view.reachBend ?? ARM_REACH.viewBend : null;
|
|
4438
|
+
if (view?.keepOutside) {
|
|
4439
|
+
view.camera.updateWorldMatrix(true, false);
|
|
4440
|
+
view.camera.matrixWorld.decompose(camera.position, camera.quaternion, v.a);
|
|
4441
|
+
camera.inverse.copy(camera.quaternion).invert();
|
|
4442
|
+
if (R) R = keepOutside(R, view.keepOutside);
|
|
4443
|
+
if (L) L = keepOutside(L, view.keepOutside);
|
|
4444
|
+
}
|
|
4445
|
+
if (L && R) turnChest(L);
|
|
4446
|
+
if (R) reach("R", R);
|
|
4447
|
+
if (L) reach("L", L);
|
|
4448
|
+
bendLimit = null;
|
|
4391
4449
|
},
|
|
4392
4450
|
restore() {
|
|
4393
4451
|
if (!applied) return;
|
|
@@ -4405,12 +4463,56 @@ var createArmReach = (THREE, rig, hands) => {
|
|
|
4405
4463
|
};
|
|
4406
4464
|
};
|
|
4407
4465
|
|
|
4466
|
+
// src/player/head-hiding.ts
|
|
4467
|
+
var isDrawable = (object) => {
|
|
4468
|
+
const flagged = object;
|
|
4469
|
+
return Boolean(flagged.isMesh || flagged.isSprite || flagged.isPoints);
|
|
4470
|
+
};
|
|
4471
|
+
var createHeadHider = (roots) => {
|
|
4472
|
+
let isHiding = false;
|
|
4473
|
+
let viewCamera = null;
|
|
4474
|
+
const drawables = [];
|
|
4475
|
+
for (const root of roots) root.traverse((object) => isDrawable(object) && drawables.push(object));
|
|
4476
|
+
for (const drawable of drawables) {
|
|
4477
|
+
const previousBefore = drawable.onBeforeRender;
|
|
4478
|
+
const previousAfter = drawable.onAfterRender;
|
|
4479
|
+
let saved = [];
|
|
4480
|
+
drawable.onBeforeRender = (renderer, scene2, camera, geometry, material, group) => {
|
|
4481
|
+
previousBefore.call(drawable, renderer, scene2, camera, geometry, material, group);
|
|
4482
|
+
if (!isHiding || camera !== viewCamera) return;
|
|
4483
|
+
const drawn = Array.isArray(drawable.material) ? drawable.material : [material];
|
|
4484
|
+
saved = drawn.map((entry) => ({ material: entry, colorWrite: entry.colorWrite, depthWrite: entry.depthWrite }));
|
|
4485
|
+
for (const entry of drawn) {
|
|
4486
|
+
entry.colorWrite = false;
|
|
4487
|
+
entry.depthWrite = false;
|
|
4488
|
+
}
|
|
4489
|
+
};
|
|
4490
|
+
drawable.onAfterRender = (renderer, scene2, camera, geometry, material, group) => {
|
|
4491
|
+
previousAfter.call(drawable, renderer, scene2, camera, geometry, material, group);
|
|
4492
|
+
for (const flags of saved) {
|
|
4493
|
+
flags.material.colorWrite = flags.colorWrite;
|
|
4494
|
+
flags.material.depthWrite = flags.depthWrite;
|
|
4495
|
+
}
|
|
4496
|
+
saved = [];
|
|
4497
|
+
};
|
|
4498
|
+
}
|
|
4499
|
+
return {
|
|
4500
|
+
setView(mode, camera) {
|
|
4501
|
+
isHiding = mode === "first" && camera !== null;
|
|
4502
|
+
viewCamera = camera;
|
|
4503
|
+
}
|
|
4504
|
+
};
|
|
4505
|
+
};
|
|
4506
|
+
|
|
4408
4507
|
// src/player/avatar.ts
|
|
4409
4508
|
var TWO_PI = Math.PI * 2;
|
|
4410
4509
|
var MAX_GAIT = 1.4;
|
|
4411
4510
|
var CLIP_BLEND = 0.12;
|
|
4412
4511
|
var CLIP_CASCADE = 5;
|
|
4413
4512
|
var FALL_SECONDS2 = 0.3;
|
|
4513
|
+
var BUILDER_EYE = [0, 1.815, 0.16];
|
|
4514
|
+
var EYE_OFFSET = [0, -0.068, 0];
|
|
4515
|
+
var EYE_BOB = 0.5;
|
|
4414
4516
|
var HIP_HEIGHT = 0.95;
|
|
4415
4517
|
var WALK_ARM = 0.28;
|
|
4416
4518
|
var WALK_BOB = 0.035;
|
|
@@ -4420,7 +4522,11 @@ var RUN_BOB = 0.05;
|
|
|
4420
4522
|
var REST_ARM_Z = 0.18;
|
|
4421
4523
|
var CROUCH = { thigh: -0.95, thighWalk: 0.3, shin: 1.9, lean: 0.25, drop: -0.35 };
|
|
4422
4524
|
var AIMED = { shoulder: -1.42, perAim: 0.85, swing: 0.02, zRight: -0.54, zLeft: 0.36, elbowRight: -0.04, elbowLeft: -0.12 };
|
|
4525
|
+
var SIT = { thigh: -1.5, lean: -0.08, arm: -0.45, armZ: 0.12, elbow: -0.75 };
|
|
4526
|
+
var LIE = { knee: 0.08, armZ: 0.12, elbow: -0.1 };
|
|
4423
4527
|
var DOWN = { thighWalk: 0.5, shinSwing: 0.85, shinBend: 1.3, armHigh: -2.8, armLow: -0.35, armWave: 0.3, armZ: 0.5, armZWave: 0.3, tilt: 1.5, roll: 0.3, hipY: 0.16, hipZ: 0.6, hipZFlip: 1.2 };
|
|
4528
|
+
var DOOR_SHOULDER = 1.42;
|
|
4529
|
+
var DOOR_ARM = 0.62;
|
|
4424
4530
|
var HAND_OFFSET = { x: 0, y: -0.33, z: 0.04 };
|
|
4425
4531
|
var hexOf = (value) => typeof value === "string" ? Number.parseInt(value, 16) : value;
|
|
4426
4532
|
var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
@@ -4450,6 +4556,8 @@ var createPlayerAvatar = (THREE, options = {}) => {
|
|
|
4450
4556
|
const fallSeconds = options.fallSeconds ?? FALL_SECONDS2;
|
|
4451
4557
|
const smooth = options.cascade ?? true;
|
|
4452
4558
|
const clipCascade = options.clipCascade ?? CLIP_CASCADE;
|
|
4559
|
+
const eyeBob = options.eyeBob ?? EYE_BOB;
|
|
4560
|
+
const eyeOffset = options.eyeOffset ?? EYE_OFFSET;
|
|
4453
4561
|
const root = new THREE.Group();
|
|
4454
4562
|
const tilt = new THREE.Group();
|
|
4455
4563
|
tilt.add(body);
|
|
@@ -4509,7 +4617,23 @@ var createPlayerAvatar = (THREE, options = {}) => {
|
|
|
4509
4617
|
if (hand.th) hand.th.rotation.z = -hand.side * (0.32 + grip * 0.25);
|
|
4510
4618
|
hand.hg.rotation.x = wristX;
|
|
4511
4619
|
};
|
|
4620
|
+
const eyeSocket = new THREE.Object3D();
|
|
4621
|
+
eyeSocket.name = "eye";
|
|
4622
|
+
eyeSocket.position.set(BUILDER_EYE[0] + eyeOffset[0], BUILDER_EYE[1] + eyeOffset[1], BUILDER_EYE[2] + eyeOffset[2]);
|
|
4623
|
+
rig.headG.children[0].add(eyeSocket);
|
|
4624
|
+
const headHider = createHeadHider([rig.headG, ...rig.neck ? [rig.neck] : []]);
|
|
4625
|
+
const eyeLocal = new THREE.Vector3();
|
|
4626
|
+
let bob = 0;
|
|
4627
|
+
let hipWithoutBob = null;
|
|
4512
4628
|
const legRestX = rig.legs.map((leg) => leg.g.position.x);
|
|
4629
|
+
const legLengths = (() => {
|
|
4630
|
+
const thigh = rig.legs[0].g;
|
|
4631
|
+
const shin = rig.legs[0].kn;
|
|
4632
|
+
root.updateMatrixWorld(true);
|
|
4633
|
+
const hipY = thigh.getWorldPosition(new THREE.Vector3()).y;
|
|
4634
|
+
const kneeY = shin.getWorldPosition(new THREE.Vector3()).y;
|
|
4635
|
+
return { hipBelowTrunk: HIP_HEIGHT - hipY, thigh: hipY - kneeY, shin: kneeY - new THREE.Box3().setFromObject(shin).min.y };
|
|
4636
|
+
})();
|
|
4513
4637
|
const legSide = (index) => index === 0 ? 1 : -1;
|
|
4514
4638
|
let cycles = 0;
|
|
4515
4639
|
let time = 0;
|
|
@@ -4568,10 +4692,29 @@ var createPlayerAvatar = (THREE, options = {}) => {
|
|
|
4568
4692
|
...strain ? { legL: -0.5, legR: 0.4, kneeL: 0.55, kneeR: 0.08, drop: -0.05 } : {}
|
|
4569
4693
|
};
|
|
4570
4694
|
};
|
|
4695
|
+
const doorPose = (door) => {
|
|
4696
|
+
const { phase, progress } = door;
|
|
4697
|
+
const on = phase === "reach" ? progress : phase === "release" ? 1 - progress : 1;
|
|
4698
|
+
const swing = phase === "swing" ? progress : phase === "release" ? 1 : 0;
|
|
4699
|
+
const shake = phase === "rattle" ? Math.sin(time * 55) * 0.06 * (1 - progress) : 0;
|
|
4700
|
+
const drop = clamp((DOOR_SHOULDER - door.height) / DOOR_ARM, -0.9, 1);
|
|
4701
|
+
const low = clamp((0.75 - door.height) / 0.5, 0, 1);
|
|
4702
|
+
const raise = -Math.acos(clamp(drop, -1, 1)) * on - 0.35 * low * on;
|
|
4703
|
+
const elbow = door.pull ? -0.35 - 0.75 * swing : -0.95 + 0.75 * swing;
|
|
4704
|
+
return {
|
|
4705
|
+
armR: raise + shake,
|
|
4706
|
+
armRz: REST_ARM_Z * (1 - on) + 0.05 * on,
|
|
4707
|
+
elbR: -0.12 + (elbow + 0.12) * on,
|
|
4708
|
+
armLz: -REST_ARM_Z,
|
|
4709
|
+
elbL: -0.12,
|
|
4710
|
+
lean: ((door.pull ? -0.06 : 0.1) * swing + 0.35 * low) * on,
|
|
4711
|
+
headX: 0.06 * on + 0.2 * low * on
|
|
4712
|
+
};
|
|
4713
|
+
};
|
|
4571
4714
|
const holdingPose = (gait, itemUse) => {
|
|
4572
|
-
const
|
|
4715
|
+
const bob2 = Math.sin(cycles * TWO_PI) * 0.05 * gait;
|
|
4573
4716
|
if (!itemUse) {
|
|
4574
|
-
return { armL: -0.45 +
|
|
4717
|
+
return { armL: -0.45 + bob2, armLz: 0.22, elbL: -1.05 };
|
|
4575
4718
|
}
|
|
4576
4719
|
const { id, position, rotation } = itemUse;
|
|
4577
4720
|
if (id === "drink" || id === "sip" || id === "chug") {
|
|
@@ -4584,7 +4727,7 @@ var createPlayerAvatar = (THREE, options = {}) => {
|
|
|
4584
4727
|
headX: -0.26 * tilt3
|
|
4585
4728
|
};
|
|
4586
4729
|
}
|
|
4587
|
-
if (id === "open" || id === "close") {
|
|
4730
|
+
if (id === "open" || id === "close" || itemUse.gripL !== void 0) {
|
|
4588
4731
|
const reach = clamp((0.22 - position[0]) / 0.12, 0, 1);
|
|
4589
4732
|
return {
|
|
4590
4733
|
armL: -0.45 - 0.35 * reach,
|
|
@@ -4683,6 +4826,31 @@ var createPlayerAvatar = (THREE, options = {}) => {
|
|
|
4683
4826
|
drop: Math.abs(Math.sin(ph)) * WALK_BOB * gait
|
|
4684
4827
|
};
|
|
4685
4828
|
};
|
|
4829
|
+
const sitPose = (hip) => {
|
|
4830
|
+
const knee = hip - legLengths.hipBelowTrunk - legLengths.thigh * Math.cos(SIT.thigh);
|
|
4831
|
+
const shinFromVertical = Math.acos(clamp(knee / legLengths.shin, 0, 1));
|
|
4832
|
+
const bend = -SIT.thigh - shinFromVertical;
|
|
4833
|
+
return {
|
|
4834
|
+
legL: SIT.thigh,
|
|
4835
|
+
legR: SIT.thigh,
|
|
4836
|
+
kneeL: bend,
|
|
4837
|
+
kneeR: bend,
|
|
4838
|
+
lean: SIT.lean,
|
|
4839
|
+
drop: hip - HIP_HEIGHT,
|
|
4840
|
+
armR: SIT.arm,
|
|
4841
|
+
armL: SIT.arm,
|
|
4842
|
+
armRz: SIT.armZ,
|
|
4843
|
+
armLz: -SIT.armZ,
|
|
4844
|
+
elbR: SIT.elbow,
|
|
4845
|
+
elbL: SIT.elbow
|
|
4846
|
+
};
|
|
4847
|
+
};
|
|
4848
|
+
const liePose = () => ({ legL: 0, legR: 0, kneeL: LIE.knee, kneeR: LIE.knee, lean: 0, drop: 0, armR: 0, armL: 0, armRz: LIE.armZ, armLz: -LIE.armZ, elbR: LIE.elbow, elbL: LIE.elbow });
|
|
4849
|
+
const layBody = (hip) => {
|
|
4850
|
+
tilt.rotation.set(-Math.PI / 2, 0, 0, "XYZ");
|
|
4851
|
+
const pivot = new THREE.Vector3(0, HIP_HEIGHT, 0).applyEuler(tilt.rotation);
|
|
4852
|
+
tilt.position.set(0, hip, 0).sub(pivot);
|
|
4853
|
+
};
|
|
4686
4854
|
const placeBody = (progress) => {
|
|
4687
4855
|
const fk = progress * progress * (3 - 2 * progress);
|
|
4688
4856
|
const flip = fract(cycles * 1.7) >= 0.5 ? 1 : 0;
|
|
@@ -4743,13 +4911,27 @@ var createPlayerAvatar = (THREE, options = {}) => {
|
|
|
4743
4911
|
profile.bob = (running ? RUN_BOB : WALK_BOB) * gait;
|
|
4744
4912
|
time = cycles / (walkCadence(Math.max(speed, 0)) * (running ? 1.3 : 1));
|
|
4745
4913
|
animator.animate(body, time, { speed });
|
|
4914
|
+
bob = rig.fig.position.y - rig.dropBase;
|
|
4746
4915
|
fall = fallSeconds <= 0 ? down ? 1 : 0 : clamp(fall + (down ? dt : -dt) / fallSeconds, 0, 1);
|
|
4747
4916
|
resetLegYaw();
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4917
|
+
const seat = down ? null : state.seat ?? null;
|
|
4918
|
+
if (down) {
|
|
4919
|
+
animator.setPose(rig, downPose());
|
|
4920
|
+
bob = rig.fig.position.y - rig.dropBase;
|
|
4921
|
+
} else if (seat) {
|
|
4922
|
+
animator.setPose(rig, seat.pose === "lie" ? liePose() : sitPose(seat.hip));
|
|
4923
|
+
bob = 0;
|
|
4924
|
+
} else {
|
|
4925
|
+
if (running) {
|
|
4926
|
+
animator.setPose(rig, runningPose(gait, Boolean(state.armed || state.holding || state.itemUse)));
|
|
4927
|
+
bob = rig.fig.position.y - rig.dropBase;
|
|
4928
|
+
}
|
|
4929
|
+
if (state.crouch) {
|
|
4930
|
+
animator.setPose(rig, crouchPose(gait));
|
|
4931
|
+
bob = rig.fig.position.y - rig.dropBase - CROUCH.drop;
|
|
4932
|
+
}
|
|
4752
4933
|
if (state.push) animator.setPose(rig, pushingPose(state.push));
|
|
4934
|
+
else if (state.door) animator.setPose(rig, doorPose(state.door));
|
|
4753
4935
|
else if (state.armed) animator.setPose(rig, armed(state.pitch ?? 0, gait, state.hip ?? 0));
|
|
4754
4936
|
else if (state.holding || state.itemUse) animator.setPose(rig, holdingPose(gait, state.itemUse));
|
|
4755
4937
|
else if (!running) {
|
|
@@ -4761,20 +4943,33 @@ var createPlayerAvatar = (THREE, options = {}) => {
|
|
|
4761
4943
|
});
|
|
4762
4944
|
}
|
|
4763
4945
|
}
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4946
|
+
if (seat?.pose === "lie") layBody(seat.hip);
|
|
4947
|
+
else placeBody(fall);
|
|
4948
|
+
stepClip(dt, down, Boolean(state.crouch || seat));
|
|
4949
|
+
const cascadeDt = run && !run.clip.loop ? dt * clipCascade : dt;
|
|
4950
|
+
const targetWithoutBob = rig.fig.position.y - bob;
|
|
4951
|
+
if (smooth) animator.cascade(rig, cascadeDt);
|
|
4952
|
+
hipWithoutBob = smooth && hipWithoutBob !== null ? stepCascade2(hipWithoutBob, targetWithoutBob, cascadeDt, "hip") : targetWithoutBob;
|
|
4953
|
+
bob = rig.fig.position.y - hipWithoutBob;
|
|
4767
4954
|
const blow = run?.clip.events?.find((event) => (event.type === "impact" || event.type === "grip") && event.data?.kind)?.data?.kind;
|
|
4768
4955
|
const ph = cycles * TWO_PI;
|
|
4769
4956
|
hands.forEach((hand) => {
|
|
4770
4957
|
const isRight = hand.side < 0;
|
|
4771
4958
|
const holdRight = isRight && (!!state.holding || !!state.itemUse);
|
|
4772
|
-
const holdLeft = !isRight && (state.itemUse?.id === "open" || state.itemUse?.id === "close");
|
|
4773
|
-
const grip = blow === "punch" ? 1.4 : blow === "shove" ? 0.15 : state.armed || holdRight || holdLeft ? 1.22 : running ? 0.85 : 0.12;
|
|
4959
|
+
const holdLeft = !isRight && (state.itemUse?.id === "open" || state.itemUse?.id === "close" || state.itemUse?.gripL !== void 0);
|
|
4960
|
+
const grip = !isRight && state.itemUse?.gripL !== void 0 ? 1.22 * state.itemUse.gripL : blow === "punch" ? 1.4 : blow === "shove" ? 0.15 : state.armed || holdRight || holdLeft ? 1.22 : running ? 0.85 : 0.12;
|
|
4774
4961
|
const wristSwing = holdRight || state.armed || running ? 0 : -Math.min(1, gait) * Math.sin(ph - 0.6) * 0.12 * hand.side;
|
|
4775
4962
|
setHandGrip(hand, grip, wristSwing);
|
|
4776
4963
|
});
|
|
4964
|
+
root.updateMatrixWorld(true);
|
|
4965
|
+
root.worldToLocal(eyeSocket.getWorldPosition(eyeLocal));
|
|
4966
|
+
eyeLocal.y -= (1 - eyeBob) * bob;
|
|
4777
4967
|
},
|
|
4968
|
+
eye(out = new THREE.Vector3()) {
|
|
4969
|
+
root.updateWorldMatrix(true, false);
|
|
4970
|
+
return root.localToWorld(out.copy(eyeLocal));
|
|
4971
|
+
},
|
|
4972
|
+
setView: (mode, camera) => headHider.setView(mode, camera),
|
|
4778
4973
|
play(clip, playOptions = {}) {
|
|
4779
4974
|
const found = typeof clip === "string" ? clips.get(clip) : clip;
|
|
4780
4975
|
if (!found) throw new Error(`Unknown pose clip: ${String(clip)}`);
|
|
@@ -4786,10 +4981,11 @@ var createPlayerAvatar = (THREE, options = {}) => {
|
|
|
4786
4981
|
if (run) run.target = 0;
|
|
4787
4982
|
},
|
|
4788
4983
|
hand: (side) => sockets[side],
|
|
4789
|
-
|
|
4984
|
+
shoulder: (side) => armOf[side].g,
|
|
4985
|
+
reach(targets, view) {
|
|
4790
4986
|
if (run || fall > 0) return;
|
|
4791
4987
|
root.updateMatrixWorld(true);
|
|
4792
|
-
armReach.apply(targets);
|
|
4988
|
+
armReach.apply(targets, view);
|
|
4793
4989
|
},
|
|
4794
4990
|
on(_type, listener) {
|
|
4795
4991
|
listeners.add(listener);
|
|
@@ -4827,7 +5023,9 @@ var first_person_arms_default = {
|
|
|
4827
5023
|
shoulder: [0.16, -0.36, 0.18],
|
|
4828
5024
|
upper: 0.32,
|
|
4829
5025
|
fore: 0.3,
|
|
4830
|
-
reachShift: 0.
|
|
5026
|
+
reachShift: 0.42,
|
|
5027
|
+
reachBend: [1.35, 0.95],
|
|
5028
|
+
elbowView: [[0.96, -0.26, -0.06], null],
|
|
4831
5029
|
wrist: 0.07,
|
|
4832
5030
|
elbowPole: [0.45, -1, 0.2],
|
|
4833
5031
|
shoulderLeft: [-0.07, -0.46, 0.18],
|
|
@@ -4854,22 +5052,14 @@ var first_person_arms_default = {
|
|
|
4854
5052
|
};
|
|
4855
5053
|
|
|
4856
5054
|
// src/first-person/hand.ts
|
|
4857
|
-
var
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
{ z: 9e-3, lengths: [0.035, 0.025, 0.02], width: 0.0155 },
|
|
4861
|
-
{ z: 0.027, lengths: [0.029, 0.02, 0.018], width: 0.0135 }
|
|
4862
|
-
];
|
|
4863
|
-
var PALM = { length: 0.09, thick: 0.026, width: 0.09, wristWidth: 0.066 };
|
|
4864
|
-
var FINGER_THICK = 0.0135;
|
|
4865
|
-
var CURL = { near: 1.05, mid: 1.25, far: 0.85, spread: 0.06 };
|
|
4866
|
-
var THUMB = { base: [5e-3, -6e-3, -0.044], near: 0.034, far: 0.028, width: 0.019 };
|
|
5055
|
+
var PALM = { radius: 0.048, scale: [0.6, 1.05, 1], down: 0.035 };
|
|
5056
|
+
var CURL = { closed: 1.25, near: 0.9, far: 1.1 };
|
|
5057
|
+
var THUMB = { open: 0.32, closed: 0.25 };
|
|
4867
5058
|
var createHandMesh = (THREE, skin, wristSkin = skin) => {
|
|
4868
5059
|
const root = new THREE.Group();
|
|
4869
5060
|
root.name = "first-person-hand";
|
|
4870
5061
|
const geometries = [];
|
|
4871
|
-
const
|
|
4872
|
-
const geometry = new THREE.BoxGeometry(sx, sy, sz);
|
|
5062
|
+
const add = (parent, geometry, material, x = 0, y = 0, z = 0) => {
|
|
4873
5063
|
geometries.push(geometry);
|
|
4874
5064
|
const mesh = new THREE.Mesh(geometry, material);
|
|
4875
5065
|
mesh.position.set(x, y, z);
|
|
@@ -4877,64 +5067,26 @@ var createHandMesh = (THREE, skin, wristSkin = skin) => {
|
|
|
4877
5067
|
parent.add(mesh);
|
|
4878
5068
|
return mesh;
|
|
4879
5069
|
};
|
|
4880
|
-
const
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
const palm = new THREE.Mesh(palmGeometry, skin);
|
|
4888
|
-
palm.frustumCulled = false;
|
|
4889
|
-
root.add(palm);
|
|
4890
|
-
const wristGeometry = new THREE.CylinderGeometry(0.03, 0.033, 0.05, 8);
|
|
5070
|
+
const group = new THREE.Group();
|
|
5071
|
+
group.quaternion.setFromRotationMatrix(new THREE.Matrix4().makeBasis(new THREE.Vector3(0, -1, 0), new THREE.Vector3(-1, 0, 0), new THREE.Vector3(0, 0, -1)));
|
|
5072
|
+
group.position.set(-PALM.down, 0, 0);
|
|
5073
|
+
root.add(group);
|
|
5074
|
+
add(group, new THREE.SphereGeometry(PALM.radius, 14, 10), skin, 0, -PALM.down, 0).scale.set(...PALM.scale);
|
|
5075
|
+
const built = buildHand({ THREE, add, hg: group, handM: skin, s: -1, detailed: true });
|
|
5076
|
+
const wristGeometry = new THREE.CylinderGeometry(0.03, 0.033, 0.05, 10);
|
|
4891
5077
|
wristGeometry.rotateZ(Math.PI / 2);
|
|
4892
|
-
|
|
4893
|
-
const wrist = new THREE.Mesh(wristGeometry, wristSkin);
|
|
4894
|
-
wrist.position.set(-PALM.length / 2 - 0.018, 0, 0);
|
|
4895
|
-
wrist.frustumCulled = false;
|
|
4896
|
-
root.add(wrist);
|
|
4897
|
-
const joints = [];
|
|
4898
|
-
FINGERS.forEach((finger, index) => {
|
|
4899
|
-
const segments = [];
|
|
4900
|
-
let parent = root;
|
|
4901
|
-
let at = PALM.length / 2;
|
|
4902
|
-
finger.lengths.forEach((length, k) => {
|
|
4903
|
-
const group = new THREE.Group();
|
|
4904
|
-
group.position.set(at, k === 0 ? 2e-3 : 0, k === 0 ? finger.z : 0);
|
|
4905
|
-
const taper = 1 - k * 0.07;
|
|
4906
|
-
box(group, length, FINGER_THICK * taper, finger.width * taper, length / 2, 0, 0);
|
|
4907
|
-
parent.add(group);
|
|
4908
|
-
segments.push(group);
|
|
4909
|
-
parent = group;
|
|
4910
|
-
at = length;
|
|
4911
|
-
});
|
|
4912
|
-
joints.push({ segments, weight: 1 + index * (CURL.spread / CURL.near) });
|
|
4913
|
-
});
|
|
4914
|
-
const thumbNear = new THREE.Group();
|
|
4915
|
-
thumbNear.rotation.order = "YZX";
|
|
4916
|
-
thumbNear.position.set(...THUMB.base);
|
|
4917
|
-
box(thumbNear, THUMB.near, FINGER_THICK * 1.1, THUMB.width, THUMB.near / 2, 0, 0);
|
|
4918
|
-
const thumbFar = new THREE.Group();
|
|
4919
|
-
thumbFar.position.set(THUMB.near, 0, 0);
|
|
4920
|
-
box(thumbFar, THUMB.far, FINGER_THICK, THUMB.width * 0.9, THUMB.far / 2, 0, 0);
|
|
4921
|
-
thumbNear.add(thumbFar);
|
|
4922
|
-
root.add(thumbNear);
|
|
5078
|
+
add(root, wristGeometry, wristSkin, -PALM.down - 0.03, 0, 0);
|
|
4923
5079
|
let lastGrip = 0;
|
|
4924
5080
|
let indexCurl;
|
|
4925
|
-
const
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
if (!finger) return;
|
|
4929
|
-
const k = indexCurl === void 0 ? lastGrip : Math.min(1, Math.max(0, indexCurl));
|
|
4930
|
-
finger.segments.forEach((segment, i) => segment.rotation.z = -curl[i] * k * finger.weight);
|
|
5081
|
+
const curlFinger = (finger, k) => {
|
|
5082
|
+
built.fingers[finger * 2].rotation.z = k * CURL.closed * CURL.near;
|
|
5083
|
+
built.fingers[finger * 2 + 1].rotation.z = k * CURL.closed * CURL.far;
|
|
4931
5084
|
};
|
|
5085
|
+
const applyIndex = () => curlFinger(0, indexCurl === void 0 ? lastGrip : Math.min(1, Math.max(0, indexCurl)));
|
|
4932
5086
|
const setGrip = (grip) => {
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
thumbNear.rotation.set(0, 0.55 - 1.45 * k, -0.1 - 0.75 * k);
|
|
4937
|
-
thumbFar.rotation.z = -0.1 - 0.7 * k;
|
|
5087
|
+
lastGrip = Math.min(1, Math.max(0, grip));
|
|
5088
|
+
for (let finger = 1; finger < 4; finger++) curlFinger(finger, lastGrip);
|
|
5089
|
+
if (built.th) built.th.rotation.z = THUMB.open + lastGrip * THUMB.closed;
|
|
4938
5090
|
applyIndex();
|
|
4939
5091
|
};
|
|
4940
5092
|
const setIndex = (value) => {
|
|
@@ -4956,6 +5108,8 @@ var createHandMesh = (THREE, skin, wristSkin = skin) => {
|
|
|
4956
5108
|
var DEFAULT_BLEND = 0.18;
|
|
4957
5109
|
var ELBOW_SEGMENTS = 8;
|
|
4958
5110
|
var REACH_SLACK = 0.97;
|
|
5111
|
+
var ELBOW_VIEW_MARGIN = 0.86;
|
|
5112
|
+
var ELBOW_VIEW_PASSES = 4;
|
|
4959
5113
|
var CONTACT_PROBE = 1.4;
|
|
4960
5114
|
var CONTACT_MIN = 0.12;
|
|
4961
5115
|
var CONTACT_MARGIN = 5e-3;
|
|
@@ -5104,6 +5258,11 @@ function createFirstPersonArms(THREE, options = {}) {
|
|
|
5104
5258
|
const shoulderOf = (sign, out) => sign === -1 && rig.shoulderLeft ? out.set(...rig.shoulderLeft) : out.set(rig.shoulder[0] * sign, rig.shoulder[1], rig.shoulder[2]);
|
|
5105
5259
|
const poleOf = (sign) => sign === -1 && rig.elbowPoleLeft ? new THREE.Vector3(...rig.elbowPoleLeft) : new THREE.Vector3(rig.elbowPole[0] * sign, rig.elbowPole[1], rig.elbowPole[2]);
|
|
5106
5260
|
const kneePole = new THREE.Vector3(...rig.kneePole);
|
|
5261
|
+
const reachOf = (sign) => {
|
|
5262
|
+
const bend = rig.reachBend?.[sign === 1 ? 0 : 1];
|
|
5263
|
+
if (bend === void 0) return (rig.upper + rig.fore) * REACH_SLACK;
|
|
5264
|
+
return Math.sqrt(rig.upper * rig.upper + rig.fore * rig.fore + 2 * rig.upper * rig.fore * Math.cos(bend));
|
|
5265
|
+
};
|
|
5107
5266
|
const hip = new THREE.Vector3(...rig.hip);
|
|
5108
5267
|
const euler = new THREE.Euler(0, 0, 0, "YZX");
|
|
5109
5268
|
const quaternionOf = (r) => new THREE.Quaternion().setFromEuler(euler.set(r[0], r[1], r[2], "YZX"));
|
|
@@ -5193,15 +5352,45 @@ function createFirstPersonArms(THREE, options = {}) {
|
|
|
5193
5352
|
out.scale = base.scale;
|
|
5194
5353
|
return out;
|
|
5195
5354
|
};
|
|
5196
|
-
const
|
|
5355
|
+
const elbowAt = new THREE.Vector3();
|
|
5356
|
+
const viewOf = (camera) => {
|
|
5357
|
+
const lens = camera;
|
|
5358
|
+
if (!lens.isPerspectiveCamera) return null;
|
|
5359
|
+
const tanV = Math.tan(lens.fov * Math.PI / 360);
|
|
5360
|
+
return { tanV, tanH: tanV * lens.aspect };
|
|
5361
|
+
};
|
|
5362
|
+
const placeElbowInView = (sign, view) => {
|
|
5363
|
+
const way = rig.elbowView?.[sign === 1 ? 0 : 1];
|
|
5364
|
+
if (!way) return false;
|
|
5365
|
+
elbowAt.set(way[0], way[1], way[2]).setLength(rig.fore).add(wristAt);
|
|
5366
|
+
for (let pass = 0; pass < ELBOW_VIEW_PASSES; pass++) {
|
|
5367
|
+
const depth = Math.max(0.05, -elbowAt.z);
|
|
5368
|
+
const high = view.tanV * ELBOW_VIEW_MARGIN * depth;
|
|
5369
|
+
const wide = view.tanH * ELBOW_VIEW_MARGIN * depth;
|
|
5370
|
+
elbowAt.y = Math.max(elbowAt.y, -high);
|
|
5371
|
+
elbowAt.x = Math.min(wide, Math.max(-wide, elbowAt.x));
|
|
5372
|
+
elbowAt.sub(wristAt).setLength(rig.fore).add(wristAt);
|
|
5373
|
+
}
|
|
5374
|
+
shoulder.sub(elbowAt).setLength(rig.upper).add(elbowAt);
|
|
5375
|
+
return true;
|
|
5376
|
+
};
|
|
5377
|
+
const drawArm = (arm, pose, view) => {
|
|
5197
5378
|
copyPose(arm.drawn, pose);
|
|
5198
5379
|
const scale = pose.scale;
|
|
5199
5380
|
fingers.set(1, 0, 0).applyQuaternion(pose.q);
|
|
5200
5381
|
wristAt.copy(pose.p).addScaledVector(fingers, -rig.wrist * scale);
|
|
5201
5382
|
shoulderOf(arm.sign, shoulder).add(bobOffset);
|
|
5202
|
-
|
|
5383
|
+
if (view && placeElbowInView(arm.sign, view)) {
|
|
5384
|
+
solveTwoBone(shoulder, wristAt, rig.upper, rig.fore, towards.copy(elbowAt).sub(shoulder).add(elbowAt).sub(wristAt), bone);
|
|
5385
|
+
finishArm(arm, pose, scale);
|
|
5386
|
+
return;
|
|
5387
|
+
}
|
|
5388
|
+
const excess = shoulder.distanceTo(wristAt) - reachOf(arm.sign);
|
|
5203
5389
|
if (excess > 0 && rig.reachShift > 0) shoulder.addScaledVector(towards.subVectors(wristAt, shoulder).normalize(), Math.min(excess, rig.reachShift));
|
|
5204
5390
|
solveTwoBone(shoulder, wristAt, rig.upper, rig.fore, poleOf(arm.sign), bone);
|
|
5391
|
+
finishArm(arm, pose, scale);
|
|
5392
|
+
};
|
|
5393
|
+
const finishArm = (arm, pose, scale) => {
|
|
5205
5394
|
palmAt.copy(bone.end).addScaledVector(fingers, rig.wrist * scale);
|
|
5206
5395
|
arm.drawn.p.copy(palmAt);
|
|
5207
5396
|
arm.anchor.position.copy(palmAt);
|
|
@@ -5313,7 +5502,7 @@ function createFirstPersonArms(THREE, options = {}) {
|
|
|
5313
5502
|
dropped.p.y -= AWAY_DROP * ease(arm.away);
|
|
5314
5503
|
pose = dropped;
|
|
5315
5504
|
}
|
|
5316
|
-
drawArm(arm, pose);
|
|
5505
|
+
drawArm(arm, pose, mode === "target" && targets?.elbows !== "body" ? viewOf(state.camera) : null);
|
|
5317
5506
|
const shown = arm.away < AWAY_HIDDEN;
|
|
5318
5507
|
for (const part of [arm.anchor, arm.upper, arm.fore, arm.cuff, arm.elbow]) part.visible = shown;
|
|
5319
5508
|
}
|
|
@@ -5361,7 +5550,7 @@ var impactOf = (clip) => clip.events?.find((event) => event.type === "impact")?.
|
|
|
5361
5550
|
var isPunch = (clip) => clip.events?.some((event) => event.type === "impact" && event.data?.kind === "punch") ?? false;
|
|
5362
5551
|
var GUARD_SPEED = 0.3;
|
|
5363
5552
|
var toRoomAvatar = (avatar, options = {}) => {
|
|
5364
|
-
const arms = options.firstPerson === false ? null : createFirstPersonArms(avatar.three, {
|
|
5553
|
+
const arms = options.firstPerson === false || options.firstPerson === void 0 ? null : createFirstPersonArms(avatar.three, {
|
|
5365
5554
|
colors: { skin: avatar.colors.skin, sleeve: avatar.colors.longSleeves ? avatar.colors.shirt : avatar.colors.skin, trouser: avatar.colors.trousers, shoe: avatar.colors.shoes, ...options.firstPerson?.colors },
|
|
5366
5555
|
clips: options.firstPersonClips ?? FIRST_PERSON_CLIPS,
|
|
5367
5556
|
hideWhenIdle: true,
|
|
@@ -5382,7 +5571,7 @@ var toRoomAvatar = (avatar, options = {}) => {
|
|
|
5382
5571
|
let guarding = false;
|
|
5383
5572
|
const stepGuard = (dt, state) => {
|
|
5384
5573
|
if (!guard) return;
|
|
5385
|
-
const free = state.speed < GUARD_SPEED && !state.down && !state.armed && !state.holding && !state.push && !state.itemUse && !state.running;
|
|
5574
|
+
const free = state.speed < GUARD_SPEED && !state.down && !state.armed && !state.holding && !state.push && !state.door && !state.itemUse && !state.running;
|
|
5386
5575
|
if (strikeLeft > 0) {
|
|
5387
5576
|
strikeLeft -= dt;
|
|
5388
5577
|
if (strikeLeft <= 0 && guardLeft > 0 && free) {
|
|
@@ -5401,7 +5590,8 @@ var toRoomAvatar = (avatar, options = {}) => {
|
|
|
5401
5590
|
root: avatar.root,
|
|
5402
5591
|
avatar,
|
|
5403
5592
|
arms,
|
|
5404
|
-
|
|
5593
|
+
eye: (out) => avatar.eye(out),
|
|
5594
|
+
setView: (mode, camera) => avatar.setView(mode, camera),
|
|
5405
5595
|
update: (dt, state) => {
|
|
5406
5596
|
stepGuard(dt, state);
|
|
5407
5597
|
avatar.update(dt, {
|
|
@@ -5413,11 +5603,14 @@ var toRoomAvatar = (avatar, options = {}) => {
|
|
|
5413
5603
|
pitch: -state.pitch,
|
|
5414
5604
|
...state.holding !== void 0 ? { holding: state.holding } : {},
|
|
5415
5605
|
...state.itemUse !== void 0 ? { itemUse: state.itemUse } : {},
|
|
5416
|
-
...state.push !== void 0 ? { push: state.push } : {}
|
|
5606
|
+
...state.push !== void 0 ? { push: state.push } : {},
|
|
5607
|
+
...state.seat !== void 0 ? { seat: state.seat } : {},
|
|
5608
|
+
...state.door !== void 0 ? { door: state.door } : {}
|
|
5417
5609
|
});
|
|
5418
5610
|
},
|
|
5419
5611
|
hand: (side) => avatar.hand(side),
|
|
5420
|
-
|
|
5612
|
+
shoulder: (side) => avatar.shoulder(side),
|
|
5613
|
+
reach: (targets, view) => avatar.reach(targets, view),
|
|
5421
5614
|
strike: (clipId, strikeOptions) => {
|
|
5422
5615
|
const clip = strikes.get(clipId);
|
|
5423
5616
|
if (!clip) return null;
|