@laplace.live/persona-sdk 1.15.0 → 1.16.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/values/limits.d.ts +42 -1
- package/dist/values/limits.js +65 -0
- package/dist/wire/methods.d.ts +14 -0
- package/dist/wire/types.d.ts +41 -0
- package/package.json +1 -1
package/dist/values/limits.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AssetRef, Attach, EnvironmentLook, ModelFormat, MToonTuning, ObjectContent, ObjectSpace, SceneEnvironment, SceneLight, SceneLightCameraFollowOptions, SceneLightType, ScreenPlacement, VrmPlacement } from '../wire/types.ts';
|
|
1
|
+
import type { AssetRef, Attach, AttachDepth, EnvironmentLook, ModelFormat, MToonTuning, ObjectContent, ObjectSpace, SceneEnvironment, SceneLight, SceneLightCameraFollowOptions, SceneLightType, ScreenPlacement, VrmPlacement } from '../wire/types.ts';
|
|
2
2
|
export declare function clamp(v: number, min: number, max: number): number;
|
|
3
3
|
/** Clamp to the unit interval. */
|
|
4
4
|
export declare function clamp01(v: number): number;
|
|
@@ -178,6 +178,47 @@ export declare function contentAssetId(content: ObjectContent): string | null;
|
|
|
178
178
|
* would z-fight by construction.
|
|
179
179
|
*/
|
|
180
180
|
export declare function attachableParentFormat(space: ObjectSpace): ModelFormat;
|
|
181
|
+
/**
|
|
182
|
+
* Every instance that rides `instanceId`, directly or through a chain of pins — the set it can
|
|
183
|
+
* never pin to itself, or the two would ride each other in a circle. Includes `instanceId`.
|
|
184
|
+
*/
|
|
185
|
+
export declare function pinRiders(items: readonly {
|
|
186
|
+
instanceId: string;
|
|
187
|
+
attach?: {
|
|
188
|
+
parentInstanceId: string;
|
|
189
|
+
} | null;
|
|
190
|
+
}[], instanceId: string): Set<string>;
|
|
191
|
+
/**
|
|
192
|
+
* Rows for the pin picker: every other Live2D model, each flagged when it already rides
|
|
193
|
+
* `instanceId` — picking one would put the two in a circle, so both apps offer it disabled
|
|
194
|
+
* rather than hidden. One rule, or the console offers a pin the desktop refuses.
|
|
195
|
+
*/
|
|
196
|
+
export declare function pinnableParents(models: readonly {
|
|
197
|
+
instanceId: string;
|
|
198
|
+
ref: {
|
|
199
|
+
kind: string;
|
|
200
|
+
name: string;
|
|
201
|
+
};
|
|
202
|
+
}[], items: readonly {
|
|
203
|
+
instanceId: string;
|
|
204
|
+
attach?: {
|
|
205
|
+
parentInstanceId: string;
|
|
206
|
+
} | null;
|
|
207
|
+
}[], instanceId: string): {
|
|
208
|
+
instanceId: string;
|
|
209
|
+
name: string;
|
|
210
|
+
ridesThis: boolean;
|
|
211
|
+
}[];
|
|
212
|
+
/**
|
|
213
|
+
* The depth control's stops, back to front: behind the model, above each of its ArtMeshes in
|
|
214
|
+
* paint order, then in front of it all. One continuous run, so depth is a slider over the host's
|
|
215
|
+
* stack rather than a list of ArtMesh ids nobody can read.
|
|
216
|
+
*/
|
|
217
|
+
export declare function depthStops(meshes: readonly string[]): AttachDepth[];
|
|
218
|
+
/** Which stop a depth sits at; an ArtMesh the host no longer has reads as the frontmost. */
|
|
219
|
+
export declare function depthStopIndex(meshes: readonly string[], depth: AttachDepth): number;
|
|
220
|
+
/** A fresh pin onto `parentInstanceId`: root anchor, in front of the model, no response tuning. */
|
|
221
|
+
export declare function defaultAttach(parentInstanceId: string): Attach;
|
|
181
222
|
export declare const DEFAULT_HEAD_ANGLE: NonNullable<Attach['headAngle']>;
|
|
182
223
|
export declare const ATTACH_MULTIPLIER_MIN = -2;
|
|
183
224
|
export declare const ATTACH_MULTIPLIER_MAX = 2;
|
package/dist/values/limits.js
CHANGED
|
@@ -304,6 +304,71 @@ export function contentAssetId(content) {
|
|
|
304
304
|
export function attachableParentFormat(space) {
|
|
305
305
|
return space === '2d' ? 'live2d' : 'vrm';
|
|
306
306
|
}
|
|
307
|
+
/**
|
|
308
|
+
* Every instance that rides `instanceId`, directly or through a chain of pins — the set it can
|
|
309
|
+
* never pin to itself, or the two would ride each other in a circle. Includes `instanceId`.
|
|
310
|
+
*/
|
|
311
|
+
export function pinRiders(items, instanceId) {
|
|
312
|
+
const riders = new Set([instanceId]);
|
|
313
|
+
// One pass per item is enough for a chain of any depth: each pass adopts the next level down.
|
|
314
|
+
for (let i = 0; i < items.length; i++) {
|
|
315
|
+
let grew = false;
|
|
316
|
+
for (const item of items) {
|
|
317
|
+
const parent = item.attach?.parentInstanceId;
|
|
318
|
+
if (parent !== undefined && riders.has(parent) && !riders.has(item.instanceId)) {
|
|
319
|
+
riders.add(item.instanceId);
|
|
320
|
+
grew = true;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (!grew)
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
return riders;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Rows for the pin picker: every other Live2D model, each flagged when it already rides
|
|
330
|
+
* `instanceId` — picking one would put the two in a circle, so both apps offer it disabled
|
|
331
|
+
* rather than hidden. One rule, or the console offers a pin the desktop refuses.
|
|
332
|
+
*/
|
|
333
|
+
export function pinnableParents(models, items, instanceId) {
|
|
334
|
+
const riders = pinRiders(items, instanceId);
|
|
335
|
+
const out = [];
|
|
336
|
+
for (const m of models) {
|
|
337
|
+
if (m.ref.kind !== 'live2d' || m.instanceId === instanceId)
|
|
338
|
+
continue;
|
|
339
|
+
out.push({ instanceId: m.instanceId, name: m.ref.name, ridesThis: riders.has(m.instanceId) });
|
|
340
|
+
}
|
|
341
|
+
return out;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* The depth control's stops, back to front: behind the model, above each of its ArtMeshes in
|
|
345
|
+
* paint order, then in front of it all. One continuous run, so depth is a slider over the host's
|
|
346
|
+
* stack rather than a list of ArtMesh ids nobody can read.
|
|
347
|
+
*/
|
|
348
|
+
export function depthStops(meshes) {
|
|
349
|
+
return [{ kind: 'behind' }, ...meshes.map((id) => ({ kind: 'artMesh', id })), { kind: 'front' }];
|
|
350
|
+
}
|
|
351
|
+
/** Which stop a depth sits at; an ArtMesh the host no longer has reads as the frontmost. */
|
|
352
|
+
export function depthStopIndex(meshes, depth) {
|
|
353
|
+
if (depth.kind === 'behind')
|
|
354
|
+
return 0;
|
|
355
|
+
if (depth.kind === 'front')
|
|
356
|
+
return meshes.length + 1;
|
|
357
|
+
const at = meshes.indexOf(depth.id);
|
|
358
|
+
return at < 0 ? meshes.length + 1 : at + 1;
|
|
359
|
+
}
|
|
360
|
+
/** A fresh pin onto `parentInstanceId`: root anchor, in front of the model, no response tuning. */
|
|
361
|
+
export function defaultAttach(parentInstanceId) {
|
|
362
|
+
return {
|
|
363
|
+
parentInstanceId,
|
|
364
|
+
anchor: { kind: 'root' },
|
|
365
|
+
followRotation: true,
|
|
366
|
+
depth: { kind: 'front' },
|
|
367
|
+
split: null,
|
|
368
|
+
headAngle: null,
|
|
369
|
+
elasticity: null,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
307
372
|
export const DEFAULT_HEAD_ANGLE = {
|
|
308
373
|
multiplier: 1,
|
|
309
374
|
parallaxX: 0,
|
package/dist/wire/methods.d.ts
CHANGED
|
@@ -149,6 +149,16 @@ export interface InstanceSetPlacementRequest {
|
|
|
149
149
|
vrm?: Partial<VrmPlacement>;
|
|
150
150
|
}
|
|
151
151
|
export type InstanceSetPlacementResponse = EmptyResponse;
|
|
152
|
+
/**
|
|
153
|
+
* Pin a Live2D instance to another one as an item (VTS's Live2D Items): its placement becomes an
|
|
154
|
+
* offset from the anchor, and `attach.depth` says where it paints in the host's ArtMesh stack.
|
|
155
|
+
*/
|
|
156
|
+
export interface InstanceAttachRequest {
|
|
157
|
+
instanceId?: string;
|
|
158
|
+
/** Null detaches, leaving the instance where it stands. */
|
|
159
|
+
attach: AttachInput | null;
|
|
160
|
+
}
|
|
161
|
+
export type InstanceAttachResponse = EmptyResponse;
|
|
152
162
|
export interface InstanceSetMToonRequest {
|
|
153
163
|
instanceId?: string;
|
|
154
164
|
tuning: Partial<MToonTuning>;
|
|
@@ -810,6 +820,10 @@ export interface MethodMap {
|
|
|
810
820
|
request: InstanceSetPlacementRequest;
|
|
811
821
|
response: InstanceSetPlacementResponse;
|
|
812
822
|
};
|
|
823
|
+
'instance.attach': {
|
|
824
|
+
request: InstanceAttachRequest;
|
|
825
|
+
response: InstanceAttachResponse;
|
|
826
|
+
};
|
|
813
827
|
'instance.setMToon': {
|
|
814
828
|
request: InstanceSetMToonRequest;
|
|
815
829
|
response: InstanceSetMToonResponse;
|
package/dist/wire/types.d.ts
CHANGED
|
@@ -198,6 +198,12 @@ export interface SceneModelItem {
|
|
|
198
198
|
breathDepth: number;
|
|
199
199
|
/** MToon material fine-tuning, VRM only. */
|
|
200
200
|
mtoon: MToonTuning;
|
|
201
|
+
/**
|
|
202
|
+
* Live2D only: this model rides another one as an item (VTS's Live2D Items) — its placement
|
|
203
|
+
* reads as an offset from the anchor, and `depth` says where it paints in the parent's stack.
|
|
204
|
+
* Null stands alone; a VRM instance ignores it, keeping it across a format switch.
|
|
205
|
+
*/
|
|
206
|
+
attach: Attach | null;
|
|
201
207
|
}
|
|
202
208
|
export declare const OBJECT_SPACES: readonly ["2d", "3d"];
|
|
203
209
|
export type ObjectSpace = (typeof OBJECT_SPACES)[number];
|
|
@@ -275,11 +281,41 @@ export interface AttachElasticity {
|
|
|
275
281
|
damping: number;
|
|
276
282
|
maxSpeed: number;
|
|
277
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* How deep a pinned item paints in its parent — VTube Studio's Between-Layer Item Pinning, as one
|
|
286
|
+
* value: the two ends clear the parent's whole stack, and `artMesh` slots the item in directly
|
|
287
|
+
* above that ArtMesh, so every parent mesh over it paints on top. Ids rather than positions,
|
|
288
|
+
* because Cubism re-sorts the stack as motions play, and an id carries to any rig that has it.
|
|
289
|
+
* Live2D parents on the three engine only: elsewhere an item always paints in front.
|
|
290
|
+
*/
|
|
291
|
+
export type AttachDepth = {
|
|
292
|
+
kind: 'front';
|
|
293
|
+
} | {
|
|
294
|
+
kind: 'behind';
|
|
295
|
+
} | {
|
|
296
|
+
kind: 'artMesh';
|
|
297
|
+
id: string;
|
|
298
|
+
};
|
|
299
|
+
/**
|
|
300
|
+
* VTube Studio's front/back splitting: the item is cut at one of its **own** ArtMeshes, and
|
|
301
|
+
* everything it paints below that goes to a second depth in the parent — so the parent's meshes
|
|
302
|
+
* in between wrap over it (a scarf in front of the chest and behind the hair). Live2D items only.
|
|
303
|
+
*/
|
|
304
|
+
export interface AttachSplit {
|
|
305
|
+
/** ArtMesh of the item it is cut at; the item paints everything under this as its back half. */
|
|
306
|
+
itemArtMesh: string;
|
|
307
|
+
/** How deep the back half paints — the same control as the item's own depth. */
|
|
308
|
+
depth: AttachDepth;
|
|
309
|
+
}
|
|
278
310
|
export interface Attach {
|
|
279
311
|
/** Always a model instance in the same space; anything else is cleared on load. */
|
|
280
312
|
parentInstanceId: string;
|
|
281
313
|
anchor: AttachAnchor;
|
|
282
314
|
followRotation: boolean;
|
|
315
|
+
/** Where it paints in the parent's ArtMesh stack; `front` is the plain "on top of the model". */
|
|
316
|
+
depth: AttachDepth;
|
|
317
|
+
/** Front/back splitting, independent of `depth`; null keeps the item in one piece. */
|
|
318
|
+
split: AttachSplit | null;
|
|
283
319
|
headAngle: AttachHeadAngle | null;
|
|
284
320
|
elasticity: AttachElasticity | null;
|
|
285
321
|
}
|
|
@@ -1059,6 +1095,11 @@ export interface PlayingMotion {
|
|
|
1059
1095
|
export interface AnchorOption {
|
|
1060
1096
|
anchor: AttachAnchor;
|
|
1061
1097
|
label: string;
|
|
1098
|
+
/**
|
|
1099
|
+
* Paint order when the list was taken, ascending from the backmost — what the depth control
|
|
1100
|
+
* orders its stops by. Live2D only, and absent from hosts older than depth pinning.
|
|
1101
|
+
*/
|
|
1102
|
+
order?: number;
|
|
1062
1103
|
}
|
|
1063
1104
|
export type { ModelInfo } from '../values/model-info.ts';
|
|
1064
1105
|
export interface Hotkey {
|