@adatechnology/game-characters-three 0.7.0 → 0.7.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/README.md +1 -1
- package/dist/index.d.ts +98 -105
- package/dist/index.global.js +320 -239
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +237 -241
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ down turns the body about the hip (`±1.5` rad, face up or down by the phase) wi
|
|
|
48
48
|
one button per registered clip (`Tocar: grabbed_bitten_human`, `grab_bite_zombie`, and with `clips: [...POSE_CLIPS, ...ATTACK_CLIPS]` the punch, shove, kick and the recoils; `clipLocales` gives the phase texts) and stop; metrics for the camera, the clip playing, the last clip event and the joints. Every action is a JSON line in the room log (`{"type":"avatar","action":"play_clip","clip":...}`), clip events included, and an `impact` event also gets its own `{"action":"impact","clip":...,"t":...}` line.
|
|
49
49
|
The module takes the body, the view (`camera: { mode, set }`) and the state (`state: { set }`) by option and imports only `@adatechnology/game-contracts`.
|
|
50
50
|
|
|
51
|
-
`toRoomAvatar` also gives the room
|
|
51
|
+
`toRoomAvatar` also gives the room `strike(clipId)`, which plays the attack clip on the body (the only source of a strike, first and third person) and answers the seconds to the impact read from that clip (the same in both views). `strike(clip, { leg: 'left' })` kicks with the left leg and `strike(clip, { hand: 'left' })` punches with the left hand: the mirror of the clip on the body (`mirrorPoseClip`, id `<clip>_left`). After a punch (an `impact` of kind `punch`) the body holds the guard (`guardClip`, default `'fight_guard'`, `false` for none) for
|
|
52
52
|
`guardHold` seconds (default 1.2) while it stands still, so a combo goes guard, punch, guard; the punch blends in over `punchBlend` (default 0.05 s). Walking, running, a weapon or a held item drop the guard.
|
|
53
53
|
|
|
54
54
|
**First-person arms.** `createFirstPersonArms(THREE, { colors?, rig?, stances?, clips?, blend?, bob? })` builds sleeves (upper arm, forearm, elbow, cuff) and hands of skin (palm, four fingers of three segments, a thumb that close on a grip) drawn in the camera's space, plus the right leg that only shows during a kick. `arms.update(dt, { camera, targets, stance, speed, running, crouch, contact? })`: the `relaxed` and `fists` stances are rest poses (`FIRST_PERSON_STANCES`, from `presets/first-person-arms.json`), `hold` follows the `HandTargets` of `game-contracts` (world space) with a two-bone IK from fixed shoulders, the elbow bending down and out; a target out of reach is clamped (the shoulder moves `reachShift` toward it first). `arms.play('punch_right' | 'shove_two_hands' | 'front_kick')` overlays a `FirstPersonClip` (`FIRST_PERSON_CLIPS` of `game-characters-people`, same durations and impact seconds as the attack clips); `arms.on('event', fn)` gives its `impact`; `arms.handPose(side)` reads where a hand is drawn. `contact(origin, direction, maxDistance)` (optional; distance to the first surface or null) makes the hands and the kick foot stop a few millimetres before a surface along the camera forward (the elbow bends); `arms.play('front_kick', { leg: 'left' })` kicks with the left leg and `arms.play('punch_right', { hand: 'left' })` punches with the left hand (the hands of the clip in a mirror). Hand frame: x wrist to knuckles, y back of the hand, z little-finger side; a left hand is the right one mirrored.
|
package/dist/index.d.ts
CHANGED
|
@@ -1170,6 +1170,104 @@ type PlayerAvatar = {
|
|
|
1170
1170
|
*/
|
|
1171
1171
|
declare const createPlayerAvatar: (THREE: Three, options?: PlayerAvatarOptions) => PlayerAvatar;
|
|
1172
1172
|
|
|
1173
|
+
/** What `@adatechnology/game-test-room` calls a `RoomAvatar`, restated here so this package does not depend on the room. */
|
|
1174
|
+
type RoomAvatarLike = {
|
|
1175
|
+
root: THREE_NS.Object3D;
|
|
1176
|
+
update(dt: number, state: {
|
|
1177
|
+
speed: number;
|
|
1178
|
+
running: boolean;
|
|
1179
|
+
crouch: boolean;
|
|
1180
|
+
down: boolean;
|
|
1181
|
+
armed: boolean;
|
|
1182
|
+
pitch: number;
|
|
1183
|
+
push?: {
|
|
1184
|
+
readonly phase: 'grip' | 'push' | 'strain';
|
|
1185
|
+
readonly progress: number;
|
|
1186
|
+
} | null;
|
|
1187
|
+
door?: {
|
|
1188
|
+
readonly phase: 'reach' | 'swing' | 'release' | 'rattle';
|
|
1189
|
+
readonly progress: number;
|
|
1190
|
+
readonly height: number;
|
|
1191
|
+
readonly pull: boolean;
|
|
1192
|
+
} | null;
|
|
1193
|
+
holding?: boolean;
|
|
1194
|
+
itemUse?: AvatarItemUsePose | null;
|
|
1195
|
+
seat?: {
|
|
1196
|
+
readonly pose: 'sit' | 'lie';
|
|
1197
|
+
readonly hip: number;
|
|
1198
|
+
} | null;
|
|
1199
|
+
}): void;
|
|
1200
|
+
hand(side: 'R' | 'L'): THREE_NS.Object3D;
|
|
1201
|
+
shoulder(side: 'R' | 'L'): THREE_NS.Object3D;
|
|
1202
|
+
/** Where the body's eyes are after its pose (`RoomAvatar.eye`): the room draws the body in both views and puts the first-person camera there. */
|
|
1203
|
+
eye(out?: THREE_NS.Vector3): THREE_NS.Vector3;
|
|
1204
|
+
/** Hides the head and neck from `camera` in first person (`RoomAvatar.setView`). */
|
|
1205
|
+
setView(mode: AvatarViewMode, camera: THREE_NS.Object3D | null): void;
|
|
1206
|
+
/** Brings the body's hands to the tool in them, in both views; `view` keeps them in the first-person view (`RoomAvatar.reach`). */
|
|
1207
|
+
reach(targets: HandTargets | null, view?: ReachView | null): void;
|
|
1208
|
+
/** Plays a strike on the body (the only source of it, in both views) and answers the seconds to its impact (`RoomAvatar.strike`). */
|
|
1209
|
+
strike(clipId: string, options?: {
|
|
1210
|
+
leg?: 'left' | 'right';
|
|
1211
|
+
hand?: 'left' | 'right';
|
|
1212
|
+
}): number | null;
|
|
1213
|
+
/** The avatar it wraps. */
|
|
1214
|
+
readonly avatar: PlayerAvatar;
|
|
1215
|
+
};
|
|
1216
|
+
type ToRoomAvatarOptions = {
|
|
1217
|
+
/** The third-person strike clips `strike` finds by id. Default `ATTACK_CLIPS` of game-characters-people. */
|
|
1218
|
+
strikeClips?: readonly PoseClip[];
|
|
1219
|
+
/** The looping clip the body holds between punches (a clip of `strikeClips`), so a combo goes guard, punch, guard instead of dropping the hands each time; `false` for none. Default `'fight_guard'`. */
|
|
1220
|
+
guardClip?: string | false;
|
|
1221
|
+
/** Seconds the guard stays up after a punch ends. Default 1.2. */
|
|
1222
|
+
guardHold?: number;
|
|
1223
|
+
/** Seconds a punch takes to blend in over the walk (or the guard it comes from). Default 0.05: the fist leaves at once. */
|
|
1224
|
+
punchBlend?: number;
|
|
1225
|
+
};
|
|
1226
|
+
/**
|
|
1227
|
+
* Fits the player's body to the test room's `RoomAvatar` (`room.setAvatar(toRoomAvatar(createPlayerAvatar(THREE)))`). It changes the sign of the pitch: the room
|
|
1228
|
+
* counts a look up as positive, the team game's `view.pitch` (what `AvatarUpdate.pitch` reads) counts a look down as positive. The same body is the first-person view (`eye`, `setView`), and `strike(clipId)` plays the strike on the body (the attack clips) and answers the seconds to its
|
|
1229
|
+
* impact, which are the same in both views. A kick with the left leg (`leg: 'left'`) or a punch with the left hand (`hand: 'left'`) plays the mirror of the clip written for the right.
|
|
1230
|
+
* After a punch the body holds the guard (`guardClip`) for `guardHold` seconds while it stands, so the next punch leaves from the guard.
|
|
1231
|
+
*/
|
|
1232
|
+
declare const toRoomAvatar: (avatar: PlayerAvatar, options?: ToRoomAvatarOptions) => RoomAvatarLike;
|
|
1233
|
+
|
|
1234
|
+
declare const AVATAR_AREA_ID = "avatar_area";
|
|
1235
|
+
type AvatarTestOptions = {
|
|
1236
|
+
/** The body under test (the example makes it with `createPlayerAvatar(THREE)` and gives the same one to the room). */
|
|
1237
|
+
avatar: PlayerAvatar;
|
|
1238
|
+
/** The text language when the host does not ask for one. Default `pt-BR`. */
|
|
1239
|
+
locale?: string;
|
|
1240
|
+
/** The clips offered as buttons. Default `POSE_CLIPS` (the two of the Bestiário); a game adds its strikes, such as `ATTACK_CLIPS` of game-characters-people. */
|
|
1241
|
+
clips?: readonly PoseClip[];
|
|
1242
|
+
/** Texts of the `phase` labels of `clips` by locale, merged over `POSE_CLIP_LOCALES` (for example `ATTACK_CLIP_LOCALES`). */
|
|
1243
|
+
clipLocales?: Readonly<Record<string, Readonly<Record<string, string>>>>;
|
|
1244
|
+
/** The room's view: `mode()` reads it, `set` changes it (`room.cameraMode` and `room.setCameraMode`). Without it the camera buttons only log. */
|
|
1245
|
+
camera?: {
|
|
1246
|
+
mode(): 'first' | 'third';
|
|
1247
|
+
set(mode: 'first' | 'third'): void;
|
|
1248
|
+
};
|
|
1249
|
+
/** The room's avatar state (`room.setAvatarState`): the module drives crouch, down and the armed arms through it. */
|
|
1250
|
+
state?: {
|
|
1251
|
+
set(state: {
|
|
1252
|
+
crouch?: boolean;
|
|
1253
|
+
down?: boolean;
|
|
1254
|
+
armed?: boolean | null;
|
|
1255
|
+
}): void;
|
|
1256
|
+
};
|
|
1257
|
+
};
|
|
1258
|
+
/**
|
|
1259
|
+
* The player's body as a `TestableModule` for the area `avatar_area`: bench buttons for the view (1st and 3rd person), crouch, fall and get up, the armed arms and every registered
|
|
1260
|
+
* pose clip (grab, bite), and metrics for the camera, the clip, its last event and the joints. Every action goes to the room's
|
|
1261
|
+
* log as JSON. It uses only the contracts: the body, the camera and the state come in by option, so the module knows no room.
|
|
1262
|
+
*/
|
|
1263
|
+
declare function createAvatarTestModule(options: AvatarTestOptions): TestableModule & {
|
|
1264
|
+
readonly state: {
|
|
1265
|
+
crouch: boolean;
|
|
1266
|
+
down: boolean;
|
|
1267
|
+
armed: boolean | null;
|
|
1268
|
+
};
|
|
1269
|
+
};
|
|
1270
|
+
|
|
1173
1271
|
type Triple = [number, number, number];
|
|
1174
1272
|
/**
|
|
1175
1273
|
* A hand (or the foot) at rest, in the camera's space: x to the right, y up, the view looks down -z. `p` is the middle of the palm, `r` the Euler angles `[roll, yaw, pitch]` in the order YZX:
|
|
@@ -1313,111 +1411,6 @@ type FirstPersonArms = {
|
|
|
1313
1411
|
dispose(): void;
|
|
1314
1412
|
};
|
|
1315
1413
|
|
|
1316
|
-
/** What `@adatechnology/game-test-room` calls a `RoomAvatar`, restated here so this package does not depend on the room. */
|
|
1317
|
-
type RoomAvatarLike = {
|
|
1318
|
-
root: THREE_NS.Object3D;
|
|
1319
|
-
update(dt: number, state: {
|
|
1320
|
-
speed: number;
|
|
1321
|
-
running: boolean;
|
|
1322
|
-
crouch: boolean;
|
|
1323
|
-
down: boolean;
|
|
1324
|
-
armed: boolean;
|
|
1325
|
-
pitch: number;
|
|
1326
|
-
push?: {
|
|
1327
|
-
readonly phase: 'grip' | 'push' | 'strain';
|
|
1328
|
-
readonly progress: number;
|
|
1329
|
-
} | null;
|
|
1330
|
-
door?: {
|
|
1331
|
-
readonly phase: 'reach' | 'swing' | 'release' | 'rattle';
|
|
1332
|
-
readonly progress: number;
|
|
1333
|
-
readonly height: number;
|
|
1334
|
-
readonly pull: boolean;
|
|
1335
|
-
} | null;
|
|
1336
|
-
holding?: boolean;
|
|
1337
|
-
itemUse?: AvatarItemUsePose | null;
|
|
1338
|
-
seat?: {
|
|
1339
|
-
readonly pose: 'sit' | 'lie';
|
|
1340
|
-
readonly hip: number;
|
|
1341
|
-
} | null;
|
|
1342
|
-
}): void;
|
|
1343
|
-
hand(side: 'R' | 'L'): THREE_NS.Object3D;
|
|
1344
|
-
shoulder(side: 'R' | 'L'): THREE_NS.Object3D;
|
|
1345
|
-
/** Where the body's eyes are after its pose (`RoomAvatar.eye`): the room draws the body in both views and puts the first-person camera there. */
|
|
1346
|
-
eye(out?: THREE_NS.Vector3): THREE_NS.Vector3;
|
|
1347
|
-
/** Hides the head and neck from `camera` in first person (`RoomAvatar.setView`). */
|
|
1348
|
-
setView(mode: AvatarViewMode, camera: THREE_NS.Object3D | null): void;
|
|
1349
|
-
/** Brings the body's hands to the tool in them, in both views; `view` keeps them in the first-person view (`RoomAvatar.reach`). */
|
|
1350
|
-
reach(targets: HandTargets | null, view?: ReachView | null): void;
|
|
1351
|
-
/** Plays a strike on the body and the arms and answers the seconds to its impact (`RoomAvatar.strike`). */
|
|
1352
|
-
strike(clipId: string, options?: {
|
|
1353
|
-
leg?: 'left' | 'right';
|
|
1354
|
-
hand?: 'left' | 'right';
|
|
1355
|
-
}): number | null;
|
|
1356
|
-
/** The avatar it wraps. */
|
|
1357
|
-
readonly avatar: PlayerAvatar;
|
|
1358
|
-
/** Separate first-person arms, only when `toRoomAvatar` was asked for them (`firstPerson`); the room draws the body in both views and does not use them. */
|
|
1359
|
-
readonly arms: FirstPersonArms | null;
|
|
1360
|
-
};
|
|
1361
|
-
type ToRoomAvatarOptions = {
|
|
1362
|
-
/** Separate first-person arms (the options of `createFirstPersonArms`, merged over the colours of the body and `firstPersonClips`); default none: the body is the first-person view. */
|
|
1363
|
-
firstPerson?: false | FirstPersonArmsOptions;
|
|
1364
|
-
/** The third-person strike clips `strike` finds by id. Default `ATTACK_CLIPS` of game-characters-people. */
|
|
1365
|
-
strikeClips?: readonly PoseClip[];
|
|
1366
|
-
/** The first-person clips the arms play. Default `FIRST_PERSON_CLIPS` of game-characters-people. */
|
|
1367
|
-
firstPersonClips?: readonly FirstPersonClip[];
|
|
1368
|
-
/** The looping clip the body holds between punches (a clip of `strikeClips`), so a combo goes guard, punch, guard instead of dropping the hands each time; `false` for none. Default `'fight_guard'`. */
|
|
1369
|
-
guardClip?: string | false;
|
|
1370
|
-
/** Seconds the guard stays up after a punch ends. Default 1.2. */
|
|
1371
|
-
guardHold?: number;
|
|
1372
|
-
/** Seconds a punch takes to blend in over the walk (or the guard it comes from). Default 0.05: the fist leaves at once. */
|
|
1373
|
-
punchBlend?: number;
|
|
1374
|
-
};
|
|
1375
|
-
/**
|
|
1376
|
-
* Fits the player's body to the test room's `RoomAvatar` (`room.setAvatar(toRoomAvatar(createPlayerAvatar(THREE)))`). It changes the sign of the pitch: the room
|
|
1377
|
-
* counts a look up as positive, the team game's `view.pitch` (what `AvatarUpdate.pitch` reads) counts a look down as positive. The same body is the first-person view (`eye`, `setView`;
|
|
1378
|
-
* separate arms only with `firstPerson`), and `strike(clipId)` plays the strike on the body (the attack clips) and answers the seconds to its
|
|
1379
|
-
* impact, which are the same in both views. A kick with the left leg (`leg: 'left'`) or a punch with the left hand (`hand: 'left'`) plays the mirror of the clip written for the right.
|
|
1380
|
-
* After a punch the body holds the guard (`guardClip`) for `guardHold` seconds while it stands, so the next punch leaves from the guard.
|
|
1381
|
-
*/
|
|
1382
|
-
declare const toRoomAvatar: (avatar: PlayerAvatar, options?: ToRoomAvatarOptions) => RoomAvatarLike;
|
|
1383
|
-
|
|
1384
|
-
declare const AVATAR_AREA_ID = "avatar_area";
|
|
1385
|
-
type AvatarTestOptions = {
|
|
1386
|
-
/** The body under test (the example makes it with `createPlayerAvatar(THREE)` and gives the same one to the room). */
|
|
1387
|
-
avatar: PlayerAvatar;
|
|
1388
|
-
/** The text language when the host does not ask for one. Default `pt-BR`. */
|
|
1389
|
-
locale?: string;
|
|
1390
|
-
/** The clips offered as buttons. Default `POSE_CLIPS` (the two of the Bestiário); a game adds its strikes, such as `ATTACK_CLIPS` of game-characters-people. */
|
|
1391
|
-
clips?: readonly PoseClip[];
|
|
1392
|
-
/** Texts of the `phase` labels of `clips` by locale, merged over `POSE_CLIP_LOCALES` (for example `ATTACK_CLIP_LOCALES`). */
|
|
1393
|
-
clipLocales?: Readonly<Record<string, Readonly<Record<string, string>>>>;
|
|
1394
|
-
/** The room's view: `mode()` reads it, `set` changes it (`room.cameraMode` and `room.setCameraMode`). Without it the camera buttons only log. */
|
|
1395
|
-
camera?: {
|
|
1396
|
-
mode(): 'first' | 'third';
|
|
1397
|
-
set(mode: 'first' | 'third'): void;
|
|
1398
|
-
};
|
|
1399
|
-
/** The room's avatar state (`room.setAvatarState`): the module drives crouch, down and the armed arms through it. */
|
|
1400
|
-
state?: {
|
|
1401
|
-
set(state: {
|
|
1402
|
-
crouch?: boolean;
|
|
1403
|
-
down?: boolean;
|
|
1404
|
-
armed?: boolean | null;
|
|
1405
|
-
}): void;
|
|
1406
|
-
};
|
|
1407
|
-
};
|
|
1408
|
-
/**
|
|
1409
|
-
* The player's body as a `TestableModule` for the area `avatar_area`: bench buttons for the view (1st and 3rd person), crouch, fall and get up, the armed arms and every registered
|
|
1410
|
-
* pose clip (grab, bite), and metrics for the camera, the clip, its last event and the joints. Every action goes to the room's
|
|
1411
|
-
* log as JSON. It uses only the contracts: the body, the camera and the state come in by option, so the module knows no room.
|
|
1412
|
-
*/
|
|
1413
|
-
declare function createAvatarTestModule(options: AvatarTestOptions): TestableModule & {
|
|
1414
|
-
readonly state: {
|
|
1415
|
-
crouch: boolean;
|
|
1416
|
-
down: boolean;
|
|
1417
|
-
armed: boolean | null;
|
|
1418
|
-
};
|
|
1419
|
-
};
|
|
1420
|
-
|
|
1421
1414
|
/** The stances of the preset: `relaxed` and `fists` are rest poses, `hold` follows the targets of the tool in the hands. */
|
|
1422
1415
|
declare const FIRST_PERSON_STANCES: Readonly<Record<string, StanceDef>>;
|
|
1423
1416
|
/** The rig of the preset: shoulders, bones, elbow pole, hips and the leg of the kick. */
|