@laplace.live/pixijs-live2d 0.4.0 → 0.5.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 +32 -0
- package/dist/index.js +107 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -3240,6 +3240,14 @@ export declare enum MotionPreloadStrategy {
|
|
|
3240
3240
|
/** No preload. */
|
|
3241
3241
|
NONE = "NONE"
|
|
3242
3242
|
}
|
|
3243
|
+
/**
|
|
3244
|
+
* What plays when nothing else does: a motion to loop, `'idle-group'` for a random motion of
|
|
3245
|
+
* the idle group (the default), or `null` to hold still.
|
|
3246
|
+
*/
|
|
3247
|
+
export type IdleMotion = {
|
|
3248
|
+
group: string;
|
|
3249
|
+
index: number;
|
|
3250
|
+
} | 'idle-group' | null;
|
|
3243
3251
|
/**
|
|
3244
3252
|
* Handles the motion playback for Live2D models.
|
|
3245
3253
|
* Responsible for loading, playing, and managing motion states and audio.
|
|
@@ -3322,6 +3330,17 @@ export declare abstract class MotionManager<Motion = unknown, MotionSpec = unkno
|
|
|
3322
3330
|
* @type {boolean}
|
|
3323
3331
|
*/
|
|
3324
3332
|
destroyed: boolean;
|
|
3333
|
+
/** The idle selection; see {@link setIdleMotion}. */
|
|
3334
|
+
idleMotion: IdleMotion;
|
|
3335
|
+
/**
|
|
3336
|
+
* Choose what plays when nothing else does. A running idle gives way at once and a loading one
|
|
3337
|
+
* is dropped; a higher-priority motion in flight hands over to the new selection when it ends.
|
|
3338
|
+
*/
|
|
3339
|
+
setIdleMotion(motion: IdleMotion): void;
|
|
3340
|
+
/** Stop the idle so the next update starts the selection. Cubism eases its parameters home too. */
|
|
3341
|
+
protected releaseIdle(): void;
|
|
3342
|
+
/** Start the idle selection at IDLE priority; a chosen motion loops regardless of its own flag. */
|
|
3343
|
+
protected startIdleMotion(): Promise<boolean>;
|
|
3325
3344
|
/**
|
|
3326
3345
|
* Reference to the parent InternalModel.
|
|
3327
3346
|
* @type {InternalModel}
|
|
@@ -6917,6 +6936,10 @@ export declare class CubismMotionManager extends MotionManager<CubismMotion, Mot
|
|
|
6917
6936
|
expressionManager?: CubismExpressionManager;
|
|
6918
6937
|
eyeBlinkIds: string[];
|
|
6919
6938
|
lipSyncIds: string[];
|
|
6939
|
+
/** What each motion's curves write, read once when it is created. */
|
|
6940
|
+
private readonly meta;
|
|
6941
|
+
/** Eases the parameters a released idle animated back to rest; see {@link releaseIdle}. */
|
|
6942
|
+
private release;
|
|
6920
6943
|
constructor(parent: CubismInternalModel);
|
|
6921
6944
|
protected init(options?: MotionManagerOptions): void;
|
|
6922
6945
|
isFinished(): boolean;
|
|
@@ -6926,6 +6949,15 @@ export declare class CubismMotionManager extends MotionManager<CubismMotion, Mot
|
|
|
6926
6949
|
getMotionFile(definition: Motion): string;
|
|
6927
6950
|
protected getMotionName(definition: Motion): string;
|
|
6928
6951
|
protected getSoundFile(definition: Motion): string | undefined;
|
|
6952
|
+
/** Whether the playing motion animates the eyes itself, so the engine's auto-blink must yield to it. */
|
|
6953
|
+
currentMotionBlinks(): boolean;
|
|
6954
|
+
/** The parameters the playing motion writes, for a host driver handing them over to it; null when none plays. */
|
|
6955
|
+
currentMotionParameters(): ReadonlySet<string> | null;
|
|
6956
|
+
private currentMotion;
|
|
6957
|
+
private currentMeta;
|
|
6958
|
+
protected releaseIdle(): void;
|
|
6959
|
+
/** One frame of the ease-to-rest, ahead of the motions so a new idle's fade-in blends from it. */
|
|
6960
|
+
private updateRelease;
|
|
6929
6961
|
protected updateParameters(model: CubismModel, now: DOMHighResTimeStamp): boolean;
|
|
6930
6962
|
destroy(): void;
|
|
6931
6963
|
motionLastFrame(group: string, index: number, { expression }?: {
|
package/dist/index.js
CHANGED
|
@@ -3567,6 +3567,10 @@ var MotionState = class {
|
|
|
3567
3567
|
*/
|
|
3568
3568
|
start(motion, group, index, priority) {
|
|
3569
3569
|
if (priority === 1) {
|
|
3570
|
+
if (group !== this.reservedIdleGroup || index !== this.reservedIdleIndex) {
|
|
3571
|
+
logger.log(this.tag, "Cannot start idle motion because it is no longer reserved.", this.dump(group, index));
|
|
3572
|
+
return false;
|
|
3573
|
+
}
|
|
3570
3574
|
this.setReservedIdle(void 0, void 0);
|
|
3571
3575
|
if (this.currentPriority !== 0) {
|
|
3572
3576
|
logger.log(this.tag, "Cannot start idle motion because another motion is playing.", this.dump(group, index));
|
|
@@ -3912,6 +3916,10 @@ let MotionPreloadStrategy = /* @__PURE__ */ function(MotionPreloadStrategy) {
|
|
|
3912
3916
|
MotionPreloadStrategy["NONE"] = "NONE";
|
|
3913
3917
|
return MotionPreloadStrategy;
|
|
3914
3918
|
}({});
|
|
3919
|
+
function sameIdleMotion(a, b) {
|
|
3920
|
+
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return a === b;
|
|
3921
|
+
return a.group === b.group && a.index === b.index;
|
|
3922
|
+
}
|
|
3915
3923
|
/**
|
|
3916
3924
|
* Handles the motion playback for Live2D models.
|
|
3917
3925
|
* Responsible for loading, playing, and managing motion states and audio.
|
|
@@ -3966,6 +3974,29 @@ var MotionManager = class extends EventEmitter {
|
|
|
3966
3974
|
* @type {boolean}
|
|
3967
3975
|
*/
|
|
3968
3976
|
destroyed = false;
|
|
3977
|
+
/** The idle selection; see {@link setIdleMotion}. */
|
|
3978
|
+
idleMotion = "idle-group";
|
|
3979
|
+
/**
|
|
3980
|
+
* Choose what plays when nothing else does. A running idle gives way at once and a loading one
|
|
3981
|
+
* is dropped; a higher-priority motion in flight hands over to the new selection when it ends.
|
|
3982
|
+
*/
|
|
3983
|
+
setIdleMotion(motion) {
|
|
3984
|
+
if (sameIdleMotion(this.idleMotion, motion)) return;
|
|
3985
|
+
this.idleMotion = motion;
|
|
3986
|
+
this.state.setReservedIdle(void 0, void 0);
|
|
3987
|
+
if (this.state.currentPriority === 1) this.releaseIdle();
|
|
3988
|
+
}
|
|
3989
|
+
/** Stop the idle so the next update starts the selection. Cubism eases its parameters home too. */
|
|
3990
|
+
releaseIdle() {
|
|
3991
|
+
this.stopAllMotions();
|
|
3992
|
+
}
|
|
3993
|
+
/** Start the idle selection at IDLE priority; a chosen motion loops regardless of its own flag. */
|
|
3994
|
+
startIdleMotion() {
|
|
3995
|
+
const idle = this.idleMotion;
|
|
3996
|
+
if (idle === null) return Promise.resolve(false);
|
|
3997
|
+
if (idle === "idle-group") return this.startRandomMotion(this.groups.idle, 1);
|
|
3998
|
+
return this.startMotion(idle.group, idle.index, 1, { loop: true });
|
|
3999
|
+
}
|
|
3969
4000
|
/**
|
|
3970
4001
|
* Reference to the parent InternalModel.
|
|
3971
4002
|
* @type {InternalModel}
|
|
@@ -4264,7 +4295,7 @@ var MotionManager = class extends EventEmitter {
|
|
|
4264
4295
|
}
|
|
4265
4296
|
if (this.state.shouldOverrideExpression()) this.expressionManager?.restoreExpression();
|
|
4266
4297
|
this.state.complete();
|
|
4267
|
-
if (this.state.shouldRequestIdleMotion()) this.
|
|
4298
|
+
if (this.idleMotion !== null && this.state.shouldRequestIdleMotion()) this.startIdleMotion();
|
|
4268
4299
|
}
|
|
4269
4300
|
return this.updateParameters(model, now);
|
|
4270
4301
|
}
|
|
@@ -14693,6 +14724,10 @@ var CubismMotionManager = class extends MotionManager {
|
|
|
14693
14724
|
expressionManager;
|
|
14694
14725
|
eyeBlinkIds;
|
|
14695
14726
|
lipSyncIds = ["ParamMouthOpenY"];
|
|
14727
|
+
/** What each motion's curves write, read once when it is created. */
|
|
14728
|
+
meta = /* @__PURE__ */ new WeakMap();
|
|
14729
|
+
/** Eases the parameters a released idle animated back to rest; see {@link releaseIdle}. */
|
|
14730
|
+
release = null;
|
|
14696
14731
|
constructor(parent) {
|
|
14697
14732
|
super(parent);
|
|
14698
14733
|
this.definitions = parent.settings.motions ?? {};
|
|
@@ -14722,6 +14757,7 @@ var CubismMotionManager = class extends MotionManager {
|
|
|
14722
14757
|
});
|
|
14723
14758
|
motion._motionData.curves = filtered;
|
|
14724
14759
|
motion._motionData.curveCount = filtered.length;
|
|
14760
|
+
this.meta.set(motion, motionMeta(motion, this.eyeBlinkIds));
|
|
14725
14761
|
}
|
|
14726
14762
|
this.queueManager.stopAllMotions();
|
|
14727
14763
|
return this.queueManager.startMotion(motion, false);
|
|
@@ -14734,6 +14770,7 @@ var CubismMotionManager = class extends MotionManager {
|
|
|
14734
14770
|
const motion = CubismMotion.create(data, data.byteLength, void 0, void 0, shouldCheckMotionConsistency);
|
|
14735
14771
|
const json = new CubismMotionJson(data, data.byteLength);
|
|
14736
14772
|
motion.setLoop(json.isMotionLoop());
|
|
14773
|
+
this.meta.set(motion, motionMeta(motion, this.eyeBlinkIds));
|
|
14737
14774
|
const defaultFadingDuration = (group === this.groups.idle ? config.idleMotionFadingDuration : config.motionFadingDuration) / 1e3;
|
|
14738
14775
|
if (json.getMotionFadeInTime() === void 0) motion.setFadeInTime(definition.FadeInTime > 0 ? definition.FadeInTime : defaultFadingDuration);
|
|
14739
14776
|
if (json.getMotionFadeOutTime() === void 0) motion.setFadeOutTime(definition.FadeOutTime > 0 ? definition.FadeOutTime : defaultFadingDuration);
|
|
@@ -14749,7 +14786,57 @@ var CubismMotionManager = class extends MotionManager {
|
|
|
14749
14786
|
getSoundFile(definition) {
|
|
14750
14787
|
return definition.Sound;
|
|
14751
14788
|
}
|
|
14789
|
+
/** Whether the playing motion animates the eyes itself, so the engine's auto-blink must yield to it. */
|
|
14790
|
+
currentMotionBlinks() {
|
|
14791
|
+
return this.currentMeta()?.blinks ?? false;
|
|
14792
|
+
}
|
|
14793
|
+
/** The parameters the playing motion writes, for a host driver handing them over to it; null when none plays. */
|
|
14794
|
+
currentMotionParameters() {
|
|
14795
|
+
return this.currentMeta()?.animated ?? null;
|
|
14796
|
+
}
|
|
14797
|
+
currentMotion() {
|
|
14798
|
+
const { currentGroup, currentIndex } = this.state;
|
|
14799
|
+
if (currentGroup === void 0 || currentIndex === void 0) return null;
|
|
14800
|
+
return this.motionGroups[currentGroup]?.[currentIndex] ?? null;
|
|
14801
|
+
}
|
|
14802
|
+
currentMeta() {
|
|
14803
|
+
const motion = this.currentMotion();
|
|
14804
|
+
return motion ? this.meta.get(motion) ?? null : null;
|
|
14805
|
+
}
|
|
14806
|
+
releaseIdle() {
|
|
14807
|
+
const motion = this.currentMotion();
|
|
14808
|
+
super.releaseIdle();
|
|
14809
|
+
if (motion) this.release = {
|
|
14810
|
+
ids: this.meta.get(motion)?.parameterIds ?? [],
|
|
14811
|
+
seconds: motion.getFadeOutTime(),
|
|
14812
|
+
ramp: null
|
|
14813
|
+
};
|
|
14814
|
+
}
|
|
14815
|
+
/** One frame of the ease-to-rest, ahead of the motions so a new idle's fade-in blends from it. */
|
|
14816
|
+
updateRelease(model, now) {
|
|
14817
|
+
const r = this.release;
|
|
14818
|
+
if (!r) return;
|
|
14819
|
+
if (r.ramp === null) {
|
|
14820
|
+
const count = model.getParameterCount();
|
|
14821
|
+
const indices = r.ids.map((id) => model.getParameterIndex(id)).filter((index) => index < count);
|
|
14822
|
+
r.ramp = {
|
|
14823
|
+
indices,
|
|
14824
|
+
from: indices.map((index) => model.getParameterValueByIndex(index)),
|
|
14825
|
+
startedAt: now
|
|
14826
|
+
};
|
|
14827
|
+
}
|
|
14828
|
+
const { indices, from, startedAt } = r.ramp;
|
|
14829
|
+
const t = r.seconds > 0 ? Math.min(1, (now - startedAt) / r.seconds) : 1;
|
|
14830
|
+
const w = CubismMath.getEasingSine(t);
|
|
14831
|
+
for (let i = 0; i < indices.length; i++) {
|
|
14832
|
+
const index = indices[i];
|
|
14833
|
+
const start = from[i];
|
|
14834
|
+
model.setParameterValueByIndex(index, start + (model.getParameterDefaultValue(index) - start) * w);
|
|
14835
|
+
}
|
|
14836
|
+
if (t >= 1) this.release = null;
|
|
14837
|
+
}
|
|
14752
14838
|
updateParameters(model, now) {
|
|
14839
|
+
this.updateRelease(model, now);
|
|
14753
14840
|
return this.queueManager.doUpdateMotion(model, now);
|
|
14754
14841
|
}
|
|
14755
14842
|
destroy() {
|
|
@@ -14770,6 +14857,23 @@ var CubismMotionManager = class extends MotionManager {
|
|
|
14770
14857
|
return ids.map((id) => idManager.getId(id));
|
|
14771
14858
|
}
|
|
14772
14859
|
};
|
|
14860
|
+
function motionMeta(motion, eyeBlinkIds) {
|
|
14861
|
+
const parameterIds = [];
|
|
14862
|
+
const animated = /* @__PURE__ */ new Set();
|
|
14863
|
+
let blinks = false;
|
|
14864
|
+
for (const curve of motion._motionData.curves) {
|
|
14865
|
+
const id = getCurveId$1(curve);
|
|
14866
|
+
if (curve.type === 1) {
|
|
14867
|
+
parameterIds.push(curve.id);
|
|
14868
|
+
if (id !== void 0) animated.add(id);
|
|
14869
|
+
} else if (curve.type === 0 && id === "EyeBlink") blinks = true;
|
|
14870
|
+
}
|
|
14871
|
+
return {
|
|
14872
|
+
parameterIds,
|
|
14873
|
+
animated,
|
|
14874
|
+
blinks: blinks || eyeBlinkIds.some((id) => animated.has(id))
|
|
14875
|
+
};
|
|
14876
|
+
}
|
|
14773
14877
|
function getCurveId$1(curve) {
|
|
14774
14878
|
if (!curve || typeof curve !== "object") return;
|
|
14775
14879
|
const id = curve.id;
|
|
@@ -15322,10 +15426,10 @@ var CubismInternalModel = class extends InternalModel {
|
|
|
15322
15426
|
dt /= 1e3;
|
|
15323
15427
|
now /= 1e3;
|
|
15324
15428
|
const model = this.coreModel;
|
|
15325
|
-
|
|
15429
|
+
this.updateMotions(model, now);
|
|
15326
15430
|
model.saveParameters();
|
|
15327
15431
|
this.motionManager.expressionManager?.update(model, now);
|
|
15328
|
-
if (!
|
|
15432
|
+
if (!this.motionManager.currentMotionBlinks()) this.eyeBlink?.updateParameters?.(model, dt);
|
|
15329
15433
|
this.updateFocus();
|
|
15330
15434
|
this.updateNaturalMovements(dt * 1e3, now * 1e3);
|
|
15331
15435
|
if (this.lipSync && this.motionManager.currentAudio) {
|