@adatechnology/game-characters-three 0.3.0 → 0.3.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 +14 -1
- package/dist/index.global.js +181 -13
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +181 -13
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -4212,7 +4212,17 @@ var player_avatar_default = {
|
|
|
4212
4212
|
fem: false,
|
|
4213
4213
|
life: 1,
|
|
4214
4214
|
hs: "short",
|
|
4215
|
-
hair: "2a1e16"
|
|
4215
|
+
hair: "2a1e16",
|
|
4216
|
+
pose: {
|
|
4217
|
+
armL: 0,
|
|
4218
|
+
armR: 0,
|
|
4219
|
+
elbL: -0.12,
|
|
4220
|
+
elbR: -0.12,
|
|
4221
|
+
armOut: 0.11,
|
|
4222
|
+
lean: 0.04,
|
|
4223
|
+
headX: 0,
|
|
4224
|
+
headZ: 0
|
|
4225
|
+
}
|
|
4216
4226
|
},
|
|
4217
4227
|
shirtColor: "3d5a73"
|
|
4218
4228
|
};
|
|
@@ -4223,9 +4233,12 @@ var MAX_GAIT = 1.4;
|
|
|
4223
4233
|
var CLIP_BLEND = 0.12;
|
|
4224
4234
|
var FALL_SECONDS2 = 0.3;
|
|
4225
4235
|
var HIP_HEIGHT = 0.95;
|
|
4226
|
-
var WALK_ARM = 0.
|
|
4236
|
+
var WALK_ARM = 0.28;
|
|
4227
4237
|
var WALK_BOB = 0.035;
|
|
4228
4238
|
var WALK_LEAN = 0.04;
|
|
4239
|
+
var RUN_LEAN = 0.16;
|
|
4240
|
+
var RUN_BOB = 0.05;
|
|
4241
|
+
var REST_ARM_Z = 0.18;
|
|
4229
4242
|
var CROUCH = { thigh: -0.95, thighWalk: 0.3, shin: 1.9, lean: 0.25, drop: -0.35 };
|
|
4230
4243
|
var AIMED = { shoulder: -1.42, perAim: 0.85, swing: 0.02, zRight: -0.54, zLeft: 0.36, elbowRight: -0.04, elbowLeft: -0.12 };
|
|
4231
4244
|
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 };
|
|
@@ -4234,7 +4247,18 @@ var hexOf = (value) => typeof value === "string" ? Number.parseInt(value, 16) :
|
|
|
4234
4247
|
var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
4235
4248
|
var fract = (value) => value - Math.floor(value);
|
|
4236
4249
|
var createPlayerAvatar = (THREE, options = {}) => {
|
|
4237
|
-
const
|
|
4250
|
+
const pose = {
|
|
4251
|
+
armL: 0,
|
|
4252
|
+
armR: 0,
|
|
4253
|
+
elbL: -0.08,
|
|
4254
|
+
elbR: -0.08,
|
|
4255
|
+
lean: 0.04,
|
|
4256
|
+
headX: 0,
|
|
4257
|
+
headZ: 0,
|
|
4258
|
+
...player_avatar_default.spec.pose,
|
|
4259
|
+
...options.spec?.pose
|
|
4260
|
+
};
|
|
4261
|
+
const spec = { ...player_avatar_default.spec, ...options.spec, pose };
|
|
4238
4262
|
for (const key of ["skin", "hair"]) if (typeof spec[key] === "string") spec[key] = hexOf(spec[key]);
|
|
4239
4263
|
const best = createBestBuilder(THREE, { types: [{ name: String(spec.type), eye: 0 }], random: createRng4(Number(spec.seed ?? 1)) });
|
|
4240
4264
|
const body = best.build(spec);
|
|
@@ -4269,6 +4293,41 @@ var createPlayerAvatar = (THREE, options = {}) => {
|
|
|
4269
4293
|
sockets[side].position.set(HAND_OFFSET.x, HAND_OFFSET.y, HAND_OFFSET.z);
|
|
4270
4294
|
armOf[side].el.add(sockets[side]);
|
|
4271
4295
|
}
|
|
4296
|
+
const addMesh = (parent, geometry, material, x = 0, y = 0, z = 0, rx = 0, ry = 0, rz = 0) => {
|
|
4297
|
+
const mesh = new THREE.Mesh(geometry, material);
|
|
4298
|
+
mesh.position.set(x, y, z);
|
|
4299
|
+
if (rx || ry || rz) mesh.rotation.set(rx, ry, rz);
|
|
4300
|
+
mesh.castShadow = true;
|
|
4301
|
+
mesh.receiveShadow = true;
|
|
4302
|
+
parent.add(mesh);
|
|
4303
|
+
return mesh;
|
|
4304
|
+
};
|
|
4305
|
+
const hands = [];
|
|
4306
|
+
rig.arms.forEach((arm, index) => {
|
|
4307
|
+
const el = arm.el;
|
|
4308
|
+
const side = index === 0 ? 1 : -1;
|
|
4309
|
+
const oldHand = meshesOf(el).find((mesh) => Math.abs(mesh.position.y + 0.33) < 0.025);
|
|
4310
|
+
const handMaterial = oldHand?.material ?? new THREE.MeshLambertMaterial({ color: colors.skin });
|
|
4311
|
+
if (oldHand) {
|
|
4312
|
+
oldHand.geometry?.dispose();
|
|
4313
|
+
el.remove(oldHand);
|
|
4314
|
+
}
|
|
4315
|
+
const hg = new THREE.Group();
|
|
4316
|
+
hg.name = side > 0 ? "hand_group_L" : "hand_group_R";
|
|
4317
|
+
hg.position.set(side * 0.02, -0.3, 0.01);
|
|
4318
|
+
el.add(hg);
|
|
4319
|
+
const palm = addMesh(hg, new THREE.SphereGeometry(0.048, 14, 10), handMaterial, 0, -0.035, 0);
|
|
4320
|
+
palm.scale.set(0.6, 1.05, 1);
|
|
4321
|
+
const built = buildHand({ THREE, add: addMesh, hg, handM: handMaterial, s: side, detailed: true });
|
|
4322
|
+
hands.push({ side, hg, fingers: built.fingers, th: built.th });
|
|
4323
|
+
});
|
|
4324
|
+
const setHandGrip = (hand, grip, wristX = 0) => {
|
|
4325
|
+
hand.fingers.forEach((finger, j) => {
|
|
4326
|
+
finger.rotation.z = -hand.side * grip * (j % 2 ? 1.1 : 0.9);
|
|
4327
|
+
});
|
|
4328
|
+
if (hand.th) hand.th.rotation.z = -hand.side * (0.32 + grip * 0.25);
|
|
4329
|
+
hand.hg.rotation.x = wristX;
|
|
4330
|
+
};
|
|
4272
4331
|
const legRestX = rig.legs.map((leg) => leg.g.position.x);
|
|
4273
4332
|
const legSide = (index) => index === 0 ? 1 : -1;
|
|
4274
4333
|
let cycles = 0;
|
|
@@ -4310,6 +4369,42 @@ var createPlayerAvatar = (THREE, options = {}) => {
|
|
|
4310
4369
|
});
|
|
4311
4370
|
return { armR: shoulder, armL: shoulder, armRz: AIMED.zRight, armLz: AIMED.zLeft, elbR: AIMED.elbowRight, elbL: AIMED.elbowLeft };
|
|
4312
4371
|
};
|
|
4372
|
+
const holdingPose = (gait, itemUse) => {
|
|
4373
|
+
const bob = Math.sin(cycles * TWO_PI) * 0.05 * gait;
|
|
4374
|
+
if (!itemUse) {
|
|
4375
|
+
return { armL: -0.45 + bob, armLz: 0.22, elbL: -1.05 };
|
|
4376
|
+
}
|
|
4377
|
+
const { id, position, rotation } = itemUse;
|
|
4378
|
+
if (id === "drink" || id === "sip" || id === "chug") {
|
|
4379
|
+
const raise2 = clamp((position[1] + 0.2) / 0.22, 0, 1);
|
|
4380
|
+
const tilt3 = clamp(Math.abs(rotation[0]) / 1.22, 0, 1.15);
|
|
4381
|
+
return {
|
|
4382
|
+
armL: -0.45 - 0.95 * raise2 - 0.22 * tilt3,
|
|
4383
|
+
armLz: 0.22 + 0.44 * raise2,
|
|
4384
|
+
elbL: -1.05 - 0.85 * raise2 + 0.12 * tilt3,
|
|
4385
|
+
headX: -0.26 * tilt3
|
|
4386
|
+
};
|
|
4387
|
+
}
|
|
4388
|
+
if (id === "open" || id === "close") {
|
|
4389
|
+
const reach = clamp((0.22 - position[0]) / 0.12, 0, 1);
|
|
4390
|
+
return {
|
|
4391
|
+
armL: -0.45 - 0.35 * reach,
|
|
4392
|
+
armLz: 0.22 + 0.28 * reach,
|
|
4393
|
+
elbL: -1.05 - 0.25 * reach,
|
|
4394
|
+
armR: -0.78 * reach,
|
|
4395
|
+
armRz: -0.48 * reach,
|
|
4396
|
+
elbR: -1.25 * reach
|
|
4397
|
+
};
|
|
4398
|
+
}
|
|
4399
|
+
const raise = clamp((position[1] + 0.2) / 0.25, 0, 1);
|
|
4400
|
+
const tilt2 = clamp(Math.abs(rotation[0]) / 1.75, 0, 1.2);
|
|
4401
|
+
const ext = Math.max(raise, tilt2 * 0.75);
|
|
4402
|
+
return {
|
|
4403
|
+
armL: -0.45 - 0.48 * ext,
|
|
4404
|
+
armLz: 0.22 + 0.08 * ext,
|
|
4405
|
+
elbL: -1.05 + 0.38 * ext
|
|
4406
|
+
};
|
|
4407
|
+
};
|
|
4313
4408
|
const resetLegYaw = () => {
|
|
4314
4409
|
rig.legs.forEach((leg, index) => {
|
|
4315
4410
|
leg.g.rotation.y = 0;
|
|
@@ -4317,6 +4412,32 @@ var createPlayerAvatar = (THREE, options = {}) => {
|
|
|
4317
4412
|
leg.g.position.z = 0;
|
|
4318
4413
|
});
|
|
4319
4414
|
};
|
|
4415
|
+
const runningPose = (gait, busyHands = false) => {
|
|
4416
|
+
const ph = cycles * TWO_PI;
|
|
4417
|
+
const sine = Math.sin(ph);
|
|
4418
|
+
const cosine = Math.cos(ph);
|
|
4419
|
+
const legL = sine * 0.65 * gait;
|
|
4420
|
+
const legR = -sine * 0.65 * gait;
|
|
4421
|
+
const kneeL = Math.max(0, -cosine) * 1.15 * gait;
|
|
4422
|
+
const kneeR = Math.max(0, cosine) * 1.15 * gait;
|
|
4423
|
+
const targets = {
|
|
4424
|
+
lean: RUN_LEAN * Math.min(1, gait),
|
|
4425
|
+
drop: Math.abs(cosine) * RUN_BOB * gait,
|
|
4426
|
+
legL,
|
|
4427
|
+
legR,
|
|
4428
|
+
kneeL,
|
|
4429
|
+
kneeR
|
|
4430
|
+
};
|
|
4431
|
+
if (!busyHands) {
|
|
4432
|
+
targets.armR = -0.32 - sine * 0.65 * gait;
|
|
4433
|
+
targets.armL = -0.32 + sine * 0.65 * gait;
|
|
4434
|
+
targets.elbR = -1.25 + Math.max(0, sine) * 0.3 * gait;
|
|
4435
|
+
targets.elbL = -1.25 + Math.max(0, -sine) * 0.3 * gait;
|
|
4436
|
+
targets.armRz = 0.22;
|
|
4437
|
+
targets.armLz = -0.22;
|
|
4438
|
+
}
|
|
4439
|
+
return targets;
|
|
4440
|
+
};
|
|
4320
4441
|
const crouchPose = (gait) => {
|
|
4321
4442
|
const swing = (leg) => {
|
|
4322
4443
|
const legS = legSide(leg);
|
|
@@ -4412,23 +4533,44 @@ var createPlayerAvatar = (THREE, options = {}) => {
|
|
|
4412
4533
|
update(dt, state = {}) {
|
|
4413
4534
|
const speed = state.speed ?? 0;
|
|
4414
4535
|
const moving = speed >= 0.05;
|
|
4415
|
-
|
|
4536
|
+
const down = !!state.down;
|
|
4537
|
+
const running = Boolean(state.running && moving && !down && !state.crouch);
|
|
4538
|
+
if (moving) cycles += dt * (running ? walkCadence(speed) * 1.3 : walkCadence(speed));
|
|
4416
4539
|
const gait = Math.min(MAX_GAIT, walkGait(speed));
|
|
4417
|
-
profile.arm = WALK_ARM * gait;
|
|
4418
|
-
profile.bob = WALK_BOB * gait;
|
|
4419
|
-
time = cycles / walkCadence(Math.max(speed, 0));
|
|
4540
|
+
profile.arm = (running ? 0.55 : WALK_ARM) * gait;
|
|
4541
|
+
profile.bob = (running ? RUN_BOB : WALK_BOB) * gait;
|
|
4542
|
+
time = cycles / (walkCadence(Math.max(speed, 0)) * (running ? 1.3 : 1));
|
|
4420
4543
|
animator.animate(body, time, { speed });
|
|
4421
|
-
const down = !!state.down;
|
|
4422
4544
|
fall = fallSeconds <= 0 ? down ? 1 : 0 : clamp(fall + (down ? dt : -dt) / fallSeconds, 0, 1);
|
|
4423
4545
|
resetLegYaw();
|
|
4424
4546
|
if (down) animator.setPose(rig, downPose());
|
|
4425
4547
|
else {
|
|
4548
|
+
if (running) animator.setPose(rig, runningPose(gait, Boolean(state.armed || state.holding || state.itemUse)));
|
|
4426
4549
|
if (state.crouch) animator.setPose(rig, crouchPose(gait));
|
|
4427
4550
|
if (state.armed) animator.setPose(rig, armed(state.pitch ?? 0, gait, state.hip ?? 0));
|
|
4551
|
+
else if (state.holding || state.itemUse) animator.setPose(rig, holdingPose(gait, state.itemUse));
|
|
4552
|
+
else if (!running) {
|
|
4553
|
+
animator.setPose(rig, {
|
|
4554
|
+
armRz: REST_ARM_Z,
|
|
4555
|
+
armLz: -REST_ARM_Z,
|
|
4556
|
+
elbR: -0.12,
|
|
4557
|
+
elbL: -0.12
|
|
4558
|
+
});
|
|
4559
|
+
}
|
|
4428
4560
|
}
|
|
4429
4561
|
placeBody(fall);
|
|
4430
4562
|
stepClip(dt, down);
|
|
4431
4563
|
if (smooth) animator.cascade(rig, dt);
|
|
4564
|
+
const clipId = run ? run.clip.id : null;
|
|
4565
|
+
const ph = cycles * TWO_PI;
|
|
4566
|
+
hands.forEach((hand) => {
|
|
4567
|
+
const isRight = hand.side < 0;
|
|
4568
|
+
const holdRight = isRight && (!!state.holding || !!state.itemUse);
|
|
4569
|
+
const holdLeft = !isRight && (state.itemUse?.id === "open" || state.itemUse?.id === "close");
|
|
4570
|
+
const grip = clipId === "punch_right" ? 1.4 : clipId === "shove_two_hands" ? 0.15 : state.armed || holdRight || holdLeft ? 1.22 : running ? 0.85 : 0.12;
|
|
4571
|
+
const wristSwing = holdRight || state.armed || running ? 0 : -Math.min(1, gait) * Math.sin(ph - 0.6) * 0.12 * hand.side;
|
|
4572
|
+
setHandGrip(hand, grip, wristSwing);
|
|
4573
|
+
});
|
|
4432
4574
|
},
|
|
4433
4575
|
play(clip, playOptions = {}) {
|
|
4434
4576
|
const found = typeof clip === "string" ? clips.get(clip) : clip;
|
|
@@ -4490,7 +4632,7 @@ var first_person_arms_default = {
|
|
|
4490
4632
|
},
|
|
4491
4633
|
stances: {
|
|
4492
4634
|
relaxed: {
|
|
4493
|
-
R: { p: [0.2, -0.
|
|
4635
|
+
R: { p: [0.2, -0.22, -0.36], r: [0.05, 1.57, -0.05], grip: 0.2 },
|
|
4494
4636
|
L: "mirror"
|
|
4495
4637
|
},
|
|
4496
4638
|
fists: {
|
|
@@ -4634,6 +4776,10 @@ var CONTACT_MARGIN = 5e-3;
|
|
|
4634
4776
|
var CONTACT_PALM = 0.03;
|
|
4635
4777
|
var FOOT_LENGTH = 0.24;
|
|
4636
4778
|
var FOOT_SHOWN = 1e-3;
|
|
4779
|
+
var AWAY_DROP = 0.55;
|
|
4780
|
+
var AWAY_OUT = 7;
|
|
4781
|
+
var AWAY_IN = 20;
|
|
4782
|
+
var AWAY_HIDDEN = 0.97;
|
|
4637
4783
|
var FILL = 0.3;
|
|
4638
4784
|
var FIRST_PERSON_STANCES = first_person_arms_default.stances;
|
|
4639
4785
|
var FIRST_PERSON_RIG = first_person_arms_default.rig;
|
|
@@ -4747,7 +4893,7 @@ function createFirstPersonArms(THREE, options = {}) {
|
|
|
4747
4893
|
const cuff = limb(root, rig.radius.cuff, rig.radius.cuff, 0.03, materials.cuff);
|
|
4748
4894
|
const elbow = ball(root, rig.radius.elbow * 1.02, materials.sleeve);
|
|
4749
4895
|
elbow.name = `first-person-elbow-${side}`;
|
|
4750
|
-
arms[side] = { side, sign, hand, anchor, upper, fore, cuff, elbow, shown: newPose(THREE), from: newPose(THREE), mode: null, blend: 1, drawn: newPose(THREE), joints: { shoulder: new THREE.Vector3(), elbow: new THREE.Vector3(), wrist: new THREE.Vector3() } };
|
|
4896
|
+
arms[side] = { side, sign, hand, anchor, upper, fore, cuff, elbow, shown: newPose(THREE), from: newPose(THREE), mode: null, blend: 1, drawn: newPose(THREE), joints: { shoulder: new THREE.Vector3(), elbow: new THREE.Vector3(), wrist: new THREE.Vector3() }, away: options.hideWhenIdle ? 1 : 0 };
|
|
4751
4897
|
}
|
|
4752
4898
|
const leg = new THREE.Group();
|
|
4753
4899
|
leg.name = "first-person-leg";
|
|
@@ -4841,6 +4987,7 @@ function createFirstPersonArms(THREE, options = {}) {
|
|
|
4841
4987
|
const desired = newPose(THREE);
|
|
4842
4988
|
const channelPose = newPose(THREE);
|
|
4843
4989
|
const mixed = newPose(THREE);
|
|
4990
|
+
const dropped = newPose(THREE);
|
|
4844
4991
|
let indexCurl;
|
|
4845
4992
|
const bone = createTwoBone(THREE);
|
|
4846
4993
|
const shoulder = new THREE.Vector3();
|
|
@@ -4965,11 +5112,22 @@ function createFirstPersonArms(THREE, options = {}) {
|
|
|
4965
5112
|
if (arm.blend >= 1) copyPose(arm.shown, desired);
|
|
4966
5113
|
else mixPose(THREE, arm.shown, arm.from, desired, ease(arm.blend));
|
|
4967
5114
|
const channel = sample?.[side];
|
|
5115
|
+
let pose;
|
|
4968
5116
|
if (channel && channel.w > 0) {
|
|
4969
5117
|
fromChannel(channel, side, arm.shown, channelPose);
|
|
4970
5118
|
mixPose(THREE, mixed, arm.shown, channelPose, channel.w);
|
|
4971
|
-
|
|
4972
|
-
} else
|
|
5119
|
+
pose = mode === "target" ? mixed : keepOutside(mixed, handReach(mixed));
|
|
5120
|
+
} else pose = mode === "target" ? arm.shown : keepOutside(arm.shown, handReach(arm.shown));
|
|
5121
|
+
const idle = options.hideWhenIdle === true && mode === "rest:relaxed" && !(channel && channel.w > 0);
|
|
5122
|
+
arm.away = options.hideWhenIdle ? Math.min(1, Math.max(0, arm.away + ((idle ? 1 : 0) - arm.away) * Math.min(1, dt * (idle ? AWAY_OUT : AWAY_IN)))) : 0;
|
|
5123
|
+
if (arm.away > 0) {
|
|
5124
|
+
copyPose(dropped, pose);
|
|
5125
|
+
dropped.p.y -= AWAY_DROP * ease(arm.away);
|
|
5126
|
+
pose = dropped;
|
|
5127
|
+
}
|
|
5128
|
+
drawArm(arm, pose);
|
|
5129
|
+
const shown = arm.away < AWAY_HIDDEN;
|
|
5130
|
+
for (const part of [arm.anchor, arm.upper, arm.fore, arm.cuff, arm.elbow]) part.visible = shown;
|
|
4973
5131
|
}
|
|
4974
5132
|
const foot = sample?.F;
|
|
4975
5133
|
leg.visible = !!foot && foot.w > FOOT_SHOWN;
|
|
@@ -5016,6 +5174,7 @@ var toRoomAvatar = (avatar, options = {}) => {
|
|
|
5016
5174
|
const arms = options.firstPerson === false ? null : createFirstPersonArms(avatar.three, {
|
|
5017
5175
|
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 },
|
|
5018
5176
|
clips: options.firstPersonClips ?? FIRST_PERSON_CLIPS,
|
|
5177
|
+
hideWhenIdle: true,
|
|
5019
5178
|
...options.firstPerson
|
|
5020
5179
|
});
|
|
5021
5180
|
const strikes = new Map((options.strikeClips ?? ATTACK_CLIPS).map((clip) => [clip.id, clip]));
|
|
@@ -5030,7 +5189,16 @@ var toRoomAvatar = (avatar, options = {}) => {
|
|
|
5030
5189
|
avatar,
|
|
5031
5190
|
arms,
|
|
5032
5191
|
...arms ? { firstPerson: { root: arms.root, update: (dt, state) => arms.update(dt, state) } } : {},
|
|
5033
|
-
update: (dt, state) => avatar.update(dt, {
|
|
5192
|
+
update: (dt, state) => avatar.update(dt, {
|
|
5193
|
+
speed: state.speed,
|
|
5194
|
+
running: state.running,
|
|
5195
|
+
crouch: state.crouch,
|
|
5196
|
+
down: state.down,
|
|
5197
|
+
armed: state.armed,
|
|
5198
|
+
pitch: -state.pitch,
|
|
5199
|
+
...state.holding !== void 0 ? { holding: state.holding } : {},
|
|
5200
|
+
...state.itemUse !== void 0 ? { itemUse: state.itemUse } : {}
|
|
5201
|
+
}),
|
|
5034
5202
|
hand: (side) => avatar.hand(side),
|
|
5035
5203
|
strike: (clipId, strikeOptions) => {
|
|
5036
5204
|
const clip = strikes.get(clipId);
|