@adatechnology/game-characters-three 0.3.0 → 0.4.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 +17 -1
- package/dist/index.global.js +197 -16
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +193 -16
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -1017,6 +1017,9 @@ declare const registerBodyMaterial: (world: {
|
|
|
1017
1017
|
readonly materials: Map<string, unknown>;
|
|
1018
1018
|
}) => void;
|
|
1019
1019
|
|
|
1020
|
+
/** The person builder's spec for a profession of the people pack (look and gear as numbers; the builder draws the rest). */
|
|
1021
|
+
declare const personSpecOf: (profession: ProfessionCard) => Record<string, any>;
|
|
1022
|
+
|
|
1020
1023
|
/** The voice limiter group of the undead (`undead_voice`: five at once, one every 0.25 s, nearer than 40 m). */
|
|
1021
1024
|
declare const UNDEAD_VOICE_GROUP = "undead_voice";
|
|
1022
1025
|
/** The sounds of the game and of the art scene for the bodies, in one bank. */
|
|
@@ -1041,6 +1044,11 @@ type PlayerAvatarOptions = {
|
|
|
1041
1044
|
type AvatarEvent = PoseClipEvent & {
|
|
1042
1045
|
clip: string;
|
|
1043
1046
|
};
|
|
1047
|
+
type AvatarItemUsePose = {
|
|
1048
|
+
readonly id: string;
|
|
1049
|
+
readonly position: readonly [number, number, number];
|
|
1050
|
+
readonly rotation: readonly [number, number, number];
|
|
1051
|
+
};
|
|
1044
1052
|
type AvatarUpdate = {
|
|
1045
1053
|
/** Ground speed, m/s. Ties cadence and swing to the ground (the game's `walkCad` and `walkGait`). */
|
|
1046
1054
|
speed?: number;
|
|
@@ -1054,6 +1062,10 @@ type AvatarUpdate = {
|
|
|
1054
1062
|
pitch?: number;
|
|
1055
1063
|
/** Leg yaw toward the step while armed (the game's `P.hip`, radians). */
|
|
1056
1064
|
hip?: number;
|
|
1065
|
+
/** Whether the player is carrying an item in the right hand. */
|
|
1066
|
+
holding?: boolean;
|
|
1067
|
+
/** Active scripted item use (`drink`, `sip`, `chug`, `pour`, `open`, `close`, `tilt`). */
|
|
1068
|
+
itemUse?: AvatarItemUsePose | null;
|
|
1057
1069
|
};
|
|
1058
1070
|
type PlayPoseOptions = {
|
|
1059
1071
|
onEvent?: (event: AvatarEvent) => void;
|
|
@@ -1169,6 +1181,8 @@ type FirstPersonArmsOptions = {
|
|
|
1169
1181
|
clips?: readonly FirstPersonClip[];
|
|
1170
1182
|
/** Seconds to move from one stance (or from a held tool to the rest) to the next. Default 0.18. */
|
|
1171
1183
|
blend?: number;
|
|
1184
|
+
/** In the `relaxed` stance with no clip playing (walking, standing, nothing in the hands) the hands drop out of the view and are not drawn; a strike, a shove, a held tool or `fists` bring them back. Default false. */
|
|
1185
|
+
hideWhenIdle?: boolean;
|
|
1172
1186
|
bob?: Partial<FirstPersonBob>;
|
|
1173
1187
|
};
|
|
1174
1188
|
type FirstPersonArmsState = {
|
|
@@ -1229,6 +1243,8 @@ type RoomAvatarLike = {
|
|
|
1229
1243
|
down: boolean;
|
|
1230
1244
|
armed: boolean;
|
|
1231
1245
|
pitch: number;
|
|
1246
|
+
holding?: boolean;
|
|
1247
|
+
itemUse?: AvatarItemUsePose | null;
|
|
1232
1248
|
}): void;
|
|
1233
1249
|
hand(side: 'R' | 'L'): THREE_NS.Object3D;
|
|
1234
1250
|
/** The arms of the first-person view (`RoomAvatar.firstPerson`); absent when `toRoomAvatar` was told to make none. */
|
|
@@ -1341,4 +1357,4 @@ type TwoBone = {
|
|
|
1341
1357
|
*/
|
|
1342
1358
|
declare const solveTwoBone: (root: THREE_NS.Vector3, target: THREE_NS.Vector3, upper: number, lower: number, pole: THREE_NS.Vector3, out: TwoBone) => TwoBone;
|
|
1343
1359
|
|
|
1344
|
-
export { AVATAR_AREA_ID, type AreaContext, type AvatarEvent, type AvatarTestOptions, type AvatarUpdate, BAKE_NEUTRAL_POSE, BODY_CHUNK, BODY_MATERIAL_DEF, BODY_SOUNDS, type BakeBuilders, type BakeSpec, type BakedBody, type BestBuilder, type BestBuilderOptions, type BestTypeCard, type BloodAge, type BloodLook, type BloodLookOptions, type BloodSink, type BodyBatch, type BodyBatchOptions, type BodyChunkOptions, type BodyInstance, type BodyJoints, type BodyMaterialParams, type BodySoundRule, type BodyVariant, type BuildInstancedBodyParams, CHARACTERS_AREA_ID, CHARACTER_SOUNDS, CHARACTER_SOUND_BANK, type CharacterSound, type CharacterSoundOptions, type CharacterSoundSink, type CharacterSoundStyle, type CharactersTestOptions, EXTRAS, type EyeOptions, type Eyes, FACE_FEATURES, FIRST_PERSON_BOB, FIRST_PERSON_COLORS, FIRST_PERSON_RIG, FIRST_PERSON_STANCES, type FilmSink, type FirstPersonArms, type FirstPersonArmsOptions, type FirstPersonArmsState, type FirstPersonBob, type FirstPersonColors, type FirstPersonEvent, type FirstPersonRig, type FluidsBridge, type FluidsBridgeOptions, type FlyingLimb, type FlyingLimbs, type FlyingLimbsOptions, type FlyingPiece, type FlyingPieces, type FlyingPiecesOptions, HAND_ITEMS, HATS, HIT_PRESETS, type HitPreset, LOD_BAKE, LOD_BATCH_CAPACITY, LOD_CASTS_SHADOW, LOD_DISTANCES, LOD_SEGMENTS, type LimbEffects, type LimbLaunch, PENDULUM, PERSON_ITEM_PREFIX, PLAYER_SOUNDS, type Pendulum, type PersonBuilder, type PersonBuilderOptions, type PlayPoseOptions, type PlayerAvatar, type PlayerAvatarColors, type PlayerAvatarOptions, type PlayerAvatarSpec, type PoseTargets, type ProfessionCard, type RestPose, type RichRig, type RigAnimator, type RigAnimatorOptions, type RoomAvatarLike, type StanceDef, type Three, type ToRoomAvatarOptions, type TwoBone, UNDEAD_VOICES, UNDEAD_VOICE_GROUP, UNDEAD_VOICE_SOURCES, type UndeadCard, type UndeadLike, type UndeadVoice, type VariantType, type VoiceMoment, type VoiceStep, type WoundBody, type WoundMaterials, type WoundNode, type WoundSpray, type Wounds, type WoundsOptions, ZOMBIE_ITEM_PREFIX, bakeBody, bakeVariants, blobGeometry, blobRadii, bloodLookOfAge, buildInstancedBody, createAvatarTestModule, createBestBuilder, createBodyBatch, createBodyChunk, createBodyMaterial, createCharacterSound, createCharactersTestModule, createEye, createFirstPersonArms, createFluidsBridge, createFlyingLimbs, createFlyingPieces, createGlowTexture, createPendulum, createPersonBuilder, createPlayerAvatar, createRigAnimator, createVariantBatches, createWoundMaterials, createWounds, exitWound, explodeChunks, findEyes, gouge, jointsOf, lodAt, makeCut, makeStump, registerBodyMaterial, ringWound, solveTwoBone, starGeometry, stepPendulum, toRoomAvatar, woundBodyOf, woundDecal };
|
|
1360
|
+
export { AVATAR_AREA_ID, type AreaContext, type AvatarEvent, type AvatarItemUsePose, type AvatarTestOptions, type AvatarUpdate, BAKE_NEUTRAL_POSE, BODY_CHUNK, BODY_MATERIAL_DEF, BODY_SOUNDS, type BakeBuilders, type BakeSpec, type BakedBody, type BestBuilder, type BestBuilderOptions, type BestTypeCard, type BloodAge, type BloodLook, type BloodLookOptions, type BloodSink, type BodyBatch, type BodyBatchOptions, type BodyChunkOptions, type BodyInstance, type BodyJoints, type BodyMaterialParams, type BodySoundRule, type BodyVariant, type BuildInstancedBodyParams, CHARACTERS_AREA_ID, CHARACTER_SOUNDS, CHARACTER_SOUND_BANK, type CharacterSound, type CharacterSoundOptions, type CharacterSoundSink, type CharacterSoundStyle, type CharactersTestOptions, EXTRAS, type EyeOptions, type Eyes, FACE_FEATURES, FIRST_PERSON_BOB, FIRST_PERSON_COLORS, FIRST_PERSON_RIG, FIRST_PERSON_STANCES, type FilmSink, type FirstPersonArms, type FirstPersonArmsOptions, type FirstPersonArmsState, type FirstPersonBob, type FirstPersonColors, type FirstPersonEvent, type FirstPersonRig, type FluidsBridge, type FluidsBridgeOptions, type FlyingLimb, type FlyingLimbs, type FlyingLimbsOptions, type FlyingPiece, type FlyingPieces, type FlyingPiecesOptions, HAND_ITEMS, HATS, HIT_PRESETS, type HitPreset, LOD_BAKE, LOD_BATCH_CAPACITY, LOD_CASTS_SHADOW, LOD_DISTANCES, LOD_SEGMENTS, type LimbEffects, type LimbLaunch, PENDULUM, PERSON_ITEM_PREFIX, PLAYER_SOUNDS, type Pendulum, type PersonBuilder, type PersonBuilderOptions, type PlayPoseOptions, type PlayerAvatar, type PlayerAvatarColors, type PlayerAvatarOptions, type PlayerAvatarSpec, type PoseTargets, type ProfessionCard, type RestPose, type RichRig, type RigAnimator, type RigAnimatorOptions, type RoomAvatarLike, type StanceDef, type Three, type ToRoomAvatarOptions, type TwoBone, UNDEAD_VOICES, UNDEAD_VOICE_GROUP, UNDEAD_VOICE_SOURCES, type UndeadCard, type UndeadLike, type UndeadVoice, type VariantType, type VoiceMoment, type VoiceStep, type WoundBody, type WoundMaterials, type WoundNode, type WoundSpray, type Wounds, type WoundsOptions, ZOMBIE_ITEM_PREFIX, bakeBody, bakeVariants, blobGeometry, blobRadii, bloodLookOfAge, buildInstancedBody, createAvatarTestModule, createBestBuilder, createBodyBatch, createBodyChunk, createBodyMaterial, createCharacterSound, createCharactersTestModule, createEye, createFirstPersonArms, createFluidsBridge, createFlyingLimbs, createFlyingPieces, createGlowTexture, createPendulum, createPersonBuilder, createPlayerAvatar, createRigAnimator, createVariantBatches, createWoundMaterials, createWounds, exitWound, explodeChunks, findEyes, gouge, jointsOf, lodAt, makeCut, makeStump, personSpecOf, registerBodyMaterial, ringWound, solveTwoBone, starGeometry, stepPendulum, toRoomAvatar, woundBodyOf, woundDecal };
|
package/dist/index.global.js
CHANGED
|
@@ -84,6 +84,7 @@ var GameCharactersThree = (() => {
|
|
|
84
84
|
lodAt: () => lodAt,
|
|
85
85
|
makeCut: () => makeCut,
|
|
86
86
|
makeStump: () => makeStump,
|
|
87
|
+
personSpecOf: () => personSpecOf,
|
|
87
88
|
registerBodyMaterial: () => registerBodyMaterial,
|
|
88
89
|
ringWound: () => ringWound,
|
|
89
90
|
solveTwoBone: () => solveTwoBone,
|
|
@@ -1716,6 +1717,13 @@ var GameCharactersThree = (() => {
|
|
|
1716
1717
|
legRBroken: 256,
|
|
1717
1718
|
jaw: 512
|
|
1718
1719
|
};
|
|
1720
|
+
var KIT_ORIGIN_KEY = "kitOrigin";
|
|
1721
|
+
function markKitOrigin(object2, origin) {
|
|
1722
|
+
const node = object2;
|
|
1723
|
+
node.userData = node.userData ?? {};
|
|
1724
|
+
node.userData[KIT_ORIGIN_KEY] = { ...origin };
|
|
1725
|
+
return object2;
|
|
1726
|
+
}
|
|
1719
1727
|
|
|
1720
1728
|
// ../game-characters/dist/index.js
|
|
1721
1729
|
var __defProp2 = Object.defineProperty;
|
|
@@ -5430,7 +5438,8 @@ var GameCharactersThree = (() => {
|
|
|
5430
5438
|
root.userData.rig = rig;
|
|
5431
5439
|
return root;
|
|
5432
5440
|
}
|
|
5433
|
-
|
|
5441
|
+
const marked = (...args) => markKitOrigin(build(...args), { owner: "game-characters-three", kind: "person" });
|
|
5442
|
+
return { build: marked, TYPES, setLOD(k) {
|
|
5434
5443
|
LK = k;
|
|
5435
5444
|
SEG = Math.max(5, Math.round(16 * k));
|
|
5436
5445
|
}, topM: () => topM_ref };
|
|
@@ -6656,7 +6665,11 @@ var GameCharactersThree = (() => {
|
|
|
6656
6665
|
chars.forEach((c) => pose(c, c.z, 0, 0));
|
|
6657
6666
|
return { root, chars };
|
|
6658
6667
|
}
|
|
6659
|
-
|
|
6668
|
+
const mark = (c) => {
|
|
6669
|
+
markKitOrigin(c.root, { owner: "game-characters-three", kind: "person" });
|
|
6670
|
+
return c;
|
|
6671
|
+
};
|
|
6672
|
+
return { build: (sp, idx) => mark(build(sp, idx)), pose, zombify, buildPerson: (p2, zed) => mark(buildPerson(p2, zed)) };
|
|
6660
6673
|
};
|
|
6661
6674
|
|
|
6662
6675
|
// src/eyes.ts
|
|
@@ -8608,7 +8621,17 @@ var GameCharactersThree = (() => {
|
|
|
8608
8621
|
fem: false,
|
|
8609
8622
|
life: 1,
|
|
8610
8623
|
hs: "short",
|
|
8611
|
-
hair: "2a1e16"
|
|
8624
|
+
hair: "2a1e16",
|
|
8625
|
+
pose: {
|
|
8626
|
+
armL: 0,
|
|
8627
|
+
armR: 0,
|
|
8628
|
+
elbL: -0.12,
|
|
8629
|
+
elbR: -0.12,
|
|
8630
|
+
armOut: 0.11,
|
|
8631
|
+
lean: 0.04,
|
|
8632
|
+
headX: 0,
|
|
8633
|
+
headZ: 0
|
|
8634
|
+
}
|
|
8612
8635
|
},
|
|
8613
8636
|
shirtColor: "3d5a73"
|
|
8614
8637
|
};
|
|
@@ -8619,9 +8642,12 @@ var GameCharactersThree = (() => {
|
|
|
8619
8642
|
var CLIP_BLEND = 0.12;
|
|
8620
8643
|
var FALL_SECONDS2 = 0.3;
|
|
8621
8644
|
var HIP_HEIGHT = 0.95;
|
|
8622
|
-
var WALK_ARM = 0.
|
|
8645
|
+
var WALK_ARM = 0.28;
|
|
8623
8646
|
var WALK_BOB = 0.035;
|
|
8624
8647
|
var WALK_LEAN = 0.04;
|
|
8648
|
+
var RUN_LEAN = 0.16;
|
|
8649
|
+
var RUN_BOB = 0.05;
|
|
8650
|
+
var REST_ARM_Z = 0.18;
|
|
8625
8651
|
var CROUCH = { thigh: -0.95, thighWalk: 0.3, shin: 1.9, lean: 0.25, drop: -0.35 };
|
|
8626
8652
|
var AIMED = { shoulder: -1.42, perAim: 0.85, swing: 0.02, zRight: -0.54, zLeft: 0.36, elbowRight: -0.04, elbowLeft: -0.12 };
|
|
8627
8653
|
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 };
|
|
@@ -8630,7 +8656,18 @@ var GameCharactersThree = (() => {
|
|
|
8630
8656
|
var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
8631
8657
|
var fract = (value) => value - Math.floor(value);
|
|
8632
8658
|
var createPlayerAvatar = (THREE, options = {}) => {
|
|
8633
|
-
const
|
|
8659
|
+
const pose = {
|
|
8660
|
+
armL: 0,
|
|
8661
|
+
armR: 0,
|
|
8662
|
+
elbL: -0.08,
|
|
8663
|
+
elbR: -0.08,
|
|
8664
|
+
lean: 0.04,
|
|
8665
|
+
headX: 0,
|
|
8666
|
+
headZ: 0,
|
|
8667
|
+
...player_avatar_default.spec.pose,
|
|
8668
|
+
...options.spec?.pose
|
|
8669
|
+
};
|
|
8670
|
+
const spec = { ...player_avatar_default.spec, ...options.spec, pose };
|
|
8634
8671
|
for (const key of ["skin", "hair"]) if (typeof spec[key] === "string") spec[key] = hexOf(spec[key]);
|
|
8635
8672
|
const best = createBestBuilder(THREE, { types: [{ name: String(spec.type), eye: 0 }], random: createRng(Number(spec.seed ?? 1)) });
|
|
8636
8673
|
const body = best.build(spec);
|
|
@@ -8665,6 +8702,41 @@ var GameCharactersThree = (() => {
|
|
|
8665
8702
|
sockets[side].position.set(HAND_OFFSET.x, HAND_OFFSET.y, HAND_OFFSET.z);
|
|
8666
8703
|
armOf[side].el.add(sockets[side]);
|
|
8667
8704
|
}
|
|
8705
|
+
const addMesh = (parent, geometry, material, x = 0, y = 0, z = 0, rx = 0, ry = 0, rz = 0) => {
|
|
8706
|
+
const mesh2 = new THREE.Mesh(geometry, material);
|
|
8707
|
+
mesh2.position.set(x, y, z);
|
|
8708
|
+
if (rx || ry || rz) mesh2.rotation.set(rx, ry, rz);
|
|
8709
|
+
mesh2.castShadow = true;
|
|
8710
|
+
mesh2.receiveShadow = true;
|
|
8711
|
+
parent.add(mesh2);
|
|
8712
|
+
return mesh2;
|
|
8713
|
+
};
|
|
8714
|
+
const hands = [];
|
|
8715
|
+
rig.arms.forEach((arm, index) => {
|
|
8716
|
+
const el = arm.el;
|
|
8717
|
+
const side = index === 0 ? 1 : -1;
|
|
8718
|
+
const oldHand = meshesOf(el).find((mesh2) => Math.abs(mesh2.position.y + 0.33) < 0.025);
|
|
8719
|
+
const handMaterial = oldHand?.material ?? new THREE.MeshLambertMaterial({ color: colors.skin });
|
|
8720
|
+
if (oldHand) {
|
|
8721
|
+
oldHand.geometry?.dispose();
|
|
8722
|
+
el.remove(oldHand);
|
|
8723
|
+
}
|
|
8724
|
+
const hg = new THREE.Group();
|
|
8725
|
+
hg.name = side > 0 ? "hand_group_L" : "hand_group_R";
|
|
8726
|
+
hg.position.set(side * 0.02, -0.3, 0.01);
|
|
8727
|
+
el.add(hg);
|
|
8728
|
+
const palm = addMesh(hg, new THREE.SphereGeometry(0.048, 14, 10), handMaterial, 0, -0.035, 0);
|
|
8729
|
+
palm.scale.set(0.6, 1.05, 1);
|
|
8730
|
+
const built = buildHand({ THREE, add: addMesh, hg, handM: handMaterial, s: side, detailed: true });
|
|
8731
|
+
hands.push({ side, hg, fingers: built.fingers, th: built.th });
|
|
8732
|
+
});
|
|
8733
|
+
const setHandGrip = (hand, grip, wristX = 0) => {
|
|
8734
|
+
hand.fingers.forEach((finger, j) => {
|
|
8735
|
+
finger.rotation.z = -hand.side * grip * (j % 2 ? 1.1 : 0.9);
|
|
8736
|
+
});
|
|
8737
|
+
if (hand.th) hand.th.rotation.z = -hand.side * (0.32 + grip * 0.25);
|
|
8738
|
+
hand.hg.rotation.x = wristX;
|
|
8739
|
+
};
|
|
8668
8740
|
const legRestX = rig.legs.map((leg) => leg.g.position.x);
|
|
8669
8741
|
const legSide = (index) => index === 0 ? 1 : -1;
|
|
8670
8742
|
let cycles = 0;
|
|
@@ -8706,6 +8778,42 @@ var GameCharactersThree = (() => {
|
|
|
8706
8778
|
});
|
|
8707
8779
|
return { armR: shoulder, armL: shoulder, armRz: AIMED.zRight, armLz: AIMED.zLeft, elbR: AIMED.elbowRight, elbL: AIMED.elbowLeft };
|
|
8708
8780
|
};
|
|
8781
|
+
const holdingPose = (gait, itemUse) => {
|
|
8782
|
+
const bob = Math.sin(cycles * TWO_PI2) * 0.05 * gait;
|
|
8783
|
+
if (!itemUse) {
|
|
8784
|
+
return { armL: -0.45 + bob, armLz: 0.22, elbL: -1.05 };
|
|
8785
|
+
}
|
|
8786
|
+
const { id, position, rotation } = itemUse;
|
|
8787
|
+
if (id === "drink" || id === "sip" || id === "chug") {
|
|
8788
|
+
const raise2 = clamp((position[1] + 0.2) / 0.22, 0, 1);
|
|
8789
|
+
const tilt3 = clamp(Math.abs(rotation[0]) / 1.22, 0, 1.15);
|
|
8790
|
+
return {
|
|
8791
|
+
armL: -0.45 - 0.95 * raise2 - 0.22 * tilt3,
|
|
8792
|
+
armLz: 0.22 + 0.44 * raise2,
|
|
8793
|
+
elbL: -1.05 - 0.85 * raise2 + 0.12 * tilt3,
|
|
8794
|
+
headX: -0.26 * tilt3
|
|
8795
|
+
};
|
|
8796
|
+
}
|
|
8797
|
+
if (id === "open" || id === "close") {
|
|
8798
|
+
const reach = clamp((0.22 - position[0]) / 0.12, 0, 1);
|
|
8799
|
+
return {
|
|
8800
|
+
armL: -0.45 - 0.35 * reach,
|
|
8801
|
+
armLz: 0.22 + 0.28 * reach,
|
|
8802
|
+
elbL: -1.05 - 0.25 * reach,
|
|
8803
|
+
armR: -0.78 * reach,
|
|
8804
|
+
armRz: -0.48 * reach,
|
|
8805
|
+
elbR: -1.25 * reach
|
|
8806
|
+
};
|
|
8807
|
+
}
|
|
8808
|
+
const raise = clamp((position[1] + 0.2) / 0.25, 0, 1);
|
|
8809
|
+
const tilt2 = clamp(Math.abs(rotation[0]) / 1.75, 0, 1.2);
|
|
8810
|
+
const ext = Math.max(raise, tilt2 * 0.75);
|
|
8811
|
+
return {
|
|
8812
|
+
armL: -0.45 - 0.48 * ext,
|
|
8813
|
+
armLz: 0.22 + 0.08 * ext,
|
|
8814
|
+
elbL: -1.05 + 0.38 * ext
|
|
8815
|
+
};
|
|
8816
|
+
};
|
|
8709
8817
|
const resetLegYaw = () => {
|
|
8710
8818
|
rig.legs.forEach((leg, index) => {
|
|
8711
8819
|
leg.g.rotation.y = 0;
|
|
@@ -8713,6 +8821,32 @@ var GameCharactersThree = (() => {
|
|
|
8713
8821
|
leg.g.position.z = 0;
|
|
8714
8822
|
});
|
|
8715
8823
|
};
|
|
8824
|
+
const runningPose = (gait, busyHands = false) => {
|
|
8825
|
+
const ph = cycles * TWO_PI2;
|
|
8826
|
+
const sine = Math.sin(ph);
|
|
8827
|
+
const cosine = Math.cos(ph);
|
|
8828
|
+
const legL = sine * 0.65 * gait;
|
|
8829
|
+
const legR = -sine * 0.65 * gait;
|
|
8830
|
+
const kneeL = Math.max(0, -cosine) * 1.15 * gait;
|
|
8831
|
+
const kneeR = Math.max(0, cosine) * 1.15 * gait;
|
|
8832
|
+
const targets = {
|
|
8833
|
+
lean: RUN_LEAN * Math.min(1, gait),
|
|
8834
|
+
drop: Math.abs(cosine) * RUN_BOB * gait,
|
|
8835
|
+
legL,
|
|
8836
|
+
legR,
|
|
8837
|
+
kneeL,
|
|
8838
|
+
kneeR
|
|
8839
|
+
};
|
|
8840
|
+
if (!busyHands) {
|
|
8841
|
+
targets.armR = -0.32 - sine * 0.65 * gait;
|
|
8842
|
+
targets.armL = -0.32 + sine * 0.65 * gait;
|
|
8843
|
+
targets.elbR = -1.25 + Math.max(0, sine) * 0.3 * gait;
|
|
8844
|
+
targets.elbL = -1.25 + Math.max(0, -sine) * 0.3 * gait;
|
|
8845
|
+
targets.armRz = 0.22;
|
|
8846
|
+
targets.armLz = -0.22;
|
|
8847
|
+
}
|
|
8848
|
+
return targets;
|
|
8849
|
+
};
|
|
8716
8850
|
const crouchPose = (gait) => {
|
|
8717
8851
|
const swing = (leg) => {
|
|
8718
8852
|
const legS = legSide(leg);
|
|
@@ -8808,23 +8942,44 @@ var GameCharactersThree = (() => {
|
|
|
8808
8942
|
update(dt, state = {}) {
|
|
8809
8943
|
const speed = state.speed ?? 0;
|
|
8810
8944
|
const moving = speed >= 0.05;
|
|
8811
|
-
|
|
8945
|
+
const down = !!state.down;
|
|
8946
|
+
const running = Boolean(state.running && moving && !down && !state.crouch);
|
|
8947
|
+
if (moving) cycles += dt * (running ? walkCadence(speed) * 1.3 : walkCadence(speed));
|
|
8812
8948
|
const gait = Math.min(MAX_GAIT, walkGait(speed));
|
|
8813
|
-
profile.arm = WALK_ARM * gait;
|
|
8814
|
-
profile.bob = WALK_BOB * gait;
|
|
8815
|
-
time = cycles / walkCadence(Math.max(speed, 0));
|
|
8949
|
+
profile.arm = (running ? 0.55 : WALK_ARM) * gait;
|
|
8950
|
+
profile.bob = (running ? RUN_BOB : WALK_BOB) * gait;
|
|
8951
|
+
time = cycles / (walkCadence(Math.max(speed, 0)) * (running ? 1.3 : 1));
|
|
8816
8952
|
animator.animate(body, time, { speed });
|
|
8817
|
-
const down = !!state.down;
|
|
8818
8953
|
fall = fallSeconds <= 0 ? down ? 1 : 0 : clamp(fall + (down ? dt : -dt) / fallSeconds, 0, 1);
|
|
8819
8954
|
resetLegYaw();
|
|
8820
8955
|
if (down) animator.setPose(rig, downPose());
|
|
8821
8956
|
else {
|
|
8957
|
+
if (running) animator.setPose(rig, runningPose(gait, Boolean(state.armed || state.holding || state.itemUse)));
|
|
8822
8958
|
if (state.crouch) animator.setPose(rig, crouchPose(gait));
|
|
8823
8959
|
if (state.armed) animator.setPose(rig, armed(state.pitch ?? 0, gait, state.hip ?? 0));
|
|
8960
|
+
else if (state.holding || state.itemUse) animator.setPose(rig, holdingPose(gait, state.itemUse));
|
|
8961
|
+
else if (!running) {
|
|
8962
|
+
animator.setPose(rig, {
|
|
8963
|
+
armRz: REST_ARM_Z,
|
|
8964
|
+
armLz: -REST_ARM_Z,
|
|
8965
|
+
elbR: -0.12,
|
|
8966
|
+
elbL: -0.12
|
|
8967
|
+
});
|
|
8968
|
+
}
|
|
8824
8969
|
}
|
|
8825
8970
|
placeBody(fall);
|
|
8826
8971
|
stepClip(dt, down);
|
|
8827
8972
|
if (smooth) animator.cascade(rig, dt);
|
|
8973
|
+
const clipId = run ? run.clip.id : null;
|
|
8974
|
+
const ph = cycles * TWO_PI2;
|
|
8975
|
+
hands.forEach((hand) => {
|
|
8976
|
+
const isRight = hand.side < 0;
|
|
8977
|
+
const holdRight = isRight && (!!state.holding || !!state.itemUse);
|
|
8978
|
+
const holdLeft = !isRight && (state.itemUse?.id === "open" || state.itemUse?.id === "close");
|
|
8979
|
+
const grip = clipId === "punch_right" ? 1.4 : clipId === "shove_two_hands" ? 0.15 : state.armed || holdRight || holdLeft ? 1.22 : running ? 0.85 : 0.12;
|
|
8980
|
+
const wristSwing = holdRight || state.armed || running ? 0 : -Math.min(1, gait) * Math.sin(ph - 0.6) * 0.12 * hand.side;
|
|
8981
|
+
setHandGrip(hand, grip, wristSwing);
|
|
8982
|
+
});
|
|
8828
8983
|
},
|
|
8829
8984
|
play(clip, playOptions = {}) {
|
|
8830
8985
|
const found = typeof clip === "string" ? clips.get(clip) : clip;
|
|
@@ -9152,7 +9307,7 @@ var GameCharactersThree = (() => {
|
|
|
9152
9307
|
},
|
|
9153
9308
|
stances: {
|
|
9154
9309
|
relaxed: {
|
|
9155
|
-
R: { p: [0.2, -0.
|
|
9310
|
+
R: { p: [0.2, -0.22, -0.36], r: [0.05, 1.57, -0.05], grip: 0.2 },
|
|
9156
9311
|
L: "mirror"
|
|
9157
9312
|
},
|
|
9158
9313
|
fists: {
|
|
@@ -9296,6 +9451,10 @@ var GameCharactersThree = (() => {
|
|
|
9296
9451
|
var CONTACT_PALM = 0.03;
|
|
9297
9452
|
var FOOT_LENGTH = 0.24;
|
|
9298
9453
|
var FOOT_SHOWN = 1e-3;
|
|
9454
|
+
var AWAY_DROP = 0.55;
|
|
9455
|
+
var AWAY_OUT = 7;
|
|
9456
|
+
var AWAY_IN = 20;
|
|
9457
|
+
var AWAY_HIDDEN = 0.97;
|
|
9299
9458
|
var FILL = 0.3;
|
|
9300
9459
|
var FIRST_PERSON_STANCES = first_person_arms_default.stances;
|
|
9301
9460
|
var FIRST_PERSON_RIG = first_person_arms_default.rig;
|
|
@@ -9354,7 +9513,7 @@ var GameCharactersThree = (() => {
|
|
|
9354
9513
|
const bob = { ...FIRST_PERSON_BOB, ...options.bob };
|
|
9355
9514
|
const blendSeconds = options.blend ?? DEFAULT_BLEND;
|
|
9356
9515
|
const clips = new Map((options.clips ?? []).map((clip) => [clip.id, clip]));
|
|
9357
|
-
const root = new THREE.Group();
|
|
9516
|
+
const root = markKitOrigin(new THREE.Group(), { owner: "game-characters-three", kind: "person", id: "first-person-arms" });
|
|
9358
9517
|
root.name = "first-person-arms";
|
|
9359
9518
|
root.userData.viewmodel = true;
|
|
9360
9519
|
const lit = (color2) => new THREE.MeshLambertMaterial({ color: color2, emissive: scaleHex(color2, FILL) });
|
|
@@ -9409,7 +9568,7 @@ var GameCharactersThree = (() => {
|
|
|
9409
9568
|
const cuff = limb2(root, rig.radius.cuff, rig.radius.cuff, 0.03, materials.cuff);
|
|
9410
9569
|
const elbow = ball(root, rig.radius.elbow * 1.02, materials.sleeve);
|
|
9411
9570
|
elbow.name = `first-person-elbow-${side}`;
|
|
9412
|
-
arms[side] = { side, sign: sign2, 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() } };
|
|
9571
|
+
arms[side] = { side, sign: sign2, 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 };
|
|
9413
9572
|
}
|
|
9414
9573
|
const leg = new THREE.Group();
|
|
9415
9574
|
leg.name = "first-person-leg";
|
|
@@ -9503,6 +9662,7 @@ var GameCharactersThree = (() => {
|
|
|
9503
9662
|
const desired = newPose(THREE);
|
|
9504
9663
|
const channelPose = newPose(THREE);
|
|
9505
9664
|
const mixed = newPose(THREE);
|
|
9665
|
+
const dropped = newPose(THREE);
|
|
9506
9666
|
let indexCurl;
|
|
9507
9667
|
const bone = createTwoBone(THREE);
|
|
9508
9668
|
const shoulder = new THREE.Vector3();
|
|
@@ -9627,11 +9787,22 @@ var GameCharactersThree = (() => {
|
|
|
9627
9787
|
if (arm.blend >= 1) copyPose(arm.shown, desired);
|
|
9628
9788
|
else mixPose(THREE, arm.shown, arm.from, desired, ease2(arm.blend));
|
|
9629
9789
|
const channel = sample?.[side];
|
|
9790
|
+
let pose;
|
|
9630
9791
|
if (channel && channel.w > 0) {
|
|
9631
9792
|
fromChannel(channel, side, arm.shown, channelPose);
|
|
9632
9793
|
mixPose(THREE, mixed, arm.shown, channelPose, channel.w);
|
|
9633
|
-
|
|
9634
|
-
} else
|
|
9794
|
+
pose = mode === "target" ? mixed : keepOutside(mixed, handReach(mixed));
|
|
9795
|
+
} else pose = mode === "target" ? arm.shown : keepOutside(arm.shown, handReach(arm.shown));
|
|
9796
|
+
const idle = options.hideWhenIdle === true && mode === "rest:relaxed" && !(channel && channel.w > 0);
|
|
9797
|
+
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;
|
|
9798
|
+
if (arm.away > 0) {
|
|
9799
|
+
copyPose(dropped, pose);
|
|
9800
|
+
dropped.p.y -= AWAY_DROP * ease2(arm.away);
|
|
9801
|
+
pose = dropped;
|
|
9802
|
+
}
|
|
9803
|
+
drawArm(arm, pose);
|
|
9804
|
+
const shown = arm.away < AWAY_HIDDEN;
|
|
9805
|
+
for (const part of [arm.anchor, arm.upper, arm.fore, arm.cuff, arm.elbow]) part.visible = shown;
|
|
9635
9806
|
}
|
|
9636
9807
|
const foot = sample?.F;
|
|
9637
9808
|
leg.visible = !!foot && foot.w > FOOT_SHOWN;
|
|
@@ -9678,6 +9849,7 @@ var GameCharactersThree = (() => {
|
|
|
9678
9849
|
const arms = options.firstPerson === false ? null : createFirstPersonArms(avatar.three, {
|
|
9679
9850
|
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 },
|
|
9680
9851
|
clips: options.firstPersonClips ?? FIRST_PERSON_CLIPS,
|
|
9852
|
+
hideWhenIdle: true,
|
|
9681
9853
|
...options.firstPerson
|
|
9682
9854
|
});
|
|
9683
9855
|
const strikes = new Map((options.strikeClips ?? ATTACK_CLIPS).map((clip) => [clip.id, clip]));
|
|
@@ -9692,7 +9864,16 @@ var GameCharactersThree = (() => {
|
|
|
9692
9864
|
avatar,
|
|
9693
9865
|
arms,
|
|
9694
9866
|
...arms ? { firstPerson: { root: arms.root, update: (dt, state) => arms.update(dt, state) } } : {},
|
|
9695
|
-
update: (dt, state) => avatar.update(dt, {
|
|
9867
|
+
update: (dt, state) => avatar.update(dt, {
|
|
9868
|
+
speed: state.speed,
|
|
9869
|
+
running: state.running,
|
|
9870
|
+
crouch: state.crouch,
|
|
9871
|
+
down: state.down,
|
|
9872
|
+
armed: state.armed,
|
|
9873
|
+
pitch: -state.pitch,
|
|
9874
|
+
...state.holding !== void 0 ? { holding: state.holding } : {},
|
|
9875
|
+
...state.itemUse !== void 0 ? { itemUse: state.itemUse } : {}
|
|
9876
|
+
}),
|
|
9696
9877
|
hand: (side) => avatar.hand(side),
|
|
9697
9878
|
strike: (clipId, strikeOptions) => {
|
|
9698
9879
|
const clip = strikes.get(clipId);
|