From 99fd153c561a8242efc98223ebec948a1cbc0f48 Mon Sep 17 00:00:00 2001
From: Ratul Hasan <34002411+RaSan147@users.noreply.github.com>
Date: Fri, 6 Oct 2023 18:16:47 +0600
Subject: [PATCH 01/44] Added lip-sync module with audio
Changes:
1. updated model.motion(group, index, priority) to model.motion(group, index, priority, sound, volume, expression);
2. added model.stopSpeaking()
3. updated readme.MD with demos
4. Workflow will save files to dist (won't be gitignored)
5. Praying this new change doesn't break
---
.github/workflows/test.yml | 15 ++
.gitignore | 3 +-
README.md | 124 +++++++++++++----
src/Live2DModel.ts | 39 +++++-
src/cubism-common/MotionManager.ts | 213 ++++++++++++++++++++++++++---
src/cubism-common/SoundManager.ts | 54 +++++++-
6 files changed, 399 insertions(+), 49 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 792b8cb6..23098a61 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -14,6 +14,7 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
+ fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
- uses: actions/setup-node@v3
with:
@@ -36,3 +37,17 @@ jobs:
- uses: GabrielBB/xvfb-action@v1.0
with:
run: npm run test:ci
+
+ - name: Commit files
+ run: |
+ git config --global user.name 'RaSan147'
+ git config --global user.email '34002411+RaSan147@users.noreply.github.com'
+ git add --all
+ git commit -am "Automated report"
+ git push
+
+
+ - uses: actions/upload-artifact@v3
+ with:
+ name: my-artifact
+ path: ${{ github.workspace }}/dist
diff --git a/.gitignore b/.gitignore
index 8fb55f2b..76f4f0d1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,9 +7,8 @@ core
/build
/*.build
/lib
-/dist
-/types
/site
+/types
.DS_Store
node_modules
diff --git a/README.md b/README.md
index 1e5c3940..bf5362d4 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,9 @@ This project aims to be a universal Live2D framework on the web platform. While
complex and problematic, this project has rewritten it to unify and simplify the APIs, which allows you to control the
Live2D models on a high level without the need to learn how the internal system works.
+#### Feel free to support the Maintainer:
+
+
#### Features
- Supports all versions of Live2D models
@@ -81,7 +84,7 @@ To make it clear, here's how you would use these files:
## Installation
-#### Via npm
+#### Via npm (not lipsync patch)
```sh
npm install pixi-live2d-display
@@ -97,16 +100,24 @@ import { Live2DModel } from 'pixi-live2d-display/cubism2';
import { Live2DModel } from 'pixi-live2d-display/cubism4';
```
-#### Via CDN
+#### Via CDN (lipsync patched)
```html
-
+
+
+
+
+
+
+
+
+
-
+
-
+
```
In this way, all the exported members are available under `PIXI.live2d` namespace, such as `PIXI.live2d.Live2DModel`.
@@ -121,32 +132,95 @@ import { Live2DModel } from 'pixi-live2d-display';
// reference window.PIXI.Ticker to automatically update Live2D models
window.PIXI = PIXI;
+var model_proxy; //make a global scale handler to use later
+
(async function () {
- const app = new PIXI.Application({
- view: document.getElementById('canvas'),
- });
+ const app = new PIXI.Application({
+ view: document.getElementById('canvas'),
+ });
+
+ const model = await Live2DModel.from('shizuku.model.json');
+ model_proxy = model;
+
+ app.stage.addChild(model);
+
+ // transforms
+ model.x = 100;
+ model.y = 100;
+ model.rotation = Math.PI;
+ model.skew.x = Math.PI;
+ model.scale.set(2, 2);
+ model.anchor.set(0.5, 0.5);
+
+ // interaction
+ model.on('hit', (hitAreas) => {
+ if (hitAreas.includes('body')) {
+ model.motion('tap_body');
+ }
+ });
+})();
+```
- const model = await Live2DModel.from('shizuku.model.json');
+## Do some motion manually
+* First either you need to load your model on Live2d viewer app, or the Website by guansss [here](https://guansss.github.io/live2d-viewer-web/)
+* Check for motion category names (like "idle", "" (blank) etc)
+ * Screenshot will be added soon
+* Under those motion categories, each motions are used by their index
+* Motion Priority table,
+ * 0: no priority
+ * 1: maybe [for idle animation]
+ * 2: normal [default when normal action]
+ * 3: Just do it! Do id now! [Forced] [default when using audio]
+* Time to code
+```js
+var category_name = "Idle" // name of the morion category
+var animation_index = 0 // index of animation under that motion category
+var priority_number = 3 // if you want to keep the current animation going or move to new animation by force
+var audio_link = "https://cdn.jsdelivr.net/gh/RaSan147/pixi-live2d-display@v1.0.3/playground/test.mp3" //[Optional arg, can be null or empty] [relative or full url path] [mp3 or wav file]
+var volume = 1; //[Optional arg, can be null or empty] [0.0 - 1.0]
+var expression = 4; //[Optional arg, can be null or empty] [index|name of expression]
+
+model_proxy.motion(category_name, animation_index, priority_number, audio_link, volume, expression)
+// Note: during this animation with sound, other animation will be ignored, even its forced. Once over, it'll be back to normal
+```
- app.stage.addChild(model);
+## Lipsync Only
+* You can do sound lipsync even without triggering any motion
+* This supports expressions arg too (if you have/need any)
+* Demo code
+```js
+var audio_link = "https://cdn.jsdelivr.net/gh/RaSan147/pixi-live2d-display@v1.0.3/playground/test.mp3" // [relative or full url path] [mp3 or wav file]
- // transforms
- model.x = 100;
- model.y = 100;
- model.rotation = Math.PI;
- model.skew.x = Math.PI;
- model.scale.set(2, 2);
- model.anchor.set(0.5, 0.5);
-
- // interaction
- model.on('hit', (hitAreas) => {
- if (hitAreas.includes('body')) {
- model.motion('tap_body');
- }
- });
-})();
+var volume = 1; // [Optional arg, can be null or empty] [0.0 - 1.0]
+
+var expression = 4; // [Optional arg, can be null or empty] [index|name of expression]
+
+model_proxy.speak(audio_link, volume, expression)
+```
+
+## Suddenly stop audio and lipsync
+* Demo code
+```js
+model_proxy.stopSpeaking()
```
+## Reset motions as well as audio and lipsync
+* Demo code
+```js
+model_proxy.resetMotions()
+```
+
+## Totally destroy the model
+* This will also stop the motion and audio from running and hide the model
+* Demo code
+```js
+model_proxy.destroy()
+```
+
+# See here for more Documentation: [Documentation](https://guansss.github.io/pixi-live2d-display/)
+
+
+
## Package importing
When importing Pixi packages on-demand, you may need to manually register some plugins to enable optional features.
diff --git a/src/Live2DModel.ts b/src/Live2DModel.ts
index bf8d028f..32e64297 100644
--- a/src/Live2DModel.ts
+++ b/src/Live2DModel.ts
@@ -198,14 +198,45 @@ export class Live2DModel extends Conta
/**
* Shorthand to start a motion.
* @param group - The motion group.
- * @param index - The index in this group. If not presented, a random motion will be started.
- * @param priority - The motion priority. Defaults to `MotionPriority.NORMAL`.
+ * @param index - Index in the motion group.
+ * @param priority - The priority to be applied.
+ * @param sound - The audio url to file or base64 content
+ * @param volume - Volume of the sound (0-1) /*new in 1.0.4*
+ * @param expression - In case you want to mix up a expression while playing sound (bind with Model.expression())
* @return Promise that resolves with true if the motion is successfully started, with false otherwise.
*/
- motion(group: string, index?: number, priority?: MotionPriority): Promise {
+ motion(group: string, index?: number, priority?: MotionPriority, sound?: string, volume?:number, expression?: number | string): Promise {
return index === undefined
? this.internalModel.motionManager.startRandomMotion(group, priority)
- : this.internalModel.motionManager.startMotion(group, index, priority);
+ : this.internalModel.motionManager.startMotion(group, index, priority, sound, volume, expression);
+ }
+
+
+ /**
+ * Stops all playing motions as well as the sound.
+ */
+ resetMotions(): void {
+ return this.internalModel.motionManager.stopAllMotions();
+ }
+
+
+ /**
+ * Shorthand to start speaking a sound with an expression. /*new in 1.0.3*
+ * @param sound - The audio url to file or base64 content
+ * @param volume - Volume of the sound (0-1) /*new in 1.0.4*
+ * @param expression - In case you want to mix up a expression while playing sound (bind with Model.expression())
+ * @returns Promise that resolves with true if the sound is playing, false if it's not
+ */
+ speak(sound: string, volume?: number, expression?: number | string): Promise {
+ return this.internalModel.motionManager.speakUp(sound, volume, expression);
+ }
+
+
+ /**
+ * Stop current audio playback and lipsync
+ */
+ stopSpeaking(): void {
+ return this.internalModel.motionManager.stopSpeaking()
}
/**
diff --git a/src/cubism-common/MotionManager.ts b/src/cubism-common/MotionManager.ts
index 0fc89960..62f56d57 100644
--- a/src/cubism-common/MotionManager.ts
+++ b/src/cubism-common/MotionManager.ts
@@ -91,6 +91,16 @@ export abstract class MotionManager extends Even
*/
currentAudio?: HTMLAudioElement;
+ /**
+ * Analyzer element for the current sound being played.
+ */
+ currentAnalyzer?: AnalyserNode;
+
+ /**
+ * Context element for the current sound being played.
+ */
+ currentContext?: AudioContext;
+
/**
* Flags there's a motion playing.
*/
@@ -199,14 +209,122 @@ export abstract class MotionManager extends Even
throw new Error('Not implemented.');
}
+
+ /**
+ * Only play sound with lip sync /*new in 1.0.3*
+ * @param sound - The audio url to file or base64 content
+ * @param volume - Volume of the sound (0-1) /*new in 1.0.4*
+ * @param expression - In case you want to mix up a expression while playing sound (bind with Model.expression())
+ * @returns Promise that resolves with true if the sound is playing, false if it's not
+ */
+ async speakUp(sound: string, volume?: number, expression?: number | string) {
+ if (!config.sound) {
+ return false;
+ }
+
+
+
+ let audio: HTMLAudioElement | undefined;
+ let analyzer: AnalyserNode | undefined;
+ let context: AudioContext | undefined;
+
+
+ if(this.currentAudio){
+ if (!this.currentAudio.ended){
+ return false;
+ }
+ }
+ let soundURL: string | undefined;
+ const isBase64Content = sound && sound.startsWith('data:audio/wav;base64');
+
+ if(sound && !isBase64Content){
+ var A = document.createElement('a');
+ A.href = sound;
+ sound = A.href; // This should be the absolute url
+ // since resolveURL is not working for some reason
+ soundURL = sound;
+ }
+ else {
+ soundURL = 'data:audio/wav;base64';
+ }
+ const isUrlPath = sound && (sound.startsWith('http') || sound.startsWith('blob'));
+ let file: string | undefined;
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ // start to load the audio
+ audio = SoundManager.add(
+ file,
+ () => {expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = undefined}, // reset expression when audio is done
+ () => {expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = undefined} // on error
+ );
+ this.currentAudio = audio!;
+
+ let _volume: number = 1;
+ if (volume !== undefined){
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+
+ // Add context
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+
+ // Add analyzer
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+
+ } catch (e) {
+ logger.warn(this.tag, 'Failed to create audio', soundURL, e);
+ }
+ }
+
+
+ if (audio) {
+ const readyToPlay = SoundManager.play(audio)
+ .catch(e => logger.warn(this.tag, 'Failed to play audio', audio!.src, e));
+
+ if (config.motionSync) {
+ // wait until the audio is ready
+ await readyToPlay;
+ }
+ }
+
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ if (expression && this.expressionManager){
+ this.expressionManager.setExpression(expression)
+ }
+
+ this.playing = true;
+
+ return true;
+ }
+
/**
* Starts a motion as given priority.
* @param group - The motion group.
* @param index - Index in the motion group.
* @param priority - The priority to be applied.
+ * @param sound - The audio url to file or base64 content
+ * @param volume - Volume of the sound (0-1)
+ * @param expression - In case you want to mix up a expression while playing sound (bind with Model.expression())
* @return Promise that resolves with true if the motion is successfully started, with false otherwise.
*/
- async startMotion(group: string, index: number, priority = MotionPriority.NORMAL): Promise {
+ async startMotion(group: string, index: number, priority = MotionPriority.NORMAL, sound?: string, volume?: number, expression?: number | string): Promise {
+ // Does not start a new motion if audio is still playing
+ if(this.currentAudio){
+ if (!this.currentAudio.ended){
+ return false;
+ }
+ }
+
if (!this.state.reserve(group, index, priority)) {
return false;
}
@@ -223,20 +341,53 @@ export abstract class MotionManager extends Even
}
let audio: HTMLAudioElement | undefined;
+ let analyzer: AnalyserNode | undefined;
+ let context: AudioContext | undefined;
if (config.sound) {
+ const isBase64Content = sound && sound.startsWith('data:audio/wav;base64');
+ if(sound && !isBase64Content){
+ var A = document.createElement('a');
+ A.href = sound;
+ sound = A.href; // This should be the absolute url
+ // since resolveURL is not working for some reason
+ }
+ const isUrlPath = sound && (sound.startsWith('http') || sound.startsWith('blob'));
const soundURL = this.getSoundFile(definition);
-
+ let file = soundURL;
if (soundURL) {
+ file = this.settings.resolveURL(soundURL) + "?cache-buster=" + new Date().getTime();
+ }
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
try {
// start to load the audio
audio = SoundManager.add(
- this.settings.resolveURL(soundURL),
- () => this.currentAudio = undefined,
- () => this.currentAudio = undefined,
+ file,
+ () => {expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = undefined}, // reset expression when audio is done
+ () => {expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = undefined} // on error
);
+ this.currentAudio = audio!;
+
+ let _volume: number = 1;
+ if (volume !== undefined){
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+
+ // Add context
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+
+ // Add analyzer
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
- this.currentAudio = audio;
} catch (e) {
logger.warn(this.tag, 'Failed to create audio', soundURL, e);
}
@@ -246,6 +397,8 @@ export abstract class MotionManager extends Even
const motion = await this.loadMotion(group, index);
if (audio) {
+ priority = 3; // FORCED: MAKE SURE SOUND IS PLAYED
+
const readyToPlay = SoundManager.play(audio)
.catch(e => logger.warn(this.tag, 'Failed to play audio', audio!.src, e));
@@ -264,12 +417,17 @@ export abstract class MotionManager extends Even
return false;
}
+
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+
logger.log(this.tag, 'Start motion:', this.getMotionName(definition));
this.emit('motionStart', group, index, audio);
-
- if (this.state.shouldOverrideExpression()) {
- this.expressionManager && this.expressionManager.resetExpression();
+
+ if (expression && this.expressionManager){
+ this.expressionManager.setExpression(expression)
}
this.playing = true;
@@ -283,13 +441,15 @@ export abstract class MotionManager extends Even
* Starts a random Motion as given priority.
* @param group - The motion group.
* @param priority - The priority to be applied.
+ * @param sound - The wav url file or base64 content
+ * @param volume - Volume of the sound (0-1)
* @return Promise that resolves with true if the motion is successfully started, with false otherwise.
*/
- async startRandomMotion(group: string, priority?: MotionPriority): Promise {
+ async startRandomMotion(group: string, priority?: MotionPriority, sound?: string, volume?: number): Promise {
const groupDefs = this.definitions[group];
if (groupDefs?.length) {
- const availableIndices = [];
+ const availableIndices: number[] = [];
for (let i = 0; i < groupDefs!.length; i++) {
if (this.motionGroups[group]![i] !== null && !this.state.isActive(group, i)) {
@@ -298,15 +458,25 @@ export abstract class MotionManager extends Even
}
if (availableIndices.length) {
- const index = Math.floor(Math.random() * availableIndices.length);
+ const index = availableIndices[Math.floor(Math.random() * availableIndices.length)]!;
- return this.startMotion(group, availableIndices[index]!, priority);
+ return this.startMotion(group, index, priority, sound, volume);
}
}
return false;
}
+ /**
+ * Stop current audio playback and lipsync
+ */
+ stopSpeaking(): void {
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ this.currentAudio = undefined;
+ }
+ }
+
/**
* Stops all playing motions as well as the sound.
*/
@@ -315,10 +485,7 @@ export abstract class MotionManager extends Even
this.state.reset();
- if (this.currentAudio) {
- SoundManager.dispose(this.currentAudio);
- this.currentAudio = undefined;
- }
+ this.stopSpeaking()
}
/**
@@ -349,6 +516,18 @@ export abstract class MotionManager extends Even
return this.updateParameters(model, now);
}
+ /**
+ * Move the mouth
+ *
+ */
+ mouthSync(): number {
+ if (this.currentAnalyzer) {
+ return SoundManager.analyze(this.currentAnalyzer);
+ } else {
+ return 0;
+ }
+ }
+
/**
* Destroys the instance.
* @emits {@link MotionManagerEvents.destroy}
diff --git a/src/cubism-common/SoundManager.ts b/src/cubism-common/SoundManager.ts
index 842e266f..f03abc30 100644
--- a/src/cubism-common/SoundManager.ts
+++ b/src/cubism-common/SoundManager.ts
@@ -1,7 +1,7 @@
import { logger, remove } from '@/utils';
const TAG = 'SoundManager';
-const VOLUME = 0.5;
+const VOLUME = 0.9;
/**
* Manages all the sounds.
@@ -11,6 +11,8 @@ export class SoundManager {
* Audio elements playing or pending to play. Finished audios will be removed automatically.
*/
static audios: HTMLAudioElement[] = [];
+ static analysers: AnalyserNode[] = [];
+ static contexts: AudioContext[] = [];
protected static _volume = VOLUME;
@@ -39,6 +41,8 @@ export class SoundManager {
audio.volume = this._volume;
audio.preload = 'auto';
+ audio.autoplay = true;
+ audio.crossOrigin = "anonymous";
audio.addEventListener('ended', () => {
this.dispose(audio);
@@ -77,6 +81,50 @@ export class SoundManager {
});
}
+ static addContext(audio: HTMLAudioElement): AudioContext {
+ /* Create an AudioContext */
+ const context = new (AudioContext)();
+
+ this.contexts.push(context);
+ return context;
+ }
+
+ static addAnalyzer(audio: HTMLAudioElement, context: AudioContext): AnalyserNode {
+ /* Create an AnalyserNode */
+ const source = context.createMediaElementSource(audio);
+ const analyser = context.createAnalyser();
+
+ analyser.fftSize = 256;
+ analyser.minDecibels = -90;
+ analyser.maxDecibels = -10;
+ analyser.smoothingTimeConstant = 0.85;
+
+ source.connect(analyser);
+ analyser.connect(context.destination);
+
+ this.analysers.push(analyser);
+ return analyser;
+ }
+
+ /**
+ * Get volume for lip sync
+ * @param analyser - An analyzer element.
+ * @return Returns value to feed into lip sync
+ */
+ static analyze(analyser: AnalyserNode): number {
+
+ if(analyser != undefined){
+ let pcmData = new Float32Array(analyser.fftSize);
+ let sumSquares = 0.0;
+ analyser.getFloatTimeDomainData(pcmData);
+
+ for (const amplitude of pcmData) { sumSquares += amplitude*amplitude; }
+ return parseFloat(Math.sqrt((sumSquares / pcmData.length) * 20).toFixed(1));
+ } else {
+ return parseFloat(Math.random().toFixed(1));
+ }
+ }
+
/**
* Disposes an audio element and removes it from {@link audios}.
* @param audio - An audio element.
@@ -93,6 +141,10 @@ export class SoundManager {
*/
static destroy(): void {
// dispose() removes given audio from the array, so the loop must be backward
+ for (let i = this.contexts.length - 1; i >= 0; i--) {
+ this.contexts[i]!.close()
+ }
+
for (let i = this.audios.length - 1; i >= 0; i--) {
this.dispose(this.audios[i]!);
}
From d378339e4d9fbb645b69e395ca79c9eb0cb343fa Mon Sep 17 00:00:00 2001
From: RaSan147 <34002411+RaSan147@users.noreply.github.com>
Date: Fri, 6 Oct 2023 12:21:51 +0000
Subject: [PATCH 02/44] Automated report
---
dist/cubism2.es.js | 2287 ++++++++++++++
dist/cubism2.js | 2324 ++++++++++++++
dist/cubism2.min.js | 1 +
dist/cubism4.es.js | 6540 ++++++++++++++++++++++++++++++++++++++++
dist/cubism4.js | 6697 +++++++++++++++++++++++++++++++++++++++++
dist/cubism4.min.js | 1 +
dist/extra.es.js | 61 +
dist/extra.js | 64 +
dist/extra.min.js | 1 +
dist/index.es.js | 6967 ++++++++++++++++++++++++++++++++++++++++++
dist/index.js | 7010 +++++++++++++++++++++++++++++++++++++++++++
dist/index.min.js | 1 +
12 files changed, 31954 insertions(+)
create mode 100644 dist/cubism2.es.js
create mode 100644 dist/cubism2.js
create mode 100644 dist/cubism2.min.js
create mode 100644 dist/cubism4.es.js
create mode 100644 dist/cubism4.js
create mode 100644 dist/cubism4.min.js
create mode 100644 dist/extra.es.js
create mode 100644 dist/extra.js
create mode 100644 dist/extra.min.js
create mode 100644 dist/index.es.js
create mode 100644 dist/index.js
create mode 100644 dist/index.min.js
diff --git a/dist/cubism2.es.js b/dist/cubism2.es.js
new file mode 100644
index 00000000..cc571236
--- /dev/null
+++ b/dist/cubism2.es.js
@@ -0,0 +1,2287 @@
+var __pow = Math.pow;
+var __async = (__this, __arguments, generator) => {
+ return new Promise((resolve, reject) => {
+ var fulfilled = (value) => {
+ try {
+ step(generator.next(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var rejected = (value) => {
+ try {
+ step(generator.throw(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
+ step((generator = generator.apply(__this, __arguments)).next());
+ });
+};
+import { EventEmitter, url } from "@pixi/utils";
+import { Matrix, Transform, Point, ObservablePoint } from "@pixi/math";
+import { Texture } from "@pixi/core";
+import { Container } from "@pixi/display";
+const LOGICAL_WIDTH = 2;
+const LOGICAL_HEIGHT = 2;
+var CubismConfig;
+((CubismConfig2) => {
+ CubismConfig2.supportMoreMaskDivisions = true;
+ CubismConfig2.setOpacityFromMotion = false;
+})(CubismConfig || (CubismConfig = {}));
+var config;
+((config2) => {
+ config2.LOG_LEVEL_VERBOSE = 0;
+ config2.LOG_LEVEL_WARNING = 1;
+ config2.LOG_LEVEL_ERROR = 2;
+ config2.LOG_LEVEL_NONE = 999;
+ config2.logLevel = config2.LOG_LEVEL_WARNING;
+ config2.sound = true;
+ config2.motionSync = true;
+ config2.motionFadingDuration = 500;
+ config2.idleMotionFadingDuration = 2e3;
+ config2.expressionFadingDuration = 500;
+ config2.preserveExpressionOnMotion = true;
+ config2.cubism4 = CubismConfig;
+})(config || (config = {}));
+const VERSION = "0.4.0";
+const logger = {
+ log(tag, ...messages) {
+ if (config.logLevel <= config.LOG_LEVEL_VERBOSE) {
+ console.log(`[${tag}]`, ...messages);
+ }
+ },
+ warn(tag, ...messages) {
+ if (config.logLevel <= config.LOG_LEVEL_WARNING) {
+ console.warn(`[${tag}]`, ...messages);
+ }
+ },
+ error(tag, ...messages) {
+ if (config.logLevel <= config.LOG_LEVEL_ERROR) {
+ console.error(`[${tag}]`, ...messages);
+ }
+ }
+};
+function clamp(num, lower, upper) {
+ return num < lower ? lower : num > upper ? upper : num;
+}
+function rand(min, max) {
+ return Math.random() * (max - min) + min;
+}
+function copyProperty(type, from, to, fromKey, toKey) {
+ const value = from[fromKey];
+ if (value !== null && typeof value === type) {
+ to[toKey] = value;
+ }
+}
+function copyArray(type, from, to, fromKey, toKey) {
+ const array = from[fromKey];
+ if (Array.isArray(array)) {
+ to[toKey] = array.filter((item) => item !== null && typeof item === type);
+ }
+}
+function applyMixins(derivedCtor, baseCtors) {
+ baseCtors.forEach((baseCtor) => {
+ Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
+ if (name !== "constructor") {
+ Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
+ }
+ });
+ });
+}
+function folderName(url2) {
+ let lastSlashIndex = url2.lastIndexOf("/");
+ if (lastSlashIndex != -1) {
+ url2 = url2.slice(0, lastSlashIndex);
+ }
+ lastSlashIndex = url2.lastIndexOf("/");
+ if (lastSlashIndex !== -1) {
+ url2 = url2.slice(lastSlashIndex + 1);
+ }
+ return url2;
+}
+function remove(array, item) {
+ const index = array.indexOf(item);
+ if (index !== -1) {
+ array.splice(index, 1);
+ }
+}
+class ExpressionManager extends EventEmitter {
+ constructor(settings, options) {
+ super();
+ this.expressions = [];
+ this.reserveExpressionIndex = -1;
+ this.destroyed = false;
+ this.settings = settings;
+ this.tag = `ExpressionManager(${settings.name})`;
+ }
+ init() {
+ this.defaultExpression = this.createExpression({}, void 0);
+ this.currentExpression = this.defaultExpression;
+ this.stopAllExpressions();
+ }
+ loadExpression(index) {
+ return __async(this, null, function* () {
+ if (!this.definitions[index]) {
+ logger.warn(this.tag, `Undefined expression at [${index}]`);
+ return void 0;
+ }
+ if (this.expressions[index] === null) {
+ logger.warn(this.tag, `Cannot set expression at [${index}] because it's already failed in loading.`);
+ return void 0;
+ }
+ if (this.expressions[index]) {
+ return this.expressions[index];
+ }
+ const expression = yield this._loadExpression(index);
+ this.expressions[index] = expression;
+ return expression;
+ });
+ }
+ _loadExpression(index) {
+ throw new Error("Not implemented.");
+ }
+ setRandomExpression() {
+ return __async(this, null, function* () {
+ if (this.definitions.length) {
+ const availableIndices = [];
+ for (let i = 0; i < this.definitions.length; i++) {
+ if (this.expressions[i] !== null && this.expressions[i] !== this.currentExpression && i !== this.reserveExpressionIndex) {
+ availableIndices.push(i);
+ }
+ }
+ if (availableIndices.length) {
+ const index = Math.floor(Math.random() * availableIndices.length);
+ return this.setExpression(index);
+ }
+ }
+ return false;
+ });
+ }
+ resetExpression() {
+ this._setExpression(this.defaultExpression);
+ }
+ restoreExpression() {
+ this._setExpression(this.currentExpression);
+ }
+ setExpression(index) {
+ return __async(this, null, function* () {
+ if (typeof index !== "number") {
+ index = this.getExpressionIndex(index);
+ }
+ if (!(index > -1 && index < this.definitions.length)) {
+ return false;
+ }
+ if (index === this.expressions.indexOf(this.currentExpression)) {
+ return false;
+ }
+ this.reserveExpressionIndex = index;
+ const expression = yield this.loadExpression(index);
+ if (!expression || this.reserveExpressionIndex !== index) {
+ return false;
+ }
+ this.reserveExpressionIndex = -1;
+ this.currentExpression = expression;
+ this._setExpression(expression);
+ return true;
+ });
+ }
+ update(model, now) {
+ if (!this.isFinished()) {
+ return this.updateParameters(model, now);
+ }
+ return false;
+ }
+ destroy() {
+ this.destroyed = true;
+ this.emit("destroy");
+ const self = this;
+ self.definitions = void 0;
+ self.expressions = void 0;
+ }
+}
+const EPSILON = 0.01;
+const MAX_SPEED = 40 / 7.5;
+const ACCELERATION_TIME = 1 / (0.15 * 1e3);
+class FocusController {
+ constructor() {
+ this.targetX = 0;
+ this.targetY = 0;
+ this.x = 0;
+ this.y = 0;
+ this.vx = 0;
+ this.vy = 0;
+ }
+ focus(x, y, instant = false) {
+ this.targetX = clamp(x, -1, 1);
+ this.targetY = clamp(y, -1, 1);
+ if (instant) {
+ this.x = this.targetX;
+ this.y = this.targetY;
+ }
+ }
+ update(dt) {
+ const dx = this.targetX - this.x;
+ const dy = this.targetY - this.y;
+ if (Math.abs(dx) < EPSILON && Math.abs(dy) < EPSILON)
+ return;
+ const d = Math.sqrt(__pow(dx, 2) + __pow(dy, 2));
+ const maxSpeed = MAX_SPEED / (1e3 / dt);
+ let ax = maxSpeed * (dx / d) - this.vx;
+ let ay = maxSpeed * (dy / d) - this.vy;
+ const a = Math.sqrt(__pow(ax, 2) + __pow(ay, 2));
+ const maxA = maxSpeed * ACCELERATION_TIME * dt;
+ if (a > maxA) {
+ ax *= maxA / a;
+ ay *= maxA / a;
+ }
+ this.vx += ax;
+ this.vy += ay;
+ const v = Math.sqrt(__pow(this.vx, 2) + __pow(this.vy, 2));
+ const maxV = 0.5 * (Math.sqrt(__pow(maxA, 2) + 8 * maxA * d) - maxA);
+ if (v > maxV) {
+ this.vx *= maxV / v;
+ this.vy *= maxV / v;
+ }
+ this.x += this.vx;
+ this.y += this.vy;
+ }
+}
+class ModelSettings {
+ constructor(json) {
+ this.json = json;
+ let url2 = json.url;
+ if (typeof url2 !== "string") {
+ throw new TypeError("The `url` field in settings JSON must be defined as a string.");
+ }
+ this.url = url2;
+ this.name = folderName(this.url);
+ }
+ resolveURL(path) {
+ return url.resolve(this.url, path);
+ }
+ replaceFiles(replacer) {
+ this.moc = replacer(this.moc, "moc");
+ if (this.pose !== void 0) {
+ this.pose = replacer(this.pose, "pose");
+ }
+ if (this.physics !== void 0) {
+ this.physics = replacer(this.physics, "physics");
+ }
+ for (let i = 0; i < this.textures.length; i++) {
+ this.textures[i] = replacer(this.textures[i], `textures[${i}]`);
+ }
+ }
+ getDefinedFiles() {
+ const files = [];
+ this.replaceFiles((file) => {
+ files.push(file);
+ return file;
+ });
+ return files;
+ }
+ validateFiles(files) {
+ const assertFileExists = (expectedFile, shouldThrow) => {
+ const actualPath = this.resolveURL(expectedFile);
+ if (!files.includes(actualPath)) {
+ if (shouldThrow) {
+ throw new Error(`File "${expectedFile}" is defined in settings, but doesn't exist in given files`);
+ }
+ return false;
+ }
+ return true;
+ };
+ const essentialFiles = [this.moc, ...this.textures];
+ essentialFiles.forEach((texture) => assertFileExists(texture, true));
+ const definedFiles = this.getDefinedFiles();
+ return definedFiles.filter((file) => assertFileExists(file, false));
+ }
+}
+var MotionPriority = /* @__PURE__ */ ((MotionPriority2) => {
+ MotionPriority2[MotionPriority2["NONE"] = 0] = "NONE";
+ MotionPriority2[MotionPriority2["IDLE"] = 1] = "IDLE";
+ MotionPriority2[MotionPriority2["NORMAL"] = 2] = "NORMAL";
+ MotionPriority2[MotionPriority2["FORCE"] = 3] = "FORCE";
+ return MotionPriority2;
+})(MotionPriority || {});
+class MotionState {
+ constructor() {
+ this.debug = false;
+ this.currentPriority = 0;
+ this.reservePriority = 0;
+ }
+ reserve(group, index, priority) {
+ if (priority <= 0) {
+ logger.log(this.tag, `Cannot start a motion with MotionPriority.NONE.`);
+ return false;
+ }
+ if (group === this.currentGroup && index === this.currentIndex) {
+ logger.log(this.tag, `Motion is already playing.`, this.dump(group, index));
+ return false;
+ }
+ if (group === this.reservedGroup && index === this.reservedIndex || group === this.reservedIdleGroup && index === this.reservedIdleIndex) {
+ logger.log(this.tag, `Motion is already reserved.`, this.dump(group, index));
+ return false;
+ }
+ if (priority === 1) {
+ if (this.currentPriority !== 0) {
+ logger.log(this.tag, `Cannot start idle motion because another motion is playing.`, this.dump(group, index));
+ return false;
+ }
+ if (this.reservedIdleGroup !== void 0) {
+ logger.log(this.tag, `Cannot start idle motion because another idle motion has reserved.`, this.dump(group, index));
+ return false;
+ }
+ this.setReservedIdle(group, index);
+ } else {
+ if (priority < 3) {
+ if (priority <= this.currentPriority) {
+ logger.log(this.tag, "Cannot start motion because another motion is playing as an equivalent or higher priority.", this.dump(group, index));
+ return false;
+ }
+ if (priority <= this.reservePriority) {
+ logger.log(this.tag, "Cannot start motion because another motion has reserved as an equivalent or higher priority.", this.dump(group, index));
+ return false;
+ }
+ }
+ this.setReserved(group, index, priority);
+ }
+ return true;
+ }
+ start(motion, group, index, priority) {
+ if (priority === 1) {
+ this.setReservedIdle(void 0, void 0);
+ if (this.currentPriority !== 0) {
+ logger.log(this.tag, "Cannot start idle motion because another motion is playing.", this.dump(group, index));
+ return false;
+ }
+ } else {
+ if (group !== this.reservedGroup || index !== this.reservedIndex) {
+ logger.log(this.tag, "Cannot start motion because another motion has taken the place.", this.dump(group, index));
+ return false;
+ }
+ this.setReserved(void 0, void 0, 0);
+ }
+ if (!motion) {
+ return false;
+ }
+ this.setCurrent(group, index, priority);
+ return true;
+ }
+ complete() {
+ this.setCurrent(void 0, void 0, 0);
+ }
+ setCurrent(group, index, priority) {
+ this.currentPriority = priority;
+ this.currentGroup = group;
+ this.currentIndex = index;
+ }
+ setReserved(group, index, priority) {
+ this.reservePriority = priority;
+ this.reservedGroup = group;
+ this.reservedIndex = index;
+ }
+ setReservedIdle(group, index) {
+ this.reservedIdleGroup = group;
+ this.reservedIdleIndex = index;
+ }
+ isActive(group, index) {
+ return group === this.currentGroup && index === this.currentIndex || group === this.reservedGroup && index === this.reservedIndex || group === this.reservedIdleGroup && index === this.reservedIdleIndex;
+ }
+ reset() {
+ this.setCurrent(void 0, void 0, 0);
+ this.setReserved(void 0, void 0, 0);
+ this.setReservedIdle(void 0, void 0);
+ }
+ shouldRequestIdleMotion() {
+ return this.currentGroup === void 0 && this.reservedIdleGroup === void 0;
+ }
+ shouldOverrideExpression() {
+ return !config.preserveExpressionOnMotion && this.currentPriority > 1;
+ }
+ dump(requestedGroup, requestedIndex) {
+ if (this.debug) {
+ const keys = [
+ "currentPriority",
+ "reservePriority",
+ "currentGroup",
+ "currentIndex",
+ "reservedGroup",
+ "reservedIndex",
+ "reservedIdleGroup",
+ "reservedIdleIndex"
+ ];
+ return `
+ group = "${requestedGroup}", index = ${requestedIndex}
+` + keys.map((key) => "[" + key + "] " + this[key]).join("\n");
+ }
+ return "";
+ }
+}
+const TAG$2 = "SoundManager";
+const VOLUME = 0.9;
+class SoundManager {
+ static get volume() {
+ return this._volume;
+ }
+ static set volume(value) {
+ this._volume = (value > 1 ? 1 : value < 0 ? 0 : value) || 0;
+ this.audios.forEach((audio) => audio.volume = this._volume);
+ }
+ static add(file, onFinish, onError) {
+ const audio = new Audio(file);
+ audio.volume = this._volume;
+ audio.preload = "auto";
+ audio.autoplay = true;
+ audio.crossOrigin = "anonymous";
+ audio.addEventListener("ended", () => {
+ this.dispose(audio);
+ onFinish == null ? void 0 : onFinish();
+ });
+ audio.addEventListener("error", (e) => {
+ this.dispose(audio);
+ logger.warn(TAG$2, `Error occurred on "${file}"`, e.error);
+ onError == null ? void 0 : onError(e.error);
+ });
+ this.audios.push(audio);
+ return audio;
+ }
+ static play(audio) {
+ return new Promise((resolve, reject) => {
+ var _a;
+ (_a = audio.play()) == null ? void 0 : _a.catch((e) => {
+ audio.dispatchEvent(new ErrorEvent("error", { error: e }));
+ reject(e);
+ });
+ if (audio.readyState === audio.HAVE_ENOUGH_DATA) {
+ resolve();
+ } else {
+ audio.addEventListener("canplaythrough", resolve);
+ }
+ });
+ }
+ static addContext(audio) {
+ const context = new AudioContext();
+ this.contexts.push(context);
+ return context;
+ }
+ static addAnalyzer(audio, context) {
+ const source = context.createMediaElementSource(audio);
+ const analyser = context.createAnalyser();
+ analyser.fftSize = 256;
+ analyser.minDecibels = -90;
+ analyser.maxDecibels = -10;
+ analyser.smoothingTimeConstant = 0.85;
+ source.connect(analyser);
+ analyser.connect(context.destination);
+ this.analysers.push(analyser);
+ return analyser;
+ }
+ static analyze(analyser) {
+ if (analyser != void 0) {
+ let pcmData = new Float32Array(analyser.fftSize);
+ let sumSquares = 0;
+ analyser.getFloatTimeDomainData(pcmData);
+ for (const amplitude of pcmData) {
+ sumSquares += amplitude * amplitude;
+ }
+ return parseFloat(Math.sqrt(sumSquares / pcmData.length * 20).toFixed(1));
+ } else {
+ return parseFloat(Math.random().toFixed(1));
+ }
+ }
+ static dispose(audio) {
+ audio.pause();
+ audio.removeAttribute("src");
+ remove(this.audios, audio);
+ }
+ static destroy() {
+ for (let i = this.contexts.length - 1; i >= 0; i--) {
+ this.contexts[i].close();
+ }
+ for (let i = this.audios.length - 1; i >= 0; i--) {
+ this.dispose(this.audios[i]);
+ }
+ }
+}
+SoundManager.audios = [];
+SoundManager.analysers = [];
+SoundManager.contexts = [];
+SoundManager._volume = VOLUME;
+var MotionPreloadStrategy = /* @__PURE__ */ ((MotionPreloadStrategy2) => {
+ MotionPreloadStrategy2["ALL"] = "ALL";
+ MotionPreloadStrategy2["IDLE"] = "IDLE";
+ MotionPreloadStrategy2["NONE"] = "NONE";
+ return MotionPreloadStrategy2;
+})(MotionPreloadStrategy || {});
+class MotionManager extends EventEmitter {
+ constructor(settings, options) {
+ super();
+ this.motionGroups = {};
+ this.state = new MotionState();
+ this.playing = false;
+ this.destroyed = false;
+ this.settings = settings;
+ this.tag = `MotionManager(${settings.name})`;
+ this.state.tag = this.tag;
+ }
+ init(options) {
+ if (options == null ? void 0 : options.idleMotionGroup) {
+ this.groups.idle = options.idleMotionGroup;
+ }
+ this.setupMotions(options);
+ this.stopAllMotions();
+ }
+ setupMotions(options) {
+ for (const group of Object.keys(this.definitions)) {
+ this.motionGroups[group] = [];
+ }
+ let groups;
+ switch (options == null ? void 0 : options.motionPreload) {
+ case "NONE":
+ return;
+ case "ALL":
+ groups = Object.keys(this.definitions);
+ break;
+ case "IDLE":
+ default:
+ groups = [this.groups.idle];
+ break;
+ }
+ for (const group of groups) {
+ if (this.definitions[group]) {
+ for (let i = 0; i < this.definitions[group].length; i++) {
+ this.loadMotion(group, i).then();
+ }
+ }
+ }
+ }
+ loadMotion(group, index) {
+ return __async(this, null, function* () {
+ var _a;
+ if (!((_a = this.definitions[group]) == null ? void 0 : _a[index])) {
+ logger.warn(this.tag, `Undefined motion at "${group}"[${index}]`);
+ return void 0;
+ }
+ if (this.motionGroups[group][index] === null) {
+ logger.warn(this.tag, `Cannot start motion at "${group}"[${index}] because it's already failed in loading.`);
+ return void 0;
+ }
+ if (this.motionGroups[group][index]) {
+ return this.motionGroups[group][index];
+ }
+ const motion = yield this._loadMotion(group, index);
+ if (this.destroyed) {
+ return;
+ }
+ this.motionGroups[group][index] = motion != null ? motion : null;
+ return motion;
+ });
+ }
+ _loadMotion(group, index) {
+ throw new Error("Not implemented.");
+ }
+ speakUp(sound, volume, expression) {
+ return __async(this, null, function* () {
+ if (!config.sound) {
+ return false;
+ }
+ let audio;
+ let analyzer;
+ let context;
+ if (this.currentAudio) {
+ if (!this.currentAudio.ended) {
+ return false;
+ }
+ }
+ let soundURL;
+ const isBase64Content = sound && sound.startsWith("data:audio/wav;base64");
+ if (sound && !isBase64Content) {
+ var A = document.createElement("a");
+ A.href = sound;
+ sound = A.href;
+ soundURL = sound;
+ } else {
+ soundURL = "data:audio/wav;base64";
+ }
+ const isUrlPath = sound && (sound.startsWith("http") || sound.startsWith("blob"));
+ let file;
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ audio = SoundManager.add(file, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ }, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ });
+ this.currentAudio = audio;
+ let _volume = 1;
+ if (volume !== void 0) {
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+ } catch (e) {
+ logger.warn(this.tag, "Failed to create audio", soundURL, e);
+ }
+ }
+ if (audio) {
+ const readyToPlay = SoundManager.play(audio).catch((e) => logger.warn(this.tag, "Failed to play audio", audio.src, e));
+ if (config.motionSync) {
+ yield readyToPlay;
+ }
+ }
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ if (expression && this.expressionManager) {
+ this.expressionManager.setExpression(expression);
+ }
+ this.playing = true;
+ return true;
+ });
+ }
+ startMotion(_0, _1) {
+ return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, sound, volume, expression) {
+ var _a;
+ if (this.currentAudio) {
+ if (!this.currentAudio.ended) {
+ return false;
+ }
+ }
+ if (!this.state.reserve(group, index, priority)) {
+ return false;
+ }
+ const definition = (_a = this.definitions[group]) == null ? void 0 : _a[index];
+ if (!definition) {
+ return false;
+ }
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ }
+ let audio;
+ let analyzer;
+ let context;
+ if (config.sound) {
+ const isBase64Content = sound && sound.startsWith("data:audio/wav;base64");
+ if (sound && !isBase64Content) {
+ var A = document.createElement("a");
+ A.href = sound;
+ sound = A.href;
+ }
+ const isUrlPath = sound && (sound.startsWith("http") || sound.startsWith("blob"));
+ const soundURL = this.getSoundFile(definition);
+ let file = soundURL;
+ if (soundURL) {
+ file = this.settings.resolveURL(soundURL) + "?cache-buster=" + new Date().getTime();
+ }
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ audio = SoundManager.add(file, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ }, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ });
+ this.currentAudio = audio;
+ let _volume = 1;
+ if (volume !== void 0) {
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+ } catch (e) {
+ logger.warn(this.tag, "Failed to create audio", soundURL, e);
+ }
+ }
+ }
+ const motion = yield this.loadMotion(group, index);
+ if (audio) {
+ priority = 3;
+ const readyToPlay = SoundManager.play(audio).catch((e) => logger.warn(this.tag, "Failed to play audio", audio.src, e));
+ if (config.motionSync) {
+ yield readyToPlay;
+ }
+ }
+ if (!this.state.start(motion, group, index, priority)) {
+ if (audio) {
+ SoundManager.dispose(audio);
+ this.currentAudio = void 0;
+ }
+ return false;
+ }
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ logger.log(this.tag, "Start motion:", this.getMotionName(definition));
+ this.emit("motionStart", group, index, audio);
+ if (expression && this.expressionManager) {
+ this.expressionManager.setExpression(expression);
+ }
+ this.playing = true;
+ this._startMotion(motion);
+ return true;
+ });
+ }
+ startRandomMotion(group, priority, sound, volume) {
+ return __async(this, null, function* () {
+ const groupDefs = this.definitions[group];
+ if (groupDefs == null ? void 0 : groupDefs.length) {
+ const availableIndices = [];
+ for (let i = 0; i < groupDefs.length; i++) {
+ if (this.motionGroups[group][i] !== null && !this.state.isActive(group, i)) {
+ availableIndices.push(i);
+ }
+ }
+ if (availableIndices.length) {
+ const index = availableIndices[Math.floor(Math.random() * availableIndices.length)];
+ return this.startMotion(group, index, priority, sound, volume);
+ }
+ }
+ return false;
+ });
+ }
+ stopSpeaking() {
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ this.currentAudio = void 0;
+ }
+ }
+ stopAllMotions() {
+ this._stopAllMotions();
+ this.state.reset();
+ this.stopSpeaking();
+ }
+ update(model, now) {
+ var _a;
+ if (this.isFinished()) {
+ if (this.playing) {
+ this.playing = false;
+ this.emit("motionFinish");
+ }
+ if (this.state.shouldOverrideExpression()) {
+ (_a = this.expressionManager) == null ? void 0 : _a.restoreExpression();
+ }
+ this.state.complete();
+ if (this.state.shouldRequestIdleMotion()) {
+ this.startRandomMotion(this.groups.idle, MotionPriority.IDLE);
+ }
+ }
+ return this.updateParameters(model, now);
+ }
+ mouthSync() {
+ if (this.currentAnalyzer) {
+ return SoundManager.analyze(this.currentAnalyzer);
+ } else {
+ return 0;
+ }
+ }
+ destroy() {
+ var _a;
+ this.destroyed = true;
+ this.emit("destroy");
+ this.stopAllMotions();
+ (_a = this.expressionManager) == null ? void 0 : _a.destroy();
+ const self = this;
+ self.definitions = void 0;
+ self.motionGroups = void 0;
+ }
+}
+const tempBounds = { x: 0, y: 0, width: 0, height: 0 };
+class InternalModel extends EventEmitter {
+ constructor() {
+ super(...arguments);
+ this.focusController = new FocusController();
+ this.originalWidth = 0;
+ this.originalHeight = 0;
+ this.width = 0;
+ this.height = 0;
+ this.localTransform = new Matrix();
+ this.drawingMatrix = new Matrix();
+ this.hitAreas = {};
+ this.textureFlipY = false;
+ this.viewport = [0, 0, 0, 0];
+ this.destroyed = false;
+ }
+ init() {
+ this.setupLayout();
+ this.setupHitAreas();
+ }
+ setupLayout() {
+ const self = this;
+ const size = this.getSize();
+ self.originalWidth = size[0];
+ self.originalHeight = size[1];
+ const layout = Object.assign({
+ width: LOGICAL_WIDTH,
+ height: LOGICAL_HEIGHT
+ }, this.getLayout());
+ this.localTransform.scale(layout.width / LOGICAL_WIDTH, layout.height / LOGICAL_HEIGHT);
+ self.width = this.originalWidth * this.localTransform.a;
+ self.height = this.originalHeight * this.localTransform.d;
+ const offsetX = layout.x !== void 0 && layout.x - layout.width / 2 || layout.centerX !== void 0 && layout.centerX || layout.left !== void 0 && layout.left - layout.width / 2 || layout.right !== void 0 && layout.right + layout.width / 2 || 0;
+ const offsetY = layout.y !== void 0 && layout.y - layout.height / 2 || layout.centerY !== void 0 && layout.centerY || layout.top !== void 0 && layout.top - layout.height / 2 || layout.bottom !== void 0 && layout.bottom + layout.height / 2 || 0;
+ this.localTransform.translate(this.width * offsetX, -this.height * offsetY);
+ }
+ setupHitAreas() {
+ const definitions = this.getHitAreaDefs().filter((hitArea) => hitArea.index >= 0);
+ for (const def of definitions) {
+ this.hitAreas[def.name] = def;
+ }
+ }
+ hitTest(x, y) {
+ return Object.keys(this.hitAreas).filter((hitAreaName) => this.isHit(hitAreaName, x, y));
+ }
+ isHit(hitAreaName, x, y) {
+ if (!this.hitAreas[hitAreaName]) {
+ return false;
+ }
+ const drawIndex = this.hitAreas[hitAreaName].index;
+ const bounds = this.getDrawableBounds(drawIndex, tempBounds);
+ return bounds.x <= x && x <= bounds.x + bounds.width && bounds.y <= y && y <= bounds.y + bounds.height;
+ }
+ getDrawableBounds(index, bounds) {
+ const vertices = this.getDrawableVertices(index);
+ let left = vertices[0];
+ let right = vertices[0];
+ let top = vertices[1];
+ let bottom = vertices[1];
+ for (let i = 0; i < vertices.length; i += 2) {
+ const vx = vertices[i];
+ const vy = vertices[i + 1];
+ left = Math.min(vx, left);
+ right = Math.max(vx, right);
+ top = Math.min(vy, top);
+ bottom = Math.max(vy, bottom);
+ }
+ bounds != null ? bounds : bounds = {};
+ bounds.x = left;
+ bounds.y = top;
+ bounds.width = right - left;
+ bounds.height = bottom - top;
+ return bounds;
+ }
+ updateTransform(transform) {
+ this.drawingMatrix.copyFrom(transform).append(this.localTransform);
+ }
+ update(dt, now) {
+ this.focusController.update(dt);
+ }
+ destroy() {
+ this.destroyed = true;
+ this.emit("destroy");
+ this.motionManager.destroy();
+ this.motionManager = void 0;
+ }
+}
+const TAG$1 = "XHRLoader";
+class NetworkError extends Error {
+ constructor(message, url2, status, aborted = false) {
+ super(message);
+ this.url = url2;
+ this.status = status;
+ this.aborted = aborted;
+ }
+}
+const _XHRLoader = class {
+ static createXHR(target, url2, type, onload, onerror) {
+ const xhr = new XMLHttpRequest();
+ _XHRLoader.allXhrSet.add(xhr);
+ if (target) {
+ let xhrSet = _XHRLoader.xhrMap.get(target);
+ if (!xhrSet) {
+ xhrSet = /* @__PURE__ */ new Set([xhr]);
+ _XHRLoader.xhrMap.set(target, xhrSet);
+ } else {
+ xhrSet.add(xhr);
+ }
+ if (!target.listeners("destroy").includes(_XHRLoader.cancelXHRs)) {
+ target.once("destroy", _XHRLoader.cancelXHRs);
+ }
+ }
+ xhr.open("GET", url2);
+ xhr.responseType = type;
+ xhr.onload = () => {
+ if ((xhr.status === 200 || xhr.status === 0) && xhr.response) {
+ onload(xhr.response);
+ } else {
+ xhr.onerror();
+ }
+ };
+ xhr.onerror = () => {
+ logger.warn(TAG$1, `Failed to load resource as ${xhr.responseType} (Status ${xhr.status}): ${url2}`);
+ onerror(new NetworkError("Network error.", url2, xhr.status));
+ };
+ xhr.onabort = () => onerror(new NetworkError("Aborted.", url2, xhr.status, true));
+ xhr.onloadend = () => {
+ var _a;
+ _XHRLoader.allXhrSet.delete(xhr);
+ if (target) {
+ (_a = _XHRLoader.xhrMap.get(target)) == null ? void 0 : _a.delete(xhr);
+ }
+ };
+ return xhr;
+ }
+ static cancelXHRs() {
+ var _a;
+ (_a = _XHRLoader.xhrMap.get(this)) == null ? void 0 : _a.forEach((xhr) => {
+ xhr.abort();
+ _XHRLoader.allXhrSet.delete(xhr);
+ });
+ _XHRLoader.xhrMap.delete(this);
+ }
+ static release() {
+ _XHRLoader.allXhrSet.forEach((xhr) => xhr.abort());
+ _XHRLoader.allXhrSet.clear();
+ _XHRLoader.xhrMap = /* @__PURE__ */ new WeakMap();
+ }
+};
+let XHRLoader = _XHRLoader;
+XHRLoader.xhrMap = /* @__PURE__ */ new WeakMap();
+XHRLoader.allXhrSet = /* @__PURE__ */ new Set();
+XHRLoader.loader = (context, next) => {
+ return new Promise((resolve, reject) => {
+ const xhr = _XHRLoader.createXHR(context.target, context.settings ? context.settings.resolveURL(context.url) : context.url, context.type, (data) => {
+ context.result = data;
+ resolve();
+ }, reject);
+ xhr.send();
+ });
+};
+function runMiddlewares(middleware, context) {
+ let index = -1;
+ return dispatch(0);
+ function dispatch(i, err) {
+ if (err)
+ return Promise.reject(err);
+ if (i <= index)
+ return Promise.reject(new Error("next() called multiple times"));
+ index = i;
+ const fn = middleware[i];
+ if (!fn)
+ return Promise.resolve();
+ try {
+ return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
+ } catch (err2) {
+ return Promise.reject(err2);
+ }
+ }
+}
+class Live2DLoader {
+ static load(context) {
+ return runMiddlewares(this.middlewares, context).then(() => context.result);
+ }
+}
+Live2DLoader.middlewares = [XHRLoader.loader];
+function createTexture(url2, options = {}) {
+ var _a;
+ const textureOptions = { resourceOptions: { crossorigin: options.crossOrigin } };
+ if (Texture.fromURL) {
+ return Texture.fromURL(url2, textureOptions).catch((e) => {
+ if (e instanceof Error) {
+ throw e;
+ }
+ const err = new Error("Texture loading error");
+ err.event = e;
+ throw err;
+ });
+ }
+ textureOptions.resourceOptions.autoLoad = false;
+ const texture = Texture.from(url2, textureOptions);
+ if (texture.baseTexture.valid) {
+ return Promise.resolve(texture);
+ }
+ const resource = texture.baseTexture.resource;
+ (_a = resource._live2d_load) != null ? _a : resource._live2d_load = new Promise((resolve, reject) => {
+ const errorHandler = (event) => {
+ resource.source.removeEventListener("error", errorHandler);
+ const err = new Error("Texture loading error");
+ err.event = event;
+ reject(err);
+ };
+ resource.source.addEventListener("error", errorHandler);
+ resource.load().then(() => resolve(texture)).catch(errorHandler);
+ });
+ return resource._live2d_load;
+}
+const TAG = "Live2DFactory";
+const urlToJSON = (context, next) => __async(void 0, null, function* () {
+ if (typeof context.source === "string") {
+ const data = yield Live2DLoader.load({
+ url: context.source,
+ type: "json",
+ target: context.live2dModel
+ });
+ data.url = context.source;
+ context.source = data;
+ context.live2dModel.emit("settingsJSONLoaded", data);
+ }
+ return next();
+});
+const jsonToSettings = (context, next) => __async(void 0, null, function* () {
+ if (context.source instanceof ModelSettings) {
+ context.settings = context.source;
+ return next();
+ } else if (typeof context.source === "object") {
+ const runtime = Live2DFactory.findRuntime(context.source);
+ if (runtime) {
+ const settings = runtime.createModelSettings(context.source);
+ context.settings = settings;
+ context.live2dModel.emit("settingsLoaded", settings);
+ return next();
+ }
+ }
+ throw new TypeError("Unknown settings format.");
+});
+const waitUntilReady = (context, next) => {
+ if (context.settings) {
+ const runtime = Live2DFactory.findRuntime(context.settings);
+ if (runtime) {
+ return runtime.ready().then(next);
+ }
+ }
+ return next();
+};
+const setupOptionals = (context, next) => __async(void 0, null, function* () {
+ yield next();
+ const internalModel = context.internalModel;
+ if (internalModel) {
+ const settings = context.settings;
+ const runtime = Live2DFactory.findRuntime(settings);
+ if (runtime) {
+ const tasks = [];
+ if (settings.pose) {
+ tasks.push(Live2DLoader.load({
+ settings,
+ url: settings.pose,
+ type: "json",
+ target: internalModel
+ }).then((data) => {
+ internalModel.pose = runtime.createPose(internalModel.coreModel, data);
+ context.live2dModel.emit("poseLoaded", internalModel.pose);
+ }).catch((e) => {
+ context.live2dModel.emit("poseLoadError", e);
+ logger.warn(TAG, "Failed to load pose.", e);
+ }));
+ }
+ if (settings.physics) {
+ tasks.push(Live2DLoader.load({
+ settings,
+ url: settings.physics,
+ type: "json",
+ target: internalModel
+ }).then((data) => {
+ internalModel.physics = runtime.createPhysics(internalModel.coreModel, data);
+ context.live2dModel.emit("physicsLoaded", internalModel.physics);
+ }).catch((e) => {
+ context.live2dModel.emit("physicsLoadError", e);
+ logger.warn(TAG, "Failed to load physics.", e);
+ }));
+ }
+ if (tasks.length) {
+ yield Promise.all(tasks);
+ }
+ }
+ }
+});
+const setupEssentials = (context, next) => __async(void 0, null, function* () {
+ if (context.settings) {
+ const live2DModel = context.live2dModel;
+ const textureLoadings = context.settings.textures.map((tex) => {
+ const url2 = context.settings.resolveURL(tex);
+ return createTexture(url2, { crossOrigin: context.options.crossOrigin });
+ });
+ yield next();
+ if (context.internalModel) {
+ live2DModel.internalModel = context.internalModel;
+ live2DModel.emit("modelLoaded", context.internalModel);
+ } else {
+ throw new TypeError("Missing internal model.");
+ }
+ live2DModel.textures = yield Promise.all(textureLoadings);
+ live2DModel.emit("textureLoaded", live2DModel.textures);
+ } else {
+ throw new TypeError("Missing settings.");
+ }
+});
+const createInternalModel = (context, next) => __async(void 0, null, function* () {
+ const settings = context.settings;
+ if (settings instanceof ModelSettings) {
+ const runtime = Live2DFactory.findRuntime(settings);
+ if (!runtime) {
+ throw new TypeError("Unknown model settings.");
+ }
+ const modelData = yield Live2DLoader.load({
+ settings,
+ url: settings.moc,
+ type: "arraybuffer",
+ target: context.live2dModel
+ });
+ if (!runtime.isValidMoc(modelData)) {
+ throw new Error("Invalid moc data");
+ }
+ const coreModel = runtime.createCoreModel(modelData);
+ context.internalModel = runtime.createInternalModel(coreModel, settings, context.options);
+ return next();
+ }
+ throw new TypeError("Missing settings.");
+});
+const _Live2DFactory = class {
+ static registerRuntime(runtime) {
+ _Live2DFactory.runtimes.push(runtime);
+ _Live2DFactory.runtimes.sort((a, b) => b.version - a.version);
+ }
+ static findRuntime(source) {
+ for (const runtime of _Live2DFactory.runtimes) {
+ if (runtime.test(source)) {
+ return runtime;
+ }
+ }
+ }
+ static setupLive2DModel(live2dModel, source, options) {
+ return __async(this, null, function* () {
+ const textureLoaded = new Promise((resolve) => live2dModel.once("textureLoaded", resolve));
+ const modelLoaded = new Promise((resolve) => live2dModel.once("modelLoaded", resolve));
+ const readyEventEmitted = Promise.all([textureLoaded, modelLoaded]).then(() => live2dModel.emit("ready"));
+ yield runMiddlewares(_Live2DFactory.live2DModelMiddlewares, {
+ live2dModel,
+ source,
+ options: options || {}
+ });
+ yield readyEventEmitted;
+ live2dModel.emit("load");
+ });
+ }
+ static loadMotion(motionManager, group, index) {
+ var _a, _b;
+ const handleError = (e) => motionManager.emit("motionLoadError", group, index, e);
+ try {
+ const definition = (_a = motionManager.definitions[group]) == null ? void 0 : _a[index];
+ if (!definition) {
+ return Promise.resolve(void 0);
+ }
+ if (!motionManager.listeners("destroy").includes(_Live2DFactory.releaseTasks)) {
+ motionManager.once("destroy", _Live2DFactory.releaseTasks);
+ }
+ let tasks = _Live2DFactory.motionTasksMap.get(motionManager);
+ if (!tasks) {
+ tasks = {};
+ _Live2DFactory.motionTasksMap.set(motionManager, tasks);
+ }
+ let taskGroup = tasks[group];
+ if (!taskGroup) {
+ taskGroup = [];
+ tasks[group] = taskGroup;
+ }
+ const path = motionManager.getMotionFile(definition);
+ (_b = taskGroup[index]) != null ? _b : taskGroup[index] = Live2DLoader.load({
+ url: path,
+ settings: motionManager.settings,
+ type: motionManager.motionDataType,
+ target: motionManager
+ }).then((data) => {
+ var _a2;
+ const taskGroup2 = (_a2 = _Live2DFactory.motionTasksMap.get(motionManager)) == null ? void 0 : _a2[group];
+ if (taskGroup2) {
+ delete taskGroup2[index];
+ }
+ const motion = motionManager.createMotion(data, group, definition);
+ motionManager.emit("motionLoaded", group, index, motion);
+ return motion;
+ }).catch((e) => {
+ logger.warn(motionManager.tag, `Failed to load motion: ${path}
+`, e);
+ handleError(e);
+ });
+ return taskGroup[index];
+ } catch (e) {
+ logger.warn(motionManager.tag, `Failed to load motion at "${group}"[${index}]
+`, e);
+ handleError(e);
+ }
+ return Promise.resolve(void 0);
+ }
+ static loadExpression(expressionManager, index) {
+ var _a;
+ const handleError = (e) => expressionManager.emit("expressionLoadError", index, e);
+ try {
+ const definition = expressionManager.definitions[index];
+ if (!definition) {
+ return Promise.resolve(void 0);
+ }
+ if (!expressionManager.listeners("destroy").includes(_Live2DFactory.releaseTasks)) {
+ expressionManager.once("destroy", _Live2DFactory.releaseTasks);
+ }
+ let tasks = _Live2DFactory.expressionTasksMap.get(expressionManager);
+ if (!tasks) {
+ tasks = [];
+ _Live2DFactory.expressionTasksMap.set(expressionManager, tasks);
+ }
+ const path = expressionManager.getExpressionFile(definition);
+ (_a = tasks[index]) != null ? _a : tasks[index] = Live2DLoader.load({
+ url: path,
+ settings: expressionManager.settings,
+ type: "json",
+ target: expressionManager
+ }).then((data) => {
+ const tasks2 = _Live2DFactory.expressionTasksMap.get(expressionManager);
+ if (tasks2) {
+ delete tasks2[index];
+ }
+ const expression = expressionManager.createExpression(data, definition);
+ expressionManager.emit("expressionLoaded", index, expression);
+ return expression;
+ }).catch((e) => {
+ logger.warn(expressionManager.tag, `Failed to load expression: ${path}
+`, e);
+ handleError(e);
+ });
+ return tasks[index];
+ } catch (e) {
+ logger.warn(expressionManager.tag, `Failed to load expression at [${index}]
+`, e);
+ handleError(e);
+ }
+ return Promise.resolve(void 0);
+ }
+ static releaseTasks() {
+ if (this instanceof MotionManager) {
+ _Live2DFactory.motionTasksMap.delete(this);
+ } else {
+ _Live2DFactory.expressionTasksMap.delete(this);
+ }
+ }
+};
+let Live2DFactory = _Live2DFactory;
+Live2DFactory.runtimes = [];
+Live2DFactory.urlToJSON = urlToJSON;
+Live2DFactory.jsonToSettings = jsonToSettings;
+Live2DFactory.waitUntilReady = waitUntilReady;
+Live2DFactory.setupOptionals = setupOptionals;
+Live2DFactory.setupEssentials = setupEssentials;
+Live2DFactory.createInternalModel = createInternalModel;
+Live2DFactory.live2DModelMiddlewares = [
+ urlToJSON,
+ jsonToSettings,
+ waitUntilReady,
+ setupOptionals,
+ setupEssentials,
+ createInternalModel
+];
+Live2DFactory.motionTasksMap = /* @__PURE__ */ new WeakMap();
+Live2DFactory.expressionTasksMap = /* @__PURE__ */ new WeakMap();
+MotionManager.prototype["_loadMotion"] = function(group, index) {
+ return Live2DFactory.loadMotion(this, group, index);
+};
+ExpressionManager.prototype["_loadExpression"] = function(index) {
+ return Live2DFactory.loadExpression(this, index);
+};
+class InteractionMixin {
+ constructor() {
+ this._autoInteract = false;
+ }
+ get autoInteract() {
+ return this._autoInteract;
+ }
+ set autoInteract(autoInteract) {
+ if (autoInteract !== this._autoInteract) {
+ if (autoInteract) {
+ this.on("pointertap", onTap, this);
+ } else {
+ this.off("pointertap", onTap, this);
+ }
+ this._autoInteract = autoInteract;
+ }
+ }
+ registerInteraction(manager) {
+ if (manager !== this.interactionManager) {
+ this.unregisterInteraction();
+ if (this._autoInteract && manager) {
+ this.interactionManager = manager;
+ manager.on("pointermove", onPointerMove, this);
+ }
+ }
+ }
+ unregisterInteraction() {
+ var _a;
+ if (this.interactionManager) {
+ (_a = this.interactionManager) == null ? void 0 : _a.off("pointermove", onPointerMove, this);
+ this.interactionManager = void 0;
+ }
+ }
+}
+function onTap(event) {
+ this.tap(event.data.global.x, event.data.global.y);
+}
+function onPointerMove(event) {
+ this.focus(event.data.global.x, event.data.global.y);
+}
+class Live2DTransform extends Transform {
+}
+const tempPoint = new Point();
+const tempMatrix = new Matrix();
+let tickerRef;
+class Live2DModel extends Container {
+ constructor(options) {
+ super();
+ this.tag = "Live2DModel(uninitialized)";
+ this.textures = [];
+ this.transform = new Live2DTransform();
+ this.anchor = new ObservablePoint(this.onAnchorChange, this, 0, 0);
+ this.glContextID = -1;
+ this.elapsedTime = performance.now();
+ this.deltaTime = 0;
+ this._autoUpdate = false;
+ this.once("modelLoaded", () => this.init(options));
+ }
+ static from(source, options) {
+ const model = new this(options);
+ return Live2DFactory.setupLive2DModel(model, source, options).then(() => model);
+ }
+ static fromSync(source, options) {
+ const model = new this(options);
+ Live2DFactory.setupLive2DModel(model, source, options).then(options == null ? void 0 : options.onLoad).catch(options == null ? void 0 : options.onError);
+ return model;
+ }
+ static registerTicker(tickerClass) {
+ tickerRef = tickerClass;
+ }
+ get autoUpdate() {
+ return this._autoUpdate;
+ }
+ set autoUpdate(autoUpdate) {
+ var _a;
+ tickerRef || (tickerRef = (_a = window.PIXI) == null ? void 0 : _a.Ticker);
+ if (autoUpdate) {
+ if (!this._destroyed) {
+ if (tickerRef) {
+ tickerRef.shared.add(this.onTickerUpdate, this);
+ this._autoUpdate = true;
+ } else {
+ logger.warn(this.tag, "No Ticker registered, please call Live2DModel.registerTicker(Ticker).");
+ }
+ }
+ } else {
+ tickerRef == null ? void 0 : tickerRef.shared.remove(this.onTickerUpdate, this);
+ this._autoUpdate = false;
+ }
+ }
+ init(options) {
+ this.tag = `Live2DModel(${this.internalModel.settings.name})`;
+ const _options = Object.assign({
+ autoUpdate: true,
+ autoInteract: true
+ }, options);
+ if (_options.autoInteract) {
+ this.interactive = true;
+ }
+ this.autoInteract = _options.autoInteract;
+ this.autoUpdate = _options.autoUpdate;
+ }
+ onAnchorChange() {
+ this.pivot.set(this.anchor.x * this.internalModel.width, this.anchor.y * this.internalModel.height);
+ }
+ motion(group, index, priority, sound, volume, expression) {
+ return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority) : this.internalModel.motionManager.startMotion(group, index, priority, sound, volume, expression);
+ }
+ resetMotions() {
+ return this.internalModel.motionManager.stopAllMotions();
+ }
+ speak(sound, volume, expression) {
+ return this.internalModel.motionManager.speakUp(sound, volume, expression);
+ }
+ stopSpeaking() {
+ return this.internalModel.motionManager.stopSpeaking();
+ }
+ expression(id) {
+ if (this.internalModel.motionManager.expressionManager) {
+ return id === void 0 ? this.internalModel.motionManager.expressionManager.setRandomExpression() : this.internalModel.motionManager.expressionManager.setExpression(id);
+ }
+ return Promise.resolve(false);
+ }
+ focus(x, y, instant = false) {
+ tempPoint.x = x;
+ tempPoint.y = y;
+ this.toModelPosition(tempPoint, tempPoint, true);
+ let tx = tempPoint.x / this.internalModel.originalWidth * 2 - 1;
+ let ty = tempPoint.y / this.internalModel.originalHeight * 2 - 1;
+ let radian = Math.atan2(ty, tx);
+ this.internalModel.focusController.focus(Math.cos(radian), -Math.sin(radian), instant);
+ }
+ tap(x, y) {
+ const hitAreaNames = this.hitTest(x, y);
+ if (hitAreaNames.length) {
+ logger.log(this.tag, `Hit`, hitAreaNames);
+ this.emit("hit", hitAreaNames);
+ }
+ }
+ hitTest(x, y) {
+ tempPoint.x = x;
+ tempPoint.y = y;
+ this.toModelPosition(tempPoint, tempPoint);
+ return this.internalModel.hitTest(tempPoint.x, tempPoint.y);
+ }
+ toModelPosition(position, result = position.clone(), skipUpdate) {
+ if (!skipUpdate) {
+ this._recursivePostUpdateTransform();
+ if (!this.parent) {
+ this.parent = this._tempDisplayObjectParent;
+ this.displayObjectUpdateTransform();
+ this.parent = null;
+ } else {
+ this.displayObjectUpdateTransform();
+ }
+ }
+ this.transform.worldTransform.applyInverse(position, result);
+ this.internalModel.localTransform.applyInverse(result, result);
+ return result;
+ }
+ containsPoint(point) {
+ return this.getBounds(true).contains(point.x, point.y);
+ }
+ _calculateBounds() {
+ this._bounds.addFrame(this.transform, 0, 0, this.internalModel.width, this.internalModel.height);
+ }
+ onTickerUpdate() {
+ this.update(tickerRef.shared.deltaMS);
+ }
+ update(dt) {
+ this.deltaTime += dt;
+ this.elapsedTime += dt;
+ }
+ _render(renderer) {
+ this.registerInteraction(renderer.plugins.interaction);
+ renderer.batch.reset();
+ renderer.geometry.reset();
+ renderer.shader.reset();
+ renderer.state.reset();
+ let shouldUpdateTexture = false;
+ if (this.glContextID !== renderer.CONTEXT_UID) {
+ this.glContextID = renderer.CONTEXT_UID;
+ this.internalModel.updateWebGLContext(renderer.gl, this.glContextID);
+ shouldUpdateTexture = true;
+ }
+ for (let i = 0; i < this.textures.length; i++) {
+ const texture = this.textures[i];
+ if (!texture.valid) {
+ continue;
+ }
+ if (shouldUpdateTexture || !texture.baseTexture._glTextures[this.glContextID]) {
+ renderer.gl.pixelStorei(WebGLRenderingContext.UNPACK_FLIP_Y_WEBGL, this.internalModel.textureFlipY);
+ renderer.texture.bind(texture.baseTexture, 0);
+ }
+ this.internalModel.bindTexture(i, texture.baseTexture._glTextures[this.glContextID].texture);
+ texture.baseTexture.touched = renderer.textureGC.count;
+ }
+ const viewport = renderer.framebuffer.viewport;
+ this.internalModel.viewport = [viewport.x, viewport.y, viewport.width, viewport.height];
+ if (this.deltaTime) {
+ this.internalModel.update(this.deltaTime, this.elapsedTime);
+ this.deltaTime = 0;
+ }
+ const internalTransform = tempMatrix.copyFrom(renderer.globalUniforms.uniforms.projectionMatrix).append(this.worldTransform);
+ this.internalModel.updateTransform(internalTransform);
+ this.internalModel.draw(renderer.gl);
+ renderer.state.reset();
+ renderer.texture.reset();
+ }
+ destroy(options) {
+ this.emit("destroy");
+ this.autoUpdate = false;
+ this.unregisterInteraction();
+ if (options == null ? void 0 : options.texture) {
+ this.textures.forEach((texture) => texture.destroy(options.baseTexture));
+ }
+ this.internalModel.destroy();
+ super.destroy(options);
+ }
+}
+applyMixins(Live2DModel, [InteractionMixin]);
+const _FileLoader = class {
+ static resolveURL(settingsURL, filePath) {
+ var _a;
+ const resolved = (_a = _FileLoader.filesMap[settingsURL]) == null ? void 0 : _a[filePath];
+ if (resolved === void 0) {
+ throw new Error("Cannot find this file from uploaded files: " + filePath);
+ }
+ return resolved;
+ }
+ static upload(files, settings) {
+ return __async(this, null, function* () {
+ const fileMap = {};
+ for (const definedFile of settings.getDefinedFiles()) {
+ const actualPath = decodeURI(url.resolve(settings.url, definedFile));
+ const actualFile = files.find((file) => file.webkitRelativePath === actualPath);
+ if (actualFile) {
+ fileMap[definedFile] = URL.createObjectURL(actualFile);
+ }
+ }
+ _FileLoader.filesMap[settings._objectURL] = fileMap;
+ });
+ }
+ static createSettings(files) {
+ return __async(this, null, function* () {
+ const settingsFile = files.find((file) => file.name.endsWith("model.json") || file.name.endsWith("model3.json"));
+ if (!settingsFile) {
+ throw new TypeError("Settings file not found");
+ }
+ const settingsText = yield _FileLoader.readText(settingsFile);
+ const settingsJSON = JSON.parse(settingsText);
+ settingsJSON.url = settingsFile.webkitRelativePath;
+ const runtime = Live2DFactory.findRuntime(settingsJSON);
+ if (!runtime) {
+ throw new Error("Unknown settings JSON");
+ }
+ const settings = runtime.createModelSettings(settingsJSON);
+ settings._objectURL = URL.createObjectURL(settingsFile);
+ return settings;
+ });
+ }
+ static readText(file) {
+ return __async(this, null, function* () {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = () => resolve(reader.result);
+ reader.onerror = reject;
+ reader.readAsText(file, "utf8");
+ });
+ });
+ }
+};
+let FileLoader = _FileLoader;
+FileLoader.filesMap = {};
+FileLoader.factory = (context, next) => __async(void 0, null, function* () {
+ if (Array.isArray(context.source) && context.source[0] instanceof File) {
+ const files = context.source;
+ let settings = files.settings;
+ if (!settings) {
+ settings = yield _FileLoader.createSettings(files);
+ } else if (!settings._objectURL) {
+ throw new Error('"_objectURL" must be specified in ModelSettings');
+ }
+ settings.validateFiles(files.map((file) => encodeURI(file.webkitRelativePath)));
+ yield _FileLoader.upload(files, settings);
+ settings.resolveURL = function(url2) {
+ return _FileLoader.resolveURL(this._objectURL, url2);
+ };
+ context.source = settings;
+ context.live2dModel.once("modelLoaded", (internalModel) => {
+ internalModel.once("destroy", function() {
+ const objectURL = this.settings._objectURL;
+ URL.revokeObjectURL(objectURL);
+ if (_FileLoader.filesMap[objectURL]) {
+ for (const resourceObjectURL of Object.values(_FileLoader.filesMap[objectURL])) {
+ URL.revokeObjectURL(resourceObjectURL);
+ }
+ }
+ delete _FileLoader.filesMap[objectURL];
+ });
+ });
+ }
+ return next();
+});
+Live2DFactory.live2DModelMiddlewares.unshift(FileLoader.factory);
+const _ZipLoader = class {
+ static unzip(reader, settings) {
+ return __async(this, null, function* () {
+ const filePaths = yield _ZipLoader.getFilePaths(reader);
+ const requiredFilePaths = [];
+ for (const definedFile of settings.getDefinedFiles()) {
+ const actualPath = decodeURI(url.resolve(settings.url, definedFile));
+ if (filePaths.includes(actualPath)) {
+ requiredFilePaths.push(actualPath);
+ }
+ }
+ const files = yield _ZipLoader.getFiles(reader, requiredFilePaths);
+ for (let i = 0; i < files.length; i++) {
+ const path = requiredFilePaths[i];
+ const file = files[i];
+ Object.defineProperty(file, "webkitRelativePath", {
+ value: path
+ });
+ }
+ return files;
+ });
+ }
+ static createSettings(reader) {
+ return __async(this, null, function* () {
+ const filePaths = yield _ZipLoader.getFilePaths(reader);
+ const settingsFilePath = filePaths.find((path) => path.endsWith("model.json") || path.endsWith("model3.json"));
+ if (!settingsFilePath) {
+ throw new Error("Settings file not found");
+ }
+ const settingsText = yield _ZipLoader.readText(reader, settingsFilePath);
+ if (!settingsText) {
+ throw new Error("Empty settings file: " + settingsFilePath);
+ }
+ const settingsJSON = JSON.parse(settingsText);
+ settingsJSON.url = settingsFilePath;
+ const runtime = Live2DFactory.findRuntime(settingsJSON);
+ if (!runtime) {
+ throw new Error("Unknown settings JSON");
+ }
+ return runtime.createModelSettings(settingsJSON);
+ });
+ }
+ static zipReader(data, url2) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static getFilePaths(reader) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static getFiles(reader, paths) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static readText(reader, path) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static releaseReader(reader) {
+ }
+};
+let ZipLoader = _ZipLoader;
+ZipLoader.ZIP_PROTOCOL = "zip://";
+ZipLoader.uid = 0;
+ZipLoader.factory = (context, next) => __async(void 0, null, function* () {
+ const source = context.source;
+ let sourceURL;
+ let zipBlob;
+ let settings;
+ if (typeof source === "string" && (source.endsWith(".zip") || source.startsWith(_ZipLoader.ZIP_PROTOCOL))) {
+ if (source.startsWith(_ZipLoader.ZIP_PROTOCOL)) {
+ sourceURL = source.slice(_ZipLoader.ZIP_PROTOCOL.length);
+ } else {
+ sourceURL = source;
+ }
+ zipBlob = yield Live2DLoader.load({
+ url: sourceURL,
+ type: "blob",
+ target: context.live2dModel
+ });
+ } else if (Array.isArray(source) && source.length === 1 && source[0] instanceof File && source[0].name.endsWith(".zip")) {
+ zipBlob = source[0];
+ sourceURL = URL.createObjectURL(zipBlob);
+ settings = source.settings;
+ }
+ if (zipBlob) {
+ if (!zipBlob.size) {
+ throw new Error("Empty zip file");
+ }
+ const reader = yield _ZipLoader.zipReader(zipBlob, sourceURL);
+ if (!settings) {
+ settings = yield _ZipLoader.createSettings(reader);
+ }
+ settings._objectURL = _ZipLoader.ZIP_PROTOCOL + _ZipLoader.uid + "/" + settings.url;
+ const files = yield _ZipLoader.unzip(reader, settings);
+ files.settings = settings;
+ context.source = files;
+ if (sourceURL.startsWith("blob:")) {
+ context.live2dModel.once("modelLoaded", (internalModel) => {
+ internalModel.once("destroy", function() {
+ URL.revokeObjectURL(sourceURL);
+ });
+ });
+ }
+ _ZipLoader.releaseReader(reader);
+ }
+ return next();
+});
+Live2DFactory.live2DModelMiddlewares.unshift(ZipLoader.factory);
+if (!window.Live2D) {
+ throw new Error("Could not find Cubism 2 runtime. This plugin requires live2d.min.js to be loaded.");
+}
+const originalUpdateParam = Live2DMotion.prototype.updateParam;
+Live2DMotion.prototype.updateParam = function(model, entry) {
+ originalUpdateParam.call(this, model, entry);
+ if (entry.isFinished() && this.onFinishHandler) {
+ this.onFinishHandler(this);
+ delete this.onFinishHandler;
+ }
+};
+class Live2DExpression extends AMotion {
+ constructor(json) {
+ super();
+ this.params = [];
+ this.setFadeIn(json.fade_in > 0 ? json.fade_in : config.expressionFadingDuration);
+ this.setFadeOut(json.fade_out > 0 ? json.fade_out : config.expressionFadingDuration);
+ if (Array.isArray(json.params)) {
+ json.params.forEach((param) => {
+ const calc = param.calc || "add";
+ if (calc === "add") {
+ const defaultValue = param.def || 0;
+ param.val -= defaultValue;
+ } else if (calc === "mult") {
+ const defaultValue = param.def || 1;
+ param.val /= defaultValue;
+ }
+ this.params.push({
+ calc,
+ val: param.val,
+ id: param.id
+ });
+ });
+ }
+ }
+ updateParamExe(model, time, weight, motionQueueEnt) {
+ this.params.forEach((param) => {
+ model.setParamFloat(param.id, param.val * weight);
+ });
+ }
+}
+class Cubism2ExpressionManager extends ExpressionManager {
+ constructor(settings, options) {
+ var _a;
+ super(settings, options);
+ this.queueManager = new MotionQueueManager();
+ this.definitions = (_a = this.settings.expressions) != null ? _a : [];
+ this.init();
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ getExpressionIndex(name) {
+ return this.definitions.findIndex((def) => def.name === name);
+ }
+ getExpressionFile(definition) {
+ return definition.file;
+ }
+ createExpression(data, definition) {
+ return new Live2DExpression(data);
+ }
+ _setExpression(motion) {
+ return this.queueManager.startMotion(motion);
+ }
+ stopAllExpressions() {
+ this.queueManager.stopAllMotions();
+ }
+ updateParameters(model, dt) {
+ return this.queueManager.updateParam(model);
+ }
+}
+class Cubism2MotionManager extends MotionManager {
+ constructor(settings, options) {
+ super(settings, options);
+ this.groups = { idle: "idle" };
+ this.motionDataType = "arraybuffer";
+ this.queueManager = new MotionQueueManager();
+ this.definitions = this.settings.motions;
+ this.init(options);
+ }
+ init(options) {
+ super.init(options);
+ if (this.settings.expressions) {
+ this.expressionManager = new Cubism2ExpressionManager(this.settings, options);
+ }
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ createMotion(data, group, definition) {
+ const motion = Live2DMotion.loadMotion(data);
+ const defaultFadingDuration = group === this.groups.idle ? config.idleMotionFadingDuration : config.motionFadingDuration;
+ motion.setFadeIn(definition.fade_in > 0 ? definition.fade_in : defaultFadingDuration);
+ motion.setFadeOut(definition.fade_out > 0 ? definition.fade_out : defaultFadingDuration);
+ return motion;
+ }
+ getMotionFile(definition) {
+ return definition.file;
+ }
+ getMotionName(definition) {
+ return definition.file;
+ }
+ getSoundFile(definition) {
+ return definition.sound;
+ }
+ _startMotion(motion, onFinish) {
+ motion.onFinishHandler = onFinish;
+ this.queueManager.stopAllMotions();
+ return this.queueManager.startMotion(motion);
+ }
+ _stopAllMotions() {
+ this.queueManager.stopAllMotions();
+ }
+ updateParameters(model, now) {
+ return this.queueManager.updateParam(model);
+ }
+ destroy() {
+ super.destroy();
+ this.queueManager = void 0;
+ }
+}
+class Live2DEyeBlink {
+ constructor(coreModel) {
+ this.coreModel = coreModel;
+ this.blinkInterval = 4e3;
+ this.closingDuration = 100;
+ this.closedDuration = 50;
+ this.openingDuration = 150;
+ this.eyeState = 0;
+ this.eyeParamValue = 1;
+ this.closedTimer = 0;
+ this.nextBlinkTimeLeft = this.blinkInterval;
+ this.leftParam = coreModel.getParamIndex("PARAM_EYE_L_OPEN");
+ this.rightParam = coreModel.getParamIndex("PARAM_EYE_R_OPEN");
+ }
+ setEyeParams(value) {
+ this.eyeParamValue = clamp(value, 0, 1);
+ this.coreModel.setParamFloat(this.leftParam, this.eyeParamValue);
+ this.coreModel.setParamFloat(this.rightParam, this.eyeParamValue);
+ }
+ update(dt) {
+ switch (this.eyeState) {
+ case 0:
+ this.nextBlinkTimeLeft -= dt;
+ if (this.nextBlinkTimeLeft < 0) {
+ this.eyeState = 1;
+ this.nextBlinkTimeLeft = this.blinkInterval + this.closingDuration + this.closedDuration + this.openingDuration + rand(0, 2e3);
+ }
+ break;
+ case 1:
+ this.setEyeParams(this.eyeParamValue + dt / this.closingDuration);
+ if (this.eyeParamValue <= 0) {
+ this.eyeState = 2;
+ this.closedTimer = 0;
+ }
+ break;
+ case 2:
+ this.closedTimer += dt;
+ if (this.closedTimer >= this.closedDuration) {
+ this.eyeState = 3;
+ }
+ break;
+ case 3:
+ this.setEyeParams(this.eyeParamValue + dt / this.openingDuration);
+ if (this.eyeParamValue >= 1) {
+ this.eyeState = 0;
+ }
+ }
+ }
+}
+const tempMatrixArray = new Float32Array([
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+]);
+class Cubism2InternalModel extends InternalModel {
+ constructor(coreModel, settings, options) {
+ super();
+ this.textureFlipY = true;
+ this.drawDataCount = 0;
+ this.disableCulling = false;
+ this.coreModel = coreModel;
+ this.settings = settings;
+ this.motionManager = new Cubism2MotionManager(settings, options);
+ this.eyeBlink = new Live2DEyeBlink(coreModel);
+ this.eyeballXParamIndex = coreModel.getParamIndex("PARAM_EYE_BALL_X");
+ this.eyeballYParamIndex = coreModel.getParamIndex("PARAM_EYE_BALL_Y");
+ this.angleXParamIndex = coreModel.getParamIndex("PARAM_ANGLE_X");
+ this.angleYParamIndex = coreModel.getParamIndex("PARAM_ANGLE_Y");
+ this.angleZParamIndex = coreModel.getParamIndex("PARAM_ANGLE_Z");
+ this.bodyAngleXParamIndex = coreModel.getParamIndex("PARAM_BODY_ANGLE_X");
+ this.breathParamIndex = coreModel.getParamIndex("PARAM_BREATH");
+ this.init();
+ }
+ init() {
+ super.init();
+ if (this.settings.initParams) {
+ this.settings.initParams.forEach(({ id, value }) => this.coreModel.setParamFloat(id, value));
+ }
+ if (this.settings.initOpacities) {
+ this.settings.initOpacities.forEach(({ id, value }) => this.coreModel.setPartsOpacity(id, value));
+ }
+ this.coreModel.saveParam();
+ const arr = this.coreModel.getModelContext()._$aS;
+ if (arr == null ? void 0 : arr.length) {
+ this.drawDataCount = arr.length;
+ }
+ let culling = this.coreModel.drawParamWebGL.culling;
+ Object.defineProperty(this.coreModel.drawParamWebGL, "culling", {
+ set: (v) => culling = v,
+ get: () => this.disableCulling ? false : culling
+ });
+ const clipManager = this.coreModel.getModelContext().clipManager;
+ const originalSetupClip = clipManager.setupClip;
+ clipManager.setupClip = (modelContext, drawParam) => {
+ originalSetupClip.call(clipManager, modelContext, drawParam);
+ drawParam.gl.viewport(...this.viewport);
+ };
+ }
+ getSize() {
+ return [this.coreModel.getCanvasWidth(), this.coreModel.getCanvasHeight()];
+ }
+ getLayout() {
+ const layout = {};
+ if (this.settings.layout) {
+ for (const key of Object.keys(this.settings.layout)) {
+ let commonKey = key;
+ if (key === "center_x") {
+ commonKey = "centerX";
+ } else if (key === "center_y") {
+ commonKey = "centerY";
+ }
+ layout[commonKey] = this.settings.layout[key];
+ }
+ }
+ return layout;
+ }
+ updateWebGLContext(gl, glContextID) {
+ const drawParamWebGL = this.coreModel.drawParamWebGL;
+ drawParamWebGL.firstDraw = true;
+ drawParamWebGL.setGL(gl);
+ drawParamWebGL.glno = glContextID;
+ for (const prop in drawParamWebGL) {
+ if (drawParamWebGL.hasOwnProperty(prop) && drawParamWebGL[prop] instanceof WebGLBuffer) {
+ drawParamWebGL[prop] = null;
+ }
+ }
+ const clipManager = this.coreModel.getModelContext().clipManager;
+ clipManager.curFrameNo = glContextID;
+ const framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
+ clipManager.getMaskRenderTexture();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+ }
+ bindTexture(index, texture) {
+ this.coreModel.setTexture(index, texture);
+ }
+ getHitAreaDefs() {
+ var _a;
+ return ((_a = this.settings.hitAreas) == null ? void 0 : _a.map((hitArea) => ({
+ id: hitArea.id,
+ name: hitArea.name,
+ index: this.coreModel.getDrawDataIndex(hitArea.id)
+ }))) || [];
+ }
+ getDrawableIDs() {
+ const modelContext = this.coreModel.getModelContext();
+ const ids = [];
+ for (let i = 0; i < this.drawDataCount; i++) {
+ const drawData = modelContext.getDrawData(i);
+ if (drawData) {
+ ids.push(drawData.getDrawDataID().id);
+ }
+ }
+ return ids;
+ }
+ getDrawableIndex(id) {
+ return this.coreModel.getDrawDataIndex(id);
+ }
+ getDrawableVertices(drawIndex) {
+ if (typeof drawIndex === "string") {
+ drawIndex = this.coreModel.getDrawDataIndex(drawIndex);
+ if (drawIndex === -1)
+ throw new TypeError("Unable to find drawable ID: " + drawIndex);
+ }
+ return this.coreModel.getTransformedPoints(drawIndex).slice();
+ }
+ update(dt, now) {
+ var _a, _b, _c, _d;
+ super.update(dt, now);
+ const model = this.coreModel;
+ this.emit("beforeMotionUpdate");
+ const motionUpdated = this.motionManager.update(this.coreModel, now);
+ this.emit("afterMotionUpdate");
+ model.saveParam();
+ (_a = this.motionManager.expressionManager) == null ? void 0 : _a.update(model, now);
+ if (!motionUpdated) {
+ (_b = this.eyeBlink) == null ? void 0 : _b.update(dt);
+ }
+ this.updateFocus();
+ this.updateNaturalMovements(dt, now);
+ (_c = this.physics) == null ? void 0 : _c.update(now);
+ (_d = this.pose) == null ? void 0 : _d.update(dt);
+ this.emit("beforeModelUpdate");
+ model.update();
+ model.loadParam();
+ }
+ updateFocus() {
+ this.coreModel.addToParamFloat(this.eyeballXParamIndex, this.focusController.x);
+ this.coreModel.addToParamFloat(this.eyeballYParamIndex, this.focusController.y);
+ this.coreModel.addToParamFloat(this.angleXParamIndex, this.focusController.x * 30);
+ this.coreModel.addToParamFloat(this.angleYParamIndex, this.focusController.y * 30);
+ this.coreModel.addToParamFloat(this.angleZParamIndex, this.focusController.x * this.focusController.y * -30);
+ this.coreModel.addToParamFloat(this.bodyAngleXParamIndex, this.focusController.x * 10);
+ }
+ updateNaturalMovements(dt, now) {
+ const t = now / 1e3 * 2 * Math.PI;
+ this.coreModel.addToParamFloat(this.angleXParamIndex, 15 * Math.sin(t / 6.5345) * 0.5);
+ this.coreModel.addToParamFloat(this.angleYParamIndex, 8 * Math.sin(t / 3.5345) * 0.5);
+ this.coreModel.addToParamFloat(this.angleZParamIndex, 10 * Math.sin(t / 5.5345) * 0.5);
+ this.coreModel.addToParamFloat(this.bodyAngleXParamIndex, 4 * Math.sin(t / 15.5345) * 0.5);
+ this.coreModel.setParamFloat(this.breathParamIndex, 0.5 + 0.5 * Math.sin(t / 3.2345));
+ }
+ draw(gl) {
+ const disableCulling = this.disableCulling;
+ if (gl.getParameter(gl.FRAMEBUFFER_BINDING)) {
+ this.disableCulling = true;
+ }
+ const matrix = this.drawingMatrix;
+ tempMatrixArray[0] = matrix.a;
+ tempMatrixArray[1] = matrix.b;
+ tempMatrixArray[4] = matrix.c;
+ tempMatrixArray[5] = matrix.d;
+ tempMatrixArray[12] = matrix.tx;
+ tempMatrixArray[13] = matrix.ty;
+ this.coreModel.setMatrix(tempMatrixArray);
+ this.coreModel.draw();
+ this.disableCulling = disableCulling;
+ }
+ destroy() {
+ super.destroy();
+ this.coreModel = void 0;
+ }
+}
+class Cubism2ModelSettings extends ModelSettings {
+ constructor(json) {
+ super(json);
+ this.motions = {};
+ if (!Cubism2ModelSettings.isValidJSON(json)) {
+ throw new TypeError("Invalid JSON.");
+ }
+ this.moc = json.model;
+ copyArray("string", json, this, "textures", "textures");
+ this.copy(json);
+ }
+ static isValidJSON(json) {
+ var _a;
+ return !!json && typeof json.model === "string" && ((_a = json.textures) == null ? void 0 : _a.length) > 0 && json.textures.every((item) => typeof item === "string");
+ }
+ copy(json) {
+ copyProperty("string", json, this, "name", "name");
+ copyProperty("string", json, this, "pose", "pose");
+ copyProperty("string", json, this, "physics", "physics");
+ copyProperty("object", json, this, "layout", "layout");
+ copyProperty("object", json, this, "motions", "motions");
+ copyArray("object", json, this, "hit_areas", "hitAreas");
+ copyArray("object", json, this, "expressions", "expressions");
+ copyArray("object", json, this, "init_params", "initParams");
+ copyArray("object", json, this, "init_opacities", "initOpacities");
+ }
+ replaceFiles(replace) {
+ super.replaceFiles(replace);
+ for (const [group, motions] of Object.entries(this.motions)) {
+ for (let i = 0; i < motions.length; i++) {
+ motions[i].file = replace(motions[i].file, `motions.${group}[${i}].file`);
+ if (motions[i].sound !== void 0) {
+ motions[i].sound = replace(motions[i].sound, `motions.${group}[${i}].sound`);
+ }
+ }
+ }
+ if (this.expressions) {
+ for (let i = 0; i < this.expressions.length; i++) {
+ this.expressions[i].file = replace(this.expressions[i].file, `expressions[${i}].file`);
+ }
+ }
+ }
+}
+const SRC_TYPE_MAP = {
+ x: PhysicsHair.Src.SRC_TO_X,
+ y: PhysicsHair.Src.SRC_TO_Y,
+ angle: PhysicsHair.Src.SRC_TO_G_ANGLE
+};
+const TARGET_TYPE_MAP = {
+ x: PhysicsHair.Src.SRC_TO_X,
+ y: PhysicsHair.Src.SRC_TO_Y,
+ angle: PhysicsHair.Src.SRC_TO_G_ANGLE
+};
+class Live2DPhysics {
+ constructor(coreModel, json) {
+ this.coreModel = coreModel;
+ this.physicsHairs = [];
+ if (json.physics_hair) {
+ this.physicsHairs = json.physics_hair.map((definition) => {
+ const physicsHair = new PhysicsHair();
+ physicsHair.setup(definition.setup.length, definition.setup.regist, definition.setup.mass);
+ definition.src.forEach(({ id, ptype, scale, weight }) => {
+ const type = SRC_TYPE_MAP[ptype];
+ if (type) {
+ physicsHair.addSrcParam(type, id, scale, weight);
+ }
+ });
+ definition.targets.forEach(({ id, ptype, scale, weight }) => {
+ const type = TARGET_TYPE_MAP[ptype];
+ if (type) {
+ physicsHair.addTargetParam(type, id, scale, weight);
+ }
+ });
+ return physicsHair;
+ });
+ }
+ }
+ update(elapsed) {
+ this.physicsHairs.forEach((physicsHair) => physicsHair.update(this.coreModel, elapsed));
+ }
+}
+class Live2DPartsParam {
+ constructor(id) {
+ this.id = id;
+ this.paramIndex = -1;
+ this.partsIndex = -1;
+ this.link = [];
+ }
+ initIndex(model) {
+ this.paramIndex = model.getParamIndex("VISIBLE:" + this.id);
+ this.partsIndex = model.getPartsDataIndex(PartsDataID.getID(this.id));
+ model.setParamFloat(this.paramIndex, 1);
+ }
+}
+class Live2DPose {
+ constructor(coreModel, json) {
+ this.coreModel = coreModel;
+ this.opacityAnimDuration = 500;
+ this.partsGroups = [];
+ if (json.parts_visible) {
+ this.partsGroups = json.parts_visible.map(({ group }) => group.map(({ id, link }) => {
+ const parts = new Live2DPartsParam(id);
+ if (link) {
+ parts.link = link.map((l) => new Live2DPartsParam(l));
+ }
+ return parts;
+ }));
+ this.init();
+ }
+ }
+ init() {
+ this.partsGroups.forEach((group) => {
+ group.forEach((parts) => {
+ parts.initIndex(this.coreModel);
+ if (parts.paramIndex >= 0) {
+ const visible = this.coreModel.getParamFloat(parts.paramIndex) !== 0;
+ this.coreModel.setPartsOpacity(parts.partsIndex, visible ? 1 : 0);
+ this.coreModel.setParamFloat(parts.paramIndex, visible ? 1 : 0);
+ if (parts.link.length > 0) {
+ parts.link.forEach((p) => p.initIndex(this.coreModel));
+ }
+ }
+ });
+ });
+ }
+ normalizePartsOpacityGroup(partsGroup, dt) {
+ const model = this.coreModel;
+ const phi = 0.5;
+ const maxBackOpacity = 0.15;
+ let visibleOpacity = 1;
+ let visibleIndex = partsGroup.findIndex(({ paramIndex, partsIndex }) => partsIndex >= 0 && model.getParamFloat(paramIndex) !== 0);
+ if (visibleIndex >= 0) {
+ const originalOpacity = model.getPartsOpacity(partsGroup[visibleIndex].partsIndex);
+ visibleOpacity = clamp(originalOpacity + dt / this.opacityAnimDuration, 0, 1);
+ } else {
+ visibleIndex = 0;
+ visibleOpacity = 1;
+ }
+ partsGroup.forEach(({ partsIndex }, index) => {
+ if (partsIndex >= 0) {
+ if (visibleIndex == index) {
+ model.setPartsOpacity(partsIndex, visibleOpacity);
+ } else {
+ let opacity = model.getPartsOpacity(partsIndex);
+ let a1;
+ if (visibleOpacity < phi) {
+ a1 = visibleOpacity * (phi - 1) / phi + 1;
+ } else {
+ a1 = (1 - visibleOpacity) * phi / (1 - phi);
+ }
+ let backOp = (1 - a1) * (1 - visibleOpacity);
+ if (backOp > maxBackOpacity) {
+ a1 = 1 - maxBackOpacity / (1 - visibleOpacity);
+ }
+ if (opacity > a1) {
+ opacity = a1;
+ }
+ model.setPartsOpacity(partsIndex, opacity);
+ }
+ }
+ });
+ }
+ copyOpacity(partsGroup) {
+ const model = this.coreModel;
+ partsGroup.forEach(({ partsIndex, link }) => {
+ if (partsIndex >= 0 && link) {
+ const opacity = model.getPartsOpacity(partsIndex);
+ link.forEach(({ partsIndex: partsIndex2 }) => {
+ if (partsIndex2 >= 0) {
+ model.setPartsOpacity(partsIndex2, opacity);
+ }
+ });
+ }
+ });
+ }
+ update(dt) {
+ this.partsGroups.forEach((partGroup) => {
+ this.normalizePartsOpacityGroup(partGroup, dt);
+ this.copyOpacity(partGroup);
+ });
+ }
+}
+Live2DFactory.registerRuntime({
+ version: 2,
+ test(source) {
+ return source instanceof Cubism2ModelSettings || Cubism2ModelSettings.isValidJSON(source);
+ },
+ ready() {
+ return Promise.resolve();
+ },
+ isValidMoc(modelData) {
+ if (modelData.byteLength < 3) {
+ return false;
+ }
+ const view = new Int8Array(modelData, 0, 3);
+ return String.fromCharCode(...view) === "moc";
+ },
+ createModelSettings(json) {
+ return new Cubism2ModelSettings(json);
+ },
+ createCoreModel(data) {
+ const model = Live2DModelWebGL.loadModel(data);
+ const error = Live2D.getError();
+ if (error)
+ throw error;
+ return model;
+ },
+ createInternalModel(coreModel, settings, options) {
+ return new Cubism2InternalModel(coreModel, settings, options);
+ },
+ createPose(coreModel, data) {
+ return new Live2DPose(coreModel, data);
+ },
+ createPhysics(coreModel, data) {
+ return new Live2DPhysics(coreModel, data);
+ }
+});
+export { Cubism2ExpressionManager, Cubism2InternalModel, Cubism2ModelSettings, Cubism2MotionManager, ExpressionManager, FileLoader, FocusController, InteractionMixin, InternalModel, LOGICAL_HEIGHT, LOGICAL_WIDTH, Live2DExpression, Live2DEyeBlink, Live2DFactory, Live2DLoader, Live2DModel, Live2DPhysics, Live2DPose, Live2DTransform, ModelSettings, MotionManager, MotionPreloadStrategy, MotionPriority, MotionState, SoundManager, VERSION, XHRLoader, ZipLoader, applyMixins, clamp, config, copyArray, copyProperty, folderName, logger, rand, remove };
diff --git a/dist/cubism2.js b/dist/cubism2.js
new file mode 100644
index 00000000..4e1b5539
--- /dev/null
+++ b/dist/cubism2.js
@@ -0,0 +1,2324 @@
+var __pow = Math.pow;
+var __async = (__this, __arguments, generator) => {
+ return new Promise((resolve, reject) => {
+ var fulfilled = (value) => {
+ try {
+ step(generator.next(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var rejected = (value) => {
+ try {
+ step(generator.throw(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
+ step((generator = generator.apply(__this, __arguments)).next());
+ });
+};
+(function(global, factory) {
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@pixi/utils"), require("@pixi/math"), require("@pixi/core"), require("@pixi/display")) : typeof define === "function" && define.amd ? define(["exports", "@pixi/utils", "@pixi/math", "@pixi/core", "@pixi/display"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory((global.PIXI = global.PIXI || {}, global.PIXI.live2d = global.PIXI.live2d || {}), global.PIXI.utils, global.PIXI, global.PIXI, global.PIXI));
+})(this, function(exports2, utils, math, core, display) {
+ "use strict";
+ const LOGICAL_WIDTH = 2;
+ const LOGICAL_HEIGHT = 2;
+ var CubismConfig;
+ ((CubismConfig2) => {
+ CubismConfig2.supportMoreMaskDivisions = true;
+ CubismConfig2.setOpacityFromMotion = false;
+ })(CubismConfig || (CubismConfig = {}));
+ exports2.config = void 0;
+ ((config2) => {
+ config2.LOG_LEVEL_VERBOSE = 0;
+ config2.LOG_LEVEL_WARNING = 1;
+ config2.LOG_LEVEL_ERROR = 2;
+ config2.LOG_LEVEL_NONE = 999;
+ config2.logLevel = config2.LOG_LEVEL_WARNING;
+ config2.sound = true;
+ config2.motionSync = true;
+ config2.motionFadingDuration = 500;
+ config2.idleMotionFadingDuration = 2e3;
+ config2.expressionFadingDuration = 500;
+ config2.preserveExpressionOnMotion = true;
+ config2.cubism4 = CubismConfig;
+ })(exports2.config || (exports2.config = {}));
+ const VERSION = "0.4.0";
+ const logger = {
+ log(tag, ...messages) {
+ if (exports2.config.logLevel <= exports2.config.LOG_LEVEL_VERBOSE) {
+ console.log(`[${tag}]`, ...messages);
+ }
+ },
+ warn(tag, ...messages) {
+ if (exports2.config.logLevel <= exports2.config.LOG_LEVEL_WARNING) {
+ console.warn(`[${tag}]`, ...messages);
+ }
+ },
+ error(tag, ...messages) {
+ if (exports2.config.logLevel <= exports2.config.LOG_LEVEL_ERROR) {
+ console.error(`[${tag}]`, ...messages);
+ }
+ }
+ };
+ function clamp(num, lower, upper) {
+ return num < lower ? lower : num > upper ? upper : num;
+ }
+ function rand(min, max) {
+ return Math.random() * (max - min) + min;
+ }
+ function copyProperty(type, from, to, fromKey, toKey) {
+ const value = from[fromKey];
+ if (value !== null && typeof value === type) {
+ to[toKey] = value;
+ }
+ }
+ function copyArray(type, from, to, fromKey, toKey) {
+ const array = from[fromKey];
+ if (Array.isArray(array)) {
+ to[toKey] = array.filter((item) => item !== null && typeof item === type);
+ }
+ }
+ function applyMixins(derivedCtor, baseCtors) {
+ baseCtors.forEach((baseCtor) => {
+ Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
+ if (name !== "constructor") {
+ Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
+ }
+ });
+ });
+ }
+ function folderName(url) {
+ let lastSlashIndex = url.lastIndexOf("/");
+ if (lastSlashIndex != -1) {
+ url = url.slice(0, lastSlashIndex);
+ }
+ lastSlashIndex = url.lastIndexOf("/");
+ if (lastSlashIndex !== -1) {
+ url = url.slice(lastSlashIndex + 1);
+ }
+ return url;
+ }
+ function remove(array, item) {
+ const index = array.indexOf(item);
+ if (index !== -1) {
+ array.splice(index, 1);
+ }
+ }
+ class ExpressionManager extends utils.EventEmitter {
+ constructor(settings, options) {
+ super();
+ this.expressions = [];
+ this.reserveExpressionIndex = -1;
+ this.destroyed = false;
+ this.settings = settings;
+ this.tag = `ExpressionManager(${settings.name})`;
+ }
+ init() {
+ this.defaultExpression = this.createExpression({}, void 0);
+ this.currentExpression = this.defaultExpression;
+ this.stopAllExpressions();
+ }
+ loadExpression(index) {
+ return __async(this, null, function* () {
+ if (!this.definitions[index]) {
+ logger.warn(this.tag, `Undefined expression at [${index}]`);
+ return void 0;
+ }
+ if (this.expressions[index] === null) {
+ logger.warn(this.tag, `Cannot set expression at [${index}] because it's already failed in loading.`);
+ return void 0;
+ }
+ if (this.expressions[index]) {
+ return this.expressions[index];
+ }
+ const expression = yield this._loadExpression(index);
+ this.expressions[index] = expression;
+ return expression;
+ });
+ }
+ _loadExpression(index) {
+ throw new Error("Not implemented.");
+ }
+ setRandomExpression() {
+ return __async(this, null, function* () {
+ if (this.definitions.length) {
+ const availableIndices = [];
+ for (let i = 0; i < this.definitions.length; i++) {
+ if (this.expressions[i] !== null && this.expressions[i] !== this.currentExpression && i !== this.reserveExpressionIndex) {
+ availableIndices.push(i);
+ }
+ }
+ if (availableIndices.length) {
+ const index = Math.floor(Math.random() * availableIndices.length);
+ return this.setExpression(index);
+ }
+ }
+ return false;
+ });
+ }
+ resetExpression() {
+ this._setExpression(this.defaultExpression);
+ }
+ restoreExpression() {
+ this._setExpression(this.currentExpression);
+ }
+ setExpression(index) {
+ return __async(this, null, function* () {
+ if (typeof index !== "number") {
+ index = this.getExpressionIndex(index);
+ }
+ if (!(index > -1 && index < this.definitions.length)) {
+ return false;
+ }
+ if (index === this.expressions.indexOf(this.currentExpression)) {
+ return false;
+ }
+ this.reserveExpressionIndex = index;
+ const expression = yield this.loadExpression(index);
+ if (!expression || this.reserveExpressionIndex !== index) {
+ return false;
+ }
+ this.reserveExpressionIndex = -1;
+ this.currentExpression = expression;
+ this._setExpression(expression);
+ return true;
+ });
+ }
+ update(model, now) {
+ if (!this.isFinished()) {
+ return this.updateParameters(model, now);
+ }
+ return false;
+ }
+ destroy() {
+ this.destroyed = true;
+ this.emit("destroy");
+ const self2 = this;
+ self2.definitions = void 0;
+ self2.expressions = void 0;
+ }
+ }
+ const EPSILON = 0.01;
+ const MAX_SPEED = 40 / 7.5;
+ const ACCELERATION_TIME = 1 / (0.15 * 1e3);
+ class FocusController {
+ constructor() {
+ this.targetX = 0;
+ this.targetY = 0;
+ this.x = 0;
+ this.y = 0;
+ this.vx = 0;
+ this.vy = 0;
+ }
+ focus(x, y, instant = false) {
+ this.targetX = clamp(x, -1, 1);
+ this.targetY = clamp(y, -1, 1);
+ if (instant) {
+ this.x = this.targetX;
+ this.y = this.targetY;
+ }
+ }
+ update(dt) {
+ const dx = this.targetX - this.x;
+ const dy = this.targetY - this.y;
+ if (Math.abs(dx) < EPSILON && Math.abs(dy) < EPSILON)
+ return;
+ const d = Math.sqrt(__pow(dx, 2) + __pow(dy, 2));
+ const maxSpeed = MAX_SPEED / (1e3 / dt);
+ let ax = maxSpeed * (dx / d) - this.vx;
+ let ay = maxSpeed * (dy / d) - this.vy;
+ const a = Math.sqrt(__pow(ax, 2) + __pow(ay, 2));
+ const maxA = maxSpeed * ACCELERATION_TIME * dt;
+ if (a > maxA) {
+ ax *= maxA / a;
+ ay *= maxA / a;
+ }
+ this.vx += ax;
+ this.vy += ay;
+ const v = Math.sqrt(__pow(this.vx, 2) + __pow(this.vy, 2));
+ const maxV = 0.5 * (Math.sqrt(__pow(maxA, 2) + 8 * maxA * d) - maxA);
+ if (v > maxV) {
+ this.vx *= maxV / v;
+ this.vy *= maxV / v;
+ }
+ this.x += this.vx;
+ this.y += this.vy;
+ }
+ }
+ class ModelSettings {
+ constructor(json) {
+ this.json = json;
+ let url2 = json.url;
+ if (typeof url2 !== "string") {
+ throw new TypeError("The `url` field in settings JSON must be defined as a string.");
+ }
+ this.url = url2;
+ this.name = folderName(this.url);
+ }
+ resolveURL(path) {
+ return utils.url.resolve(this.url, path);
+ }
+ replaceFiles(replacer) {
+ this.moc = replacer(this.moc, "moc");
+ if (this.pose !== void 0) {
+ this.pose = replacer(this.pose, "pose");
+ }
+ if (this.physics !== void 0) {
+ this.physics = replacer(this.physics, "physics");
+ }
+ for (let i = 0; i < this.textures.length; i++) {
+ this.textures[i] = replacer(this.textures[i], `textures[${i}]`);
+ }
+ }
+ getDefinedFiles() {
+ const files = [];
+ this.replaceFiles((file) => {
+ files.push(file);
+ return file;
+ });
+ return files;
+ }
+ validateFiles(files) {
+ const assertFileExists = (expectedFile, shouldThrow) => {
+ const actualPath = this.resolveURL(expectedFile);
+ if (!files.includes(actualPath)) {
+ if (shouldThrow) {
+ throw new Error(`File "${expectedFile}" is defined in settings, but doesn't exist in given files`);
+ }
+ return false;
+ }
+ return true;
+ };
+ const essentialFiles = [this.moc, ...this.textures];
+ essentialFiles.forEach((texture) => assertFileExists(texture, true));
+ const definedFiles = this.getDefinedFiles();
+ return definedFiles.filter((file) => assertFileExists(file, false));
+ }
+ }
+ var MotionPriority = /* @__PURE__ */ ((MotionPriority2) => {
+ MotionPriority2[MotionPriority2["NONE"] = 0] = "NONE";
+ MotionPriority2[MotionPriority2["IDLE"] = 1] = "IDLE";
+ MotionPriority2[MotionPriority2["NORMAL"] = 2] = "NORMAL";
+ MotionPriority2[MotionPriority2["FORCE"] = 3] = "FORCE";
+ return MotionPriority2;
+ })(MotionPriority || {});
+ class MotionState {
+ constructor() {
+ this.debug = false;
+ this.currentPriority = 0;
+ this.reservePriority = 0;
+ }
+ reserve(group, index, priority) {
+ if (priority <= 0) {
+ logger.log(this.tag, `Cannot start a motion with MotionPriority.NONE.`);
+ return false;
+ }
+ if (group === this.currentGroup && index === this.currentIndex) {
+ logger.log(this.tag, `Motion is already playing.`, this.dump(group, index));
+ return false;
+ }
+ if (group === this.reservedGroup && index === this.reservedIndex || group === this.reservedIdleGroup && index === this.reservedIdleIndex) {
+ logger.log(this.tag, `Motion is already reserved.`, this.dump(group, index));
+ return false;
+ }
+ if (priority === 1) {
+ if (this.currentPriority !== 0) {
+ logger.log(this.tag, `Cannot start idle motion because another motion is playing.`, this.dump(group, index));
+ return false;
+ }
+ if (this.reservedIdleGroup !== void 0) {
+ logger.log(this.tag, `Cannot start idle motion because another idle motion has reserved.`, this.dump(group, index));
+ return false;
+ }
+ this.setReservedIdle(group, index);
+ } else {
+ if (priority < 3) {
+ if (priority <= this.currentPriority) {
+ logger.log(this.tag, "Cannot start motion because another motion is playing as an equivalent or higher priority.", this.dump(group, index));
+ return false;
+ }
+ if (priority <= this.reservePriority) {
+ logger.log(this.tag, "Cannot start motion because another motion has reserved as an equivalent or higher priority.", this.dump(group, index));
+ return false;
+ }
+ }
+ this.setReserved(group, index, priority);
+ }
+ return true;
+ }
+ start(motion, group, index, priority) {
+ if (priority === 1) {
+ this.setReservedIdle(void 0, void 0);
+ if (this.currentPriority !== 0) {
+ logger.log(this.tag, "Cannot start idle motion because another motion is playing.", this.dump(group, index));
+ return false;
+ }
+ } else {
+ if (group !== this.reservedGroup || index !== this.reservedIndex) {
+ logger.log(this.tag, "Cannot start motion because another motion has taken the place.", this.dump(group, index));
+ return false;
+ }
+ this.setReserved(void 0, void 0, 0);
+ }
+ if (!motion) {
+ return false;
+ }
+ this.setCurrent(group, index, priority);
+ return true;
+ }
+ complete() {
+ this.setCurrent(void 0, void 0, 0);
+ }
+ setCurrent(group, index, priority) {
+ this.currentPriority = priority;
+ this.currentGroup = group;
+ this.currentIndex = index;
+ }
+ setReserved(group, index, priority) {
+ this.reservePriority = priority;
+ this.reservedGroup = group;
+ this.reservedIndex = index;
+ }
+ setReservedIdle(group, index) {
+ this.reservedIdleGroup = group;
+ this.reservedIdleIndex = index;
+ }
+ isActive(group, index) {
+ return group === this.currentGroup && index === this.currentIndex || group === this.reservedGroup && index === this.reservedIndex || group === this.reservedIdleGroup && index === this.reservedIdleIndex;
+ }
+ reset() {
+ this.setCurrent(void 0, void 0, 0);
+ this.setReserved(void 0, void 0, 0);
+ this.setReservedIdle(void 0, void 0);
+ }
+ shouldRequestIdleMotion() {
+ return this.currentGroup === void 0 && this.reservedIdleGroup === void 0;
+ }
+ shouldOverrideExpression() {
+ return !exports2.config.preserveExpressionOnMotion && this.currentPriority > 1;
+ }
+ dump(requestedGroup, requestedIndex) {
+ if (this.debug) {
+ const keys = [
+ "currentPriority",
+ "reservePriority",
+ "currentGroup",
+ "currentIndex",
+ "reservedGroup",
+ "reservedIndex",
+ "reservedIdleGroup",
+ "reservedIdleIndex"
+ ];
+ return `
+ group = "${requestedGroup}", index = ${requestedIndex}
+` + keys.map((key) => "[" + key + "] " + this[key]).join("\n");
+ }
+ return "";
+ }
+ }
+ const TAG$2 = "SoundManager";
+ const VOLUME = 0.9;
+ class SoundManager {
+ static get volume() {
+ return this._volume;
+ }
+ static set volume(value) {
+ this._volume = (value > 1 ? 1 : value < 0 ? 0 : value) || 0;
+ this.audios.forEach((audio) => audio.volume = this._volume);
+ }
+ static add(file, onFinish, onError) {
+ const audio = new Audio(file);
+ audio.volume = this._volume;
+ audio.preload = "auto";
+ audio.autoplay = true;
+ audio.crossOrigin = "anonymous";
+ audio.addEventListener("ended", () => {
+ this.dispose(audio);
+ onFinish == null ? void 0 : onFinish();
+ });
+ audio.addEventListener("error", (e) => {
+ this.dispose(audio);
+ logger.warn(TAG$2, `Error occurred on "${file}"`, e.error);
+ onError == null ? void 0 : onError(e.error);
+ });
+ this.audios.push(audio);
+ return audio;
+ }
+ static play(audio) {
+ return new Promise((resolve, reject) => {
+ var _a;
+ (_a = audio.play()) == null ? void 0 : _a.catch((e) => {
+ audio.dispatchEvent(new ErrorEvent("error", { error: e }));
+ reject(e);
+ });
+ if (audio.readyState === audio.HAVE_ENOUGH_DATA) {
+ resolve();
+ } else {
+ audio.addEventListener("canplaythrough", resolve);
+ }
+ });
+ }
+ static addContext(audio) {
+ const context = new AudioContext();
+ this.contexts.push(context);
+ return context;
+ }
+ static addAnalyzer(audio, context) {
+ const source = context.createMediaElementSource(audio);
+ const analyser = context.createAnalyser();
+ analyser.fftSize = 256;
+ analyser.minDecibels = -90;
+ analyser.maxDecibels = -10;
+ analyser.smoothingTimeConstant = 0.85;
+ source.connect(analyser);
+ analyser.connect(context.destination);
+ this.analysers.push(analyser);
+ return analyser;
+ }
+ static analyze(analyser) {
+ if (analyser != void 0) {
+ let pcmData = new Float32Array(analyser.fftSize);
+ let sumSquares = 0;
+ analyser.getFloatTimeDomainData(pcmData);
+ for (const amplitude of pcmData) {
+ sumSquares += amplitude * amplitude;
+ }
+ return parseFloat(Math.sqrt(sumSquares / pcmData.length * 20).toFixed(1));
+ } else {
+ return parseFloat(Math.random().toFixed(1));
+ }
+ }
+ static dispose(audio) {
+ audio.pause();
+ audio.removeAttribute("src");
+ remove(this.audios, audio);
+ }
+ static destroy() {
+ for (let i = this.contexts.length - 1; i >= 0; i--) {
+ this.contexts[i].close();
+ }
+ for (let i = this.audios.length - 1; i >= 0; i--) {
+ this.dispose(this.audios[i]);
+ }
+ }
+ }
+ SoundManager.audios = [];
+ SoundManager.analysers = [];
+ SoundManager.contexts = [];
+ SoundManager._volume = VOLUME;
+ var MotionPreloadStrategy = /* @__PURE__ */ ((MotionPreloadStrategy2) => {
+ MotionPreloadStrategy2["ALL"] = "ALL";
+ MotionPreloadStrategy2["IDLE"] = "IDLE";
+ MotionPreloadStrategy2["NONE"] = "NONE";
+ return MotionPreloadStrategy2;
+ })(MotionPreloadStrategy || {});
+ class MotionManager extends utils.EventEmitter {
+ constructor(settings, options) {
+ super();
+ this.motionGroups = {};
+ this.state = new MotionState();
+ this.playing = false;
+ this.destroyed = false;
+ this.settings = settings;
+ this.tag = `MotionManager(${settings.name})`;
+ this.state.tag = this.tag;
+ }
+ init(options) {
+ if (options == null ? void 0 : options.idleMotionGroup) {
+ this.groups.idle = options.idleMotionGroup;
+ }
+ this.setupMotions(options);
+ this.stopAllMotions();
+ }
+ setupMotions(options) {
+ for (const group of Object.keys(this.definitions)) {
+ this.motionGroups[group] = [];
+ }
+ let groups;
+ switch (options == null ? void 0 : options.motionPreload) {
+ case "NONE":
+ return;
+ case "ALL":
+ groups = Object.keys(this.definitions);
+ break;
+ case "IDLE":
+ default:
+ groups = [this.groups.idle];
+ break;
+ }
+ for (const group of groups) {
+ if (this.definitions[group]) {
+ for (let i = 0; i < this.definitions[group].length; i++) {
+ this.loadMotion(group, i).then();
+ }
+ }
+ }
+ }
+ loadMotion(group, index) {
+ return __async(this, null, function* () {
+ var _a;
+ if (!((_a = this.definitions[group]) == null ? void 0 : _a[index])) {
+ logger.warn(this.tag, `Undefined motion at "${group}"[${index}]`);
+ return void 0;
+ }
+ if (this.motionGroups[group][index] === null) {
+ logger.warn(this.tag, `Cannot start motion at "${group}"[${index}] because it's already failed in loading.`);
+ return void 0;
+ }
+ if (this.motionGroups[group][index]) {
+ return this.motionGroups[group][index];
+ }
+ const motion = yield this._loadMotion(group, index);
+ if (this.destroyed) {
+ return;
+ }
+ this.motionGroups[group][index] = motion != null ? motion : null;
+ return motion;
+ });
+ }
+ _loadMotion(group, index) {
+ throw new Error("Not implemented.");
+ }
+ speakUp(sound, volume, expression) {
+ return __async(this, null, function* () {
+ if (!exports2.config.sound) {
+ return false;
+ }
+ let audio;
+ let analyzer;
+ let context;
+ if (this.currentAudio) {
+ if (!this.currentAudio.ended) {
+ return false;
+ }
+ }
+ let soundURL;
+ const isBase64Content = sound && sound.startsWith("data:audio/wav;base64");
+ if (sound && !isBase64Content) {
+ var A = document.createElement("a");
+ A.href = sound;
+ sound = A.href;
+ soundURL = sound;
+ } else {
+ soundURL = "data:audio/wav;base64";
+ }
+ const isUrlPath = sound && (sound.startsWith("http") || sound.startsWith("blob"));
+ let file;
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ audio = SoundManager.add(file, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ }, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ });
+ this.currentAudio = audio;
+ let _volume = 1;
+ if (volume !== void 0) {
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+ } catch (e) {
+ logger.warn(this.tag, "Failed to create audio", soundURL, e);
+ }
+ }
+ if (audio) {
+ const readyToPlay = SoundManager.play(audio).catch((e) => logger.warn(this.tag, "Failed to play audio", audio.src, e));
+ if (exports2.config.motionSync) {
+ yield readyToPlay;
+ }
+ }
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ if (expression && this.expressionManager) {
+ this.expressionManager.setExpression(expression);
+ }
+ this.playing = true;
+ return true;
+ });
+ }
+ startMotion(_0, _1) {
+ return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, sound, volume, expression) {
+ var _a;
+ if (this.currentAudio) {
+ if (!this.currentAudio.ended) {
+ return false;
+ }
+ }
+ if (!this.state.reserve(group, index, priority)) {
+ return false;
+ }
+ const definition = (_a = this.definitions[group]) == null ? void 0 : _a[index];
+ if (!definition) {
+ return false;
+ }
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ }
+ let audio;
+ let analyzer;
+ let context;
+ if (exports2.config.sound) {
+ const isBase64Content = sound && sound.startsWith("data:audio/wav;base64");
+ if (sound && !isBase64Content) {
+ var A = document.createElement("a");
+ A.href = sound;
+ sound = A.href;
+ }
+ const isUrlPath = sound && (sound.startsWith("http") || sound.startsWith("blob"));
+ const soundURL = this.getSoundFile(definition);
+ let file = soundURL;
+ if (soundURL) {
+ file = this.settings.resolveURL(soundURL) + "?cache-buster=" + new Date().getTime();
+ }
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ audio = SoundManager.add(file, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ }, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ });
+ this.currentAudio = audio;
+ let _volume = 1;
+ if (volume !== void 0) {
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+ } catch (e) {
+ logger.warn(this.tag, "Failed to create audio", soundURL, e);
+ }
+ }
+ }
+ const motion = yield this.loadMotion(group, index);
+ if (audio) {
+ priority = 3;
+ const readyToPlay = SoundManager.play(audio).catch((e) => logger.warn(this.tag, "Failed to play audio", audio.src, e));
+ if (exports2.config.motionSync) {
+ yield readyToPlay;
+ }
+ }
+ if (!this.state.start(motion, group, index, priority)) {
+ if (audio) {
+ SoundManager.dispose(audio);
+ this.currentAudio = void 0;
+ }
+ return false;
+ }
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ logger.log(this.tag, "Start motion:", this.getMotionName(definition));
+ this.emit("motionStart", group, index, audio);
+ if (expression && this.expressionManager) {
+ this.expressionManager.setExpression(expression);
+ }
+ this.playing = true;
+ this._startMotion(motion);
+ return true;
+ });
+ }
+ startRandomMotion(group, priority, sound, volume) {
+ return __async(this, null, function* () {
+ const groupDefs = this.definitions[group];
+ if (groupDefs == null ? void 0 : groupDefs.length) {
+ const availableIndices = [];
+ for (let i = 0; i < groupDefs.length; i++) {
+ if (this.motionGroups[group][i] !== null && !this.state.isActive(group, i)) {
+ availableIndices.push(i);
+ }
+ }
+ if (availableIndices.length) {
+ const index = availableIndices[Math.floor(Math.random() * availableIndices.length)];
+ return this.startMotion(group, index, priority, sound, volume);
+ }
+ }
+ return false;
+ });
+ }
+ stopSpeaking() {
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ this.currentAudio = void 0;
+ }
+ }
+ stopAllMotions() {
+ this._stopAllMotions();
+ this.state.reset();
+ this.stopSpeaking();
+ }
+ update(model, now) {
+ var _a;
+ if (this.isFinished()) {
+ if (this.playing) {
+ this.playing = false;
+ this.emit("motionFinish");
+ }
+ if (this.state.shouldOverrideExpression()) {
+ (_a = this.expressionManager) == null ? void 0 : _a.restoreExpression();
+ }
+ this.state.complete();
+ if (this.state.shouldRequestIdleMotion()) {
+ this.startRandomMotion(this.groups.idle, MotionPriority.IDLE);
+ }
+ }
+ return this.updateParameters(model, now);
+ }
+ mouthSync() {
+ if (this.currentAnalyzer) {
+ return SoundManager.analyze(this.currentAnalyzer);
+ } else {
+ return 0;
+ }
+ }
+ destroy() {
+ var _a;
+ this.destroyed = true;
+ this.emit("destroy");
+ this.stopAllMotions();
+ (_a = this.expressionManager) == null ? void 0 : _a.destroy();
+ const self2 = this;
+ self2.definitions = void 0;
+ self2.motionGroups = void 0;
+ }
+ }
+ const tempBounds = { x: 0, y: 0, width: 0, height: 0 };
+ class InternalModel extends utils.EventEmitter {
+ constructor() {
+ super(...arguments);
+ this.focusController = new FocusController();
+ this.originalWidth = 0;
+ this.originalHeight = 0;
+ this.width = 0;
+ this.height = 0;
+ this.localTransform = new math.Matrix();
+ this.drawingMatrix = new math.Matrix();
+ this.hitAreas = {};
+ this.textureFlipY = false;
+ this.viewport = [0, 0, 0, 0];
+ this.destroyed = false;
+ }
+ init() {
+ this.setupLayout();
+ this.setupHitAreas();
+ }
+ setupLayout() {
+ const self2 = this;
+ const size = this.getSize();
+ self2.originalWidth = size[0];
+ self2.originalHeight = size[1];
+ const layout = Object.assign({
+ width: LOGICAL_WIDTH,
+ height: LOGICAL_HEIGHT
+ }, this.getLayout());
+ this.localTransform.scale(layout.width / LOGICAL_WIDTH, layout.height / LOGICAL_HEIGHT);
+ self2.width = this.originalWidth * this.localTransform.a;
+ self2.height = this.originalHeight * this.localTransform.d;
+ const offsetX = layout.x !== void 0 && layout.x - layout.width / 2 || layout.centerX !== void 0 && layout.centerX || layout.left !== void 0 && layout.left - layout.width / 2 || layout.right !== void 0 && layout.right + layout.width / 2 || 0;
+ const offsetY = layout.y !== void 0 && layout.y - layout.height / 2 || layout.centerY !== void 0 && layout.centerY || layout.top !== void 0 && layout.top - layout.height / 2 || layout.bottom !== void 0 && layout.bottom + layout.height / 2 || 0;
+ this.localTransform.translate(this.width * offsetX, -this.height * offsetY);
+ }
+ setupHitAreas() {
+ const definitions = this.getHitAreaDefs().filter((hitArea) => hitArea.index >= 0);
+ for (const def of definitions) {
+ this.hitAreas[def.name] = def;
+ }
+ }
+ hitTest(x, y) {
+ return Object.keys(this.hitAreas).filter((hitAreaName) => this.isHit(hitAreaName, x, y));
+ }
+ isHit(hitAreaName, x, y) {
+ if (!this.hitAreas[hitAreaName]) {
+ return false;
+ }
+ const drawIndex = this.hitAreas[hitAreaName].index;
+ const bounds = this.getDrawableBounds(drawIndex, tempBounds);
+ return bounds.x <= x && x <= bounds.x + bounds.width && bounds.y <= y && y <= bounds.y + bounds.height;
+ }
+ getDrawableBounds(index, bounds) {
+ const vertices = this.getDrawableVertices(index);
+ let left = vertices[0];
+ let right = vertices[0];
+ let top = vertices[1];
+ let bottom = vertices[1];
+ for (let i = 0; i < vertices.length; i += 2) {
+ const vx = vertices[i];
+ const vy = vertices[i + 1];
+ left = Math.min(vx, left);
+ right = Math.max(vx, right);
+ top = Math.min(vy, top);
+ bottom = Math.max(vy, bottom);
+ }
+ bounds != null ? bounds : bounds = {};
+ bounds.x = left;
+ bounds.y = top;
+ bounds.width = right - left;
+ bounds.height = bottom - top;
+ return bounds;
+ }
+ updateTransform(transform) {
+ this.drawingMatrix.copyFrom(transform).append(this.localTransform);
+ }
+ update(dt, now) {
+ this.focusController.update(dt);
+ }
+ destroy() {
+ this.destroyed = true;
+ this.emit("destroy");
+ this.motionManager.destroy();
+ this.motionManager = void 0;
+ }
+ }
+ const TAG$1 = "XHRLoader";
+ class NetworkError extends Error {
+ constructor(message, url, status, aborted = false) {
+ super(message);
+ this.url = url;
+ this.status = status;
+ this.aborted = aborted;
+ }
+ }
+ const _XHRLoader = class {
+ static createXHR(target, url, type, onload, onerror) {
+ const xhr = new XMLHttpRequest();
+ _XHRLoader.allXhrSet.add(xhr);
+ if (target) {
+ let xhrSet = _XHRLoader.xhrMap.get(target);
+ if (!xhrSet) {
+ xhrSet = /* @__PURE__ */ new Set([xhr]);
+ _XHRLoader.xhrMap.set(target, xhrSet);
+ } else {
+ xhrSet.add(xhr);
+ }
+ if (!target.listeners("destroy").includes(_XHRLoader.cancelXHRs)) {
+ target.once("destroy", _XHRLoader.cancelXHRs);
+ }
+ }
+ xhr.open("GET", url);
+ xhr.responseType = type;
+ xhr.onload = () => {
+ if ((xhr.status === 200 || xhr.status === 0) && xhr.response) {
+ onload(xhr.response);
+ } else {
+ xhr.onerror();
+ }
+ };
+ xhr.onerror = () => {
+ logger.warn(TAG$1, `Failed to load resource as ${xhr.responseType} (Status ${xhr.status}): ${url}`);
+ onerror(new NetworkError("Network error.", url, xhr.status));
+ };
+ xhr.onabort = () => onerror(new NetworkError("Aborted.", url, xhr.status, true));
+ xhr.onloadend = () => {
+ var _a;
+ _XHRLoader.allXhrSet.delete(xhr);
+ if (target) {
+ (_a = _XHRLoader.xhrMap.get(target)) == null ? void 0 : _a.delete(xhr);
+ }
+ };
+ return xhr;
+ }
+ static cancelXHRs() {
+ var _a;
+ (_a = _XHRLoader.xhrMap.get(this)) == null ? void 0 : _a.forEach((xhr) => {
+ xhr.abort();
+ _XHRLoader.allXhrSet.delete(xhr);
+ });
+ _XHRLoader.xhrMap.delete(this);
+ }
+ static release() {
+ _XHRLoader.allXhrSet.forEach((xhr) => xhr.abort());
+ _XHRLoader.allXhrSet.clear();
+ _XHRLoader.xhrMap = /* @__PURE__ */ new WeakMap();
+ }
+ };
+ let XHRLoader = _XHRLoader;
+ XHRLoader.xhrMap = /* @__PURE__ */ new WeakMap();
+ XHRLoader.allXhrSet = /* @__PURE__ */ new Set();
+ XHRLoader.loader = (context, next) => {
+ return new Promise((resolve, reject) => {
+ const xhr = _XHRLoader.createXHR(context.target, context.settings ? context.settings.resolveURL(context.url) : context.url, context.type, (data) => {
+ context.result = data;
+ resolve();
+ }, reject);
+ xhr.send();
+ });
+ };
+ function runMiddlewares(middleware, context) {
+ let index = -1;
+ return dispatch(0);
+ function dispatch(i, err) {
+ if (err)
+ return Promise.reject(err);
+ if (i <= index)
+ return Promise.reject(new Error("next() called multiple times"));
+ index = i;
+ const fn = middleware[i];
+ if (!fn)
+ return Promise.resolve();
+ try {
+ return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
+ } catch (err2) {
+ return Promise.reject(err2);
+ }
+ }
+ }
+ class Live2DLoader {
+ static load(context) {
+ return runMiddlewares(this.middlewares, context).then(() => context.result);
+ }
+ }
+ Live2DLoader.middlewares = [XHRLoader.loader];
+ function createTexture(url, options = {}) {
+ var _a;
+ const textureOptions = { resourceOptions: { crossorigin: options.crossOrigin } };
+ if (core.Texture.fromURL) {
+ return core.Texture.fromURL(url, textureOptions).catch((e) => {
+ if (e instanceof Error) {
+ throw e;
+ }
+ const err = new Error("Texture loading error");
+ err.event = e;
+ throw err;
+ });
+ }
+ textureOptions.resourceOptions.autoLoad = false;
+ const texture = core.Texture.from(url, textureOptions);
+ if (texture.baseTexture.valid) {
+ return Promise.resolve(texture);
+ }
+ const resource = texture.baseTexture.resource;
+ (_a = resource._live2d_load) != null ? _a : resource._live2d_load = new Promise((resolve, reject) => {
+ const errorHandler = (event) => {
+ resource.source.removeEventListener("error", errorHandler);
+ const err = new Error("Texture loading error");
+ err.event = event;
+ reject(err);
+ };
+ resource.source.addEventListener("error", errorHandler);
+ resource.load().then(() => resolve(texture)).catch(errorHandler);
+ });
+ return resource._live2d_load;
+ }
+ const TAG = "Live2DFactory";
+ const urlToJSON = (context, next) => __async(this, null, function* () {
+ if (typeof context.source === "string") {
+ const data = yield Live2DLoader.load({
+ url: context.source,
+ type: "json",
+ target: context.live2dModel
+ });
+ data.url = context.source;
+ context.source = data;
+ context.live2dModel.emit("settingsJSONLoaded", data);
+ }
+ return next();
+ });
+ const jsonToSettings = (context, next) => __async(this, null, function* () {
+ if (context.source instanceof ModelSettings) {
+ context.settings = context.source;
+ return next();
+ } else if (typeof context.source === "object") {
+ const runtime = Live2DFactory.findRuntime(context.source);
+ if (runtime) {
+ const settings = runtime.createModelSettings(context.source);
+ context.settings = settings;
+ context.live2dModel.emit("settingsLoaded", settings);
+ return next();
+ }
+ }
+ throw new TypeError("Unknown settings format.");
+ });
+ const waitUntilReady = (context, next) => {
+ if (context.settings) {
+ const runtime = Live2DFactory.findRuntime(context.settings);
+ if (runtime) {
+ return runtime.ready().then(next);
+ }
+ }
+ return next();
+ };
+ const setupOptionals = (context, next) => __async(this, null, function* () {
+ yield next();
+ const internalModel = context.internalModel;
+ if (internalModel) {
+ const settings = context.settings;
+ const runtime = Live2DFactory.findRuntime(settings);
+ if (runtime) {
+ const tasks = [];
+ if (settings.pose) {
+ tasks.push(Live2DLoader.load({
+ settings,
+ url: settings.pose,
+ type: "json",
+ target: internalModel
+ }).then((data) => {
+ internalModel.pose = runtime.createPose(internalModel.coreModel, data);
+ context.live2dModel.emit("poseLoaded", internalModel.pose);
+ }).catch((e) => {
+ context.live2dModel.emit("poseLoadError", e);
+ logger.warn(TAG, "Failed to load pose.", e);
+ }));
+ }
+ if (settings.physics) {
+ tasks.push(Live2DLoader.load({
+ settings,
+ url: settings.physics,
+ type: "json",
+ target: internalModel
+ }).then((data) => {
+ internalModel.physics = runtime.createPhysics(internalModel.coreModel, data);
+ context.live2dModel.emit("physicsLoaded", internalModel.physics);
+ }).catch((e) => {
+ context.live2dModel.emit("physicsLoadError", e);
+ logger.warn(TAG, "Failed to load physics.", e);
+ }));
+ }
+ if (tasks.length) {
+ yield Promise.all(tasks);
+ }
+ }
+ }
+ });
+ const setupEssentials = (context, next) => __async(this, null, function* () {
+ if (context.settings) {
+ const live2DModel = context.live2dModel;
+ const textureLoadings = context.settings.textures.map((tex) => {
+ const url = context.settings.resolveURL(tex);
+ return createTexture(url, { crossOrigin: context.options.crossOrigin });
+ });
+ yield next();
+ if (context.internalModel) {
+ live2DModel.internalModel = context.internalModel;
+ live2DModel.emit("modelLoaded", context.internalModel);
+ } else {
+ throw new TypeError("Missing internal model.");
+ }
+ live2DModel.textures = yield Promise.all(textureLoadings);
+ live2DModel.emit("textureLoaded", live2DModel.textures);
+ } else {
+ throw new TypeError("Missing settings.");
+ }
+ });
+ const createInternalModel = (context, next) => __async(this, null, function* () {
+ const settings = context.settings;
+ if (settings instanceof ModelSettings) {
+ const runtime = Live2DFactory.findRuntime(settings);
+ if (!runtime) {
+ throw new TypeError("Unknown model settings.");
+ }
+ const modelData = yield Live2DLoader.load({
+ settings,
+ url: settings.moc,
+ type: "arraybuffer",
+ target: context.live2dModel
+ });
+ if (!runtime.isValidMoc(modelData)) {
+ throw new Error("Invalid moc data");
+ }
+ const coreModel = runtime.createCoreModel(modelData);
+ context.internalModel = runtime.createInternalModel(coreModel, settings, context.options);
+ return next();
+ }
+ throw new TypeError("Missing settings.");
+ });
+ const _Live2DFactory = class {
+ static registerRuntime(runtime) {
+ _Live2DFactory.runtimes.push(runtime);
+ _Live2DFactory.runtimes.sort((a, b) => b.version - a.version);
+ }
+ static findRuntime(source) {
+ for (const runtime of _Live2DFactory.runtimes) {
+ if (runtime.test(source)) {
+ return runtime;
+ }
+ }
+ }
+ static setupLive2DModel(live2dModel, source, options) {
+ return __async(this, null, function* () {
+ const textureLoaded = new Promise((resolve) => live2dModel.once("textureLoaded", resolve));
+ const modelLoaded = new Promise((resolve) => live2dModel.once("modelLoaded", resolve));
+ const readyEventEmitted = Promise.all([textureLoaded, modelLoaded]).then(() => live2dModel.emit("ready"));
+ yield runMiddlewares(_Live2DFactory.live2DModelMiddlewares, {
+ live2dModel,
+ source,
+ options: options || {}
+ });
+ yield readyEventEmitted;
+ live2dModel.emit("load");
+ });
+ }
+ static loadMotion(motionManager, group, index) {
+ var _a, _b;
+ const handleError = (e) => motionManager.emit("motionLoadError", group, index, e);
+ try {
+ const definition = (_a = motionManager.definitions[group]) == null ? void 0 : _a[index];
+ if (!definition) {
+ return Promise.resolve(void 0);
+ }
+ if (!motionManager.listeners("destroy").includes(_Live2DFactory.releaseTasks)) {
+ motionManager.once("destroy", _Live2DFactory.releaseTasks);
+ }
+ let tasks = _Live2DFactory.motionTasksMap.get(motionManager);
+ if (!tasks) {
+ tasks = {};
+ _Live2DFactory.motionTasksMap.set(motionManager, tasks);
+ }
+ let taskGroup = tasks[group];
+ if (!taskGroup) {
+ taskGroup = [];
+ tasks[group] = taskGroup;
+ }
+ const path = motionManager.getMotionFile(definition);
+ (_b = taskGroup[index]) != null ? _b : taskGroup[index] = Live2DLoader.load({
+ url: path,
+ settings: motionManager.settings,
+ type: motionManager.motionDataType,
+ target: motionManager
+ }).then((data) => {
+ var _a2;
+ const taskGroup2 = (_a2 = _Live2DFactory.motionTasksMap.get(motionManager)) == null ? void 0 : _a2[group];
+ if (taskGroup2) {
+ delete taskGroup2[index];
+ }
+ const motion = motionManager.createMotion(data, group, definition);
+ motionManager.emit("motionLoaded", group, index, motion);
+ return motion;
+ }).catch((e) => {
+ logger.warn(motionManager.tag, `Failed to load motion: ${path}
+`, e);
+ handleError(e);
+ });
+ return taskGroup[index];
+ } catch (e) {
+ logger.warn(motionManager.tag, `Failed to load motion at "${group}"[${index}]
+`, e);
+ handleError(e);
+ }
+ return Promise.resolve(void 0);
+ }
+ static loadExpression(expressionManager, index) {
+ var _a;
+ const handleError = (e) => expressionManager.emit("expressionLoadError", index, e);
+ try {
+ const definition = expressionManager.definitions[index];
+ if (!definition) {
+ return Promise.resolve(void 0);
+ }
+ if (!expressionManager.listeners("destroy").includes(_Live2DFactory.releaseTasks)) {
+ expressionManager.once("destroy", _Live2DFactory.releaseTasks);
+ }
+ let tasks = _Live2DFactory.expressionTasksMap.get(expressionManager);
+ if (!tasks) {
+ tasks = [];
+ _Live2DFactory.expressionTasksMap.set(expressionManager, tasks);
+ }
+ const path = expressionManager.getExpressionFile(definition);
+ (_a = tasks[index]) != null ? _a : tasks[index] = Live2DLoader.load({
+ url: path,
+ settings: expressionManager.settings,
+ type: "json",
+ target: expressionManager
+ }).then((data) => {
+ const tasks2 = _Live2DFactory.expressionTasksMap.get(expressionManager);
+ if (tasks2) {
+ delete tasks2[index];
+ }
+ const expression = expressionManager.createExpression(data, definition);
+ expressionManager.emit("expressionLoaded", index, expression);
+ return expression;
+ }).catch((e) => {
+ logger.warn(expressionManager.tag, `Failed to load expression: ${path}
+`, e);
+ handleError(e);
+ });
+ return tasks[index];
+ } catch (e) {
+ logger.warn(expressionManager.tag, `Failed to load expression at [${index}]
+`, e);
+ handleError(e);
+ }
+ return Promise.resolve(void 0);
+ }
+ static releaseTasks() {
+ if (this instanceof MotionManager) {
+ _Live2DFactory.motionTasksMap.delete(this);
+ } else {
+ _Live2DFactory.expressionTasksMap.delete(this);
+ }
+ }
+ };
+ let Live2DFactory = _Live2DFactory;
+ Live2DFactory.runtimes = [];
+ Live2DFactory.urlToJSON = urlToJSON;
+ Live2DFactory.jsonToSettings = jsonToSettings;
+ Live2DFactory.waitUntilReady = waitUntilReady;
+ Live2DFactory.setupOptionals = setupOptionals;
+ Live2DFactory.setupEssentials = setupEssentials;
+ Live2DFactory.createInternalModel = createInternalModel;
+ Live2DFactory.live2DModelMiddlewares = [
+ urlToJSON,
+ jsonToSettings,
+ waitUntilReady,
+ setupOptionals,
+ setupEssentials,
+ createInternalModel
+ ];
+ Live2DFactory.motionTasksMap = /* @__PURE__ */ new WeakMap();
+ Live2DFactory.expressionTasksMap = /* @__PURE__ */ new WeakMap();
+ MotionManager.prototype["_loadMotion"] = function(group, index) {
+ return Live2DFactory.loadMotion(this, group, index);
+ };
+ ExpressionManager.prototype["_loadExpression"] = function(index) {
+ return Live2DFactory.loadExpression(this, index);
+ };
+ class InteractionMixin {
+ constructor() {
+ this._autoInteract = false;
+ }
+ get autoInteract() {
+ return this._autoInteract;
+ }
+ set autoInteract(autoInteract) {
+ if (autoInteract !== this._autoInteract) {
+ if (autoInteract) {
+ this.on("pointertap", onTap, this);
+ } else {
+ this.off("pointertap", onTap, this);
+ }
+ this._autoInteract = autoInteract;
+ }
+ }
+ registerInteraction(manager) {
+ if (manager !== this.interactionManager) {
+ this.unregisterInteraction();
+ if (this._autoInteract && manager) {
+ this.interactionManager = manager;
+ manager.on("pointermove", onPointerMove, this);
+ }
+ }
+ }
+ unregisterInteraction() {
+ var _a;
+ if (this.interactionManager) {
+ (_a = this.interactionManager) == null ? void 0 : _a.off("pointermove", onPointerMove, this);
+ this.interactionManager = void 0;
+ }
+ }
+ }
+ function onTap(event) {
+ this.tap(event.data.global.x, event.data.global.y);
+ }
+ function onPointerMove(event) {
+ this.focus(event.data.global.x, event.data.global.y);
+ }
+ class Live2DTransform extends math.Transform {
+ }
+ const tempPoint = new math.Point();
+ const tempMatrix = new math.Matrix();
+ let tickerRef;
+ class Live2DModel extends display.Container {
+ constructor(options) {
+ super();
+ this.tag = "Live2DModel(uninitialized)";
+ this.textures = [];
+ this.transform = new Live2DTransform();
+ this.anchor = new math.ObservablePoint(this.onAnchorChange, this, 0, 0);
+ this.glContextID = -1;
+ this.elapsedTime = performance.now();
+ this.deltaTime = 0;
+ this._autoUpdate = false;
+ this.once("modelLoaded", () => this.init(options));
+ }
+ static from(source, options) {
+ const model = new this(options);
+ return Live2DFactory.setupLive2DModel(model, source, options).then(() => model);
+ }
+ static fromSync(source, options) {
+ const model = new this(options);
+ Live2DFactory.setupLive2DModel(model, source, options).then(options == null ? void 0 : options.onLoad).catch(options == null ? void 0 : options.onError);
+ return model;
+ }
+ static registerTicker(tickerClass) {
+ tickerRef = tickerClass;
+ }
+ get autoUpdate() {
+ return this._autoUpdate;
+ }
+ set autoUpdate(autoUpdate) {
+ var _a;
+ tickerRef || (tickerRef = (_a = window.PIXI) == null ? void 0 : _a.Ticker);
+ if (autoUpdate) {
+ if (!this._destroyed) {
+ if (tickerRef) {
+ tickerRef.shared.add(this.onTickerUpdate, this);
+ this._autoUpdate = true;
+ } else {
+ logger.warn(this.tag, "No Ticker registered, please call Live2DModel.registerTicker(Ticker).");
+ }
+ }
+ } else {
+ tickerRef == null ? void 0 : tickerRef.shared.remove(this.onTickerUpdate, this);
+ this._autoUpdate = false;
+ }
+ }
+ init(options) {
+ this.tag = `Live2DModel(${this.internalModel.settings.name})`;
+ const _options = Object.assign({
+ autoUpdate: true,
+ autoInteract: true
+ }, options);
+ if (_options.autoInteract) {
+ this.interactive = true;
+ }
+ this.autoInteract = _options.autoInteract;
+ this.autoUpdate = _options.autoUpdate;
+ }
+ onAnchorChange() {
+ this.pivot.set(this.anchor.x * this.internalModel.width, this.anchor.y * this.internalModel.height);
+ }
+ motion(group, index, priority, sound, volume, expression) {
+ return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority) : this.internalModel.motionManager.startMotion(group, index, priority, sound, volume, expression);
+ }
+ resetMotions() {
+ return this.internalModel.motionManager.stopAllMotions();
+ }
+ speak(sound, volume, expression) {
+ return this.internalModel.motionManager.speakUp(sound, volume, expression);
+ }
+ stopSpeaking() {
+ return this.internalModel.motionManager.stopSpeaking();
+ }
+ expression(id) {
+ if (this.internalModel.motionManager.expressionManager) {
+ return id === void 0 ? this.internalModel.motionManager.expressionManager.setRandomExpression() : this.internalModel.motionManager.expressionManager.setExpression(id);
+ }
+ return Promise.resolve(false);
+ }
+ focus(x, y, instant = false) {
+ tempPoint.x = x;
+ tempPoint.y = y;
+ this.toModelPosition(tempPoint, tempPoint, true);
+ let tx = tempPoint.x / this.internalModel.originalWidth * 2 - 1;
+ let ty = tempPoint.y / this.internalModel.originalHeight * 2 - 1;
+ let radian = Math.atan2(ty, tx);
+ this.internalModel.focusController.focus(Math.cos(radian), -Math.sin(radian), instant);
+ }
+ tap(x, y) {
+ const hitAreaNames = this.hitTest(x, y);
+ if (hitAreaNames.length) {
+ logger.log(this.tag, `Hit`, hitAreaNames);
+ this.emit("hit", hitAreaNames);
+ }
+ }
+ hitTest(x, y) {
+ tempPoint.x = x;
+ tempPoint.y = y;
+ this.toModelPosition(tempPoint, tempPoint);
+ return this.internalModel.hitTest(tempPoint.x, tempPoint.y);
+ }
+ toModelPosition(position, result = position.clone(), skipUpdate) {
+ if (!skipUpdate) {
+ this._recursivePostUpdateTransform();
+ if (!this.parent) {
+ this.parent = this._tempDisplayObjectParent;
+ this.displayObjectUpdateTransform();
+ this.parent = null;
+ } else {
+ this.displayObjectUpdateTransform();
+ }
+ }
+ this.transform.worldTransform.applyInverse(position, result);
+ this.internalModel.localTransform.applyInverse(result, result);
+ return result;
+ }
+ containsPoint(point) {
+ return this.getBounds(true).contains(point.x, point.y);
+ }
+ _calculateBounds() {
+ this._bounds.addFrame(this.transform, 0, 0, this.internalModel.width, this.internalModel.height);
+ }
+ onTickerUpdate() {
+ this.update(tickerRef.shared.deltaMS);
+ }
+ update(dt) {
+ this.deltaTime += dt;
+ this.elapsedTime += dt;
+ }
+ _render(renderer) {
+ this.registerInteraction(renderer.plugins.interaction);
+ renderer.batch.reset();
+ renderer.geometry.reset();
+ renderer.shader.reset();
+ renderer.state.reset();
+ let shouldUpdateTexture = false;
+ if (this.glContextID !== renderer.CONTEXT_UID) {
+ this.glContextID = renderer.CONTEXT_UID;
+ this.internalModel.updateWebGLContext(renderer.gl, this.glContextID);
+ shouldUpdateTexture = true;
+ }
+ for (let i = 0; i < this.textures.length; i++) {
+ const texture = this.textures[i];
+ if (!texture.valid) {
+ continue;
+ }
+ if (shouldUpdateTexture || !texture.baseTexture._glTextures[this.glContextID]) {
+ renderer.gl.pixelStorei(WebGLRenderingContext.UNPACK_FLIP_Y_WEBGL, this.internalModel.textureFlipY);
+ renderer.texture.bind(texture.baseTexture, 0);
+ }
+ this.internalModel.bindTexture(i, texture.baseTexture._glTextures[this.glContextID].texture);
+ texture.baseTexture.touched = renderer.textureGC.count;
+ }
+ const viewport = renderer.framebuffer.viewport;
+ this.internalModel.viewport = [viewport.x, viewport.y, viewport.width, viewport.height];
+ if (this.deltaTime) {
+ this.internalModel.update(this.deltaTime, this.elapsedTime);
+ this.deltaTime = 0;
+ }
+ const internalTransform = tempMatrix.copyFrom(renderer.globalUniforms.uniforms.projectionMatrix).append(this.worldTransform);
+ this.internalModel.updateTransform(internalTransform);
+ this.internalModel.draw(renderer.gl);
+ renderer.state.reset();
+ renderer.texture.reset();
+ }
+ destroy(options) {
+ this.emit("destroy");
+ this.autoUpdate = false;
+ this.unregisterInteraction();
+ if (options == null ? void 0 : options.texture) {
+ this.textures.forEach((texture) => texture.destroy(options.baseTexture));
+ }
+ this.internalModel.destroy();
+ super.destroy(options);
+ }
+ }
+ applyMixins(Live2DModel, [InteractionMixin]);
+ const _FileLoader = class {
+ static resolveURL(settingsURL, filePath) {
+ var _a;
+ const resolved = (_a = _FileLoader.filesMap[settingsURL]) == null ? void 0 : _a[filePath];
+ if (resolved === void 0) {
+ throw new Error("Cannot find this file from uploaded files: " + filePath);
+ }
+ return resolved;
+ }
+ static upload(files, settings) {
+ return __async(this, null, function* () {
+ const fileMap = {};
+ for (const definedFile of settings.getDefinedFiles()) {
+ const actualPath = decodeURI(utils.url.resolve(settings.url, definedFile));
+ const actualFile = files.find((file) => file.webkitRelativePath === actualPath);
+ if (actualFile) {
+ fileMap[definedFile] = URL.createObjectURL(actualFile);
+ }
+ }
+ _FileLoader.filesMap[settings._objectURL] = fileMap;
+ });
+ }
+ static createSettings(files) {
+ return __async(this, null, function* () {
+ const settingsFile = files.find((file) => file.name.endsWith("model.json") || file.name.endsWith("model3.json"));
+ if (!settingsFile) {
+ throw new TypeError("Settings file not found");
+ }
+ const settingsText = yield _FileLoader.readText(settingsFile);
+ const settingsJSON = JSON.parse(settingsText);
+ settingsJSON.url = settingsFile.webkitRelativePath;
+ const runtime = Live2DFactory.findRuntime(settingsJSON);
+ if (!runtime) {
+ throw new Error("Unknown settings JSON");
+ }
+ const settings = runtime.createModelSettings(settingsJSON);
+ settings._objectURL = URL.createObjectURL(settingsFile);
+ return settings;
+ });
+ }
+ static readText(file) {
+ return __async(this, null, function* () {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = () => resolve(reader.result);
+ reader.onerror = reject;
+ reader.readAsText(file, "utf8");
+ });
+ });
+ }
+ };
+ let FileLoader = _FileLoader;
+ FileLoader.filesMap = {};
+ FileLoader.factory = (context, next) => __async(this, null, function* () {
+ if (Array.isArray(context.source) && context.source[0] instanceof File) {
+ const files = context.source;
+ let settings = files.settings;
+ if (!settings) {
+ settings = yield _FileLoader.createSettings(files);
+ } else if (!settings._objectURL) {
+ throw new Error('"_objectURL" must be specified in ModelSettings');
+ }
+ settings.validateFiles(files.map((file) => encodeURI(file.webkitRelativePath)));
+ yield _FileLoader.upload(files, settings);
+ settings.resolveURL = function(url) {
+ return _FileLoader.resolveURL(this._objectURL, url);
+ };
+ context.source = settings;
+ context.live2dModel.once("modelLoaded", (internalModel) => {
+ internalModel.once("destroy", function() {
+ const objectURL = this.settings._objectURL;
+ URL.revokeObjectURL(objectURL);
+ if (_FileLoader.filesMap[objectURL]) {
+ for (const resourceObjectURL of Object.values(_FileLoader.filesMap[objectURL])) {
+ URL.revokeObjectURL(resourceObjectURL);
+ }
+ }
+ delete _FileLoader.filesMap[objectURL];
+ });
+ });
+ }
+ return next();
+ });
+ Live2DFactory.live2DModelMiddlewares.unshift(FileLoader.factory);
+ const _ZipLoader = class {
+ static unzip(reader, settings) {
+ return __async(this, null, function* () {
+ const filePaths = yield _ZipLoader.getFilePaths(reader);
+ const requiredFilePaths = [];
+ for (const definedFile of settings.getDefinedFiles()) {
+ const actualPath = decodeURI(utils.url.resolve(settings.url, definedFile));
+ if (filePaths.includes(actualPath)) {
+ requiredFilePaths.push(actualPath);
+ }
+ }
+ const files = yield _ZipLoader.getFiles(reader, requiredFilePaths);
+ for (let i = 0; i < files.length; i++) {
+ const path = requiredFilePaths[i];
+ const file = files[i];
+ Object.defineProperty(file, "webkitRelativePath", {
+ value: path
+ });
+ }
+ return files;
+ });
+ }
+ static createSettings(reader) {
+ return __async(this, null, function* () {
+ const filePaths = yield _ZipLoader.getFilePaths(reader);
+ const settingsFilePath = filePaths.find((path) => path.endsWith("model.json") || path.endsWith("model3.json"));
+ if (!settingsFilePath) {
+ throw new Error("Settings file not found");
+ }
+ const settingsText = yield _ZipLoader.readText(reader, settingsFilePath);
+ if (!settingsText) {
+ throw new Error("Empty settings file: " + settingsFilePath);
+ }
+ const settingsJSON = JSON.parse(settingsText);
+ settingsJSON.url = settingsFilePath;
+ const runtime = Live2DFactory.findRuntime(settingsJSON);
+ if (!runtime) {
+ throw new Error("Unknown settings JSON");
+ }
+ return runtime.createModelSettings(settingsJSON);
+ });
+ }
+ static zipReader(data, url) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static getFilePaths(reader) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static getFiles(reader, paths) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static readText(reader, path) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static releaseReader(reader) {
+ }
+ };
+ let ZipLoader = _ZipLoader;
+ ZipLoader.ZIP_PROTOCOL = "zip://";
+ ZipLoader.uid = 0;
+ ZipLoader.factory = (context, next) => __async(this, null, function* () {
+ const source = context.source;
+ let sourceURL;
+ let zipBlob;
+ let settings;
+ if (typeof source === "string" && (source.endsWith(".zip") || source.startsWith(_ZipLoader.ZIP_PROTOCOL))) {
+ if (source.startsWith(_ZipLoader.ZIP_PROTOCOL)) {
+ sourceURL = source.slice(_ZipLoader.ZIP_PROTOCOL.length);
+ } else {
+ sourceURL = source;
+ }
+ zipBlob = yield Live2DLoader.load({
+ url: sourceURL,
+ type: "blob",
+ target: context.live2dModel
+ });
+ } else if (Array.isArray(source) && source.length === 1 && source[0] instanceof File && source[0].name.endsWith(".zip")) {
+ zipBlob = source[0];
+ sourceURL = URL.createObjectURL(zipBlob);
+ settings = source.settings;
+ }
+ if (zipBlob) {
+ if (!zipBlob.size) {
+ throw new Error("Empty zip file");
+ }
+ const reader = yield _ZipLoader.zipReader(zipBlob, sourceURL);
+ if (!settings) {
+ settings = yield _ZipLoader.createSettings(reader);
+ }
+ settings._objectURL = _ZipLoader.ZIP_PROTOCOL + _ZipLoader.uid + "/" + settings.url;
+ const files = yield _ZipLoader.unzip(reader, settings);
+ files.settings = settings;
+ context.source = files;
+ if (sourceURL.startsWith("blob:")) {
+ context.live2dModel.once("modelLoaded", (internalModel) => {
+ internalModel.once("destroy", function() {
+ URL.revokeObjectURL(sourceURL);
+ });
+ });
+ }
+ _ZipLoader.releaseReader(reader);
+ }
+ return next();
+ });
+ Live2DFactory.live2DModelMiddlewares.unshift(ZipLoader.factory);
+ if (!window.Live2D) {
+ throw new Error("Could not find Cubism 2 runtime. This plugin requires live2d.min.js to be loaded.");
+ }
+ const originalUpdateParam = Live2DMotion.prototype.updateParam;
+ Live2DMotion.prototype.updateParam = function(model, entry) {
+ originalUpdateParam.call(this, model, entry);
+ if (entry.isFinished() && this.onFinishHandler) {
+ this.onFinishHandler(this);
+ delete this.onFinishHandler;
+ }
+ };
+ class Live2DExpression extends AMotion {
+ constructor(json) {
+ super();
+ this.params = [];
+ this.setFadeIn(json.fade_in > 0 ? json.fade_in : exports2.config.expressionFadingDuration);
+ this.setFadeOut(json.fade_out > 0 ? json.fade_out : exports2.config.expressionFadingDuration);
+ if (Array.isArray(json.params)) {
+ json.params.forEach((param) => {
+ const calc = param.calc || "add";
+ if (calc === "add") {
+ const defaultValue = param.def || 0;
+ param.val -= defaultValue;
+ } else if (calc === "mult") {
+ const defaultValue = param.def || 1;
+ param.val /= defaultValue;
+ }
+ this.params.push({
+ calc,
+ val: param.val,
+ id: param.id
+ });
+ });
+ }
+ }
+ updateParamExe(model, time, weight, motionQueueEnt) {
+ this.params.forEach((param) => {
+ model.setParamFloat(param.id, param.val * weight);
+ });
+ }
+ }
+ class Cubism2ExpressionManager extends ExpressionManager {
+ constructor(settings, options) {
+ var _a;
+ super(settings, options);
+ this.queueManager = new MotionQueueManager();
+ this.definitions = (_a = this.settings.expressions) != null ? _a : [];
+ this.init();
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ getExpressionIndex(name) {
+ return this.definitions.findIndex((def) => def.name === name);
+ }
+ getExpressionFile(definition) {
+ return definition.file;
+ }
+ createExpression(data, definition) {
+ return new Live2DExpression(data);
+ }
+ _setExpression(motion) {
+ return this.queueManager.startMotion(motion);
+ }
+ stopAllExpressions() {
+ this.queueManager.stopAllMotions();
+ }
+ updateParameters(model, dt) {
+ return this.queueManager.updateParam(model);
+ }
+ }
+ class Cubism2MotionManager extends MotionManager {
+ constructor(settings, options) {
+ super(settings, options);
+ this.groups = { idle: "idle" };
+ this.motionDataType = "arraybuffer";
+ this.queueManager = new MotionQueueManager();
+ this.definitions = this.settings.motions;
+ this.init(options);
+ }
+ init(options) {
+ super.init(options);
+ if (this.settings.expressions) {
+ this.expressionManager = new Cubism2ExpressionManager(this.settings, options);
+ }
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ createMotion(data, group, definition) {
+ const motion = Live2DMotion.loadMotion(data);
+ const defaultFadingDuration = group === this.groups.idle ? exports2.config.idleMotionFadingDuration : exports2.config.motionFadingDuration;
+ motion.setFadeIn(definition.fade_in > 0 ? definition.fade_in : defaultFadingDuration);
+ motion.setFadeOut(definition.fade_out > 0 ? definition.fade_out : defaultFadingDuration);
+ return motion;
+ }
+ getMotionFile(definition) {
+ return definition.file;
+ }
+ getMotionName(definition) {
+ return definition.file;
+ }
+ getSoundFile(definition) {
+ return definition.sound;
+ }
+ _startMotion(motion, onFinish) {
+ motion.onFinishHandler = onFinish;
+ this.queueManager.stopAllMotions();
+ return this.queueManager.startMotion(motion);
+ }
+ _stopAllMotions() {
+ this.queueManager.stopAllMotions();
+ }
+ updateParameters(model, now) {
+ return this.queueManager.updateParam(model);
+ }
+ destroy() {
+ super.destroy();
+ this.queueManager = void 0;
+ }
+ }
+ class Live2DEyeBlink {
+ constructor(coreModel) {
+ this.coreModel = coreModel;
+ this.blinkInterval = 4e3;
+ this.closingDuration = 100;
+ this.closedDuration = 50;
+ this.openingDuration = 150;
+ this.eyeState = 0;
+ this.eyeParamValue = 1;
+ this.closedTimer = 0;
+ this.nextBlinkTimeLeft = this.blinkInterval;
+ this.leftParam = coreModel.getParamIndex("PARAM_EYE_L_OPEN");
+ this.rightParam = coreModel.getParamIndex("PARAM_EYE_R_OPEN");
+ }
+ setEyeParams(value) {
+ this.eyeParamValue = clamp(value, 0, 1);
+ this.coreModel.setParamFloat(this.leftParam, this.eyeParamValue);
+ this.coreModel.setParamFloat(this.rightParam, this.eyeParamValue);
+ }
+ update(dt) {
+ switch (this.eyeState) {
+ case 0:
+ this.nextBlinkTimeLeft -= dt;
+ if (this.nextBlinkTimeLeft < 0) {
+ this.eyeState = 1;
+ this.nextBlinkTimeLeft = this.blinkInterval + this.closingDuration + this.closedDuration + this.openingDuration + rand(0, 2e3);
+ }
+ break;
+ case 1:
+ this.setEyeParams(this.eyeParamValue + dt / this.closingDuration);
+ if (this.eyeParamValue <= 0) {
+ this.eyeState = 2;
+ this.closedTimer = 0;
+ }
+ break;
+ case 2:
+ this.closedTimer += dt;
+ if (this.closedTimer >= this.closedDuration) {
+ this.eyeState = 3;
+ }
+ break;
+ case 3:
+ this.setEyeParams(this.eyeParamValue + dt / this.openingDuration);
+ if (this.eyeParamValue >= 1) {
+ this.eyeState = 0;
+ }
+ }
+ }
+ }
+ const tempMatrixArray = new Float32Array([
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ]);
+ class Cubism2InternalModel extends InternalModel {
+ constructor(coreModel, settings, options) {
+ super();
+ this.textureFlipY = true;
+ this.drawDataCount = 0;
+ this.disableCulling = false;
+ this.coreModel = coreModel;
+ this.settings = settings;
+ this.motionManager = new Cubism2MotionManager(settings, options);
+ this.eyeBlink = new Live2DEyeBlink(coreModel);
+ this.eyeballXParamIndex = coreModel.getParamIndex("PARAM_EYE_BALL_X");
+ this.eyeballYParamIndex = coreModel.getParamIndex("PARAM_EYE_BALL_Y");
+ this.angleXParamIndex = coreModel.getParamIndex("PARAM_ANGLE_X");
+ this.angleYParamIndex = coreModel.getParamIndex("PARAM_ANGLE_Y");
+ this.angleZParamIndex = coreModel.getParamIndex("PARAM_ANGLE_Z");
+ this.bodyAngleXParamIndex = coreModel.getParamIndex("PARAM_BODY_ANGLE_X");
+ this.breathParamIndex = coreModel.getParamIndex("PARAM_BREATH");
+ this.init();
+ }
+ init() {
+ super.init();
+ if (this.settings.initParams) {
+ this.settings.initParams.forEach(({ id, value }) => this.coreModel.setParamFloat(id, value));
+ }
+ if (this.settings.initOpacities) {
+ this.settings.initOpacities.forEach(({ id, value }) => this.coreModel.setPartsOpacity(id, value));
+ }
+ this.coreModel.saveParam();
+ const arr = this.coreModel.getModelContext()._$aS;
+ if (arr == null ? void 0 : arr.length) {
+ this.drawDataCount = arr.length;
+ }
+ let culling = this.coreModel.drawParamWebGL.culling;
+ Object.defineProperty(this.coreModel.drawParamWebGL, "culling", {
+ set: (v) => culling = v,
+ get: () => this.disableCulling ? false : culling
+ });
+ const clipManager = this.coreModel.getModelContext().clipManager;
+ const originalSetupClip = clipManager.setupClip;
+ clipManager.setupClip = (modelContext, drawParam) => {
+ originalSetupClip.call(clipManager, modelContext, drawParam);
+ drawParam.gl.viewport(...this.viewport);
+ };
+ }
+ getSize() {
+ return [this.coreModel.getCanvasWidth(), this.coreModel.getCanvasHeight()];
+ }
+ getLayout() {
+ const layout = {};
+ if (this.settings.layout) {
+ for (const key of Object.keys(this.settings.layout)) {
+ let commonKey = key;
+ if (key === "center_x") {
+ commonKey = "centerX";
+ } else if (key === "center_y") {
+ commonKey = "centerY";
+ }
+ layout[commonKey] = this.settings.layout[key];
+ }
+ }
+ return layout;
+ }
+ updateWebGLContext(gl, glContextID) {
+ const drawParamWebGL = this.coreModel.drawParamWebGL;
+ drawParamWebGL.firstDraw = true;
+ drawParamWebGL.setGL(gl);
+ drawParamWebGL.glno = glContextID;
+ for (const prop in drawParamWebGL) {
+ if (drawParamWebGL.hasOwnProperty(prop) && drawParamWebGL[prop] instanceof WebGLBuffer) {
+ drawParamWebGL[prop] = null;
+ }
+ }
+ const clipManager = this.coreModel.getModelContext().clipManager;
+ clipManager.curFrameNo = glContextID;
+ const framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
+ clipManager.getMaskRenderTexture();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+ }
+ bindTexture(index, texture) {
+ this.coreModel.setTexture(index, texture);
+ }
+ getHitAreaDefs() {
+ var _a;
+ return ((_a = this.settings.hitAreas) == null ? void 0 : _a.map((hitArea) => ({
+ id: hitArea.id,
+ name: hitArea.name,
+ index: this.coreModel.getDrawDataIndex(hitArea.id)
+ }))) || [];
+ }
+ getDrawableIDs() {
+ const modelContext = this.coreModel.getModelContext();
+ const ids = [];
+ for (let i = 0; i < this.drawDataCount; i++) {
+ const drawData = modelContext.getDrawData(i);
+ if (drawData) {
+ ids.push(drawData.getDrawDataID().id);
+ }
+ }
+ return ids;
+ }
+ getDrawableIndex(id) {
+ return this.coreModel.getDrawDataIndex(id);
+ }
+ getDrawableVertices(drawIndex) {
+ if (typeof drawIndex === "string") {
+ drawIndex = this.coreModel.getDrawDataIndex(drawIndex);
+ if (drawIndex === -1)
+ throw new TypeError("Unable to find drawable ID: " + drawIndex);
+ }
+ return this.coreModel.getTransformedPoints(drawIndex).slice();
+ }
+ update(dt, now) {
+ var _a, _b, _c, _d;
+ super.update(dt, now);
+ const model = this.coreModel;
+ this.emit("beforeMotionUpdate");
+ const motionUpdated = this.motionManager.update(this.coreModel, now);
+ this.emit("afterMotionUpdate");
+ model.saveParam();
+ (_a = this.motionManager.expressionManager) == null ? void 0 : _a.update(model, now);
+ if (!motionUpdated) {
+ (_b = this.eyeBlink) == null ? void 0 : _b.update(dt);
+ }
+ this.updateFocus();
+ this.updateNaturalMovements(dt, now);
+ (_c = this.physics) == null ? void 0 : _c.update(now);
+ (_d = this.pose) == null ? void 0 : _d.update(dt);
+ this.emit("beforeModelUpdate");
+ model.update();
+ model.loadParam();
+ }
+ updateFocus() {
+ this.coreModel.addToParamFloat(this.eyeballXParamIndex, this.focusController.x);
+ this.coreModel.addToParamFloat(this.eyeballYParamIndex, this.focusController.y);
+ this.coreModel.addToParamFloat(this.angleXParamIndex, this.focusController.x * 30);
+ this.coreModel.addToParamFloat(this.angleYParamIndex, this.focusController.y * 30);
+ this.coreModel.addToParamFloat(this.angleZParamIndex, this.focusController.x * this.focusController.y * -30);
+ this.coreModel.addToParamFloat(this.bodyAngleXParamIndex, this.focusController.x * 10);
+ }
+ updateNaturalMovements(dt, now) {
+ const t = now / 1e3 * 2 * Math.PI;
+ this.coreModel.addToParamFloat(this.angleXParamIndex, 15 * Math.sin(t / 6.5345) * 0.5);
+ this.coreModel.addToParamFloat(this.angleYParamIndex, 8 * Math.sin(t / 3.5345) * 0.5);
+ this.coreModel.addToParamFloat(this.angleZParamIndex, 10 * Math.sin(t / 5.5345) * 0.5);
+ this.coreModel.addToParamFloat(this.bodyAngleXParamIndex, 4 * Math.sin(t / 15.5345) * 0.5);
+ this.coreModel.setParamFloat(this.breathParamIndex, 0.5 + 0.5 * Math.sin(t / 3.2345));
+ }
+ draw(gl) {
+ const disableCulling = this.disableCulling;
+ if (gl.getParameter(gl.FRAMEBUFFER_BINDING)) {
+ this.disableCulling = true;
+ }
+ const matrix = this.drawingMatrix;
+ tempMatrixArray[0] = matrix.a;
+ tempMatrixArray[1] = matrix.b;
+ tempMatrixArray[4] = matrix.c;
+ tempMatrixArray[5] = matrix.d;
+ tempMatrixArray[12] = matrix.tx;
+ tempMatrixArray[13] = matrix.ty;
+ this.coreModel.setMatrix(tempMatrixArray);
+ this.coreModel.draw();
+ this.disableCulling = disableCulling;
+ }
+ destroy() {
+ super.destroy();
+ this.coreModel = void 0;
+ }
+ }
+ class Cubism2ModelSettings extends ModelSettings {
+ constructor(json) {
+ super(json);
+ this.motions = {};
+ if (!Cubism2ModelSettings.isValidJSON(json)) {
+ throw new TypeError("Invalid JSON.");
+ }
+ this.moc = json.model;
+ copyArray("string", json, this, "textures", "textures");
+ this.copy(json);
+ }
+ static isValidJSON(json) {
+ var _a;
+ return !!json && typeof json.model === "string" && ((_a = json.textures) == null ? void 0 : _a.length) > 0 && json.textures.every((item) => typeof item === "string");
+ }
+ copy(json) {
+ copyProperty("string", json, this, "name", "name");
+ copyProperty("string", json, this, "pose", "pose");
+ copyProperty("string", json, this, "physics", "physics");
+ copyProperty("object", json, this, "layout", "layout");
+ copyProperty("object", json, this, "motions", "motions");
+ copyArray("object", json, this, "hit_areas", "hitAreas");
+ copyArray("object", json, this, "expressions", "expressions");
+ copyArray("object", json, this, "init_params", "initParams");
+ copyArray("object", json, this, "init_opacities", "initOpacities");
+ }
+ replaceFiles(replace) {
+ super.replaceFiles(replace);
+ for (const [group, motions] of Object.entries(this.motions)) {
+ for (let i = 0; i < motions.length; i++) {
+ motions[i].file = replace(motions[i].file, `motions.${group}[${i}].file`);
+ if (motions[i].sound !== void 0) {
+ motions[i].sound = replace(motions[i].sound, `motions.${group}[${i}].sound`);
+ }
+ }
+ }
+ if (this.expressions) {
+ for (let i = 0; i < this.expressions.length; i++) {
+ this.expressions[i].file = replace(this.expressions[i].file, `expressions[${i}].file`);
+ }
+ }
+ }
+ }
+ const SRC_TYPE_MAP = {
+ x: PhysicsHair.Src.SRC_TO_X,
+ y: PhysicsHair.Src.SRC_TO_Y,
+ angle: PhysicsHair.Src.SRC_TO_G_ANGLE
+ };
+ const TARGET_TYPE_MAP = {
+ x: PhysicsHair.Src.SRC_TO_X,
+ y: PhysicsHair.Src.SRC_TO_Y,
+ angle: PhysicsHair.Src.SRC_TO_G_ANGLE
+ };
+ class Live2DPhysics {
+ constructor(coreModel, json) {
+ this.coreModel = coreModel;
+ this.physicsHairs = [];
+ if (json.physics_hair) {
+ this.physicsHairs = json.physics_hair.map((definition) => {
+ const physicsHair = new PhysicsHair();
+ physicsHair.setup(definition.setup.length, definition.setup.regist, definition.setup.mass);
+ definition.src.forEach(({ id, ptype, scale, weight }) => {
+ const type = SRC_TYPE_MAP[ptype];
+ if (type) {
+ physicsHair.addSrcParam(type, id, scale, weight);
+ }
+ });
+ definition.targets.forEach(({ id, ptype, scale, weight }) => {
+ const type = TARGET_TYPE_MAP[ptype];
+ if (type) {
+ physicsHair.addTargetParam(type, id, scale, weight);
+ }
+ });
+ return physicsHair;
+ });
+ }
+ }
+ update(elapsed) {
+ this.physicsHairs.forEach((physicsHair) => physicsHair.update(this.coreModel, elapsed));
+ }
+ }
+ class Live2DPartsParam {
+ constructor(id) {
+ this.id = id;
+ this.paramIndex = -1;
+ this.partsIndex = -1;
+ this.link = [];
+ }
+ initIndex(model) {
+ this.paramIndex = model.getParamIndex("VISIBLE:" + this.id);
+ this.partsIndex = model.getPartsDataIndex(PartsDataID.getID(this.id));
+ model.setParamFloat(this.paramIndex, 1);
+ }
+ }
+ class Live2DPose {
+ constructor(coreModel, json) {
+ this.coreModel = coreModel;
+ this.opacityAnimDuration = 500;
+ this.partsGroups = [];
+ if (json.parts_visible) {
+ this.partsGroups = json.parts_visible.map(({ group }) => group.map(({ id, link }) => {
+ const parts = new Live2DPartsParam(id);
+ if (link) {
+ parts.link = link.map((l) => new Live2DPartsParam(l));
+ }
+ return parts;
+ }));
+ this.init();
+ }
+ }
+ init() {
+ this.partsGroups.forEach((group) => {
+ group.forEach((parts) => {
+ parts.initIndex(this.coreModel);
+ if (parts.paramIndex >= 0) {
+ const visible = this.coreModel.getParamFloat(parts.paramIndex) !== 0;
+ this.coreModel.setPartsOpacity(parts.partsIndex, visible ? 1 : 0);
+ this.coreModel.setParamFloat(parts.paramIndex, visible ? 1 : 0);
+ if (parts.link.length > 0) {
+ parts.link.forEach((p) => p.initIndex(this.coreModel));
+ }
+ }
+ });
+ });
+ }
+ normalizePartsOpacityGroup(partsGroup, dt) {
+ const model = this.coreModel;
+ const phi = 0.5;
+ const maxBackOpacity = 0.15;
+ let visibleOpacity = 1;
+ let visibleIndex = partsGroup.findIndex(({ paramIndex, partsIndex }) => partsIndex >= 0 && model.getParamFloat(paramIndex) !== 0);
+ if (visibleIndex >= 0) {
+ const originalOpacity = model.getPartsOpacity(partsGroup[visibleIndex].partsIndex);
+ visibleOpacity = clamp(originalOpacity + dt / this.opacityAnimDuration, 0, 1);
+ } else {
+ visibleIndex = 0;
+ visibleOpacity = 1;
+ }
+ partsGroup.forEach(({ partsIndex }, index) => {
+ if (partsIndex >= 0) {
+ if (visibleIndex == index) {
+ model.setPartsOpacity(partsIndex, visibleOpacity);
+ } else {
+ let opacity = model.getPartsOpacity(partsIndex);
+ let a1;
+ if (visibleOpacity < phi) {
+ a1 = visibleOpacity * (phi - 1) / phi + 1;
+ } else {
+ a1 = (1 - visibleOpacity) * phi / (1 - phi);
+ }
+ let backOp = (1 - a1) * (1 - visibleOpacity);
+ if (backOp > maxBackOpacity) {
+ a1 = 1 - maxBackOpacity / (1 - visibleOpacity);
+ }
+ if (opacity > a1) {
+ opacity = a1;
+ }
+ model.setPartsOpacity(partsIndex, opacity);
+ }
+ }
+ });
+ }
+ copyOpacity(partsGroup) {
+ const model = this.coreModel;
+ partsGroup.forEach(({ partsIndex, link }) => {
+ if (partsIndex >= 0 && link) {
+ const opacity = model.getPartsOpacity(partsIndex);
+ link.forEach(({ partsIndex: partsIndex2 }) => {
+ if (partsIndex2 >= 0) {
+ model.setPartsOpacity(partsIndex2, opacity);
+ }
+ });
+ }
+ });
+ }
+ update(dt) {
+ this.partsGroups.forEach((partGroup) => {
+ this.normalizePartsOpacityGroup(partGroup, dt);
+ this.copyOpacity(partGroup);
+ });
+ }
+ }
+ Live2DFactory.registerRuntime({
+ version: 2,
+ test(source) {
+ return source instanceof Cubism2ModelSettings || Cubism2ModelSettings.isValidJSON(source);
+ },
+ ready() {
+ return Promise.resolve();
+ },
+ isValidMoc(modelData) {
+ if (modelData.byteLength < 3) {
+ return false;
+ }
+ const view = new Int8Array(modelData, 0, 3);
+ return String.fromCharCode(...view) === "moc";
+ },
+ createModelSettings(json) {
+ return new Cubism2ModelSettings(json);
+ },
+ createCoreModel(data) {
+ const model = Live2DModelWebGL.loadModel(data);
+ const error = Live2D.getError();
+ if (error)
+ throw error;
+ return model;
+ },
+ createInternalModel(coreModel, settings, options) {
+ return new Cubism2InternalModel(coreModel, settings, options);
+ },
+ createPose(coreModel, data) {
+ return new Live2DPose(coreModel, data);
+ },
+ createPhysics(coreModel, data) {
+ return new Live2DPhysics(coreModel, data);
+ }
+ });
+ exports2.Cubism2ExpressionManager = Cubism2ExpressionManager;
+ exports2.Cubism2InternalModel = Cubism2InternalModel;
+ exports2.Cubism2ModelSettings = Cubism2ModelSettings;
+ exports2.Cubism2MotionManager = Cubism2MotionManager;
+ exports2.ExpressionManager = ExpressionManager;
+ exports2.FileLoader = FileLoader;
+ exports2.FocusController = FocusController;
+ exports2.InteractionMixin = InteractionMixin;
+ exports2.InternalModel = InternalModel;
+ exports2.LOGICAL_HEIGHT = LOGICAL_HEIGHT;
+ exports2.LOGICAL_WIDTH = LOGICAL_WIDTH;
+ exports2.Live2DExpression = Live2DExpression;
+ exports2.Live2DEyeBlink = Live2DEyeBlink;
+ exports2.Live2DFactory = Live2DFactory;
+ exports2.Live2DLoader = Live2DLoader;
+ exports2.Live2DModel = Live2DModel;
+ exports2.Live2DPhysics = Live2DPhysics;
+ exports2.Live2DPose = Live2DPose;
+ exports2.Live2DTransform = Live2DTransform;
+ exports2.ModelSettings = ModelSettings;
+ exports2.MotionManager = MotionManager;
+ exports2.MotionPreloadStrategy = MotionPreloadStrategy;
+ exports2.MotionPriority = MotionPriority;
+ exports2.MotionState = MotionState;
+ exports2.SoundManager = SoundManager;
+ exports2.VERSION = VERSION;
+ exports2.XHRLoader = XHRLoader;
+ exports2.ZipLoader = ZipLoader;
+ exports2.applyMixins = applyMixins;
+ exports2.clamp = clamp;
+ exports2.copyArray = copyArray;
+ exports2.copyProperty = copyProperty;
+ exports2.folderName = folderName;
+ exports2.logger = logger;
+ exports2.rand = rand;
+ exports2.remove = remove;
+ Object.defineProperties(exports2, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
+});
diff --git a/dist/cubism2.min.js b/dist/cubism2.min.js
new file mode 100644
index 00000000..bf8ea022
--- /dev/null
+++ b/dist/cubism2.min.js
@@ -0,0 +1 @@
+var __pow=Math.pow,__async=(t,e,s)=>new Promise(((i,r)=>{var o=t=>{try{a(s.next(t))}catch(e){r(e)}},n=t=>{try{a(s.throw(t))}catch(e){r(e)}},a=t=>t.done?i(t.value):Promise.resolve(t.value).then(o,n);a((s=s.apply(t,e)).next())}));!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@pixi/utils"),require("@pixi/math"),require("@pixi/core"),require("@pixi/display")):"function"==typeof define&&define.amd?define(["exports","@pixi/utils","@pixi/math","@pixi/core","@pixi/display"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).PIXI=t.PIXI||{},t.PIXI.live2d=t.PIXI.live2d||{}),t.PIXI.utils,t.PIXI,t.PIXI,t.PIXI)}(this,(function(t,e,s,i,r){"use strict";var o,n,a;(n=o||(o={})).supportMoreMaskDivisions=!0,n.setOpacityFromMotion=!1,t.config=void 0,(a=t.config||(t.config={})).LOG_LEVEL_VERBOSE=0,a.LOG_LEVEL_WARNING=1,a.LOG_LEVEL_ERROR=2,a.LOG_LEVEL_NONE=999,a.logLevel=a.LOG_LEVEL_WARNING,a.sound=!0,a.motionSync=!0,a.motionFadingDuration=500,a.idleMotionFadingDuration=2e3,a.expressionFadingDuration=500,a.preserveExpressionOnMotion=!0,a.cubism4=o;const l={log(e,...s){t.config.logLevel<=t.config.LOG_LEVEL_VERBOSE&&console.log(`[${e}]`,...s)},warn(e,...s){t.config.logLevel<=t.config.LOG_LEVEL_WARNING&&console.warn(`[${e}]`,...s)},error(e,...s){t.config.logLevel<=t.config.LOG_LEVEL_ERROR&&console.error(`[${e}]`,...s)}};function d(t,e,s){return ts?s:t}function h(t,e){return Math.random()*(e-t)+t}function c(t,e,s,i,r){const o=e[i];null!==o&&typeof o===t&&(s[r]=o)}function u(t,e,s,i,r){const o=e[i];Array.isArray(o)&&(s[r]=o.filter((e=>null!==e&&typeof e===t)))}function p(t,e){e.forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((s=>{"constructor"!==s&&Object.defineProperty(t.prototype,s,Object.getOwnPropertyDescriptor(e.prototype,s))}))}))}function g(t){let e=t.lastIndexOf("/");return-1!=e&&(t=t.slice(0,e)),e=t.lastIndexOf("/"),-1!==e&&(t=t.slice(e+1)),t}function m(t,e){const s=t.indexOf(e);-1!==s&&t.splice(s,1)}class f extends e.EventEmitter{constructor(t,e){super(),this.expressions=[],this.reserveExpressionIndex=-1,this.destroyed=!1,this.settings=t,this.tag=`ExpressionManager(${t.name})`}init(){this.defaultExpression=this.createExpression({},void 0),this.currentExpression=this.defaultExpression,this.stopAllExpressions()}loadExpression(t){return __async(this,null,(function*(){if(!this.definitions[t])return void l.warn(this.tag,`Undefined expression at [${t}]`);if(null===this.expressions[t])return void l.warn(this.tag,`Cannot set expression at [${t}] because it's already failed in loading.`);if(this.expressions[t])return this.expressions[t];const e=yield this._loadExpression(t);return this.expressions[t]=e,e}))}_loadExpression(t){throw new Error("Not implemented.")}setRandomExpression(){return __async(this,null,(function*(){if(this.definitions.length){const t=[];for(let e=0;e-1&&tl&&(o*=l/a,n*=l/a),this.vx+=o,this.vy+=n;const d=Math.sqrt(__pow(this.vx,2)+__pow(this.vy,2)),h=.5*(Math.sqrt(__pow(l,2)+8*l*i)-l);d>h&&(this.vx*=h/d,this.vy*=h/d),this.x+=this.vx,this.y+=this.vy}}class x{constructor(t){this.json=t;let e=t.url;if("string"!=typeof e)throw new TypeError("The `url` field in settings JSON must be defined as a string.");this.url=e,this.name=g(this.url)}resolveURL(t){return e.url.resolve(this.url,t)}replaceFiles(t){this.moc=t(this.moc,"moc"),void 0!==this.pose&&(this.pose=t(this.pose,"pose")),void 0!==this.physics&&(this.physics=t(this.physics,"physics"));for(let e=0;e(t.push(e),e))),t}validateFiles(t){const e=(e,s)=>{const i=this.resolveURL(e);if(!t.includes(i)){if(s)throw new Error(`File "${e}" is defined in settings, but doesn't exist in given files`);return!1}return!0};[this.moc,...this.textures].forEach((t=>e(t,!0)));return this.getDefinedFiles().filter((t=>e(t,!1)))}}var M=(t=>(t[t.NONE=0]="NONE",t[t.IDLE=1]="IDLE",t[t.NORMAL=2]="NORMAL",t[t.FORCE=3]="FORCE",t))(M||{});class v{constructor(){this.debug=!1,this.currentPriority=0,this.reservePriority=0}reserve(t,e,s){if(s<=0)return l.log(this.tag,"Cannot start a motion with MotionPriority.NONE."),!1;if(t===this.currentGroup&&e===this.currentIndex)return l.log(this.tag,"Motion is already playing.",this.dump(t,e)),!1;if(t===this.reservedGroup&&e===this.reservedIndex||t===this.reservedIdleGroup&&e===this.reservedIdleIndex)return l.log(this.tag,"Motion is already reserved.",this.dump(t,e)),!1;if(1===s){if(0!==this.currentPriority)return l.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(t,e)),!1;if(void 0!==this.reservedIdleGroup)return l.log(this.tag,"Cannot start idle motion because another idle motion has reserved.",this.dump(t,e)),!1;this.setReservedIdle(t,e)}else{if(s<3){if(s<=this.currentPriority)return l.log(this.tag,"Cannot start motion because another motion is playing as an equivalent or higher priority.",this.dump(t,e)),!1;if(s<=this.reservePriority)return l.log(this.tag,"Cannot start motion because another motion has reserved as an equivalent or higher priority.",this.dump(t,e)),!1}this.setReserved(t,e,s)}return!0}start(t,e,s,i){if(1===i){if(this.setReservedIdle(void 0,void 0),0!==this.currentPriority)return l.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(e,s)),!1}else{if(e!==this.reservedGroup||s!==this.reservedIndex)return l.log(this.tag,"Cannot start motion because another motion has taken the place.",this.dump(e,s)),!1;this.setReserved(void 0,void 0,0)}return!!t&&(this.setCurrent(e,s,i),!0)}complete(){this.setCurrent(void 0,void 0,0)}setCurrent(t,e,s){this.currentPriority=s,this.currentGroup=t,this.currentIndex=e}setReserved(t,e,s){this.reservePriority=s,this.reservedGroup=t,this.reservedIndex=e}setReservedIdle(t,e){this.reservedIdleGroup=t,this.reservedIdleIndex=e}isActive(t,e){return t===this.currentGroup&&e===this.currentIndex||t===this.reservedGroup&&e===this.reservedIndex||t===this.reservedIdleGroup&&e===this.reservedIdleIndex}reset(){this.setCurrent(void 0,void 0,0),this.setReserved(void 0,void 0,0),this.setReservedIdle(void 0,void 0)}shouldRequestIdleMotion(){return void 0===this.currentGroup&&void 0===this.reservedIdleGroup}shouldOverrideExpression(){return!t.config.preserveExpressionOnMotion&&this.currentPriority>1}dump(t,e){if(this.debug){return`\n group = "${t}", index = ${e}\n`+["currentPriority","reservePriority","currentGroup","currentIndex","reservedGroup","reservedIndex","reservedIdleGroup","reservedIdleIndex"].map((t=>"["+t+"] "+this[t])).join("\n")}return""}}class w{static get volume(){return this._volume}static set volume(t){this._volume=(t>1?1:t<0?0:t)||0,this.audios.forEach((t=>t.volume=this._volume))}static add(t,e,s){const i=new Audio(t);return i.volume=this._volume,i.preload="auto",i.autoplay=!0,i.crossOrigin="anonymous",i.addEventListener("ended",(()=>{this.dispose(i),null==e||e()})),i.addEventListener("error",(e=>{this.dispose(i),l.warn("SoundManager",`Error occurred on "${t}"`,e.error),null==s||s(e.error)})),this.audios.push(i),i}static play(t){return new Promise(((e,s)=>{var i;null==(i=t.play())||i.catch((e=>{t.dispatchEvent(new ErrorEvent("error",{error:e})),s(e)})),t.readyState===t.HAVE_ENOUGH_DATA?e():t.addEventListener("canplaythrough",e)}))}static addContext(t){const e=new AudioContext;return this.contexts.push(e),e}static addAnalyzer(t,e){const s=e.createMediaElementSource(t),i=e.createAnalyser();return i.fftSize=256,i.minDecibels=-90,i.maxDecibels=-10,i.smoothingTimeConstant=.85,s.connect(i),i.connect(e.destination),this.analysers.push(i),i}static analyze(t){if(null!=t){let e=new Float32Array(t.fftSize),s=0;t.getFloatTimeDomainData(e);for(const t of e)s+=t*t;return parseFloat(Math.sqrt(s/e.length*20).toFixed(1))}return parseFloat(Math.random().toFixed(1))}static dispose(t){t.pause(),t.removeAttribute("src"),m(this.audios,t)}static destroy(){for(let t=this.contexts.length-1;t>=0;t--)this.contexts[t].close();for(let t=this.audios.length-1;t>=0;t--)this.dispose(this.audios[t])}}w.audios=[],w.analysers=[],w.contexts=[],w._volume=.9;var E=(t=>(t.ALL="ALL",t.IDLE="IDLE",t.NONE="NONE",t))(E||{});class P extends e.EventEmitter{constructor(t,e){super(),this.motionGroups={},this.state=new v,this.playing=!1,this.destroyed=!1,this.settings=t,this.tag=`MotionManager(${t.name})`,this.state.tag=this.tag}init(t){(null==t?void 0:t.idleMotionGroup)&&(this.groups.idle=t.idleMotionGroup),this.setupMotions(t),this.stopAllMotions()}setupMotions(t){for(const s of Object.keys(this.definitions))this.motionGroups[s]=[];let e;switch(null==t?void 0:t.motionPreload){case"NONE":return;case"ALL":e=Object.keys(this.definitions);break;default:e=[this.groups.idle]}for(const s of e)if(this.definitions[s])for(let t=0;t{i&&u.expressionManager&&u.expressionManager.resetExpression(),u.currentAudio=void 0}),(()=>{i&&u.expressionManager&&u.expressionManager.resetExpression(),u.currentAudio=void 0})),this.currentAudio=r;let t=1;void 0!==s&&(t=s),w.volume=t,n=w.addContext(this.currentAudio),this.currentContext=n,o=w.addAnalyzer(this.currentAudio,this.currentContext),this.currentAnalyzer=o}catch(p){l.warn(this.tag,"Failed to create audio",a,p)}if(r){const e=w.play(r).catch((t=>l.warn(this.tag,"Failed to play audio",r.src,t)));t.config.motionSync&&(yield e)}return this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),i&&this.expressionManager&&this.expressionManager.setExpression(i),this.playing=!0,!0}))}startMotion(e,s){return __async(this,arguments,(function*(e,s,i=M.NORMAL,r,o,n){var a;if(this.currentAudio&&!this.currentAudio.ended)return!1;if(!this.state.reserve(e,s,i))return!1;const d=null==(a=this.definitions[e])?void 0:a[s];if(!d)return!1;let h,c,u;if(this.currentAudio&&w.dispose(this.currentAudio),t.config.sound){const t=r&&r.startsWith("data:audio/wav;base64");if(r&&!t){var p=document.createElement("a");p.href=r,r=p.href}const e=r&&(r.startsWith("http")||r.startsWith("blob")),s=this.getSoundFile(d);let i=s;s&&(i=this.settings.resolveURL(s)+"?cache-buster="+(new Date).getTime()),(e||t)&&(i=r);const a=this;if(i)try{h=w.add(i,(()=>{n&&a.expressionManager&&a.expressionManager.resetExpression(),a.currentAudio=void 0}),(()=>{n&&a.expressionManager&&a.expressionManager.resetExpression(),a.currentAudio=void 0})),this.currentAudio=h;let t=1;void 0!==o&&(t=o),w.volume=t,u=w.addContext(this.currentAudio),this.currentContext=u,c=w.addAnalyzer(this.currentAudio,this.currentContext),this.currentAnalyzer=c}catch(m){l.warn(this.tag,"Failed to create audio",s,m)}}const g=yield this.loadMotion(e,s);if(h){i=3;const e=w.play(h).catch((t=>l.warn(this.tag,"Failed to play audio",h.src,t)));t.config.motionSync&&(yield e)}return this.state.start(g,e,s,i)?(this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),l.log(this.tag,"Start motion:",this.getMotionName(d)),this.emit("motionStart",e,s,h),n&&this.expressionManager&&this.expressionManager.setExpression(n),this.playing=!0,this._startMotion(g),!0):(h&&(w.dispose(h),this.currentAudio=void 0),!1)}))}startRandomMotion(t,e,s,i){return __async(this,null,(function*(){const r=this.definitions[t];if(null==r?void 0:r.length){const o=[];for(let e=0;et.index>=0));for(const e of t)this.hitAreas[e.name]=e}hitTest(t,e){return Object.keys(this.hitAreas).filter((s=>this.isHit(s,t,e)))}isHit(t,e,s){if(!this.hitAreas[t])return!1;const i=this.hitAreas[t].index,r=this.getDrawableBounds(i,_);return r.x<=e&&e<=r.x+r.width&&r.y<=s&&s<=r.y+r.height}getDrawableBounds(t,e){const s=this.getDrawableVertices(t);let i=s[0],r=s[0],o=s[1],n=s[1];for(let a=0;a{200!==o.status&&0!==o.status||!o.response?o.onerror():i(o.response)},o.onerror=()=>{l.warn("XHRLoader",`Failed to load resource as ${o.responseType} (Status ${o.status}): ${e}`),r(new L("Network error.",e,o.status))},o.onabort=()=>r(new L("Aborted.",e,o.status,!0)),o.onloadend=()=>{var e;b.allXhrSet.delete(o),t&&(null==(e=b.xhrMap.get(t))||e.delete(o))},o}static cancelXHRs(){var t;null==(t=b.xhrMap.get(this))||t.forEach((t=>{t.abort(),b.allXhrSet.delete(t)})),b.xhrMap.delete(this)}static release(){b.allXhrSet.forEach((t=>t.abort())),b.allXhrSet.clear(),b.xhrMap=new WeakMap}};let T=b;function O(t,e){let s=-1;return function i(r,o){if(o)return Promise.reject(o);if(r<=s)return Promise.reject(new Error("next() called multiple times"));s=r;const n=t[r];if(!n)return Promise.resolve();try{return Promise.resolve(n(e,i.bind(null,r+1)))}catch(a){return Promise.reject(a)}}(0)}T.xhrMap=new WeakMap,T.allXhrSet=new Set,T.loader=(t,e)=>new Promise(((e,s)=>{b.createXHR(t.target,t.settings?t.settings.resolveURL(t.url):t.url,t.type,(s=>{t.result=s,e()}),s).send()}));class A{static load(t){return O(this.middlewares,t).then((()=>t.result))}}A.middlewares=[T.loader];const R="Live2DFactory",F=(t,e)=>__async(this,null,(function*(){if("string"==typeof t.source){const e=yield A.load({url:t.source,type:"json",target:t.live2dModel});e.url=t.source,t.source=e,t.live2dModel.emit("settingsJSONLoaded",e)}return e()})),D=(t,e)=>__async(this,null,(function*(){if(t.source instanceof x)return t.settings=t.source,e();if("object"==typeof t.source){const s=N.findRuntime(t.source);if(s){const i=s.createModelSettings(t.source);return t.settings=i,t.live2dModel.emit("settingsLoaded",i),e()}}throw new TypeError("Unknown settings format.")})),C=(t,e)=>{if(t.settings){const s=N.findRuntime(t.settings);if(s)return s.ready().then(e)}return e()},S=(t,e)=>__async(this,null,(function*(){yield e();const s=t.internalModel;if(s){const e=t.settings,i=N.findRuntime(e);if(i){const r=[];e.pose&&r.push(A.load({settings:e,url:e.pose,type:"json",target:s}).then((e=>{s.pose=i.createPose(s.coreModel,e),t.live2dModel.emit("poseLoaded",s.pose)})).catch((e=>{t.live2dModel.emit("poseLoadError",e),l.warn(R,"Failed to load pose.",e)}))),e.physics&&r.push(A.load({settings:e,url:e.physics,type:"json",target:s}).then((e=>{s.physics=i.createPhysics(s.coreModel,e),t.live2dModel.emit("physicsLoaded",s.physics)})).catch((e=>{t.live2dModel.emit("physicsLoadError",e),l.warn(R,"Failed to load physics.",e)}))),r.length&&(yield Promise.all(r))}}})),k=(t,e)=>__async(this,null,(function*(){if(!t.settings)throw new TypeError("Missing settings.");{const s=t.live2dModel,r=t.settings.textures.map((e=>function(t,e={}){const s={resourceOptions:{crossorigin:e.crossOrigin}};if(i.Texture.fromURL)return i.Texture.fromURL(t,s).catch((t=>{if(t instanceof Error)throw t;const e=new Error("Texture loading error");throw e.event=t,e}));s.resourceOptions.autoLoad=!1;const r=i.Texture.from(t,s);if(r.baseTexture.valid)return Promise.resolve(r);const o=r.baseTexture.resource;return null!=o._live2d_load||(o._live2d_load=new Promise(((t,e)=>{const s=t=>{o.source.removeEventListener("error",s);const i=new Error("Texture loading error");i.event=t,e(i)};o.source.addEventListener("error",s),o.load().then((()=>t(r))).catch(s)}))),o._live2d_load}(t.settings.resolveURL(e),{crossOrigin:t.options.crossOrigin})));if(yield e(),!t.internalModel)throw new TypeError("Missing internal model.");s.internalModel=t.internalModel,s.emit("modelLoaded",t.internalModel),s.textures=yield Promise.all(r),s.emit("textureLoaded",s.textures)}})),G=(t,e)=>__async(this,null,(function*(){const s=t.settings;if(s instanceof x){const i=N.findRuntime(s);if(!i)throw new TypeError("Unknown model settings.");const r=yield A.load({settings:s,url:s.moc,type:"arraybuffer",target:t.live2dModel});if(!i.isValidMoc(r))throw new Error("Invalid moc data");const o=i.createCoreModel(r);return t.internalModel=i.createInternalModel(o,s,t.options),e()}throw new TypeError("Missing settings.")})),U=class{static registerRuntime(t){U.runtimes.push(t),U.runtimes.sort(((t,e)=>e.version-t.version))}static findRuntime(t){for(const e of U.runtimes)if(e.test(t))return e}static setupLive2DModel(t,e,s){return __async(this,null,(function*(){const i=new Promise((e=>t.once("textureLoaded",e))),r=new Promise((e=>t.once("modelLoaded",e))),o=Promise.all([i,r]).then((()=>t.emit("ready")));yield O(U.live2DModelMiddlewares,{live2dModel:t,source:e,options:s||{}}),yield o,t.emit("load")}))}static loadMotion(t,e,s){var i;const r=i=>t.emit("motionLoadError",e,s,i);try{const o=null==(i=t.definitions[e])?void 0:i[s];if(!o)return Promise.resolve(void 0);t.listeners("destroy").includes(U.releaseTasks)||t.once("destroy",U.releaseTasks);let n=U.motionTasksMap.get(t);n||(n={},U.motionTasksMap.set(t,n));let a=n[e];a||(a=[],n[e]=a);const d=t.getMotionFile(o);return null!=a[s]||(a[s]=A.load({url:d,settings:t.settings,type:t.motionDataType,target:t}).then((i=>{var r;const n=null==(r=U.motionTasksMap.get(t))?void 0:r[e];n&&delete n[s];const a=t.createMotion(i,e,o);return t.emit("motionLoaded",e,s,a),a})).catch((e=>{l.warn(t.tag,`Failed to load motion: ${d}\n`,e),r(e)}))),a[s]}catch(o){l.warn(t.tag,`Failed to load motion at "${e}"[${s}]\n`,o),r(o)}return Promise.resolve(void 0)}static loadExpression(t,e){const s=s=>t.emit("expressionLoadError",e,s);try{const i=t.definitions[e];if(!i)return Promise.resolve(void 0);t.listeners("destroy").includes(U.releaseTasks)||t.once("destroy",U.releaseTasks);let r=U.expressionTasksMap.get(t);r||(r=[],U.expressionTasksMap.set(t,r));const o=t.getExpressionFile(i);return null!=r[e]||(r[e]=A.load({url:o,settings:t.settings,type:"json",target:t}).then((s=>{const r=U.expressionTasksMap.get(t);r&&delete r[e];const o=t.createExpression(s,i);return t.emit("expressionLoaded",e,o),o})).catch((e=>{l.warn(t.tag,`Failed to load expression: ${o}\n`,e),s(e)}))),r[e]}catch(i){l.warn(t.tag,`Failed to load expression at [${e}]\n`,i),s(i)}return Promise.resolve(void 0)}static releaseTasks(){this instanceof P?U.motionTasksMap.delete(this):U.expressionTasksMap.delete(this)}};let N=U;N.runtimes=[],N.urlToJSON=F,N.jsonToSettings=D,N.waitUntilReady=C,N.setupOptionals=S,N.setupEssentials=k,N.createInternalModel=G,N.live2DModelMiddlewares=[F,D,C,S,k,G],N.motionTasksMap=new WeakMap,N.expressionTasksMap=new WeakMap,P.prototype._loadMotion=function(t,e){return N.loadMotion(this,t,e)},f.prototype._loadExpression=function(t){return N.loadExpression(this,t)};class j{constructor(){this._autoInteract=!1}get autoInteract(){return this._autoInteract}set autoInteract(t){t!==this._autoInteract&&(t?this.on("pointertap",X,this):this.off("pointertap",X,this),this._autoInteract=t)}registerInteraction(t){t!==this.interactionManager&&(this.unregisterInteraction(),this._autoInteract&&t&&(this.interactionManager=t,t.on("pointermove",H,this)))}unregisterInteraction(){var t;this.interactionManager&&(null==(t=this.interactionManager)||t.off("pointermove",H,this),this.interactionManager=void 0)}}function X(t){this.tap(t.data.global.x,t.data.global.y)}function H(t){this.focus(t.data.global.x,t.data.global.y)}class W extends s.Transform{}const $=new s.Point,q=new s.Matrix;let V;class z extends r.Container{constructor(t){super(),this.tag="Live2DModel(uninitialized)",this.textures=[],this.transform=new W,this.anchor=new s.ObservablePoint(this.onAnchorChange,this,0,0),this.glContextID=-1,this.elapsedTime=performance.now(),this.deltaTime=0,this._autoUpdate=!1,this.once("modelLoaded",(()=>this.init(t)))}static from(t,e){const s=new this(e);return N.setupLive2DModel(s,t,e).then((()=>s))}static fromSync(t,e){const s=new this(e);return N.setupLive2DModel(s,t,e).then(null==e?void 0:e.onLoad).catch(null==e?void 0:e.onError),s}static registerTicker(t){V=t}get autoUpdate(){return this._autoUpdate}set autoUpdate(t){var e;V||(V=null==(e=window.PIXI)?void 0:e.Ticker),t?this._destroyed||(V?(V.shared.add(this.onTickerUpdate,this),this._autoUpdate=!0):l.warn(this.tag,"No Ticker registered, please call Live2DModel.registerTicker(Ticker).")):(null==V||V.shared.remove(this.onTickerUpdate,this),this._autoUpdate=!1)}init(t){this.tag=`Live2DModel(${this.internalModel.settings.name})`;const e=Object.assign({autoUpdate:!0,autoInteract:!0},t);e.autoInteract&&(this.interactive=!0),this.autoInteract=e.autoInteract,this.autoUpdate=e.autoUpdate}onAnchorChange(){this.pivot.set(this.anchor.x*this.internalModel.width,this.anchor.y*this.internalModel.height)}motion(t,e,s,i,r,o){return void 0===e?this.internalModel.motionManager.startRandomMotion(t,s):this.internalModel.motionManager.startMotion(t,e,s,i,r,o)}resetMotions(){return this.internalModel.motionManager.stopAllMotions()}speak(t,e,s){return this.internalModel.motionManager.speakUp(t,e,s)}stopSpeaking(){return this.internalModel.motionManager.stopSpeaking()}expression(t){return this.internalModel.motionManager.expressionManager?void 0===t?this.internalModel.motionManager.expressionManager.setRandomExpression():this.internalModel.motionManager.expressionManager.setExpression(t):Promise.resolve(!1)}focus(t,e,s=!1){$.x=t,$.y=e,this.toModelPosition($,$,!0);let i=$.x/this.internalModel.originalWidth*2-1,r=$.y/this.internalModel.originalHeight*2-1,o=Math.atan2(r,i);this.internalModel.focusController.focus(Math.cos(o),-Math.sin(o),s)}tap(t,e){const s=this.hitTest(t,e);s.length&&(l.log(this.tag,"Hit",s),this.emit("hit",s))}hitTest(t,e){return $.x=t,$.y=e,this.toModelPosition($,$),this.internalModel.hitTest($.x,$.y)}toModelPosition(t,e=t.clone(),s){return s||(this._recursivePostUpdateTransform(),this.parent?this.displayObjectUpdateTransform():(this.parent=this._tempDisplayObjectParent,this.displayObjectUpdateTransform(),this.parent=null)),this.transform.worldTransform.applyInverse(t,e),this.internalModel.localTransform.applyInverse(e,e),e}containsPoint(t){return this.getBounds(!0).contains(t.x,t.y)}_calculateBounds(){this._bounds.addFrame(this.transform,0,0,this.internalModel.width,this.internalModel.height)}onTickerUpdate(){this.update(V.shared.deltaMS)}update(t){this.deltaTime+=t,this.elapsedTime+=t}_render(t){this.registerInteraction(t.plugins.interaction),t.batch.reset(),t.geometry.reset(),t.shader.reset(),t.state.reset();let e=!1;this.glContextID!==t.CONTEXT_UID&&(this.glContextID=t.CONTEXT_UID,this.internalModel.updateWebGLContext(t.gl,this.glContextID),e=!0);for(let r=0;re.destroy(t.baseTexture))),this.internalModel.destroy(),super.destroy(t)}}p(z,[j]);const B=class{static resolveURL(t,e){var s;const i=null==(s=B.filesMap[t])?void 0:s[e];if(void 0===i)throw new Error("Cannot find this file from uploaded files: "+e);return i}static upload(t,s){return __async(this,null,(function*(){const i={};for(const r of s.getDefinedFiles()){const o=decodeURI(e.url.resolve(s.url,r)),n=t.find((t=>t.webkitRelativePath===o));n&&(i[r]=URL.createObjectURL(n))}B.filesMap[s._objectURL]=i}))}static createSettings(t){return __async(this,null,(function*(){const e=t.find((t=>t.name.endsWith("model.json")||t.name.endsWith("model3.json")));if(!e)throw new TypeError("Settings file not found");const s=yield B.readText(e),i=JSON.parse(s);i.url=e.webkitRelativePath;const r=N.findRuntime(i);if(!r)throw new Error("Unknown settings JSON");const o=r.createModelSettings(i);return o._objectURL=URL.createObjectURL(e),o}))}static readText(t){return __async(this,null,(function*(){return new Promise(((e,s)=>{const i=new FileReader;i.onload=()=>e(i.result),i.onerror=s,i.readAsText(t,"utf8")}))}))}};let Y=B;Y.filesMap={},Y.factory=(t,e)=>__async(this,null,(function*(){if(Array.isArray(t.source)&&t.source[0]instanceof File){const e=t.source;let s=e.settings;if(s){if(!s._objectURL)throw new Error('"_objectURL" must be specified in ModelSettings')}else s=yield B.createSettings(e);s.validateFiles(e.map((t=>encodeURI(t.webkitRelativePath)))),yield B.upload(e,s),s.resolveURL=function(t){return B.resolveURL(this._objectURL,t)},t.source=s,t.live2dModel.once("modelLoaded",(t=>{t.once("destroy",(function(){const t=this.settings._objectURL;if(URL.revokeObjectURL(t),B.filesMap[t])for(const e of Object.values(B.filesMap[t]))URL.revokeObjectURL(e);delete B.filesMap[t]}))}))}return e()})),N.live2DModelMiddlewares.unshift(Y.factory);const J=class{static unzip(t,s){return __async(this,null,(function*(){const i=yield J.getFilePaths(t),r=[];for(const t of s.getDefinedFiles()){const o=decodeURI(e.url.resolve(s.url,t));i.includes(o)&&r.push(o)}const o=yield J.getFiles(t,r);for(let t=0;tt.endsWith("model.json")||t.endsWith("model3.json")));if(!e)throw new Error("Settings file not found");const s=yield J.readText(t,e);if(!s)throw new Error("Empty settings file: "+e);const i=JSON.parse(s);i.url=e;const r=N.findRuntime(i);if(!r)throw new Error("Unknown settings JSON");return r.createModelSettings(i)}))}static zipReader(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFilePaths(t){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFiles(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static readText(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static releaseReader(t){}};let Z=J;if(Z.ZIP_PROTOCOL="zip://",Z.uid=0,Z.factory=(t,e)=>__async(this,null,(function*(){const s=t.source;let i,r,o;if("string"==typeof s&&(s.endsWith(".zip")||s.startsWith(J.ZIP_PROTOCOL))?(i=s.startsWith(J.ZIP_PROTOCOL)?s.slice(J.ZIP_PROTOCOL.length):s,r=yield A.load({url:i,type:"blob",target:t.live2dModel})):Array.isArray(s)&&1===s.length&&s[0]instanceof File&&s[0].name.endsWith(".zip")&&(r=s[0],i=URL.createObjectURL(r),o=s.settings),r){if(!r.size)throw new Error("Empty zip file");const e=yield J.zipReader(r,i);o||(o=yield J.createSettings(e)),o._objectURL=J.ZIP_PROTOCOL+J.uid+"/"+o.url;const s=yield J.unzip(e,o);s.settings=o,t.source=s,i.startsWith("blob:")&&t.live2dModel.once("modelLoaded",(t=>{t.once("destroy",(function(){URL.revokeObjectURL(i)}))})),J.releaseReader(e)}return e()})),N.live2DModelMiddlewares.unshift(Z.factory),!window.Live2D)throw new Error("Could not find Cubism 2 runtime. This plugin requires live2d.min.js to be loaded.");const Q=Live2DMotion.prototype.updateParam;Live2DMotion.prototype.updateParam=function(t,e){Q.call(this,t,e),e.isFinished()&&this.onFinishHandler&&(this.onFinishHandler(this),delete this.onFinishHandler)};class K extends AMotion{constructor(e){super(),this.params=[],this.setFadeIn(e.fade_in>0?e.fade_in:t.config.expressionFadingDuration),this.setFadeOut(e.fade_out>0?e.fade_out:t.config.expressionFadingDuration),Array.isArray(e.params)&&e.params.forEach((t=>{const e=t.calc||"add";if("add"===e){const e=t.def||0;t.val-=e}else if("mult"===e){const e=t.def||1;t.val/=e}this.params.push({calc:e,val:t.val,id:t.id})}))}updateParamExe(t,e,s,i){this.params.forEach((e=>{t.setParamFloat(e.id,e.val*s)}))}}class tt extends f{constructor(t,e){var s;super(t,e),this.queueManager=new MotionQueueManager,this.definitions=null!=(s=this.settings.expressions)?s:[],this.init()}isFinished(){return this.queueManager.isFinished()}getExpressionIndex(t){return this.definitions.findIndex((e=>e.name===t))}getExpressionFile(t){return t.file}createExpression(t,e){return new K(t)}_setExpression(t){return this.queueManager.startMotion(t)}stopAllExpressions(){this.queueManager.stopAllMotions()}updateParameters(t,e){return this.queueManager.updateParam(t)}}class et extends P{constructor(t,e){super(t,e),this.groups={idle:"idle"},this.motionDataType="arraybuffer",this.queueManager=new MotionQueueManager,this.definitions=this.settings.motions,this.init(e)}init(t){super.init(t),this.settings.expressions&&(this.expressionManager=new tt(this.settings,t))}isFinished(){return this.queueManager.isFinished()}createMotion(e,s,i){const r=Live2DMotion.loadMotion(e),o=s===this.groups.idle?t.config.idleMotionFadingDuration:t.config.motionFadingDuration;return r.setFadeIn(i.fade_in>0?i.fade_in:o),r.setFadeOut(i.fade_out>0?i.fade_out:o),r}getMotionFile(t){return t.file}getMotionName(t){return t.file}getSoundFile(t){return t.sound}_startMotion(t,e){return t.onFinishHandler=e,this.queueManager.stopAllMotions(),this.queueManager.startMotion(t)}_stopAllMotions(){this.queueManager.stopAllMotions()}updateParameters(t,e){return this.queueManager.updateParam(t)}destroy(){super.destroy(),this.queueManager=void 0}}class st{constructor(t){this.coreModel=t,this.blinkInterval=4e3,this.closingDuration=100,this.closedDuration=50,this.openingDuration=150,this.eyeState=0,this.eyeParamValue=1,this.closedTimer=0,this.nextBlinkTimeLeft=this.blinkInterval,this.leftParam=t.getParamIndex("PARAM_EYE_L_OPEN"),this.rightParam=t.getParamIndex("PARAM_EYE_R_OPEN")}setEyeParams(t){this.eyeParamValue=d(t,0,1),this.coreModel.setParamFloat(this.leftParam,this.eyeParamValue),this.coreModel.setParamFloat(this.rightParam,this.eyeParamValue)}update(t){switch(this.eyeState){case 0:this.nextBlinkTimeLeft-=t,this.nextBlinkTimeLeft<0&&(this.eyeState=1,this.nextBlinkTimeLeft=this.blinkInterval+this.closingDuration+this.closedDuration+this.openingDuration+h(0,2e3));break;case 1:this.setEyeParams(this.eyeParamValue+t/this.closingDuration),this.eyeParamValue<=0&&(this.eyeState=2,this.closedTimer=0);break;case 2:this.closedTimer+=t,this.closedTimer>=this.closedDuration&&(this.eyeState=3);break;case 3:this.setEyeParams(this.eyeParamValue+t/this.openingDuration),this.eyeParamValue>=1&&(this.eyeState=0)}}}const it=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);class rt extends I{constructor(t,e,s){super(),this.textureFlipY=!0,this.drawDataCount=0,this.disableCulling=!1,this.coreModel=t,this.settings=e,this.motionManager=new et(e,s),this.eyeBlink=new st(t),this.eyeballXParamIndex=t.getParamIndex("PARAM_EYE_BALL_X"),this.eyeballYParamIndex=t.getParamIndex("PARAM_EYE_BALL_Y"),this.angleXParamIndex=t.getParamIndex("PARAM_ANGLE_X"),this.angleYParamIndex=t.getParamIndex("PARAM_ANGLE_Y"),this.angleZParamIndex=t.getParamIndex("PARAM_ANGLE_Z"),this.bodyAngleXParamIndex=t.getParamIndex("PARAM_BODY_ANGLE_X"),this.breathParamIndex=t.getParamIndex("PARAM_BREATH"),this.init()}init(){super.init(),this.settings.initParams&&this.settings.initParams.forEach((({id:t,value:e})=>this.coreModel.setParamFloat(t,e))),this.settings.initOpacities&&this.settings.initOpacities.forEach((({id:t,value:e})=>this.coreModel.setPartsOpacity(t,e))),this.coreModel.saveParam();const t=this.coreModel.getModelContext()._$aS;(null==t?void 0:t.length)&&(this.drawDataCount=t.length);let e=this.coreModel.drawParamWebGL.culling;Object.defineProperty(this.coreModel.drawParamWebGL,"culling",{set:t=>e=t,get:()=>!this.disableCulling&&e});const s=this.coreModel.getModelContext().clipManager,i=s.setupClip;s.setupClip=(t,e)=>{i.call(s,t,e),e.gl.viewport(...this.viewport)}}getSize(){return[this.coreModel.getCanvasWidth(),this.coreModel.getCanvasHeight()]}getLayout(){const t={};if(this.settings.layout)for(const e of Object.keys(this.settings.layout)){let s=e;"center_x"===e?s="centerX":"center_y"===e&&(s="centerY"),t[s]=this.settings.layout[e]}return t}updateWebGLContext(t,e){const s=this.coreModel.drawParamWebGL;s.firstDraw=!0,s.setGL(t),s.glno=e;for(const o in s)s.hasOwnProperty(o)&&s[o]instanceof WebGLBuffer&&(s[o]=null);const i=this.coreModel.getModelContext().clipManager;i.curFrameNo=e;const r=t.getParameter(t.FRAMEBUFFER_BINDING);i.getMaskRenderTexture(),t.bindFramebuffer(t.FRAMEBUFFER,r)}bindTexture(t,e){this.coreModel.setTexture(t,e)}getHitAreaDefs(){var t;return(null==(t=this.settings.hitAreas)?void 0:t.map((t=>({id:t.id,name:t.name,index:this.coreModel.getDrawDataIndex(t.id)}))))||[]}getDrawableIDs(){const t=this.coreModel.getModelContext(),e=[];for(let s=0;s0&&t.textures.every((t=>"string"==typeof t))}copy(t){c("string",t,this,"name","name"),c("string",t,this,"pose","pose"),c("string",t,this,"physics","physics"),c("object",t,this,"layout","layout"),c("object",t,this,"motions","motions"),u("object",t,this,"hit_areas","hitAreas"),u("object",t,this,"expressions","expressions"),u("object",t,this,"init_params","initParams"),u("object",t,this,"init_opacities","initOpacities")}replaceFiles(t){super.replaceFiles(t);for(const[e,s]of Object.entries(this.motions))for(let i=0;i{const e=new PhysicsHair;return e.setup(t.setup.length,t.setup.regist,t.setup.mass),t.src.forEach((({id:t,ptype:s,scale:i,weight:r})=>{const o=nt[s];o&&e.addSrcParam(o,t,i,r)})),t.targets.forEach((({id:t,ptype:s,scale:i,weight:r})=>{const o=at[s];o&&e.addTargetParam(o,t,i,r)})),e})))}update(t){this.physicsHairs.forEach((e=>e.update(this.coreModel,t)))}}class dt{constructor(t){this.id=t,this.paramIndex=-1,this.partsIndex=-1,this.link=[]}initIndex(t){this.paramIndex=t.getParamIndex("VISIBLE:"+this.id),this.partsIndex=t.getPartsDataIndex(PartsDataID.getID(this.id)),t.setParamFloat(this.paramIndex,1)}}class ht{constructor(t,e){this.coreModel=t,this.opacityAnimDuration=500,this.partsGroups=[],e.parts_visible&&(this.partsGroups=e.parts_visible.map((({group:t})=>t.map((({id:t,link:e})=>{const s=new dt(t);return e&&(s.link=e.map((t=>new dt(t)))),s})))),this.init())}init(){this.partsGroups.forEach((t=>{t.forEach((t=>{if(t.initIndex(this.coreModel),t.paramIndex>=0){const e=0!==this.coreModel.getParamFloat(t.paramIndex);this.coreModel.setPartsOpacity(t.partsIndex,e?1:0),this.coreModel.setParamFloat(t.paramIndex,e?1:0),t.link.length>0&&t.link.forEach((t=>t.initIndex(this.coreModel)))}}))}))}normalizePartsOpacityGroup(t,e){const s=this.coreModel,i=.5;let r=1,o=t.findIndex((({paramIndex:t,partsIndex:e})=>e>=0&&0!==s.getParamFloat(t)));if(o>=0){const i=s.getPartsOpacity(t[o].partsIndex);r=d(i+e/this.opacityAnimDuration,0,1)}else o=0,r=1;t.forEach((({partsIndex:t},e)=>{if(t>=0)if(o==e)s.setPartsOpacity(t,r);else{let e,o=s.getPartsOpacity(t);e=r.15&&(e=1-.15/(1-r)),o>e&&(o=e),s.setPartsOpacity(t,o)}}))}copyOpacity(t){const e=this.coreModel;t.forEach((({partsIndex:t,link:s})=>{if(t>=0&&s){const i=e.getPartsOpacity(t);s.forEach((({partsIndex:t})=>{t>=0&&e.setPartsOpacity(t,i)}))}}))}update(t){this.partsGroups.forEach((e=>{this.normalizePartsOpacityGroup(e,t),this.copyOpacity(e)}))}}N.registerRuntime({version:2,test:t=>t instanceof ot||ot.isValidJSON(t),ready:()=>Promise.resolve(),isValidMoc(t){if(t.byteLength<3)return!1;const e=new Int8Array(t,0,3);return"moc"===String.fromCharCode(...e)},createModelSettings:t=>new ot(t),createCoreModel(t){const e=Live2DModelWebGL.loadModel(t),s=Live2D.getError();if(s)throw s;return e},createInternalModel:(t,e,s)=>new rt(t,e,s),createPose:(t,e)=>new ht(t,e),createPhysics:(t,e)=>new lt(t,e)}),t.Cubism2ExpressionManager=tt,t.Cubism2InternalModel=rt,t.Cubism2ModelSettings=ot,t.Cubism2MotionManager=et,t.ExpressionManager=f,t.FileLoader=Y,t.FocusController=y,t.InteractionMixin=j,t.InternalModel=I,t.LOGICAL_HEIGHT=2,t.LOGICAL_WIDTH=2,t.Live2DExpression=K,t.Live2DEyeBlink=st,t.Live2DFactory=N,t.Live2DLoader=A,t.Live2DModel=z,t.Live2DPhysics=lt,t.Live2DPose=ht,t.Live2DTransform=W,t.ModelSettings=x,t.MotionManager=P,t.MotionPreloadStrategy=E,t.MotionPriority=M,t.MotionState=v,t.SoundManager=w,t.VERSION="0.4.0",t.XHRLoader=T,t.ZipLoader=Z,t.applyMixins=p,t.clamp=d,t.copyArray=u,t.copyProperty=c,t.folderName=g,t.logger=l,t.rand=h,t.remove=m,Object.defineProperties(t,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
diff --git a/dist/cubism4.es.js b/dist/cubism4.es.js
new file mode 100644
index 00000000..6a7e7d7a
--- /dev/null
+++ b/dist/cubism4.es.js
@@ -0,0 +1,6540 @@
+var __pow = Math.pow;
+var __async = (__this, __arguments, generator) => {
+ return new Promise((resolve, reject) => {
+ var fulfilled = (value) => {
+ try {
+ step(generator.next(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var rejected = (value) => {
+ try {
+ step(generator.throw(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
+ step((generator = generator.apply(__this, __arguments)).next());
+ });
+};
+import { EventEmitter, url } from "@pixi/utils";
+import { Matrix, Transform, Point, ObservablePoint } from "@pixi/math";
+import { Texture } from "@pixi/core";
+import { Container } from "@pixi/display";
+class CubismBreath {
+ constructor() {
+ this._breathParameters = [];
+ this._currentTime = 0;
+ }
+ static create() {
+ return new CubismBreath();
+ }
+ setParameters(breathParameters) {
+ this._breathParameters = breathParameters;
+ }
+ getParameters() {
+ return this._breathParameters;
+ }
+ updateParameters(model, deltaTimeSeconds) {
+ this._currentTime += deltaTimeSeconds;
+ const t = this._currentTime * 2 * 3.14159;
+ for (let i = 0; i < this._breathParameters.length; ++i) {
+ const data = this._breathParameters[i];
+ model.addParameterValueById(data.parameterId, data.offset + data.peak * Math.sin(t / data.cycle), data.weight);
+ }
+ }
+}
+class BreathParameterData {
+ constructor(parameterId, offset, peak, cycle, weight) {
+ this.parameterId = parameterId == void 0 ? void 0 : parameterId;
+ this.offset = offset == void 0 ? 0 : offset;
+ this.peak = peak == void 0 ? 0 : peak;
+ this.cycle = cycle == void 0 ? 0 : cycle;
+ this.weight = weight == void 0 ? 0 : weight;
+ }
+}
+const _CubismEyeBlink = class {
+ static create(modelSetting) {
+ return new _CubismEyeBlink(modelSetting);
+ }
+ setBlinkingInterval(blinkingInterval) {
+ this._blinkingIntervalSeconds = blinkingInterval;
+ }
+ setBlinkingSetting(closing, closed, opening) {
+ this._closingSeconds = closing;
+ this._closedSeconds = closed;
+ this._openingSeconds = opening;
+ }
+ setParameterIds(parameterIds) {
+ this._parameterIds = parameterIds;
+ }
+ getParameterIds() {
+ return this._parameterIds;
+ }
+ updateParameters(model, deltaTimeSeconds) {
+ this._userTimeSeconds += deltaTimeSeconds;
+ let parameterValue;
+ let t = 0;
+ switch (this._blinkingState) {
+ case EyeState.EyeState_Closing:
+ t = (this._userTimeSeconds - this._stateStartTimeSeconds) / this._closingSeconds;
+ if (t >= 1) {
+ t = 1;
+ this._blinkingState = EyeState.EyeState_Closed;
+ this._stateStartTimeSeconds = this._userTimeSeconds;
+ }
+ parameterValue = 1 - t;
+ break;
+ case EyeState.EyeState_Closed:
+ t = (this._userTimeSeconds - this._stateStartTimeSeconds) / this._closedSeconds;
+ if (t >= 1) {
+ this._blinkingState = EyeState.EyeState_Opening;
+ this._stateStartTimeSeconds = this._userTimeSeconds;
+ }
+ parameterValue = 0;
+ break;
+ case EyeState.EyeState_Opening:
+ t = (this._userTimeSeconds - this._stateStartTimeSeconds) / this._openingSeconds;
+ if (t >= 1) {
+ t = 1;
+ this._blinkingState = EyeState.EyeState_Interval;
+ this._nextBlinkingTime = this.determinNextBlinkingTiming();
+ }
+ parameterValue = t;
+ break;
+ case EyeState.EyeState_Interval:
+ if (this._nextBlinkingTime < this._userTimeSeconds) {
+ this._blinkingState = EyeState.EyeState_Closing;
+ this._stateStartTimeSeconds = this._userTimeSeconds;
+ }
+ parameterValue = 1;
+ break;
+ case EyeState.EyeState_First:
+ default:
+ this._blinkingState = EyeState.EyeState_Interval;
+ this._nextBlinkingTime = this.determinNextBlinkingTiming();
+ parameterValue = 1;
+ break;
+ }
+ if (!_CubismEyeBlink.CloseIfZero) {
+ parameterValue = -parameterValue;
+ }
+ for (let i = 0; i < this._parameterIds.length; ++i) {
+ model.setParameterValueById(this._parameterIds[i], parameterValue);
+ }
+ }
+ constructor(modelSetting) {
+ var _a, _b;
+ this._blinkingState = EyeState.EyeState_First;
+ this._nextBlinkingTime = 0;
+ this._stateStartTimeSeconds = 0;
+ this._blinkingIntervalSeconds = 4;
+ this._closingSeconds = 0.1;
+ this._closedSeconds = 0.05;
+ this._openingSeconds = 0.15;
+ this._userTimeSeconds = 0;
+ this._parameterIds = [];
+ if (modelSetting == null) {
+ return;
+ }
+ this._parameterIds = (_b = (_a = modelSetting.getEyeBlinkParameters()) == null ? void 0 : _a.slice()) != null ? _b : this._parameterIds;
+ }
+ determinNextBlinkingTiming() {
+ const r = Math.random();
+ return this._userTimeSeconds + r * (2 * this._blinkingIntervalSeconds - 1);
+ }
+};
+let CubismEyeBlink = _CubismEyeBlink;
+CubismEyeBlink.CloseIfZero = true;
+var EyeState = /* @__PURE__ */ ((EyeState2) => {
+ EyeState2[EyeState2["EyeState_First"] = 0] = "EyeState_First";
+ EyeState2[EyeState2["EyeState_Interval"] = 1] = "EyeState_Interval";
+ EyeState2[EyeState2["EyeState_Closing"] = 2] = "EyeState_Closing";
+ EyeState2[EyeState2["EyeState_Closed"] = 3] = "EyeState_Closed";
+ EyeState2[EyeState2["EyeState_Opening"] = 4] = "EyeState_Opening";
+ return EyeState2;
+})(EyeState || {});
+const Epsilon = 1e-3;
+const DefaultFadeInSeconds = 0.5;
+class CubismPose {
+ static create(pose3json) {
+ const ret = new CubismPose();
+ if (typeof pose3json.FadeInTime === "number") {
+ ret._fadeTimeSeconds = pose3json.FadeInTime;
+ if (ret._fadeTimeSeconds <= 0) {
+ ret._fadeTimeSeconds = DefaultFadeInSeconds;
+ }
+ }
+ const poseListInfo = pose3json.Groups;
+ const poseCount = poseListInfo.length;
+ for (let poseIndex = 0; poseIndex < poseCount; ++poseIndex) {
+ const idListInfo = poseListInfo[poseIndex];
+ const idCount = idListInfo.length;
+ let groupCount = 0;
+ for (let groupIndex = 0; groupIndex < idCount; ++groupIndex) {
+ const partInfo = idListInfo[groupIndex];
+ const partData = new PartData();
+ partData.partId = partInfo.Id;
+ const linkListInfo = partInfo.Link;
+ if (linkListInfo) {
+ const linkCount = linkListInfo.length;
+ for (let linkIndex = 0; linkIndex < linkCount; ++linkIndex) {
+ const linkPart = new PartData();
+ linkPart.partId = linkListInfo[linkIndex];
+ partData.link.push(linkPart);
+ }
+ }
+ ret._partGroups.push(partData);
+ ++groupCount;
+ }
+ ret._partGroupCounts.push(groupCount);
+ }
+ return ret;
+ }
+ updateParameters(model, deltaTimeSeconds) {
+ if (model != this._lastModel) {
+ this.reset(model);
+ }
+ this._lastModel = model;
+ if (deltaTimeSeconds < 0) {
+ deltaTimeSeconds = 0;
+ }
+ let beginIndex = 0;
+ for (let i = 0; i < this._partGroupCounts.length; i++) {
+ const partGroupCount = this._partGroupCounts[i];
+ this.doFade(model, deltaTimeSeconds, beginIndex, partGroupCount);
+ beginIndex += partGroupCount;
+ }
+ this.copyPartOpacities(model);
+ }
+ reset(model) {
+ let beginIndex = 0;
+ for (let i = 0; i < this._partGroupCounts.length; ++i) {
+ const groupCount = this._partGroupCounts[i];
+ for (let j = beginIndex; j < beginIndex + groupCount; ++j) {
+ this._partGroups[j].initialize(model);
+ const partsIndex = this._partGroups[j].partIndex;
+ const paramIndex = this._partGroups[j].parameterIndex;
+ if (partsIndex < 0) {
+ continue;
+ }
+ model.setPartOpacityByIndex(partsIndex, j == beginIndex ? 1 : 0);
+ model.setParameterValueByIndex(paramIndex, j == beginIndex ? 1 : 0);
+ for (let k = 0; k < this._partGroups[j].link.length; ++k) {
+ this._partGroups[j].link[k].initialize(model);
+ }
+ }
+ beginIndex += groupCount;
+ }
+ }
+ copyPartOpacities(model) {
+ for (let groupIndex = 0; groupIndex < this._partGroups.length; ++groupIndex) {
+ const partData = this._partGroups[groupIndex];
+ if (partData.link.length == 0) {
+ continue;
+ }
+ const partIndex = this._partGroups[groupIndex].partIndex;
+ const opacity = model.getPartOpacityByIndex(partIndex);
+ for (let linkIndex = 0; linkIndex < partData.link.length; ++linkIndex) {
+ const linkPart = partData.link[linkIndex];
+ const linkPartIndex = linkPart.partIndex;
+ if (linkPartIndex < 0) {
+ continue;
+ }
+ model.setPartOpacityByIndex(linkPartIndex, opacity);
+ }
+ }
+ }
+ doFade(model, deltaTimeSeconds, beginIndex, partGroupCount) {
+ let visiblePartIndex = -1;
+ let newOpacity = 1;
+ const phi = 0.5;
+ const backOpacityThreshold = 0.15;
+ for (let i = beginIndex; i < beginIndex + partGroupCount; ++i) {
+ const partIndex = this._partGroups[i].partIndex;
+ const paramIndex = this._partGroups[i].parameterIndex;
+ if (model.getParameterValueByIndex(paramIndex) > Epsilon) {
+ if (visiblePartIndex >= 0) {
+ break;
+ }
+ visiblePartIndex = i;
+ newOpacity = model.getPartOpacityByIndex(partIndex);
+ newOpacity += deltaTimeSeconds / this._fadeTimeSeconds;
+ if (newOpacity > 1) {
+ newOpacity = 1;
+ }
+ }
+ }
+ if (visiblePartIndex < 0) {
+ visiblePartIndex = 0;
+ newOpacity = 1;
+ }
+ for (let i = beginIndex; i < beginIndex + partGroupCount; ++i) {
+ const partsIndex = this._partGroups[i].partIndex;
+ if (visiblePartIndex == i) {
+ model.setPartOpacityByIndex(partsIndex, newOpacity);
+ } else {
+ let opacity = model.getPartOpacityByIndex(partsIndex);
+ let a1;
+ if (newOpacity < phi) {
+ a1 = newOpacity * (phi - 1) / phi + 1;
+ } else {
+ a1 = (1 - newOpacity) * phi / (1 - phi);
+ }
+ const backOpacity = (1 - a1) * (1 - newOpacity);
+ if (backOpacity > backOpacityThreshold) {
+ a1 = 1 - backOpacityThreshold / (1 - newOpacity);
+ }
+ if (opacity > a1) {
+ opacity = a1;
+ }
+ model.setPartOpacityByIndex(partsIndex, opacity);
+ }
+ }
+ }
+ constructor() {
+ this._fadeTimeSeconds = DefaultFadeInSeconds;
+ this._lastModel = void 0;
+ this._partGroups = [];
+ this._partGroupCounts = [];
+ }
+}
+class PartData {
+ constructor(v) {
+ this.parameterIndex = 0;
+ this.partIndex = 0;
+ this.partId = "";
+ this.link = [];
+ if (v != void 0) {
+ this.assignment(v);
+ }
+ }
+ assignment(v) {
+ this.partId = v.partId;
+ this.link = v.link.map((link) => link.clone());
+ return this;
+ }
+ initialize(model) {
+ this.parameterIndex = model.getParameterIndex(this.partId);
+ this.partIndex = model.getPartIndex(this.partId);
+ model.setParameterValueByIndex(this.parameterIndex, 1);
+ }
+ clone() {
+ const clonePartData = new PartData();
+ clonePartData.partId = this.partId;
+ clonePartData.parameterIndex = this.parameterIndex;
+ clonePartData.partIndex = this.partIndex;
+ clonePartData.link = this.link.map((link) => link.clone());
+ return clonePartData;
+ }
+}
+class CubismVector2 {
+ constructor(x, y) {
+ this.x = x || 0;
+ this.y = y || 0;
+ }
+ add(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x + vector2.x;
+ ret.y = this.y + vector2.y;
+ return ret;
+ }
+ substract(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x - vector2.x;
+ ret.y = this.y - vector2.y;
+ return ret;
+ }
+ multiply(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x * vector2.x;
+ ret.y = this.y * vector2.y;
+ return ret;
+ }
+ multiplyByScaler(scalar) {
+ return this.multiply(new CubismVector2(scalar, scalar));
+ }
+ division(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x / vector2.x;
+ ret.y = this.y / vector2.y;
+ return ret;
+ }
+ divisionByScalar(scalar) {
+ return this.division(new CubismVector2(scalar, scalar));
+ }
+ getLength() {
+ return Math.sqrt(this.x * this.x + this.y * this.y);
+ }
+ getDistanceWith(a) {
+ return Math.sqrt((this.x - a.x) * (this.x - a.x) + (this.y - a.y) * (this.y - a.y));
+ }
+ dot(a) {
+ return this.x * a.x + this.y * a.y;
+ }
+ normalize() {
+ const length = Math.pow(this.x * this.x + this.y * this.y, 0.5);
+ this.x = this.x / length;
+ this.y = this.y / length;
+ }
+ isEqual(rhs) {
+ return this.x == rhs.x && this.y == rhs.y;
+ }
+ isNotEqual(rhs) {
+ return !this.isEqual(rhs);
+ }
+}
+const _CubismMath = class {
+ static range(value, min, max) {
+ if (value < min) {
+ value = min;
+ } else if (value > max) {
+ value = max;
+ }
+ return value;
+ }
+ static sin(x) {
+ return Math.sin(x);
+ }
+ static cos(x) {
+ return Math.cos(x);
+ }
+ static abs(x) {
+ return Math.abs(x);
+ }
+ static sqrt(x) {
+ return Math.sqrt(x);
+ }
+ static cbrt(x) {
+ if (x === 0) {
+ return x;
+ }
+ let cx = x;
+ const isNegativeNumber = cx < 0;
+ if (isNegativeNumber) {
+ cx = -cx;
+ }
+ let ret;
+ if (cx === Infinity) {
+ ret = Infinity;
+ } else {
+ ret = Math.exp(Math.log(cx) / 3);
+ ret = (cx / (ret * ret) + 2 * ret) / 3;
+ }
+ return isNegativeNumber ? -ret : ret;
+ }
+ static getEasingSine(value) {
+ if (value < 0) {
+ return 0;
+ } else if (value > 1) {
+ return 1;
+ }
+ return 0.5 - 0.5 * this.cos(value * Math.PI);
+ }
+ static max(left, right) {
+ return left > right ? left : right;
+ }
+ static min(left, right) {
+ return left > right ? right : left;
+ }
+ static degreesToRadian(degrees) {
+ return degrees / 180 * Math.PI;
+ }
+ static radianToDegrees(radian) {
+ return radian * 180 / Math.PI;
+ }
+ static directionToRadian(from, to) {
+ const q1 = Math.atan2(to.y, to.x);
+ const q2 = Math.atan2(from.y, from.x);
+ let ret = q1 - q2;
+ while (ret < -Math.PI) {
+ ret += Math.PI * 2;
+ }
+ while (ret > Math.PI) {
+ ret -= Math.PI * 2;
+ }
+ return ret;
+ }
+ static directionToDegrees(from, to) {
+ const radian = this.directionToRadian(from, to);
+ let degree = this.radianToDegrees(radian);
+ if (to.x - from.x > 0) {
+ degree = -degree;
+ }
+ return degree;
+ }
+ static radianToDirection(totalAngle) {
+ const ret = new CubismVector2();
+ ret.x = this.sin(totalAngle);
+ ret.y = this.cos(totalAngle);
+ return ret;
+ }
+ static quadraticEquation(a, b, c) {
+ if (this.abs(a) < _CubismMath.Epsilon) {
+ if (this.abs(b) < _CubismMath.Epsilon) {
+ return -c;
+ }
+ return -c / b;
+ }
+ return -(b + this.sqrt(b * b - 4 * a * c)) / (2 * a);
+ }
+ static cardanoAlgorithmForBezier(a, b, c, d) {
+ if (this.sqrt(a) < _CubismMath.Epsilon) {
+ return this.range(this.quadraticEquation(b, c, d), 0, 1);
+ }
+ const ba = b / a;
+ const ca = c / a;
+ const da = d / a;
+ const p = (3 * ca - ba * ba) / 3;
+ const p3 = p / 3;
+ const q = (2 * ba * ba * ba - 9 * ba * ca + 27 * da) / 27;
+ const q2 = q / 2;
+ const discriminant = q2 * q2 + p3 * p3 * p3;
+ const center = 0.5;
+ const threshold = center + 0.01;
+ if (discriminant < 0) {
+ const mp3 = -p / 3;
+ const mp33 = mp3 * mp3 * mp3;
+ const r = this.sqrt(mp33);
+ const t = -q / (2 * r);
+ const cosphi = this.range(t, -1, 1);
+ const phi = Math.acos(cosphi);
+ const crtr = this.cbrt(r);
+ const t1 = 2 * crtr;
+ const root12 = t1 * this.cos(phi / 3) - ba / 3;
+ if (this.abs(root12 - center) < threshold) {
+ return this.range(root12, 0, 1);
+ }
+ const root2 = t1 * this.cos((phi + 2 * Math.PI) / 3) - ba / 3;
+ if (this.abs(root2 - center) < threshold) {
+ return this.range(root2, 0, 1);
+ }
+ const root3 = t1 * this.cos((phi + 4 * Math.PI) / 3) - ba / 3;
+ return this.range(root3, 0, 1);
+ }
+ if (discriminant == 0) {
+ let u12;
+ if (q2 < 0) {
+ u12 = this.cbrt(-q2);
+ } else {
+ u12 = -this.cbrt(q2);
+ }
+ const root12 = 2 * u12 - ba / 3;
+ if (this.abs(root12 - center) < threshold) {
+ return this.range(root12, 0, 1);
+ }
+ const root2 = -u12 - ba / 3;
+ return this.range(root2, 0, 1);
+ }
+ const sd = this.sqrt(discriminant);
+ const u1 = this.cbrt(sd - q2);
+ const v1 = this.cbrt(sd + q2);
+ const root1 = u1 - v1 - ba / 3;
+ return this.range(root1, 0, 1);
+ }
+ constructor() {
+ }
+};
+let CubismMath = _CubismMath;
+CubismMath.Epsilon = 1e-5;
+class CubismMatrix44 {
+ constructor() {
+ this._tr = new Float32Array(16);
+ this.loadIdentity();
+ }
+ static multiply(a, b, dst) {
+ const c = new Float32Array([
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]);
+ const n = 4;
+ for (let i = 0; i < n; ++i) {
+ for (let j = 0; j < n; ++j) {
+ for (let k = 0; k < n; ++k) {
+ c[j + i * 4] += a[k + i * 4] * b[j + k * 4];
+ }
+ }
+ }
+ for (let i = 0; i < 16; ++i) {
+ dst[i] = c[i];
+ }
+ }
+ loadIdentity() {
+ const c = new Float32Array([
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ]);
+ this.setMatrix(c);
+ }
+ setMatrix(tr) {
+ for (let i = 0; i < 16; ++i) {
+ this._tr[i] = tr[i];
+ }
+ }
+ getArray() {
+ return this._tr;
+ }
+ getScaleX() {
+ return this._tr[0];
+ }
+ getScaleY() {
+ return this._tr[5];
+ }
+ getTranslateX() {
+ return this._tr[12];
+ }
+ getTranslateY() {
+ return this._tr[13];
+ }
+ transformX(src) {
+ return this._tr[0] * src + this._tr[12];
+ }
+ transformY(src) {
+ return this._tr[5] * src + this._tr[13];
+ }
+ invertTransformX(src) {
+ return (src - this._tr[12]) / this._tr[0];
+ }
+ invertTransformY(src) {
+ return (src - this._tr[13]) / this._tr[5];
+ }
+ translateRelative(x, y) {
+ const tr1 = new Float32Array([
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ x,
+ y,
+ 0,
+ 1
+ ]);
+ CubismMatrix44.multiply(tr1, this._tr, this._tr);
+ }
+ translate(x, y) {
+ this._tr[12] = x;
+ this._tr[13] = y;
+ }
+ translateX(x) {
+ this._tr[12] = x;
+ }
+ translateY(y) {
+ this._tr[13] = y;
+ }
+ scaleRelative(x, y) {
+ const tr1 = new Float32Array([
+ x,
+ 0,
+ 0,
+ 0,
+ 0,
+ y,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ]);
+ CubismMatrix44.multiply(tr1, this._tr, this._tr);
+ }
+ scale(x, y) {
+ this._tr[0] = x;
+ this._tr[5] = y;
+ }
+ multiplyByMatrix(m) {
+ CubismMatrix44.multiply(m.getArray(), this._tr, this._tr);
+ }
+ clone() {
+ const cloneMatrix = new CubismMatrix44();
+ for (let i = 0; i < this._tr.length; i++) {
+ cloneMatrix._tr[i] = this._tr[i];
+ }
+ return cloneMatrix;
+ }
+}
+class CubismRenderer {
+ initialize(model) {
+ this._model = model;
+ }
+ drawModel() {
+ if (this.getModel() == null)
+ return;
+ this.saveProfile();
+ this.doDrawModel();
+ this.restoreProfile();
+ }
+ setMvpMatrix(matrix44) {
+ this._mvpMatrix4x4.setMatrix(matrix44.getArray());
+ }
+ getMvpMatrix() {
+ return this._mvpMatrix4x4;
+ }
+ setModelColor(red, green, blue, alpha) {
+ if (red < 0) {
+ red = 0;
+ } else if (red > 1) {
+ red = 1;
+ }
+ if (green < 0) {
+ green = 0;
+ } else if (green > 1) {
+ green = 1;
+ }
+ if (blue < 0) {
+ blue = 0;
+ } else if (blue > 1) {
+ blue = 1;
+ }
+ if (alpha < 0) {
+ alpha = 0;
+ } else if (alpha > 1) {
+ alpha = 1;
+ }
+ this._modelColor.R = red;
+ this._modelColor.G = green;
+ this._modelColor.B = blue;
+ this._modelColor.A = alpha;
+ }
+ getModelColor() {
+ return Object.assign({}, this._modelColor);
+ }
+ setIsPremultipliedAlpha(enable) {
+ this._isPremultipliedAlpha = enable;
+ }
+ isPremultipliedAlpha() {
+ return this._isPremultipliedAlpha;
+ }
+ setIsCulling(culling) {
+ this._isCulling = culling;
+ }
+ isCulling() {
+ return this._isCulling;
+ }
+ setAnisotropy(n) {
+ this._anisotropy = n;
+ }
+ getAnisotropy() {
+ return this._anisotropy;
+ }
+ getModel() {
+ return this._model;
+ }
+ useHighPrecisionMask(high) {
+ this._useHighPrecisionMask = high;
+ }
+ isUsingHighPrecisionMask() {
+ return this._useHighPrecisionMask;
+ }
+ constructor() {
+ this._isCulling = false;
+ this._isPremultipliedAlpha = false;
+ this._anisotropy = 0;
+ this._modelColor = new CubismTextureColor();
+ this._useHighPrecisionMask = false;
+ this._mvpMatrix4x4 = new CubismMatrix44();
+ this._mvpMatrix4x4.loadIdentity();
+ }
+}
+var CubismBlendMode = /* @__PURE__ */ ((CubismBlendMode2) => {
+ CubismBlendMode2[CubismBlendMode2["CubismBlendMode_Normal"] = 0] = "CubismBlendMode_Normal";
+ CubismBlendMode2[CubismBlendMode2["CubismBlendMode_Additive"] = 1] = "CubismBlendMode_Additive";
+ CubismBlendMode2[CubismBlendMode2["CubismBlendMode_Multiplicative"] = 2] = "CubismBlendMode_Multiplicative";
+ return CubismBlendMode2;
+})(CubismBlendMode || {});
+class CubismTextureColor {
+ constructor(r = 1, g = 1, b = 1, a = 1) {
+ this.R = r;
+ this.G = g;
+ this.B = b;
+ this.A = a;
+ }
+}
+let s_isStarted = false;
+let s_isInitialized = false;
+let s_option = void 0;
+const Constant = {
+ vertexOffset: 0,
+ vertexStep: 2
+};
+class CubismFramework {
+ static startUp(option) {
+ if (s_isStarted) {
+ CubismLogInfo("CubismFramework.startUp() is already done.");
+ return s_isStarted;
+ }
+ if (Live2DCubismCore._isStarted) {
+ s_isStarted = true;
+ return true;
+ }
+ Live2DCubismCore._isStarted = true;
+ s_option = option;
+ if (s_option) {
+ Live2DCubismCore.Logging.csmSetLogFunction(s_option.logFunction);
+ }
+ s_isStarted = true;
+ if (s_isStarted) {
+ const version = Live2DCubismCore.Version.csmGetVersion();
+ const major = (version & 4278190080) >> 24;
+ const minor = (version & 16711680) >> 16;
+ const patch = version & 65535;
+ const versionNumber = version;
+ CubismLogInfo(`Live2D Cubism Core version: {0}.{1}.{2} ({3})`, ("00" + major).slice(-2), ("00" + minor).slice(-2), ("0000" + patch).slice(-4), versionNumber);
+ }
+ CubismLogInfo("CubismFramework.startUp() is complete.");
+ return s_isStarted;
+ }
+ static cleanUp() {
+ s_isStarted = false;
+ s_isInitialized = false;
+ s_option = void 0;
+ }
+ static initialize(memorySize = 0) {
+ if (!s_isStarted) {
+ CubismLogWarning("CubismFramework is not started.");
+ return;
+ }
+ if (s_isInitialized) {
+ CubismLogWarning("CubismFramework.initialize() skipped, already initialized.");
+ return;
+ }
+ Live2DCubismCore.Memory.initializeAmountOfMemory(memorySize);
+ s_isInitialized = true;
+ CubismLogInfo("CubismFramework.initialize() is complete.");
+ }
+ static dispose() {
+ if (!s_isStarted) {
+ CubismLogWarning("CubismFramework is not started.");
+ return;
+ }
+ if (!s_isInitialized) {
+ CubismLogWarning("CubismFramework.dispose() skipped, not initialized.");
+ return;
+ }
+ CubismRenderer.staticRelease();
+ s_isInitialized = false;
+ CubismLogInfo("CubismFramework.dispose() is complete.");
+ }
+ static isStarted() {
+ return s_isStarted;
+ }
+ static isInitialized() {
+ return s_isInitialized;
+ }
+ static coreLogFunction(message) {
+ if (!Live2DCubismCore.Logging.csmGetLogFunction()) {
+ return;
+ }
+ Live2DCubismCore.Logging.csmGetLogFunction()(message);
+ }
+ static getLoggingLevel() {
+ if (s_option != null) {
+ return s_option.loggingLevel;
+ }
+ return LogLevel.LogLevel_Off;
+ }
+ constructor() {
+ }
+}
+var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
+ LogLevel2[LogLevel2["LogLevel_Verbose"] = 0] = "LogLevel_Verbose";
+ LogLevel2[LogLevel2["LogLevel_Debug"] = 1] = "LogLevel_Debug";
+ LogLevel2[LogLevel2["LogLevel_Info"] = 2] = "LogLevel_Info";
+ LogLevel2[LogLevel2["LogLevel_Warning"] = 3] = "LogLevel_Warning";
+ LogLevel2[LogLevel2["LogLevel_Error"] = 4] = "LogLevel_Error";
+ LogLevel2[LogLevel2["LogLevel_Off"] = 5] = "LogLevel_Off";
+ return LogLevel2;
+})(LogLevel || {});
+const CSM_ASSERT = () => {
+};
+function CubismLogVerbose(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Verbose, "[CSM][V]" + fmt + "\n", args);
+}
+function CubismLogDebug(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Debug, "[CSM][D]" + fmt + "\n", args);
+}
+function CubismLogInfo(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Info, "[CSM][I]" + fmt + "\n", args);
+}
+function CubismLogWarning(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Warning, "[CSM][W]" + fmt + "\n", args);
+}
+function CubismLogError(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Error, "[CSM][E]" + fmt + "\n", args);
+}
+class CubismDebug {
+ static print(logLevel, format, args) {
+ if (logLevel < CubismFramework.getLoggingLevel()) {
+ return;
+ }
+ const logPrint = CubismFramework.coreLogFunction;
+ if (!logPrint)
+ return;
+ const buffer = format.replace(/{(\d+)}/g, (m, k) => {
+ return args[k];
+ });
+ logPrint(buffer);
+ }
+ static dumpBytes(logLevel, data, length) {
+ for (let i = 0; i < length; i++) {
+ if (i % 16 == 0 && i > 0)
+ this.print(logLevel, "\n");
+ else if (i % 8 == 0 && i > 0)
+ this.print(logLevel, " ");
+ this.print(logLevel, "{0} ", [data[i] & 255]);
+ }
+ this.print(logLevel, "\n");
+ }
+ constructor() {
+ }
+}
+class DrawableColorData {
+ constructor(isOverwritten = false, color = new CubismTextureColor()) {
+ this.isOverwritten = isOverwritten;
+ this.Color = color;
+ }
+}
+class PartColorData {
+ constructor(isOverwritten = false, color = new CubismTextureColor()) {
+ this.isOverwritten = isOverwritten;
+ this.Color = color;
+ }
+}
+class DrawableCullingData {
+ constructor(isOverwritten = false, isCulling = false) {
+ this.isOverwritten = isOverwritten;
+ this.isCulling = isCulling;
+ }
+}
+class CubismModel {
+ update() {
+ this._model.update();
+ this._model.drawables.resetDynamicFlags();
+ }
+ getPixelsPerUnit() {
+ if (this._model == null) {
+ return 0;
+ }
+ return this._model.canvasinfo.PixelsPerUnit;
+ }
+ getCanvasWidth() {
+ if (this._model == null) {
+ return 0;
+ }
+ return this._model.canvasinfo.CanvasWidth / this._model.canvasinfo.PixelsPerUnit;
+ }
+ getCanvasHeight() {
+ if (this._model == null) {
+ return 0;
+ }
+ return this._model.canvasinfo.CanvasHeight / this._model.canvasinfo.PixelsPerUnit;
+ }
+ saveParameters() {
+ const parameterCount = this._model.parameters.count;
+ const savedParameterCount = this._savedParameters.length;
+ for (let i = 0; i < parameterCount; ++i) {
+ if (i < savedParameterCount) {
+ this._savedParameters[i] = this._parameterValues[i];
+ } else {
+ this._savedParameters.push(this._parameterValues[i]);
+ }
+ }
+ }
+ getMultiplyColor(index) {
+ if (this.getOverwriteFlagForModelMultiplyColors() || this.getOverwriteFlagForDrawableMultiplyColors(index)) {
+ return this._userMultiplyColors[index].Color;
+ }
+ const color = this.getDrawableMultiplyColor(index);
+ return color;
+ }
+ getScreenColor(index) {
+ if (this.getOverwriteFlagForModelScreenColors() || this.getOverwriteFlagForDrawableScreenColors(index)) {
+ return this._userScreenColors[index].Color;
+ }
+ const color = this.getDrawableScreenColor(index);
+ return color;
+ }
+ setMultiplyColorByTextureColor(index, color) {
+ this.setMultiplyColorByRGBA(index, color.R, color.G, color.B, color.A);
+ }
+ setMultiplyColorByRGBA(index, r, g, b, a = 1) {
+ this._userMultiplyColors[index].Color.R = r;
+ this._userMultiplyColors[index].Color.G = g;
+ this._userMultiplyColors[index].Color.B = b;
+ this._userMultiplyColors[index].Color.A = a;
+ }
+ setScreenColorByTextureColor(index, color) {
+ this.setScreenColorByRGBA(index, color.R, color.G, color.B, color.A);
+ }
+ setScreenColorByRGBA(index, r, g, b, a = 1) {
+ this._userScreenColors[index].Color.R = r;
+ this._userScreenColors[index].Color.G = g;
+ this._userScreenColors[index].Color.B = b;
+ this._userScreenColors[index].Color.A = a;
+ }
+ getPartMultiplyColor(partIndex) {
+ return this._userPartMultiplyColors[partIndex].Color;
+ }
+ getPartScreenColor(partIndex) {
+ return this._userPartScreenColors[partIndex].Color;
+ }
+ setPartColor(partIndex, r, g, b, a, partColors, drawableColors) {
+ partColors[partIndex].Color.R = r;
+ partColors[partIndex].Color.G = g;
+ partColors[partIndex].Color.B = b;
+ partColors[partIndex].Color.A = a;
+ if (partColors[partIndex].isOverwritten) {
+ for (let i = 0; i < this._partChildDrawables[partIndex].length; ++i) {
+ const drawableIndex = this._partChildDrawables[partIndex][i];
+ drawableColors[drawableIndex].Color.R = r;
+ drawableColors[drawableIndex].Color.G = g;
+ drawableColors[drawableIndex].Color.B = b;
+ drawableColors[drawableIndex].Color.A = a;
+ }
+ }
+ }
+ setPartMultiplyColorByTextureColor(partIndex, color) {
+ this.setPartMultiplyColorByRGBA(partIndex, color.R, color.G, color.B, color.A);
+ }
+ setPartMultiplyColorByRGBA(partIndex, r, g, b, a) {
+ this.setPartColor(partIndex, r, g, b, a, this._userPartMultiplyColors, this._userMultiplyColors);
+ }
+ setPartScreenColorByTextureColor(partIndex, color) {
+ this.setPartScreenColorByRGBA(partIndex, color.R, color.G, color.B, color.A);
+ }
+ setPartScreenColorByRGBA(partIndex, r, g, b, a) {
+ this.setPartColor(partIndex, r, g, b, a, this._userPartScreenColors, this._userScreenColors);
+ }
+ getOverwriteFlagForModelMultiplyColors() {
+ return this._isOverwrittenModelMultiplyColors;
+ }
+ getOverwriteFlagForModelScreenColors() {
+ return this._isOverwrittenModelScreenColors;
+ }
+ setOverwriteFlagForModelMultiplyColors(value) {
+ this._isOverwrittenModelMultiplyColors = value;
+ }
+ setOverwriteFlagForModelScreenColors(value) {
+ this._isOverwrittenModelScreenColors = value;
+ }
+ getOverwriteFlagForDrawableMultiplyColors(drawableindex) {
+ return this._userMultiplyColors[drawableindex].isOverwritten;
+ }
+ getOverwriteFlagForDrawableScreenColors(drawableindex) {
+ return this._userScreenColors[drawableindex].isOverwritten;
+ }
+ setOverwriteFlagForDrawableMultiplyColors(drawableindex, value) {
+ this._userMultiplyColors[drawableindex].isOverwritten = value;
+ }
+ setOverwriteFlagForDrawableScreenColors(drawableindex, value) {
+ this._userScreenColors[drawableindex].isOverwritten = value;
+ }
+ getOverwriteColorForPartMultiplyColors(partIndex) {
+ return this._userPartMultiplyColors[partIndex].isOverwritten;
+ }
+ getOverwriteColorForPartScreenColors(partIndex) {
+ return this._userPartScreenColors[partIndex].isOverwritten;
+ }
+ setOverwriteColorForPartColors(partIndex, value, partColors, drawableColors) {
+ partColors[partIndex].isOverwritten = value;
+ for (let i = 0; i < this._partChildDrawables[partIndex].length; ++i) {
+ const drawableIndex = this._partChildDrawables[partIndex][i];
+ drawableColors[drawableIndex].isOverwritten = value;
+ if (value) {
+ drawableColors[drawableIndex].Color.R = partColors[partIndex].Color.R;
+ drawableColors[drawableIndex].Color.G = partColors[partIndex].Color.G;
+ drawableColors[drawableIndex].Color.B = partColors[partIndex].Color.B;
+ drawableColors[drawableIndex].Color.A = partColors[partIndex].Color.A;
+ }
+ }
+ }
+ setOverwriteColorForPartMultiplyColors(partIndex, value) {
+ this._userPartMultiplyColors[partIndex].isOverwritten = value;
+ this.setOverwriteColorForPartColors(partIndex, value, this._userPartMultiplyColors, this._userMultiplyColors);
+ }
+ setOverwriteColorForPartScreenColors(partIndex, value) {
+ this._userPartScreenColors[partIndex].isOverwritten = value;
+ this.setOverwriteColorForPartColors(partIndex, value, this._userPartScreenColors, this._userScreenColors);
+ }
+ getDrawableCulling(drawableIndex) {
+ if (this.getOverwriteFlagForModelCullings() || this.getOverwriteFlagForDrawableCullings(drawableIndex)) {
+ return this._userCullings[drawableIndex].isCulling;
+ }
+ const constantFlags = this._model.drawables.constantFlags;
+ return !Live2DCubismCore.Utils.hasIsDoubleSidedBit(constantFlags[drawableIndex]);
+ }
+ setDrawableCulling(drawableIndex, isCulling) {
+ this._userCullings[drawableIndex].isCulling = isCulling;
+ }
+ getOverwriteFlagForModelCullings() {
+ return this._isOverwrittenCullings;
+ }
+ setOverwriteFlagForModelCullings(isOverwrittenCullings) {
+ this._isOverwrittenCullings = isOverwrittenCullings;
+ }
+ getOverwriteFlagForDrawableCullings(drawableIndex) {
+ return this._userCullings[drawableIndex].isOverwritten;
+ }
+ setOverwriteFlagForDrawableCullings(drawableIndex, isOverwrittenCullings) {
+ this._userCullings[drawableIndex].isOverwritten = isOverwrittenCullings;
+ }
+ getModelOapcity() {
+ return this._modelOpacity;
+ }
+ setModelOapcity(value) {
+ this._modelOpacity = value;
+ }
+ getModel() {
+ return this._model;
+ }
+ getPartIndex(partId) {
+ let partIndex;
+ const partCount = this._model.parts.count;
+ for (partIndex = 0; partIndex < partCount; ++partIndex) {
+ if (partId == this._partIds[partIndex]) {
+ return partIndex;
+ }
+ }
+ if (partId in this._notExistPartId) {
+ return this._notExistPartId[partId];
+ }
+ partIndex = partCount + this._notExistPartId.length;
+ this._notExistPartId[partId] = partIndex;
+ this._notExistPartOpacities[partIndex] = 0;
+ return partIndex;
+ }
+ getPartId(partIndex) {
+ return this._model.parts.ids[partIndex];
+ }
+ getPartCount() {
+ return this._model.parts.count;
+ }
+ setPartOpacityByIndex(partIndex, opacity) {
+ if (partIndex in this._notExistPartOpacities) {
+ this._notExistPartOpacities[partIndex] = opacity;
+ return;
+ }
+ CSM_ASSERT(0 <= partIndex && partIndex < this.getPartCount());
+ this._partOpacities[partIndex] = opacity;
+ }
+ setPartOpacityById(partId, opacity) {
+ const index = this.getPartIndex(partId);
+ if (index < 0) {
+ return;
+ }
+ this.setPartOpacityByIndex(index, opacity);
+ }
+ getPartOpacityByIndex(partIndex) {
+ if (partIndex in this._notExistPartOpacities) {
+ return this._notExistPartOpacities[partIndex];
+ }
+ CSM_ASSERT(0 <= partIndex && partIndex < this.getPartCount());
+ return this._partOpacities[partIndex];
+ }
+ getPartOpacityById(partId) {
+ const index = this.getPartIndex(partId);
+ if (index < 0) {
+ return 0;
+ }
+ return this.getPartOpacityByIndex(index);
+ }
+ getParameterIndex(parameterId) {
+ let parameterIndex;
+ const idCount = this._model.parameters.count;
+ for (parameterIndex = 0; parameterIndex < idCount; ++parameterIndex) {
+ if (parameterId != this._parameterIds[parameterIndex]) {
+ continue;
+ }
+ return parameterIndex;
+ }
+ if (parameterId in this._notExistParameterId) {
+ return this._notExistParameterId[parameterId];
+ }
+ parameterIndex = this._model.parameters.count + Object.keys(this._notExistParameterId).length;
+ this._notExistParameterId[parameterId] = parameterIndex;
+ this._notExistParameterValues[parameterIndex] = 0;
+ return parameterIndex;
+ }
+ getParameterCount() {
+ return this._model.parameters.count;
+ }
+ getParameterType(parameterIndex) {
+ return this._model.parameters.types[parameterIndex];
+ }
+ getParameterMaximumValue(parameterIndex) {
+ return this._model.parameters.maximumValues[parameterIndex];
+ }
+ getParameterMinimumValue(parameterIndex) {
+ return this._model.parameters.minimumValues[parameterIndex];
+ }
+ getParameterDefaultValue(parameterIndex) {
+ return this._model.parameters.defaultValues[parameterIndex];
+ }
+ getParameterValueByIndex(parameterIndex) {
+ if (parameterIndex in this._notExistParameterValues) {
+ return this._notExistParameterValues[parameterIndex];
+ }
+ CSM_ASSERT(0 <= parameterIndex && parameterIndex < this.getParameterCount());
+ return this._parameterValues[parameterIndex];
+ }
+ getParameterValueById(parameterId) {
+ const parameterIndex = this.getParameterIndex(parameterId);
+ return this.getParameterValueByIndex(parameterIndex);
+ }
+ setParameterValueByIndex(parameterIndex, value, weight = 1) {
+ if (parameterIndex in this._notExistParameterValues) {
+ this._notExistParameterValues[parameterIndex] = weight == 1 ? value : this._notExistParameterValues[parameterIndex] * (1 - weight) + value * weight;
+ return;
+ }
+ CSM_ASSERT(0 <= parameterIndex && parameterIndex < this.getParameterCount());
+ if (this._model.parameters.maximumValues[parameterIndex] < value) {
+ value = this._model.parameters.maximumValues[parameterIndex];
+ }
+ if (this._model.parameters.minimumValues[parameterIndex] > value) {
+ value = this._model.parameters.minimumValues[parameterIndex];
+ }
+ this._parameterValues[parameterIndex] = weight == 1 ? value : this._parameterValues[parameterIndex] = this._parameterValues[parameterIndex] * (1 - weight) + value * weight;
+ }
+ setParameterValueById(parameterId, value, weight = 1) {
+ const index = this.getParameterIndex(parameterId);
+ this.setParameterValueByIndex(index, value, weight);
+ }
+ addParameterValueByIndex(parameterIndex, value, weight = 1) {
+ this.setParameterValueByIndex(parameterIndex, this.getParameterValueByIndex(parameterIndex) + value * weight);
+ }
+ addParameterValueById(parameterId, value, weight = 1) {
+ const index = this.getParameterIndex(parameterId);
+ this.addParameterValueByIndex(index, value, weight);
+ }
+ multiplyParameterValueById(parameterId, value, weight = 1) {
+ const index = this.getParameterIndex(parameterId);
+ this.multiplyParameterValueByIndex(index, value, weight);
+ }
+ multiplyParameterValueByIndex(parameterIndex, value, weight = 1) {
+ this.setParameterValueByIndex(parameterIndex, this.getParameterValueByIndex(parameterIndex) * (1 + (value - 1) * weight));
+ }
+ getDrawableIds() {
+ return this._drawableIds.slice();
+ }
+ getDrawableIndex(drawableId) {
+ const drawableCount = this._model.drawables.count;
+ for (let drawableIndex = 0; drawableIndex < drawableCount; ++drawableIndex) {
+ if (this._drawableIds[drawableIndex] == drawableId) {
+ return drawableIndex;
+ }
+ }
+ return -1;
+ }
+ getDrawableCount() {
+ return this._model.drawables.count;
+ }
+ getDrawableId(drawableIndex) {
+ return this._model.drawables.ids[drawableIndex];
+ }
+ getDrawableRenderOrders() {
+ return this._model.drawables.renderOrders;
+ }
+ getDrawableTextureIndices(drawableIndex) {
+ return this.getDrawableTextureIndex(drawableIndex);
+ }
+ getDrawableTextureIndex(drawableIndex) {
+ const textureIndices = this._model.drawables.textureIndices;
+ return textureIndices[drawableIndex];
+ }
+ getDrawableDynamicFlagVertexPositionsDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasVertexPositionsDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableVertexIndexCount(drawableIndex) {
+ return this._model.drawables.indexCounts[drawableIndex];
+ }
+ getDrawableVertexCount(drawableIndex) {
+ return this._model.drawables.vertexCounts[drawableIndex];
+ }
+ getDrawableVertices(drawableIndex) {
+ return this.getDrawableVertexPositions(drawableIndex);
+ }
+ getDrawableVertexIndices(drawableIndex) {
+ return this._model.drawables.indices[drawableIndex];
+ }
+ getDrawableVertexPositions(drawableIndex) {
+ return this._model.drawables.vertexPositions[drawableIndex];
+ }
+ getDrawableVertexUvs(drawableIndex) {
+ return this._model.drawables.vertexUvs[drawableIndex];
+ }
+ getDrawableOpacity(drawableIndex) {
+ return this._model.drawables.opacities[drawableIndex];
+ }
+ getDrawableMultiplyColor(drawableIndex) {
+ const multiplyColors = this._model.drawables.multiplyColors;
+ const index = drawableIndex * 4;
+ const multiplyColor = new CubismTextureColor();
+ multiplyColor.R = multiplyColors[index];
+ multiplyColor.G = multiplyColors[index + 1];
+ multiplyColor.B = multiplyColors[index + 2];
+ multiplyColor.A = multiplyColors[index + 3];
+ return multiplyColor;
+ }
+ getDrawableScreenColor(drawableIndex) {
+ const screenColors = this._model.drawables.screenColors;
+ const index = drawableIndex * 4;
+ const screenColor = new CubismTextureColor();
+ screenColor.R = screenColors[index];
+ screenColor.G = screenColors[index + 1];
+ screenColor.B = screenColors[index + 2];
+ screenColor.A = screenColors[index + 3];
+ return screenColor;
+ }
+ getDrawableParentPartIndex(drawableIndex) {
+ return this._model.drawables.parentPartIndices[drawableIndex];
+ }
+ getDrawableBlendMode(drawableIndex) {
+ const constantFlags = this._model.drawables.constantFlags;
+ return Live2DCubismCore.Utils.hasBlendAdditiveBit(constantFlags[drawableIndex]) ? CubismBlendMode.CubismBlendMode_Additive : Live2DCubismCore.Utils.hasBlendMultiplicativeBit(constantFlags[drawableIndex]) ? CubismBlendMode.CubismBlendMode_Multiplicative : CubismBlendMode.CubismBlendMode_Normal;
+ }
+ getDrawableInvertedMaskBit(drawableIndex) {
+ const constantFlags = this._model.drawables.constantFlags;
+ return Live2DCubismCore.Utils.hasIsInvertedMaskBit(constantFlags[drawableIndex]);
+ }
+ getDrawableMasks() {
+ return this._model.drawables.masks;
+ }
+ getDrawableMaskCounts() {
+ return this._model.drawables.maskCounts;
+ }
+ isUsingMasking() {
+ for (let d = 0; d < this._model.drawables.count; ++d) {
+ if (this._model.drawables.maskCounts[d] <= 0) {
+ continue;
+ }
+ return true;
+ }
+ return false;
+ }
+ getDrawableDynamicFlagIsVisible(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasIsVisibleBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagVisibilityDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasVisibilityDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagOpacityDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasOpacityDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagRenderOrderDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasRenderOrderDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagBlendColorDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasBlendColorDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ loadParameters() {
+ let parameterCount = this._model.parameters.count;
+ const savedParameterCount = this._savedParameters.length;
+ if (parameterCount > savedParameterCount) {
+ parameterCount = savedParameterCount;
+ }
+ for (let i = 0; i < parameterCount; ++i) {
+ this._parameterValues[i] = this._savedParameters[i];
+ }
+ }
+ initialize() {
+ this._parameterValues = this._model.parameters.values;
+ this._partOpacities = this._model.parts.opacities;
+ this._parameterMaximumValues = this._model.parameters.maximumValues;
+ this._parameterMinimumValues = this._model.parameters.minimumValues;
+ {
+ const parameterIds = this._model.parameters.ids;
+ const parameterCount = this._model.parameters.count;
+ for (let i = 0; i < parameterCount; ++i) {
+ this._parameterIds.push(parameterIds[i]);
+ }
+ }
+ const partCount = this._model.parts.count;
+ {
+ const partIds = this._model.parts.ids;
+ for (let i = 0; i < partCount; ++i) {
+ this._partIds.push(partIds[i]);
+ }
+ }
+ {
+ const drawableIds = this._model.drawables.ids;
+ const drawableCount = this._model.drawables.count;
+ const userCulling = new DrawableCullingData(false, false);
+ {
+ for (let i = 0; i < partCount; ++i) {
+ const multiplyColor = new CubismTextureColor(1, 1, 1, 1);
+ const screenColor = new CubismTextureColor(0, 0, 0, 1);
+ const userMultiplyColor = new PartColorData(false, multiplyColor);
+ const userScreenColor = new PartColorData(false, screenColor);
+ this._userPartMultiplyColors.push(userMultiplyColor);
+ this._userPartScreenColors.push(userScreenColor);
+ this._partChildDrawables.push([]);
+ }
+ }
+ {
+ for (let i = 0; i < drawableCount; ++i) {
+ const multiplyColor = new CubismTextureColor(1, 1, 1, 1);
+ const screenColor = new CubismTextureColor(0, 0, 0, 1);
+ const userMultiplyColor = new DrawableColorData(false, multiplyColor);
+ const userScreenColor = new DrawableColorData(false, screenColor);
+ this._drawableIds.push(drawableIds[i]);
+ this._userMultiplyColors.push(userMultiplyColor);
+ this._userScreenColors.push(userScreenColor);
+ this._userCullings.push(userCulling);
+ const parentIndex = this.getDrawableParentPartIndex(i);
+ if (parentIndex >= 0) {
+ this._partChildDrawables[parentIndex].push(i);
+ }
+ }
+ }
+ }
+ }
+ constructor(model) {
+ this._model = model;
+ this._savedParameters = [];
+ this._parameterIds = [];
+ this._drawableIds = [];
+ this._partIds = [];
+ this._isOverwrittenModelMultiplyColors = false;
+ this._isOverwrittenModelScreenColors = false;
+ this._isOverwrittenCullings = false;
+ this._modelOpacity = 1;
+ this._userMultiplyColors = [];
+ this._userScreenColors = [];
+ this._userCullings = [];
+ this._userPartMultiplyColors = [];
+ this._userPartScreenColors = [];
+ this._partChildDrawables = [];
+ this._notExistPartId = {};
+ this._notExistParameterId = {};
+ this._notExistParameterValues = {};
+ this._notExistPartOpacities = {};
+ this.initialize();
+ }
+ release() {
+ this._model.release();
+ this._model = void 0;
+ }
+}
+class CubismMoc {
+ static create(mocBytes, shouldCheckMocConsistency) {
+ if (shouldCheckMocConsistency) {
+ const consistency = this.hasMocConsistency(mocBytes);
+ if (!consistency) {
+ throw new Error(`Inconsistent MOC3.`);
+ }
+ }
+ const moc = Live2DCubismCore.Moc.fromArrayBuffer(mocBytes);
+ if (moc) {
+ const cubismMoc = new CubismMoc(moc);
+ cubismMoc._mocVersion = Live2DCubismCore.Version.csmGetMocVersion(moc, mocBytes);
+ return cubismMoc;
+ }
+ throw new Error("Failed to CubismMoc.create().");
+ }
+ createModel() {
+ let cubismModel;
+ const model = Live2DCubismCore.Model.fromMoc(this._moc);
+ if (model) {
+ cubismModel = new CubismModel(model);
+ ++this._modelCount;
+ return cubismModel;
+ }
+ throw new Error("Unknown error");
+ }
+ deleteModel(model) {
+ if (model != null) {
+ --this._modelCount;
+ }
+ }
+ constructor(moc) {
+ this._moc = moc;
+ this._modelCount = 0;
+ this._mocVersion = 0;
+ }
+ release() {
+ this._moc._release();
+ this._moc = void 0;
+ }
+ getLatestMocVersion() {
+ return Live2DCubismCore.Version.csmGetLatestMocVersion();
+ }
+ getMocVersion() {
+ return this._mocVersion;
+ }
+ static hasMocConsistency(mocBytes) {
+ const isConsistent = Live2DCubismCore.Moc.prototype.hasMocConsistency(mocBytes);
+ return isConsistent === 1 ? true : false;
+ }
+}
+class CubismModelUserDataJson {
+ constructor(json, size) {
+ this._json = json;
+ }
+ release() {
+ this._json = void 0;
+ }
+ getUserDataCount() {
+ return this._json.Meta.UserDataCount;
+ }
+ getTotalUserDataSize() {
+ return this._json.Meta.TotalUserDataSize;
+ }
+ getUserDataTargetType(i) {
+ return this._json.UserData[i].Target;
+ }
+ getUserDataId(i) {
+ return this._json.UserData[i].Id;
+ }
+ getUserDataValue(i) {
+ return this._json.UserData[i].Value;
+ }
+}
+const ArtMesh = "ArtMesh";
+class CubismModelUserData {
+ static create(json, size) {
+ const ret = new CubismModelUserData();
+ ret.parseUserData(json, size);
+ return ret;
+ }
+ getArtMeshUserDatas() {
+ return this._artMeshUserDataNode;
+ }
+ parseUserData(data, size) {
+ const json = new CubismModelUserDataJson(data, size);
+ const typeOfArtMesh = ArtMesh;
+ const nodeCount = json.getUserDataCount();
+ for (let i = 0; i < nodeCount; i++) {
+ const addNode = {
+ targetId: json.getUserDataId(i),
+ targetType: json.getUserDataTargetType(i),
+ value: json.getUserDataValue(i)
+ };
+ this._userDataNodes.push(addNode);
+ if (addNode.targetType == typeOfArtMesh) {
+ this._artMeshUserDataNode.push(addNode);
+ }
+ }
+ json.release();
+ }
+ constructor() {
+ this._userDataNodes = [];
+ this._artMeshUserDataNode = [];
+ }
+ release() {
+ this._userDataNodes = null;
+ }
+}
+class ACubismMotion {
+ constructor() {
+ this._fadeInSeconds = -1;
+ this._fadeOutSeconds = -1;
+ this._weight = 1;
+ this._offsetSeconds = 0;
+ this._firedEventValues = [];
+ }
+ release() {
+ this._weight = 0;
+ }
+ updateParameters(model, motionQueueEntry, userTimeSeconds) {
+ if (!motionQueueEntry.isAvailable() || motionQueueEntry.isFinished()) {
+ return;
+ }
+ if (!motionQueueEntry.isStarted()) {
+ motionQueueEntry.setIsStarted(true);
+ motionQueueEntry.setStartTime(userTimeSeconds - this._offsetSeconds);
+ motionQueueEntry.setFadeInStartTime(userTimeSeconds);
+ const duration = this.getDuration();
+ if (motionQueueEntry.getEndTime() < 0) {
+ motionQueueEntry.setEndTime(duration <= 0 ? -1 : motionQueueEntry.getStartTime() + duration);
+ }
+ }
+ let fadeWeight = this._weight;
+ const fadeIn = this._fadeInSeconds == 0 ? 1 : CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / this._fadeInSeconds);
+ const fadeOut = this._fadeOutSeconds == 0 || motionQueueEntry.getEndTime() < 0 ? 1 : CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / this._fadeOutSeconds);
+ fadeWeight = fadeWeight * fadeIn * fadeOut;
+ motionQueueEntry.setState(userTimeSeconds, fadeWeight);
+ this.doUpdateParameters(model, userTimeSeconds, fadeWeight, motionQueueEntry);
+ if (motionQueueEntry.getEndTime() > 0 && motionQueueEntry.getEndTime() < userTimeSeconds) {
+ motionQueueEntry.setIsFinished(true);
+ }
+ }
+ setFadeInTime(fadeInSeconds) {
+ this._fadeInSeconds = fadeInSeconds;
+ }
+ setFadeOutTime(fadeOutSeconds) {
+ this._fadeOutSeconds = fadeOutSeconds;
+ }
+ getFadeOutTime() {
+ return this._fadeOutSeconds;
+ }
+ getFadeInTime() {
+ return this._fadeInSeconds;
+ }
+ setWeight(weight) {
+ this._weight = weight;
+ }
+ getWeight() {
+ return this._weight;
+ }
+ getDuration() {
+ return -1;
+ }
+ getLoopDuration() {
+ return -1;
+ }
+ setOffsetTime(offsetSeconds) {
+ this._offsetSeconds = offsetSeconds;
+ }
+ getFiredEvent(beforeCheckTimeSeconds, motionTimeSeconds) {
+ return this._firedEventValues;
+ }
+ setFinishedMotionHandler(onFinishedMotionHandler) {
+ this._onFinishedMotion = onFinishedMotionHandler;
+ }
+ getFinishedMotionHandler() {
+ return this._onFinishedMotion;
+ }
+ isExistModelOpacity() {
+ return false;
+ }
+ getModelOpacityIndex() {
+ return -1;
+ }
+ getModelOpacityId(index) {
+ return void 0;
+ }
+ getModelOpacityValue() {
+ return 1;
+ }
+}
+const DefaultFadeTime = 1;
+class CubismExpressionMotion extends ACubismMotion {
+ constructor() {
+ super();
+ this._parameters = [];
+ }
+ static create(json) {
+ const expression = new CubismExpressionMotion();
+ expression.parse(json);
+ return expression;
+ }
+ doUpdateParameters(model, userTimeSeconds, weight, motionQueueEntry) {
+ for (let i = 0; i < this._parameters.length; ++i) {
+ const parameter = this._parameters[i];
+ switch (parameter.blendType) {
+ case ExpressionBlendType.ExpressionBlendType_Add: {
+ model.addParameterValueById(parameter.parameterId, parameter.value, weight);
+ break;
+ }
+ case ExpressionBlendType.ExpressionBlendType_Multiply: {
+ model.multiplyParameterValueById(parameter.parameterId, parameter.value, weight);
+ break;
+ }
+ case ExpressionBlendType.ExpressionBlendType_Overwrite: {
+ model.setParameterValueById(parameter.parameterId, parameter.value, weight);
+ break;
+ }
+ }
+ }
+ }
+ parse(json) {
+ this.setFadeInTime(json.FadeInTime != void 0 ? json.FadeInTime : DefaultFadeTime);
+ this.setFadeOutTime(json.FadeOutTime != void 0 ? json.FadeOutTime : DefaultFadeTime);
+ const parameterCount = (json.Parameters || []).length;
+ for (let i = 0; i < parameterCount; ++i) {
+ const param = json.Parameters[i];
+ const parameterId = param.Id;
+ const value = param.Value;
+ let blendType;
+ if (!param.Blend || param.Blend === "Add") {
+ blendType = ExpressionBlendType.ExpressionBlendType_Add;
+ } else if (param.Blend === "Multiply") {
+ blendType = ExpressionBlendType.ExpressionBlendType_Multiply;
+ } else if (param.Blend === "Overwrite") {
+ blendType = ExpressionBlendType.ExpressionBlendType_Overwrite;
+ } else {
+ blendType = ExpressionBlendType.ExpressionBlendType_Add;
+ }
+ const item = {
+ parameterId,
+ blendType,
+ value
+ };
+ this._parameters.push(item);
+ }
+ }
+}
+var ExpressionBlendType = /* @__PURE__ */ ((ExpressionBlendType2) => {
+ ExpressionBlendType2[ExpressionBlendType2["ExpressionBlendType_Add"] = 0] = "ExpressionBlendType_Add";
+ ExpressionBlendType2[ExpressionBlendType2["ExpressionBlendType_Multiply"] = 1] = "ExpressionBlendType_Multiply";
+ ExpressionBlendType2[ExpressionBlendType2["ExpressionBlendType_Overwrite"] = 2] = "ExpressionBlendType_Overwrite";
+ return ExpressionBlendType2;
+})(ExpressionBlendType || {});
+var CubismConfig;
+((CubismConfig2) => {
+ CubismConfig2.supportMoreMaskDivisions = true;
+ CubismConfig2.setOpacityFromMotion = false;
+})(CubismConfig || (CubismConfig = {}));
+var CubismMotionCurveTarget = /* @__PURE__ */ ((CubismMotionCurveTarget2) => {
+ CubismMotionCurveTarget2[CubismMotionCurveTarget2["CubismMotionCurveTarget_Model"] = 0] = "CubismMotionCurveTarget_Model";
+ CubismMotionCurveTarget2[CubismMotionCurveTarget2["CubismMotionCurveTarget_Parameter"] = 1] = "CubismMotionCurveTarget_Parameter";
+ CubismMotionCurveTarget2[CubismMotionCurveTarget2["CubismMotionCurveTarget_PartOpacity"] = 2] = "CubismMotionCurveTarget_PartOpacity";
+ return CubismMotionCurveTarget2;
+})(CubismMotionCurveTarget || {});
+var CubismMotionSegmentType = /* @__PURE__ */ ((CubismMotionSegmentType2) => {
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_Linear"] = 0] = "CubismMotionSegmentType_Linear";
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_Bezier"] = 1] = "CubismMotionSegmentType_Bezier";
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_Stepped"] = 2] = "CubismMotionSegmentType_Stepped";
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_InverseStepped"] = 3] = "CubismMotionSegmentType_InverseStepped";
+ return CubismMotionSegmentType2;
+})(CubismMotionSegmentType || {});
+class CubismMotionPoint {
+ constructor(time = 0, value = 0) {
+ this.time = time;
+ this.value = value;
+ }
+}
+class CubismMotionSegment {
+ constructor() {
+ this.basePointIndex = 0;
+ this.segmentType = 0;
+ }
+}
+class CubismMotionCurve {
+ constructor() {
+ this.id = "";
+ this.type = 0;
+ this.segmentCount = 0;
+ this.baseSegmentIndex = 0;
+ this.fadeInTime = 0;
+ this.fadeOutTime = 0;
+ }
+}
+class CubismMotionEvent {
+ constructor() {
+ this.fireTime = 0;
+ this.value = "";
+ }
+}
+class CubismMotionData {
+ constructor() {
+ this.duration = 0;
+ this.loop = false;
+ this.curveCount = 0;
+ this.eventCount = 0;
+ this.fps = 0;
+ this.curves = [];
+ this.segments = [];
+ this.points = [];
+ this.events = [];
+ }
+}
+class CubismMotionJson {
+ constructor(json) {
+ this._json = json;
+ }
+ release() {
+ this._json = void 0;
+ }
+ getMotionDuration() {
+ return this._json.Meta.Duration;
+ }
+ isMotionLoop() {
+ return this._json.Meta.Loop || false;
+ }
+ getEvaluationOptionFlag(flagType) {
+ if (EvaluationOptionFlag.EvaluationOptionFlag_AreBeziersRistricted == flagType) {
+ return !!this._json.Meta.AreBeziersRestricted;
+ }
+ return false;
+ }
+ getMotionCurveCount() {
+ return this._json.Meta.CurveCount;
+ }
+ getMotionFps() {
+ return this._json.Meta.Fps;
+ }
+ getMotionTotalSegmentCount() {
+ return this._json.Meta.TotalSegmentCount;
+ }
+ getMotionTotalPointCount() {
+ return this._json.Meta.TotalPointCount;
+ }
+ getMotionFadeInTime() {
+ return this._json.Meta.FadeInTime;
+ }
+ getMotionFadeOutTime() {
+ return this._json.Meta.FadeOutTime;
+ }
+ getMotionCurveTarget(curveIndex) {
+ return this._json.Curves[curveIndex].Target;
+ }
+ getMotionCurveId(curveIndex) {
+ return this._json.Curves[curveIndex].Id;
+ }
+ getMotionCurveFadeInTime(curveIndex) {
+ return this._json.Curves[curveIndex].FadeInTime;
+ }
+ getMotionCurveFadeOutTime(curveIndex) {
+ return this._json.Curves[curveIndex].FadeOutTime;
+ }
+ getMotionCurveSegmentCount(curveIndex) {
+ return this._json.Curves[curveIndex].Segments.length;
+ }
+ getMotionCurveSegment(curveIndex, segmentIndex) {
+ return this._json.Curves[curveIndex].Segments[segmentIndex];
+ }
+ getEventCount() {
+ return this._json.Meta.UserDataCount || 0;
+ }
+ getTotalEventValueSize() {
+ return this._json.Meta.TotalUserDataSize;
+ }
+ getEventTime(userDataIndex) {
+ return this._json.UserData[userDataIndex].Time;
+ }
+ getEventValue(userDataIndex) {
+ return this._json.UserData[userDataIndex].Value;
+ }
+}
+var EvaluationOptionFlag = /* @__PURE__ */ ((EvaluationOptionFlag2) => {
+ EvaluationOptionFlag2[EvaluationOptionFlag2["EvaluationOptionFlag_AreBeziersRistricted"] = 0] = "EvaluationOptionFlag_AreBeziersRistricted";
+ return EvaluationOptionFlag2;
+})(EvaluationOptionFlag || {});
+const EffectNameEyeBlink = "EyeBlink";
+const EffectNameLipSync = "LipSync";
+const TargetNameModel = "Model";
+const TargetNameParameter = "Parameter";
+const TargetNamePartOpacity = "PartOpacity";
+const IdNameOpacity = "Opacity";
+const UseOldBeziersCurveMotion = false;
+function lerpPoints(a, b, t) {
+ const result = new CubismMotionPoint();
+ result.time = a.time + (b.time - a.time) * t;
+ result.value = a.value + (b.value - a.value) * t;
+ return result;
+}
+function linearEvaluate(points, time) {
+ let t = (time - points[0].time) / (points[1].time - points[0].time);
+ if (t < 0) {
+ t = 0;
+ }
+ return points[0].value + (points[1].value - points[0].value) * t;
+}
+function bezierEvaluate(points, time) {
+ let t = (time - points[0].time) / (points[3].time - points[0].time);
+ if (t < 0) {
+ t = 0;
+ }
+ const p01 = lerpPoints(points[0], points[1], t);
+ const p12 = lerpPoints(points[1], points[2], t);
+ const p23 = lerpPoints(points[2], points[3], t);
+ const p012 = lerpPoints(p01, p12, t);
+ const p123 = lerpPoints(p12, p23, t);
+ return lerpPoints(p012, p123, t).value;
+}
+function bezierEvaluateCardanoInterpretation(points, time) {
+ const x = time;
+ const x1 = points[0].time;
+ const x2 = points[3].time;
+ const cx1 = points[1].time;
+ const cx2 = points[2].time;
+ const a = x2 - 3 * cx2 + 3 * cx1 - x1;
+ const b = 3 * cx2 - 6 * cx1 + 3 * x1;
+ const c = 3 * cx1 - 3 * x1;
+ const d = x1 - x;
+ const t = CubismMath.cardanoAlgorithmForBezier(a, b, c, d);
+ const p01 = lerpPoints(points[0], points[1], t);
+ const p12 = lerpPoints(points[1], points[2], t);
+ const p23 = lerpPoints(points[2], points[3], t);
+ const p012 = lerpPoints(p01, p12, t);
+ const p123 = lerpPoints(p12, p23, t);
+ return lerpPoints(p012, p123, t).value;
+}
+function steppedEvaluate(points, time) {
+ return points[0].value;
+}
+function inverseSteppedEvaluate(points, time) {
+ return points[1].value;
+}
+function evaluateCurve(motionData, index, time) {
+ const curve = motionData.curves[index];
+ let target = -1;
+ const totalSegmentCount = curve.baseSegmentIndex + curve.segmentCount;
+ let pointPosition = 0;
+ for (let i = curve.baseSegmentIndex; i < totalSegmentCount; ++i) {
+ pointPosition = motionData.segments[i].basePointIndex + (motionData.segments[i].segmentType == CubismMotionSegmentType.CubismMotionSegmentType_Bezier ? 3 : 1);
+ if (motionData.points[pointPosition].time > time) {
+ target = i;
+ break;
+ }
+ }
+ if (target == -1) {
+ return motionData.points[pointPosition].value;
+ }
+ const segment = motionData.segments[target];
+ return segment.evaluate(motionData.points.slice(segment.basePointIndex), time);
+}
+class CubismMotion extends ACubismMotion {
+ constructor() {
+ super();
+ this._eyeBlinkParameterIds = [];
+ this._lipSyncParameterIds = [];
+ this._sourceFrameRate = 30;
+ this._loopDurationSeconds = -1;
+ this._isLoop = false;
+ this._isLoopFadeIn = true;
+ this._lastWeight = 0;
+ this._modelOpacity = 1;
+ }
+ static create(json, onFinishedMotionHandler) {
+ const ret = new CubismMotion();
+ ret.parse(json);
+ ret._sourceFrameRate = ret._motionData.fps;
+ ret._loopDurationSeconds = ret._motionData.duration;
+ ret._onFinishedMotion = onFinishedMotionHandler;
+ return ret;
+ }
+ doUpdateParameters(model, userTimeSeconds, fadeWeight, motionQueueEntry) {
+ if (this._modelCurveIdEyeBlink == null) {
+ this._modelCurveIdEyeBlink = EffectNameEyeBlink;
+ }
+ if (this._modelCurveIdLipSync == null) {
+ this._modelCurveIdLipSync = EffectNameLipSync;
+ }
+ if (this._modelCurveIdOpacity == null) {
+ this._modelCurveIdOpacity = IdNameOpacity;
+ }
+ let timeOffsetSeconds = userTimeSeconds - motionQueueEntry.getStartTime();
+ if (timeOffsetSeconds < 0) {
+ timeOffsetSeconds = 0;
+ }
+ let lipSyncValue = Number.MAX_VALUE;
+ let eyeBlinkValue = Number.MAX_VALUE;
+ const MaxTargetSize = 64;
+ let lipSyncFlags = 0;
+ let eyeBlinkFlags = 0;
+ if (this._eyeBlinkParameterIds.length > MaxTargetSize) {
+ CubismLogDebug("too many eye blink targets : {0}", this._eyeBlinkParameterIds.length);
+ }
+ if (this._lipSyncParameterIds.length > MaxTargetSize) {
+ CubismLogDebug("too many lip sync targets : {0}", this._lipSyncParameterIds.length);
+ }
+ const tmpFadeIn = this._fadeInSeconds <= 0 ? 1 : CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / this._fadeInSeconds);
+ const tmpFadeOut = this._fadeOutSeconds <= 0 || motionQueueEntry.getEndTime() < 0 ? 1 : CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / this._fadeOutSeconds);
+ let value;
+ let c, parameterIndex;
+ let time = timeOffsetSeconds;
+ if (this._isLoop) {
+ while (time > this._motionData.duration) {
+ time -= this._motionData.duration;
+ }
+ }
+ const curves = this._motionData.curves;
+ for (c = 0; c < this._motionData.curveCount && curves[c].type == CubismMotionCurveTarget.CubismMotionCurveTarget_Model; ++c) {
+ value = evaluateCurve(this._motionData, c, time);
+ if (curves[c].id == this._modelCurveIdEyeBlink) {
+ eyeBlinkValue = value;
+ } else if (curves[c].id == this._modelCurveIdLipSync) {
+ lipSyncValue = value;
+ } else if (curves[c].id == this._modelCurveIdOpacity) {
+ this._modelOpacity = value;
+ model.setModelOapcity(this.getModelOpacityValue());
+ }
+ }
+ for (; c < this._motionData.curveCount && curves[c].type == CubismMotionCurveTarget.CubismMotionCurveTarget_Parameter; ++c) {
+ parameterIndex = model.getParameterIndex(curves[c].id);
+ if (parameterIndex == -1) {
+ continue;
+ }
+ const sourceValue = model.getParameterValueByIndex(parameterIndex);
+ value = evaluateCurve(this._motionData, c, time);
+ if (eyeBlinkValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._eyeBlinkParameterIds.length && i < MaxTargetSize; ++i) {
+ if (this._eyeBlinkParameterIds[i] == curves[c].id) {
+ value *= eyeBlinkValue;
+ eyeBlinkFlags |= 1 << i;
+ break;
+ }
+ }
+ }
+ if (lipSyncValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._lipSyncParameterIds.length && i < MaxTargetSize; ++i) {
+ if (this._lipSyncParameterIds[i] == curves[c].id) {
+ value += lipSyncValue;
+ lipSyncFlags |= 1 << i;
+ break;
+ }
+ }
+ }
+ let v;
+ if (curves[c].fadeInTime < 0 && curves[c].fadeOutTime < 0) {
+ v = sourceValue + (value - sourceValue) * fadeWeight;
+ } else {
+ let fin;
+ let fout;
+ if (curves[c].fadeInTime < 0) {
+ fin = tmpFadeIn;
+ } else {
+ fin = curves[c].fadeInTime == 0 ? 1 : CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / curves[c].fadeInTime);
+ }
+ if (curves[c].fadeOutTime < 0) {
+ fout = tmpFadeOut;
+ } else {
+ fout = curves[c].fadeOutTime == 0 || motionQueueEntry.getEndTime() < 0 ? 1 : CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / curves[c].fadeOutTime);
+ }
+ const paramWeight = this._weight * fin * fout;
+ v = sourceValue + (value - sourceValue) * paramWeight;
+ }
+ model.setParameterValueByIndex(parameterIndex, v, 1);
+ }
+ {
+ if (eyeBlinkValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._eyeBlinkParameterIds.length && i < MaxTargetSize; ++i) {
+ const sourceValue = model.getParameterValueById(this._eyeBlinkParameterIds[i]);
+ if (eyeBlinkFlags >> i & 1) {
+ continue;
+ }
+ const v = sourceValue + (eyeBlinkValue - sourceValue) * fadeWeight;
+ model.setParameterValueById(this._eyeBlinkParameterIds[i], v);
+ }
+ }
+ if (lipSyncValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._lipSyncParameterIds.length && i < MaxTargetSize; ++i) {
+ const sourceValue = model.getParameterValueById(this._lipSyncParameterIds[i]);
+ if (lipSyncFlags >> i & 1) {
+ continue;
+ }
+ const v = sourceValue + (lipSyncValue - sourceValue) * fadeWeight;
+ model.setParameterValueById(this._lipSyncParameterIds[i], v);
+ }
+ }
+ }
+ for (; c < this._motionData.curveCount && curves[c].type == CubismMotionCurveTarget.CubismMotionCurveTarget_PartOpacity; ++c) {
+ value = evaluateCurve(this._motionData, c, time);
+ if (CubismConfig.setOpacityFromMotion) {
+ model.setPartOpacityById(curves[c].id, value);
+ } else {
+ parameterIndex = model.getParameterIndex(curves[c].id);
+ if (parameterIndex == -1) {
+ continue;
+ }
+ model.setParameterValueByIndex(parameterIndex, value);
+ }
+ }
+ if (timeOffsetSeconds >= this._motionData.duration) {
+ if (this._isLoop) {
+ motionQueueEntry.setStartTime(userTimeSeconds);
+ if (this._isLoopFadeIn) {
+ motionQueueEntry.setFadeInStartTime(userTimeSeconds);
+ }
+ } else {
+ if (this._onFinishedMotion) {
+ this._onFinishedMotion(this);
+ }
+ motionQueueEntry.setIsFinished(true);
+ }
+ }
+ this._lastWeight = fadeWeight;
+ }
+ setIsLoop(loop) {
+ this._isLoop = loop;
+ }
+ isLoop() {
+ return this._isLoop;
+ }
+ setIsLoopFadeIn(loopFadeIn) {
+ this._isLoopFadeIn = loopFadeIn;
+ }
+ isLoopFadeIn() {
+ return this._isLoopFadeIn;
+ }
+ getDuration() {
+ return this._isLoop ? -1 : this._loopDurationSeconds;
+ }
+ getLoopDuration() {
+ return this._loopDurationSeconds;
+ }
+ setParameterFadeInTime(parameterId, value) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ curves[i].fadeInTime = value;
+ return;
+ }
+ }
+ }
+ setParameterFadeOutTime(parameterId, value) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ curves[i].fadeOutTime = value;
+ return;
+ }
+ }
+ }
+ getParameterFadeInTime(parameterId) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ return curves[i].fadeInTime;
+ }
+ }
+ return -1;
+ }
+ getParameterFadeOutTime(parameterId) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ return curves[i].fadeOutTime;
+ }
+ }
+ return -1;
+ }
+ setEffectIds(eyeBlinkParameterIds, lipSyncParameterIds) {
+ this._eyeBlinkParameterIds = eyeBlinkParameterIds;
+ this._lipSyncParameterIds = lipSyncParameterIds;
+ }
+ release() {
+ this._motionData = void 0;
+ }
+ parse(motionJson) {
+ this._motionData = new CubismMotionData();
+ const json = new CubismMotionJson(motionJson);
+ this._motionData.duration = json.getMotionDuration();
+ this._motionData.loop = json.isMotionLoop();
+ this._motionData.curveCount = json.getMotionCurveCount();
+ this._motionData.fps = json.getMotionFps();
+ this._motionData.eventCount = json.getEventCount();
+ const areBeziersRestructed = json.getEvaluationOptionFlag(EvaluationOptionFlag.EvaluationOptionFlag_AreBeziersRistricted);
+ const fadeInSeconds = json.getMotionFadeInTime();
+ const fadeOutSeconds = json.getMotionFadeOutTime();
+ if (fadeInSeconds !== void 0) {
+ this._fadeInSeconds = fadeInSeconds < 0 ? 1 : fadeInSeconds;
+ } else {
+ this._fadeInSeconds = 1;
+ }
+ if (fadeOutSeconds !== void 0) {
+ this._fadeOutSeconds = fadeOutSeconds < 0 ? 1 : fadeOutSeconds;
+ } else {
+ this._fadeOutSeconds = 1;
+ }
+ this._motionData.curves = Array.from({
+ length: this._motionData.curveCount
+ }).map(() => new CubismMotionCurve());
+ this._motionData.segments = Array.from({
+ length: json.getMotionTotalSegmentCount()
+ }).map(() => new CubismMotionSegment());
+ this._motionData.events = Array.from({
+ length: this._motionData.eventCount
+ }).map(() => new CubismMotionEvent());
+ this._motionData.points = [];
+ let totalPointCount = 0;
+ let totalSegmentCount = 0;
+ for (let curveCount = 0; curveCount < this._motionData.curveCount; ++curveCount) {
+ const curve = this._motionData.curves[curveCount];
+ switch (json.getMotionCurveTarget(curveCount)) {
+ case TargetNameModel:
+ curve.type = CubismMotionCurveTarget.CubismMotionCurveTarget_Model;
+ break;
+ case TargetNameParameter:
+ curve.type = CubismMotionCurveTarget.CubismMotionCurveTarget_Parameter;
+ break;
+ case TargetNamePartOpacity:
+ curve.type = CubismMotionCurveTarget.CubismMotionCurveTarget_PartOpacity;
+ break;
+ default:
+ CubismLogWarning('Warning : Unable to get segment type from Curve! The number of "CurveCount" may be incorrect!');
+ }
+ curve.id = json.getMotionCurveId(curveCount);
+ curve.baseSegmentIndex = totalSegmentCount;
+ const fadeInTime = json.getMotionCurveFadeInTime(curveCount);
+ const fadeOutTime = json.getMotionCurveFadeOutTime(curveCount);
+ curve.fadeInTime = fadeInTime !== void 0 ? fadeInTime : -1;
+ curve.fadeOutTime = fadeOutTime !== void 0 ? fadeOutTime : -1;
+ for (let segmentPosition = 0; segmentPosition < json.getMotionCurveSegmentCount(curveCount); ) {
+ if (segmentPosition == 0) {
+ this._motionData.segments[totalSegmentCount].basePointIndex = totalPointCount;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition), json.getMotionCurveSegment(curveCount, segmentPosition + 1));
+ totalPointCount += 1;
+ segmentPosition += 2;
+ } else {
+ this._motionData.segments[totalSegmentCount].basePointIndex = totalPointCount - 1;
+ }
+ const segment = json.getMotionCurveSegment(curveCount, segmentPosition);
+ switch (segment) {
+ case CubismMotionSegmentType.CubismMotionSegmentType_Linear: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Linear;
+ this._motionData.segments[totalSegmentCount].evaluate = linearEvaluate;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ totalPointCount += 1;
+ segmentPosition += 3;
+ break;
+ }
+ case CubismMotionSegmentType.CubismMotionSegmentType_Bezier: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Bezier;
+ if (areBeziersRestructed || UseOldBeziersCurveMotion) {
+ this._motionData.segments[totalSegmentCount].evaluate = bezierEvaluate;
+ } else {
+ this._motionData.segments[totalSegmentCount].evaluate = bezierEvaluateCardanoInterpretation;
+ }
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ this._motionData.points[totalPointCount + 1] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 3), json.getMotionCurveSegment(curveCount, segmentPosition + 4));
+ this._motionData.points[totalPointCount + 2] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 5), json.getMotionCurveSegment(curveCount, segmentPosition + 6));
+ totalPointCount += 3;
+ segmentPosition += 7;
+ break;
+ }
+ case CubismMotionSegmentType.CubismMotionSegmentType_Stepped: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Stepped;
+ this._motionData.segments[totalSegmentCount].evaluate = steppedEvaluate;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ totalPointCount += 1;
+ segmentPosition += 3;
+ break;
+ }
+ case CubismMotionSegmentType.CubismMotionSegmentType_InverseStepped: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_InverseStepped;
+ this._motionData.segments[totalSegmentCount].evaluate = inverseSteppedEvaluate;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ totalPointCount += 1;
+ segmentPosition += 3;
+ break;
+ }
+ }
+ ++curve.segmentCount;
+ ++totalSegmentCount;
+ }
+ this._motionData.curves.push(curve);
+ }
+ for (let userdatacount = 0; userdatacount < json.getEventCount(); ++userdatacount) {
+ this._motionData.events[userdatacount].fireTime = json.getEventTime(userdatacount);
+ this._motionData.events[userdatacount].value = json.getEventValue(userdatacount);
+ }
+ json.release();
+ }
+ getFiredEvent(beforeCheckTimeSeconds, motionTimeSeconds) {
+ this._firedEventValues.length = 0;
+ for (let u = 0; u < this._motionData.eventCount; ++u) {
+ if (this._motionData.events[u].fireTime > beforeCheckTimeSeconds && this._motionData.events[u].fireTime <= motionTimeSeconds) {
+ this._firedEventValues.push(this._motionData.events[u].value);
+ }
+ }
+ return this._firedEventValues;
+ }
+ isExistModelOpacity() {
+ for (let i = 0; i < this._motionData.curveCount; i++) {
+ const curve = this._motionData.curves[i];
+ if (curve.type != CubismMotionCurveTarget.CubismMotionCurveTarget_Model) {
+ continue;
+ }
+ if (curve.id === IdNameOpacity) {
+ return true;
+ }
+ }
+ return false;
+ }
+ getModelOpacityIndex() {
+ if (this.isExistModelOpacity()) {
+ for (let i = 0; i < this._motionData.curveCount; i++) {
+ const curve = this._motionData.curves[i];
+ if (curve.type != CubismMotionCurveTarget.CubismMotionCurveTarget_Model) {
+ continue;
+ }
+ if (curve.id === IdNameOpacity) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+ getModelOpacityId(index) {
+ if (index != -1) {
+ const curve = this._motionData.curves[index];
+ if (curve.type == CubismMotionCurveTarget.CubismMotionCurveTarget_Model) {
+ if (curve.id === IdNameOpacity) {
+ return curve.id;
+ }
+ }
+ }
+ return void 0;
+ }
+ getModelOpacityValue() {
+ return this._modelOpacity;
+ }
+}
+class CubismMotionQueueEntry {
+ constructor() {
+ this._autoDelete = false;
+ this._available = true;
+ this._finished = false;
+ this._started = false;
+ this._startTimeSeconds = -1;
+ this._fadeInStartTimeSeconds = 0;
+ this._endTimeSeconds = -1;
+ this._stateTimeSeconds = 0;
+ this._stateWeight = 0;
+ this._lastEventCheckSeconds = 0;
+ this._motionQueueEntryHandle = this;
+ this._fadeOutSeconds = 0;
+ this._isTriggeredFadeOut = false;
+ }
+ release() {
+ if (this._autoDelete && this._motion) {
+ this._motion.release();
+ }
+ }
+ setFadeOut(fadeOutSeconds) {
+ this._fadeOutSeconds = fadeOutSeconds;
+ this._isTriggeredFadeOut = true;
+ }
+ startFadeOut(fadeOutSeconds, userTimeSeconds) {
+ const newEndTimeSeconds = userTimeSeconds + fadeOutSeconds;
+ this._isTriggeredFadeOut = true;
+ if (this._endTimeSeconds < 0 || newEndTimeSeconds < this._endTimeSeconds) {
+ this._endTimeSeconds = newEndTimeSeconds;
+ }
+ }
+ isFinished() {
+ return this._finished;
+ }
+ isStarted() {
+ return this._started;
+ }
+ getStartTime() {
+ return this._startTimeSeconds;
+ }
+ getFadeInStartTime() {
+ return this._fadeInStartTimeSeconds;
+ }
+ getEndTime() {
+ return this._endTimeSeconds;
+ }
+ setStartTime(startTime) {
+ this._startTimeSeconds = startTime;
+ }
+ setFadeInStartTime(startTime) {
+ this._fadeInStartTimeSeconds = startTime;
+ }
+ setEndTime(endTime) {
+ this._endTimeSeconds = endTime;
+ }
+ setIsFinished(f) {
+ this._finished = f;
+ }
+ setIsStarted(f) {
+ this._started = f;
+ }
+ isAvailable() {
+ return this._available;
+ }
+ setIsAvailable(v) {
+ this._available = v;
+ }
+ setState(timeSeconds, weight) {
+ this._stateTimeSeconds = timeSeconds;
+ this._stateWeight = weight;
+ }
+ getStateTime() {
+ return this._stateTimeSeconds;
+ }
+ getStateWeight() {
+ return this._stateWeight;
+ }
+ getLastCheckEventSeconds() {
+ return this._lastEventCheckSeconds;
+ }
+ setLastCheckEventSeconds(checkSeconds) {
+ this._lastEventCheckSeconds = checkSeconds;
+ }
+ isTriggeredFadeOut() {
+ return this._isTriggeredFadeOut;
+ }
+ getFadeOutSeconds() {
+ return this._fadeOutSeconds;
+ }
+}
+class CubismMotionQueueManager {
+ constructor() {
+ this._userTimeSeconds = 0;
+ this._eventCustomData = null;
+ this._motions = [];
+ }
+ release() {
+ for (let i = 0; i < this._motions.length; ++i) {
+ if (this._motions[i]) {
+ this._motions[i].release();
+ }
+ }
+ this._motions = void 0;
+ }
+ startMotion(motion, autoDelete, userTimeSeconds) {
+ if (motion == null) {
+ return InvalidMotionQueueEntryHandleValue;
+ }
+ let motionQueueEntry;
+ for (let i = 0; i < this._motions.length; ++i) {
+ motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ continue;
+ }
+ motionQueueEntry.setFadeOut(motionQueueEntry._motion.getFadeOutTime());
+ }
+ motionQueueEntry = new CubismMotionQueueEntry();
+ motionQueueEntry._autoDelete = autoDelete;
+ motionQueueEntry._motion = motion;
+ this._motions.push(motionQueueEntry);
+ return motionQueueEntry._motionQueueEntryHandle;
+ }
+ isFinished() {
+ let i = 0;
+ while (i < this._motions.length) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ this._motions.splice(i, 1);
+ continue;
+ }
+ const motion = motionQueueEntry._motion;
+ if (motion == null) {
+ motionQueueEntry.release();
+ this._motions.splice(i, 1);
+ continue;
+ }
+ if (!motionQueueEntry.isFinished()) {
+ return false;
+ }
+ i++;
+ }
+ return true;
+ }
+ isFinishedByHandle(motionQueueEntryNumber) {
+ for (let i = 0; i < this._motions.length; i++) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ continue;
+ }
+ if (motionQueueEntry._motionQueueEntryHandle == motionQueueEntryNumber && !motionQueueEntry.isFinished()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ stopAllMotions() {
+ for (let i = 0; i < this._motions.length; i++) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry != null) {
+ motionQueueEntry.release();
+ }
+ }
+ this._motions = [];
+ }
+ getCubismMotionQueueEntry(motionQueueEntryNumber) {
+ return this._motions.find((entry) => entry != null && entry._motionQueueEntryHandle == motionQueueEntryNumber);
+ }
+ setEventCallback(callback, customData = null) {
+ this._eventCallBack = callback;
+ this._eventCustomData = customData;
+ }
+ doUpdateMotion(model, userTimeSeconds) {
+ let updated = false;
+ let i = 0;
+ while (i < this._motions.length) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ this._motions.splice(i, 1);
+ continue;
+ }
+ const motion = motionQueueEntry._motion;
+ if (motion == null) {
+ motionQueueEntry.release();
+ this._motions.splice(i, 1);
+ continue;
+ }
+ motion.updateParameters(model, motionQueueEntry, userTimeSeconds);
+ updated = true;
+ const firedList = motion.getFiredEvent(motionQueueEntry.getLastCheckEventSeconds() - motionQueueEntry.getStartTime(), userTimeSeconds - motionQueueEntry.getStartTime());
+ for (let i2 = 0; i2 < firedList.length; ++i2) {
+ this._eventCallBack(this, firedList[i2], this._eventCustomData);
+ }
+ motionQueueEntry.setLastCheckEventSeconds(userTimeSeconds);
+ if (motionQueueEntry.isFinished()) {
+ motionQueueEntry.release();
+ this._motions.splice(i, 1);
+ } else {
+ if (motionQueueEntry.isTriggeredFadeOut()) {
+ motionQueueEntry.startFadeOut(motionQueueEntry.getFadeOutSeconds(), userTimeSeconds);
+ }
+ i++;
+ }
+ }
+ return updated;
+ }
+}
+const InvalidMotionQueueEntryHandleValue = -1;
+class CubismMotionManager extends CubismMotionQueueManager {
+ constructor() {
+ super();
+ this._currentPriority = 0;
+ this._reservePriority = 0;
+ }
+ getCurrentPriority() {
+ return this._currentPriority;
+ }
+ getReservePriority() {
+ return this._reservePriority;
+ }
+ setReservePriority(val) {
+ this._reservePriority = val;
+ }
+ startMotionPriority(motion, autoDelete, priority) {
+ if (priority == this._reservePriority) {
+ this._reservePriority = 0;
+ }
+ this._currentPriority = priority;
+ return super.startMotion(motion, autoDelete, this._userTimeSeconds);
+ }
+ updateMotion(model, deltaTimeSeconds) {
+ this._userTimeSeconds += deltaTimeSeconds;
+ const updated = super.doUpdateMotion(model, this._userTimeSeconds);
+ if (this.isFinished()) {
+ this._currentPriority = 0;
+ }
+ return updated;
+ }
+ reserveMotion(priority) {
+ if (priority <= this._reservePriority || priority <= this._currentPriority) {
+ return false;
+ }
+ this._reservePriority = priority;
+ return true;
+ }
+}
+var CubismPhysicsTargetType = /* @__PURE__ */ ((CubismPhysicsTargetType2) => {
+ CubismPhysicsTargetType2[CubismPhysicsTargetType2["CubismPhysicsTargetType_Parameter"] = 0] = "CubismPhysicsTargetType_Parameter";
+ return CubismPhysicsTargetType2;
+})(CubismPhysicsTargetType || {});
+var CubismPhysicsSource = /* @__PURE__ */ ((CubismPhysicsSource2) => {
+ CubismPhysicsSource2[CubismPhysicsSource2["CubismPhysicsSource_X"] = 0] = "CubismPhysicsSource_X";
+ CubismPhysicsSource2[CubismPhysicsSource2["CubismPhysicsSource_Y"] = 1] = "CubismPhysicsSource_Y";
+ CubismPhysicsSource2[CubismPhysicsSource2["CubismPhysicsSource_Angle"] = 2] = "CubismPhysicsSource_Angle";
+ return CubismPhysicsSource2;
+})(CubismPhysicsSource || {});
+class PhysicsJsonEffectiveForces {
+ constructor() {
+ this.gravity = new CubismVector2(0, 0);
+ this.wind = new CubismVector2(0, 0);
+ }
+}
+class CubismPhysicsParticle {
+ constructor() {
+ this.initialPosition = new CubismVector2(0, 0);
+ this.position = new CubismVector2(0, 0);
+ this.lastPosition = new CubismVector2(0, 0);
+ this.lastGravity = new CubismVector2(0, 0);
+ this.force = new CubismVector2(0, 0);
+ this.velocity = new CubismVector2(0, 0);
+ }
+}
+class CubismPhysicsSubRig {
+ constructor() {
+ this.normalizationPosition = {};
+ this.normalizationAngle = {};
+ }
+}
+class CubismPhysicsInput {
+ constructor() {
+ this.source = {};
+ }
+}
+class CubismPhysicsOutput {
+ constructor() {
+ this.destination = {};
+ this.translationScale = new CubismVector2(0, 0);
+ }
+}
+class CubismPhysicsRig {
+ constructor() {
+ this.settings = [];
+ this.inputs = [];
+ this.outputs = [];
+ this.particles = [];
+ this.gravity = new CubismVector2(0, 0);
+ this.wind = new CubismVector2(0, 0);
+ this.fps = 0;
+ }
+}
+class CubismPhysicsJson {
+ constructor(json) {
+ this._json = json;
+ }
+ release() {
+ this._json = void 0;
+ }
+ getGravity() {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this._json.Meta.EffectiveForces.Gravity.X;
+ ret.y = this._json.Meta.EffectiveForces.Gravity.Y;
+ return ret;
+ }
+ getWind() {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this._json.Meta.EffectiveForces.Wind.X;
+ ret.y = this._json.Meta.EffectiveForces.Wind.Y;
+ return ret;
+ }
+ getFps() {
+ return this._json.Meta.Fps || 0;
+ }
+ getSubRigCount() {
+ return this._json.Meta.PhysicsSettingCount;
+ }
+ getTotalInputCount() {
+ return this._json.Meta.TotalInputCount;
+ }
+ getTotalOutputCount() {
+ return this._json.Meta.TotalOutputCount;
+ }
+ getVertexCount() {
+ return this._json.Meta.VertexCount;
+ }
+ getNormalizationPositionMinimumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Position.Minimum;
+ }
+ getNormalizationPositionMaximumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Position.Maximum;
+ }
+ getNormalizationPositionDefaultValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Position.Default;
+ }
+ getNormalizationAngleMinimumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Angle.Minimum;
+ }
+ getNormalizationAngleMaximumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Angle.Maximum;
+ }
+ getNormalizationAngleDefaultValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Angle.Default;
+ }
+ getInputCount(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input.length;
+ }
+ getInputWeight(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Weight;
+ }
+ getInputReflect(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Reflect;
+ }
+ getInputType(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Type;
+ }
+ getInputSourceId(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Source.Id;
+ }
+ getOutputCount(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output.length;
+ }
+ getOutputVertexIndex(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].VertexIndex;
+ }
+ getOutputAngleScale(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Scale;
+ }
+ getOutputWeight(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Weight;
+ }
+ getOutputDestinationId(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Destination.Id;
+ }
+ getOutputType(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Type;
+ }
+ getOutputReflect(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Reflect;
+ }
+ getParticleCount(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices.length;
+ }
+ getParticleMobility(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Mobility;
+ }
+ getParticleDelay(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Delay;
+ }
+ getParticleAcceleration(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Acceleration;
+ }
+ getParticleRadius(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Radius;
+ }
+ getParticlePosition(physicsSettingIndex, vertexIndex) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Position.X;
+ ret.y = this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Position.Y;
+ return ret;
+ }
+}
+const PhysicsTypeTagX = "X";
+const PhysicsTypeTagY = "Y";
+const PhysicsTypeTagAngle = "Angle";
+const AirResistance = 5;
+const MaximumWeight = 100;
+const MovementThreshold = 1e-3;
+const MaxDeltaTime = 5;
+class CubismPhysics {
+ static create(json) {
+ const ret = new CubismPhysics();
+ ret.parse(json);
+ ret._physicsRig.gravity.y = 0;
+ return ret;
+ }
+ static delete(physics) {
+ if (physics != null) {
+ physics.release();
+ }
+ }
+ parse(physicsJson) {
+ this._physicsRig = new CubismPhysicsRig();
+ const json = new CubismPhysicsJson(physicsJson);
+ this._physicsRig.gravity = json.getGravity();
+ this._physicsRig.wind = json.getWind();
+ this._physicsRig.subRigCount = json.getSubRigCount();
+ this._physicsRig.fps = json.getFps();
+ this._currentRigOutputs = [];
+ this._previousRigOutputs = [];
+ let inputIndex = 0, outputIndex = 0, particleIndex = 0;
+ for (let i = 0; i < this._physicsRig.subRigCount; ++i) {
+ const setting = new CubismPhysicsSubRig();
+ setting.normalizationPosition.minimum = json.getNormalizationPositionMinimumValue(i);
+ setting.normalizationPosition.maximum = json.getNormalizationPositionMaximumValue(i);
+ setting.normalizationPosition.defalut = json.getNormalizationPositionDefaultValue(i);
+ setting.normalizationAngle.minimum = json.getNormalizationAngleMinimumValue(i);
+ setting.normalizationAngle.maximum = json.getNormalizationAngleMaximumValue(i);
+ setting.normalizationAngle.defalut = json.getNormalizationAngleDefaultValue(i);
+ setting.inputCount = json.getInputCount(i);
+ setting.baseInputIndex = inputIndex;
+ inputIndex += setting.inputCount;
+ for (let j = 0; j < setting.inputCount; ++j) {
+ const input = new CubismPhysicsInput();
+ input.sourceParameterIndex = -1;
+ input.weight = json.getInputWeight(i, j);
+ input.reflect = json.getInputReflect(i, j);
+ switch (json.getInputType(i, j)) {
+ case PhysicsTypeTagX:
+ input.type = CubismPhysicsSource.CubismPhysicsSource_X;
+ input.getNormalizedParameterValue = getInputTranslationXFromNormalizedParameterValue;
+ break;
+ case PhysicsTypeTagY:
+ input.type = CubismPhysicsSource.CubismPhysicsSource_Y;
+ input.getNormalizedParameterValue = getInputTranslationYFromNormalizedParamterValue;
+ break;
+ case PhysicsTypeTagAngle:
+ input.type = CubismPhysicsSource.CubismPhysicsSource_Angle;
+ input.getNormalizedParameterValue = getInputAngleFromNormalizedParameterValue;
+ break;
+ }
+ input.source.targetType = CubismPhysicsTargetType.CubismPhysicsTargetType_Parameter;
+ input.source.id = json.getInputSourceId(i, j);
+ this._physicsRig.inputs.push(input);
+ }
+ setting.outputCount = json.getOutputCount(i);
+ setting.baseOutputIndex = outputIndex;
+ const currentRigOutput = new PhysicsOutput();
+ const previousRigOutput = new PhysicsOutput();
+ for (let j = 0; j < setting.outputCount; ++j) {
+ currentRigOutput.outputs[j] = 0;
+ previousRigOutput.outputs[j] = 0;
+ let output = this._physicsRig.outputs[outputIndex + j];
+ if (!output) {
+ output = new CubismPhysicsOutput();
+ this._physicsRig.outputs[outputIndex + j] = output;
+ }
+ output.destinationParameterIndex = -1;
+ output.vertexIndex = json.getOutputVertexIndex(i, j);
+ output.angleScale = json.getOutputAngleScale(i, j);
+ output.weight = json.getOutputWeight(i, j);
+ output.destination.targetType = CubismPhysicsTargetType.CubismPhysicsTargetType_Parameter;
+ output.destination.id = json.getOutputDestinationId(i, j);
+ switch (json.getOutputType(i, j)) {
+ case PhysicsTypeTagX:
+ output.type = CubismPhysicsSource.CubismPhysicsSource_X;
+ output.getValue = getOutputTranslationX;
+ output.getScale = getOutputScaleTranslationX;
+ break;
+ case PhysicsTypeTagY:
+ output.type = CubismPhysicsSource.CubismPhysicsSource_Y;
+ output.getValue = getOutputTranslationY;
+ output.getScale = getOutputScaleTranslationY;
+ break;
+ case PhysicsTypeTagAngle:
+ output.type = CubismPhysicsSource.CubismPhysicsSource_Angle;
+ output.getValue = getOutputAngle;
+ output.getScale = getOutputScaleAngle;
+ break;
+ }
+ output.reflect = json.getOutputReflect(i, j);
+ }
+ this._currentRigOutputs.push(currentRigOutput);
+ this._previousRigOutputs.push(previousRigOutput);
+ outputIndex += setting.outputCount;
+ setting.particleCount = json.getParticleCount(i);
+ setting.baseParticleIndex = particleIndex;
+ particleIndex += setting.particleCount;
+ for (let j = 0; j < setting.particleCount; ++j) {
+ const particle = new CubismPhysicsParticle();
+ particle.mobility = json.getParticleMobility(i, j);
+ particle.delay = json.getParticleDelay(i, j);
+ particle.acceleration = json.getParticleAcceleration(i, j);
+ particle.radius = json.getParticleRadius(i, j);
+ particle.position = json.getParticlePosition(i, j);
+ this._physicsRig.particles.push(particle);
+ }
+ this._physicsRig.settings.push(setting);
+ }
+ this.initialize();
+ json.release();
+ }
+ stabilization(model) {
+ var _a, _b, _c, _d;
+ let totalAngle;
+ let weight;
+ let radAngle;
+ let outputValue;
+ const totalTranslation = new CubismVector2();
+ let currentSetting;
+ let currentInputs;
+ let currentOutputs;
+ let currentParticles;
+ let parameterValues;
+ let parameterMaximumValues;
+ let parameterMinimumValues;
+ let parameterDefaultValues;
+ parameterValues = model.getModel().parameters.values;
+ parameterMaximumValues = model.getModel().parameters.maximumValues;
+ parameterMinimumValues = model.getModel().parameters.minimumValues;
+ parameterDefaultValues = model.getModel().parameters.defaultValues;
+ if (((_b = (_a = this._parameterCaches) == null ? void 0 : _a.length) != null ? _b : 0) < model.getParameterCount()) {
+ this._parameterCaches = new Float32Array(model.getParameterCount());
+ }
+ if (((_d = (_c = this._parameterInputCaches) == null ? void 0 : _c.length) != null ? _d : 0) < model.getParameterCount()) {
+ this._parameterInputCaches = new Float32Array(model.getParameterCount());
+ }
+ for (let j = 0; j < model.getParameterCount(); ++j) {
+ this._parameterCaches[j] = parameterValues[j];
+ this._parameterInputCaches[j] = parameterValues[j];
+ }
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ totalAngle = { angle: 0 };
+ totalTranslation.x = 0;
+ totalTranslation.y = 0;
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentInputs = this._physicsRig.inputs.slice(currentSetting.baseInputIndex);
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ currentParticles = this._physicsRig.particles.slice(currentSetting.baseParticleIndex);
+ for (let i = 0; i < currentSetting.inputCount; ++i) {
+ weight = currentInputs[i].weight / MaximumWeight;
+ if (currentInputs[i].sourceParameterIndex == -1) {
+ currentInputs[i].sourceParameterIndex = model.getParameterIndex(currentInputs[i].source.id);
+ }
+ currentInputs[i].getNormalizedParameterValue(totalTranslation, totalAngle, parameterValues[currentInputs[i].sourceParameterIndex], parameterMinimumValues[currentInputs[i].sourceParameterIndex], parameterMaximumValues[currentInputs[i].sourceParameterIndex], parameterDefaultValues[currentInputs[i].sourceParameterIndex], currentSetting.normalizationPosition, currentSetting.normalizationAngle, currentInputs[i].reflect, weight);
+ this._parameterCaches[currentInputs[i].sourceParameterIndex] = parameterValues[currentInputs[i].sourceParameterIndex];
+ }
+ radAngle = CubismMath.degreesToRadian(-totalAngle.angle);
+ totalTranslation.x = totalTranslation.x * CubismMath.cos(radAngle) - totalTranslation.y * CubismMath.sin(radAngle);
+ totalTranslation.y = totalTranslation.x * CubismMath.sin(radAngle) + totalTranslation.y * CubismMath.cos(radAngle);
+ updateParticlesForStabilization(currentParticles, currentSetting.particleCount, totalTranslation, totalAngle.angle, this._options.wind, MovementThreshold * currentSetting.normalizationPosition.maximum);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ const particleIndex = currentOutputs[i].vertexIndex;
+ if (currentOutputs[i].destinationParameterIndex == -1) {
+ currentOutputs[i].destinationParameterIndex = model.getParameterIndex(currentOutputs[i].destination.id);
+ }
+ if (particleIndex < 1 || particleIndex >= currentSetting.particleCount) {
+ continue;
+ }
+ let translation = new CubismVector2();
+ translation = currentParticles[particleIndex].position.substract(currentParticles[particleIndex - 1].position);
+ outputValue = currentOutputs[i].getValue(translation, currentParticles, particleIndex, currentOutputs[i].reflect, this._options.gravity);
+ this._currentRigOutputs[settingIndex].outputs[i] = outputValue;
+ this._previousRigOutputs[settingIndex].outputs[i] = outputValue;
+ const destinationParameterIndex = currentOutputs[i].destinationParameterIndex;
+ const outParameterCaches = !Float32Array.prototype.slice && "subarray" in Float32Array.prototype ? JSON.parse(JSON.stringify(parameterValues.subarray(destinationParameterIndex))) : parameterValues.slice(destinationParameterIndex);
+ updateOutputParameterValue(outParameterCaches, parameterMinimumValues[destinationParameterIndex], parameterMaximumValues[destinationParameterIndex], outputValue, currentOutputs[i]);
+ for (let offset = destinationParameterIndex, outParamIndex = 0; offset < this._parameterCaches.length; offset++, outParamIndex++) {
+ parameterValues[offset] = this._parameterCaches[offset] = outParameterCaches[outParamIndex];
+ }
+ }
+ }
+ }
+ evaluate(model, deltaTimeSeconds) {
+ var _a, _b, _c, _d;
+ let totalAngle;
+ let weight;
+ let radAngle;
+ let outputValue;
+ const totalTranslation = new CubismVector2();
+ let currentSetting;
+ let currentInputs;
+ let currentOutputs;
+ let currentParticles;
+ if (0 >= deltaTimeSeconds) {
+ return;
+ }
+ let parameterValues;
+ let parameterMaximumValues;
+ let parameterMinimumValues;
+ let parameterDefaultValues;
+ let physicsDeltaTime;
+ this._currentRemainTime += deltaTimeSeconds;
+ if (this._currentRemainTime > MaxDeltaTime) {
+ this._currentRemainTime = 0;
+ }
+ parameterValues = model.getModel().parameters.values;
+ parameterMaximumValues = model.getModel().parameters.maximumValues;
+ parameterMinimumValues = model.getModel().parameters.minimumValues;
+ parameterDefaultValues = model.getModel().parameters.defaultValues;
+ if (((_b = (_a = this._parameterCaches) == null ? void 0 : _a.length) != null ? _b : 0) < model.getParameterCount()) {
+ this._parameterCaches = new Float32Array(model.getParameterCount());
+ }
+ if (((_d = (_c = this._parameterInputCaches) == null ? void 0 : _c.length) != null ? _d : 0) < model.getParameterCount()) {
+ this._parameterInputCaches = new Float32Array(model.getParameterCount());
+ for (let j = 0; j < model.getParameterCount(); ++j) {
+ this._parameterInputCaches[j] = parameterValues[j];
+ }
+ }
+ if (this._physicsRig.fps > 0) {
+ physicsDeltaTime = 1 / this._physicsRig.fps;
+ } else {
+ physicsDeltaTime = deltaTimeSeconds;
+ }
+ while (this._currentRemainTime >= physicsDeltaTime) {
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ this._previousRigOutputs[settingIndex].outputs[i] = this._currentRigOutputs[settingIndex].outputs[i];
+ }
+ }
+ const inputWeight = physicsDeltaTime / this._currentRemainTime;
+ for (let j = 0; j < model.getParameterCount(); ++j) {
+ this._parameterCaches[j] = this._parameterInputCaches[j] * (1 - inputWeight) + parameterValues[j] * inputWeight;
+ this._parameterInputCaches[j] = this._parameterCaches[j];
+ }
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ totalAngle = { angle: 0 };
+ totalTranslation.x = 0;
+ totalTranslation.y = 0;
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentInputs = this._physicsRig.inputs.slice(currentSetting.baseInputIndex);
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ currentParticles = this._physicsRig.particles.slice(currentSetting.baseParticleIndex);
+ for (let i = 0; i < currentSetting.inputCount; ++i) {
+ weight = currentInputs[i].weight / MaximumWeight;
+ if (currentInputs[i].sourceParameterIndex == -1) {
+ currentInputs[i].sourceParameterIndex = model.getParameterIndex(currentInputs[i].source.id);
+ }
+ currentInputs[i].getNormalizedParameterValue(totalTranslation, totalAngle, this._parameterCaches[currentInputs[i].sourceParameterIndex], parameterMinimumValues[currentInputs[i].sourceParameterIndex], parameterMaximumValues[currentInputs[i].sourceParameterIndex], parameterDefaultValues[currentInputs[i].sourceParameterIndex], currentSetting.normalizationPosition, currentSetting.normalizationAngle, currentInputs[i].reflect, weight);
+ }
+ radAngle = CubismMath.degreesToRadian(-totalAngle.angle);
+ totalTranslation.x = totalTranslation.x * CubismMath.cos(radAngle) - totalTranslation.y * CubismMath.sin(radAngle);
+ totalTranslation.y = totalTranslation.x * CubismMath.sin(radAngle) + totalTranslation.y * CubismMath.cos(radAngle);
+ updateParticles(currentParticles, currentSetting.particleCount, totalTranslation, totalAngle.angle, this._options.wind, MovementThreshold * currentSetting.normalizationPosition.maximum, physicsDeltaTime, AirResistance);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ const particleIndex = currentOutputs[i].vertexIndex;
+ if (currentOutputs[i].destinationParameterIndex == -1) {
+ currentOutputs[i].destinationParameterIndex = model.getParameterIndex(currentOutputs[i].destination.id);
+ }
+ if (particleIndex < 1 || particleIndex >= currentSetting.particleCount) {
+ continue;
+ }
+ const translation = new CubismVector2();
+ translation.x = currentParticles[particleIndex].position.x - currentParticles[particleIndex - 1].position.x;
+ translation.y = currentParticles[particleIndex].position.y - currentParticles[particleIndex - 1].position.y;
+ outputValue = currentOutputs[i].getValue(translation, currentParticles, particleIndex, currentOutputs[i].reflect, this._options.gravity);
+ this._currentRigOutputs[settingIndex].outputs[i] = outputValue;
+ const destinationParameterIndex = currentOutputs[i].destinationParameterIndex;
+ const outParameterCaches = !Float32Array.prototype.slice && "subarray" in Float32Array.prototype ? JSON.parse(JSON.stringify(this._parameterCaches.subarray(destinationParameterIndex))) : this._parameterCaches.slice(destinationParameterIndex);
+ updateOutputParameterValue(outParameterCaches, parameterMinimumValues[destinationParameterIndex], parameterMaximumValues[destinationParameterIndex], outputValue, currentOutputs[i]);
+ for (let offset = destinationParameterIndex, outParamIndex = 0; offset < this._parameterCaches.length; offset++, outParamIndex++) {
+ this._parameterCaches[offset] = outParameterCaches[outParamIndex];
+ }
+ }
+ }
+ this._currentRemainTime -= physicsDeltaTime;
+ }
+ const alpha = this._currentRemainTime / physicsDeltaTime;
+ this.interpolate(model, alpha);
+ }
+ interpolate(model, weight) {
+ let currentOutputs;
+ let currentSetting;
+ let parameterValues;
+ let parameterMaximumValues;
+ let parameterMinimumValues;
+ parameterValues = model.getModel().parameters.values;
+ parameterMaximumValues = model.getModel().parameters.maximumValues;
+ parameterMinimumValues = model.getModel().parameters.minimumValues;
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ if (currentOutputs[i].destinationParameterIndex == -1) {
+ continue;
+ }
+ const destinationParameterIndex = currentOutputs[i].destinationParameterIndex;
+ const outParameterValues = !Float32Array.prototype.slice && "subarray" in Float32Array.prototype ? JSON.parse(JSON.stringify(parameterValues.subarray(destinationParameterIndex))) : parameterValues.slice(destinationParameterIndex);
+ updateOutputParameterValue(outParameterValues, parameterMinimumValues[destinationParameterIndex], parameterMaximumValues[destinationParameterIndex], this._previousRigOutputs[settingIndex].outputs[i] * (1 - weight) + this._currentRigOutputs[settingIndex].outputs[i] * weight, currentOutputs[i]);
+ for (let offset = destinationParameterIndex, outParamIndex = 0; offset < parameterValues.length; offset++, outParamIndex++) {
+ parameterValues[offset] = outParameterValues[outParamIndex];
+ }
+ }
+ }
+ }
+ setOptions(options) {
+ this._options = options;
+ }
+ getOption() {
+ return this._options;
+ }
+ constructor() {
+ this._options = new Options();
+ this._options.gravity.y = -1;
+ this._options.gravity.x = 0;
+ this._options.wind.x = 0;
+ this._options.wind.y = 0;
+ this._currentRigOutputs = [];
+ this._previousRigOutputs = [];
+ this._currentRemainTime = 0;
+ }
+ release() {
+ this._physicsRig = void 0;
+ }
+ initialize() {
+ let strand;
+ let currentSetting;
+ let radius;
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ currentSetting = this._physicsRig.settings[settingIndex];
+ strand = this._physicsRig.particles.slice(currentSetting.baseParticleIndex);
+ strand[0].initialPosition = new CubismVector2(0, 0);
+ strand[0].lastPosition = new CubismVector2(strand[0].initialPosition.x, strand[0].initialPosition.y);
+ strand[0].lastGravity = new CubismVector2(0, -1);
+ strand[0].lastGravity.y *= -1;
+ strand[0].velocity = new CubismVector2(0, 0);
+ strand[0].force = new CubismVector2(0, 0);
+ for (let i = 1; i < currentSetting.particleCount; ++i) {
+ radius = new CubismVector2(0, 0);
+ radius.y = strand[i].radius;
+ strand[i].initialPosition = new CubismVector2(strand[i - 1].initialPosition.x + radius.x, strand[i - 1].initialPosition.y + radius.y);
+ strand[i].position = new CubismVector2(strand[i].initialPosition.x, strand[i].initialPosition.y);
+ strand[i].lastPosition = new CubismVector2(strand[i].initialPosition.x, strand[i].initialPosition.y);
+ strand[i].lastGravity = new CubismVector2(0, -1);
+ strand[i].lastGravity.y *= -1;
+ strand[i].velocity = new CubismVector2(0, 0);
+ strand[i].force = new CubismVector2(0, 0);
+ }
+ }
+ }
+}
+class Options {
+ constructor() {
+ this.gravity = new CubismVector2(0, 0);
+ this.wind = new CubismVector2(0, 0);
+ }
+}
+class PhysicsOutput {
+ constructor() {
+ this.outputs = [];
+ }
+}
+function getInputTranslationXFromNormalizedParameterValue(targetTranslation, targetAngle, value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition, normalizationAngle, isInverted, weight) {
+ targetTranslation.x += normalizeParameterValue(value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition.minimum, normalizationPosition.maximum, normalizationPosition.defalut, isInverted) * weight;
+}
+function getInputTranslationYFromNormalizedParamterValue(targetTranslation, targetAngle, value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition, normalizationAngle, isInverted, weight) {
+ targetTranslation.y += normalizeParameterValue(value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition.minimum, normalizationPosition.maximum, normalizationPosition.defalut, isInverted) * weight;
+}
+function getInputAngleFromNormalizedParameterValue(targetTranslation, targetAngle, value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizaitionPosition, normalizationAngle, isInverted, weight) {
+ targetAngle.angle += normalizeParameterValue(value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationAngle.minimum, normalizationAngle.maximum, normalizationAngle.defalut, isInverted) * weight;
+}
+function getOutputTranslationX(translation, particles, particleIndex, isInverted, parentGravity) {
+ let outputValue = translation.x;
+ if (isInverted) {
+ outputValue *= -1;
+ }
+ return outputValue;
+}
+function getOutputTranslationY(translation, particles, particleIndex, isInverted, parentGravity) {
+ let outputValue = translation.y;
+ if (isInverted) {
+ outputValue *= -1;
+ }
+ return outputValue;
+}
+function getOutputAngle(translation, particles, particleIndex, isInverted, parentGravity) {
+ let outputValue;
+ if (particleIndex >= 2) {
+ parentGravity = particles[particleIndex - 1].position.substract(particles[particleIndex - 2].position);
+ } else {
+ parentGravity = parentGravity.multiplyByScaler(-1);
+ }
+ outputValue = CubismMath.directionToRadian(parentGravity, translation);
+ if (isInverted) {
+ outputValue *= -1;
+ }
+ return outputValue;
+}
+function getRangeValue(min, max) {
+ return Math.abs(Math.max(min, max) - Math.min(min, max));
+}
+function getDefaultValue(min, max) {
+ const minValue = Math.min(min, max);
+ return minValue + getRangeValue(min, max) / 2;
+}
+function getOutputScaleTranslationX(translationScale, angleScale) {
+ return translationScale.x;
+}
+function getOutputScaleTranslationY(translationScale, angleScale) {
+ return translationScale.y;
+}
+function getOutputScaleAngle(translationScale, angleScale) {
+ return angleScale;
+}
+function updateParticles(strand, strandCount, totalTranslation, totalAngle, windDirection, thresholdValue, deltaTimeSeconds, airResistance) {
+ let totalRadian;
+ let delay;
+ let radian;
+ let currentGravity;
+ let direction = new CubismVector2(0, 0);
+ let velocity = new CubismVector2(0, 0);
+ let force = new CubismVector2(0, 0);
+ let newDirection = new CubismVector2(0, 0);
+ strand[0].position = new CubismVector2(totalTranslation.x, totalTranslation.y);
+ totalRadian = CubismMath.degreesToRadian(totalAngle);
+ currentGravity = CubismMath.radianToDirection(totalRadian);
+ currentGravity.normalize();
+ for (let i = 1; i < strandCount; ++i) {
+ strand[i].force = currentGravity.multiplyByScaler(strand[i].acceleration).add(windDirection);
+ strand[i].lastPosition = new CubismVector2(strand[i].position.x, strand[i].position.y);
+ delay = strand[i].delay * deltaTimeSeconds * 30;
+ direction = strand[i].position.substract(strand[i - 1].position);
+ radian = CubismMath.directionToRadian(strand[i].lastGravity, currentGravity) / airResistance;
+ direction.x = CubismMath.cos(radian) * direction.x - direction.y * CubismMath.sin(radian);
+ direction.y = CubismMath.sin(radian) * direction.x + direction.y * CubismMath.cos(radian);
+ strand[i].position = strand[i - 1].position.add(direction);
+ velocity = strand[i].velocity.multiplyByScaler(delay);
+ force = strand[i].force.multiplyByScaler(delay).multiplyByScaler(delay);
+ strand[i].position = strand[i].position.add(velocity).add(force);
+ newDirection = strand[i].position.substract(strand[i - 1].position);
+ newDirection.normalize();
+ strand[i].position = strand[i - 1].position.add(newDirection.multiplyByScaler(strand[i].radius));
+ if (CubismMath.abs(strand[i].position.x) < thresholdValue) {
+ strand[i].position.x = 0;
+ }
+ if (delay != 0) {
+ strand[i].velocity = strand[i].position.substract(strand[i].lastPosition);
+ strand[i].velocity = strand[i].velocity.divisionByScalar(delay);
+ strand[i].velocity = strand[i].velocity.multiplyByScaler(strand[i].mobility);
+ }
+ strand[i].force = new CubismVector2(0, 0);
+ strand[i].lastGravity = new CubismVector2(currentGravity.x, currentGravity.y);
+ }
+}
+function updateParticlesForStabilization(strand, strandCount, totalTranslation, totalAngle, windDirection, thresholdValue) {
+ let totalRadian;
+ let currentGravity;
+ let force = new CubismVector2(0, 0);
+ strand[0].position = new CubismVector2(totalTranslation.x, totalTranslation.y);
+ totalRadian = CubismMath.degreesToRadian(totalAngle);
+ currentGravity = CubismMath.radianToDirection(totalRadian);
+ currentGravity.normalize();
+ for (let i = 1; i < strandCount; ++i) {
+ strand[i].force = currentGravity.multiplyByScaler(strand[i].acceleration).add(windDirection);
+ strand[i].lastPosition = new CubismVector2(strand[i].position.x, strand[i].position.y);
+ strand[i].velocity = new CubismVector2(0, 0);
+ force = strand[i].force;
+ force.normalize();
+ force = force.multiplyByScaler(strand[i].radius);
+ strand[i].position = strand[i - 1].position.add(force);
+ if (CubismMath.abs(strand[i].position.x) < thresholdValue) {
+ strand[i].position.x = 0;
+ }
+ strand[i].force = new CubismVector2(0, 0);
+ strand[i].lastGravity = new CubismVector2(currentGravity.x, currentGravity.y);
+ }
+}
+function updateOutputParameterValue(parameterValue, parameterValueMinimum, parameterValueMaximum, translation, output) {
+ let outputScale;
+ let value;
+ let weight;
+ outputScale = output.getScale(output.translationScale, output.angleScale);
+ value = translation * outputScale;
+ if (value < parameterValueMinimum) {
+ if (value < output.valueBelowMinimum) {
+ output.valueBelowMinimum = value;
+ }
+ value = parameterValueMinimum;
+ } else if (value > parameterValueMaximum) {
+ if (value > output.valueExceededMaximum) {
+ output.valueExceededMaximum = value;
+ }
+ value = parameterValueMaximum;
+ }
+ weight = output.weight / MaximumWeight;
+ if (weight >= 1) {
+ parameterValue[0] = value;
+ } else {
+ value = parameterValue[0] * (1 - weight) + value * weight;
+ parameterValue[0] = value;
+ }
+}
+function normalizeParameterValue(value, parameterMinimum, parameterMaximum, parameterDefault, normalizedMinimum, normalizedMaximum, normalizedDefault, isInverted) {
+ let result = 0;
+ const maxValue = CubismMath.max(parameterMaximum, parameterMinimum);
+ if (maxValue < value) {
+ value = maxValue;
+ }
+ const minValue = CubismMath.min(parameterMaximum, parameterMinimum);
+ if (minValue > value) {
+ value = minValue;
+ }
+ const minNormValue = CubismMath.min(normalizedMinimum, normalizedMaximum);
+ const maxNormValue = CubismMath.max(normalizedMinimum, normalizedMaximum);
+ const middleNormValue = normalizedDefault;
+ const middleValue = getDefaultValue(minValue, maxValue);
+ const paramValue = value - middleValue;
+ switch (Math.sign(paramValue)) {
+ case 1: {
+ const nLength = maxNormValue - middleNormValue;
+ const pLength = maxValue - middleValue;
+ if (pLength != 0) {
+ result = paramValue * (nLength / pLength);
+ result += middleNormValue;
+ }
+ break;
+ }
+ case -1: {
+ const nLength = minNormValue - middleNormValue;
+ const pLength = minValue - middleValue;
+ if (pLength != 0) {
+ result = paramValue * (nLength / pLength);
+ result += middleNormValue;
+ }
+ break;
+ }
+ case 0: {
+ result = middleNormValue;
+ break;
+ }
+ }
+ return isInverted ? result : result * -1;
+}
+class csmRect {
+ constructor(x = 0, y = 0, w = 0, h = 0) {
+ this.x = x;
+ this.y = y;
+ this.width = w;
+ this.height = h;
+ }
+ getCenterX() {
+ return this.x + 0.5 * this.width;
+ }
+ getCenterY() {
+ return this.y + 0.5 * this.height;
+ }
+ getRight() {
+ return this.x + this.width;
+ }
+ getBottom() {
+ return this.y + this.height;
+ }
+ setRect(r) {
+ this.x = r.x;
+ this.y = r.y;
+ this.width = r.width;
+ this.height = r.height;
+ }
+ expand(w, h) {
+ this.x -= w;
+ this.y -= h;
+ this.width += w * 2;
+ this.height += h * 2;
+ }
+}
+const ColorChannelCount = 4;
+const ClippingMaskMaxCountOnDefault = 36;
+const ClippingMaskMaxCountOnMultiRenderTexture = 32;
+const ShaderCount = 10;
+let s_instance;
+let s_viewport;
+let s_fbo;
+class CubismClippingManager_WebGL {
+ getChannelFlagAsColor(channelNo) {
+ return this._channelColors[channelNo];
+ }
+ getMaskRenderTexture() {
+ if (this._maskTexture && this._maskTexture.textures != null) {
+ this._maskTexture.frameNo = this._currentFrameNo;
+ } else {
+ this._maskRenderTextures = [];
+ this._maskColorBuffers = [];
+ const size = this._clippingMaskBufferSize;
+ for (let index = 0; index < this._renderTextureCount; index++) {
+ this._maskColorBuffers.push(this.gl.createTexture());
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this._maskColorBuffers[index]);
+ this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, size, size, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, null);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, null);
+ this._maskRenderTextures.push(this.gl.createFramebuffer());
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this._maskRenderTextures[index]);
+ this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, this._maskColorBuffers[index], 0);
+ }
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, s_fbo);
+ this._maskTexture = new CubismRenderTextureResource(this._currentFrameNo, this._maskRenderTextures);
+ }
+ return this._maskTexture.textures;
+ }
+ setGL(gl) {
+ this.gl = gl;
+ }
+ calcClippedDrawTotalBounds(model, clippingContext) {
+ let clippedDrawTotalMinX = Number.MAX_VALUE;
+ let clippedDrawTotalMinY = Number.MAX_VALUE;
+ let clippedDrawTotalMaxX = Number.MIN_VALUE;
+ let clippedDrawTotalMaxY = Number.MIN_VALUE;
+ const clippedDrawCount = clippingContext._clippedDrawableIndexList.length;
+ for (let clippedDrawableIndex = 0; clippedDrawableIndex < clippedDrawCount; clippedDrawableIndex++) {
+ const drawableIndex = clippingContext._clippedDrawableIndexList[clippedDrawableIndex];
+ const drawableVertexCount = model.getDrawableVertexCount(drawableIndex);
+ const drawableVertexes = model.getDrawableVertices(drawableIndex);
+ let minX = Number.MAX_VALUE;
+ let minY = Number.MAX_VALUE;
+ let maxX = -Number.MAX_VALUE;
+ let maxY = -Number.MAX_VALUE;
+ const loop = drawableVertexCount * Constant.vertexStep;
+ for (let pi = Constant.vertexOffset; pi < loop; pi += Constant.vertexStep) {
+ const x = drawableVertexes[pi];
+ const y = drawableVertexes[pi + 1];
+ if (x < minX) {
+ minX = x;
+ }
+ if (x > maxX) {
+ maxX = x;
+ }
+ if (y < minY) {
+ minY = y;
+ }
+ if (y > maxY) {
+ maxY = y;
+ }
+ }
+ if (minX == Number.MAX_VALUE) {
+ continue;
+ }
+ if (minX < clippedDrawTotalMinX) {
+ clippedDrawTotalMinX = minX;
+ }
+ if (minY < clippedDrawTotalMinY) {
+ clippedDrawTotalMinY = minY;
+ }
+ if (maxX > clippedDrawTotalMaxX) {
+ clippedDrawTotalMaxX = maxX;
+ }
+ if (maxY > clippedDrawTotalMaxY) {
+ clippedDrawTotalMaxY = maxY;
+ }
+ if (clippedDrawTotalMinX == Number.MAX_VALUE) {
+ clippingContext._allClippedDrawRect.x = 0;
+ clippingContext._allClippedDrawRect.y = 0;
+ clippingContext._allClippedDrawRect.width = 0;
+ clippingContext._allClippedDrawRect.height = 0;
+ clippingContext._isUsing = false;
+ } else {
+ clippingContext._isUsing = true;
+ const w = clippedDrawTotalMaxX - clippedDrawTotalMinX;
+ const h = clippedDrawTotalMaxY - clippedDrawTotalMinY;
+ clippingContext._allClippedDrawRect.x = clippedDrawTotalMinX;
+ clippingContext._allClippedDrawRect.y = clippedDrawTotalMinY;
+ clippingContext._allClippedDrawRect.width = w;
+ clippingContext._allClippedDrawRect.height = h;
+ }
+ }
+ }
+ constructor() {
+ this._currentMaskRenderTexture = null;
+ this._currentFrameNo = 0;
+ this._renderTextureCount = 0;
+ this._clippingMaskBufferSize = 256;
+ this._clippingContextListForMask = [];
+ this._clippingContextListForDraw = [];
+ this._channelColors = [];
+ this._tmpBoundsOnModel = new csmRect();
+ this._tmpMatrix = new CubismMatrix44();
+ this._tmpMatrixForMask = new CubismMatrix44();
+ this._tmpMatrixForDraw = new CubismMatrix44();
+ let tmp = new CubismTextureColor();
+ tmp.R = 1;
+ tmp.G = 0;
+ tmp.B = 0;
+ tmp.A = 0;
+ this._channelColors.push(tmp);
+ tmp = new CubismTextureColor();
+ tmp.R = 0;
+ tmp.G = 1;
+ tmp.B = 0;
+ tmp.A = 0;
+ this._channelColors.push(tmp);
+ tmp = new CubismTextureColor();
+ tmp.R = 0;
+ tmp.G = 0;
+ tmp.B = 1;
+ tmp.A = 0;
+ this._channelColors.push(tmp);
+ tmp = new CubismTextureColor();
+ tmp.R = 0;
+ tmp.G = 0;
+ tmp.B = 0;
+ tmp.A = 1;
+ this._channelColors.push(tmp);
+ }
+ release() {
+ var _a;
+ const self = this;
+ for (let i = 0; i < this._clippingContextListForMask.length; i++) {
+ if (this._clippingContextListForMask[i]) {
+ (_a = this._clippingContextListForMask[i]) == null ? void 0 : _a.release();
+ }
+ }
+ self._clippingContextListForMask = void 0;
+ self._clippingContextListForDraw = void 0;
+ if (this._maskTexture) {
+ for (let i = 0; i < this._maskTexture.textures.length; i++) {
+ this.gl.deleteFramebuffer(this._maskTexture.textures[i]);
+ }
+ this._maskTexture = void 0;
+ }
+ self._channelColors = void 0;
+ if (this._maskColorBuffers) {
+ for (let index = 0; index < this._maskColorBuffers.length; index++) {
+ this.gl.deleteTexture(this._maskColorBuffers[index]);
+ }
+ }
+ this._maskColorBuffers = void 0;
+ this._maskRenderTextures = void 0;
+ this._clearedFrameBufferflags = void 0;
+ }
+ initialize(model, drawableCount, drawableMasks, drawableMaskCounts, renderTextureCount) {
+ if (renderTextureCount % 1 != 0) {
+ CubismLogWarning("The number of render textures must be specified as an integer. The decimal point is rounded down and corrected to an integer.");
+ renderTextureCount = ~~renderTextureCount;
+ }
+ if (renderTextureCount < 1) {
+ CubismLogWarning("The number of render textures must be an integer greater than or equal to 1. Set the number of render textures to 1.");
+ }
+ this._renderTextureCount = renderTextureCount < 1 ? 1 : renderTextureCount;
+ this._clearedFrameBufferflags = [];
+ for (let i = 0; i < drawableCount; i++) {
+ if (drawableMaskCounts[i] <= 0) {
+ this._clippingContextListForDraw.push(null);
+ continue;
+ }
+ let clippingContext = this.findSameClip(drawableMasks[i], drawableMaskCounts[i]);
+ if (clippingContext == null) {
+ clippingContext = new CubismClippingContext(this, drawableMasks[i], drawableMaskCounts[i]);
+ this._clippingContextListForMask.push(clippingContext);
+ }
+ clippingContext.addClippedDrawable(i);
+ this._clippingContextListForDraw.push(clippingContext);
+ }
+ }
+ setupClippingContext(model, renderer) {
+ this._currentFrameNo++;
+ let usingClipCount = 0;
+ for (let clipIndex = 0; clipIndex < this._clippingContextListForMask.length; clipIndex++) {
+ const cc = this._clippingContextListForMask[clipIndex];
+ this.calcClippedDrawTotalBounds(model, cc);
+ if (cc._isUsing) {
+ usingClipCount++;
+ }
+ }
+ if (usingClipCount > 0) {
+ this.setupLayoutBounds(renderer.isUsingHighPrecisionMask() ? 0 : usingClipCount);
+ if (!renderer.isUsingHighPrecisionMask()) {
+ this.gl.viewport(0, 0, this._clippingMaskBufferSize, this._clippingMaskBufferSize);
+ this._currentMaskRenderTexture = this.getMaskRenderTexture()[0];
+ renderer.preDraw();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this._currentMaskRenderTexture);
+ }
+ if (!this._clearedFrameBufferflags) {
+ this._clearedFrameBufferflags = [];
+ }
+ for (let index = 0; index < this._renderTextureCount; index++) {
+ this._clearedFrameBufferflags[index] = false;
+ }
+ for (let clipIndex = 0; clipIndex < this._clippingContextListForMask.length; clipIndex++) {
+ const clipContext = this._clippingContextListForMask[clipIndex];
+ const allClipedDrawRect = clipContext._allClippedDrawRect;
+ const layoutBoundsOnTex01 = clipContext._layoutBounds;
+ const MARGIN = 0.05;
+ let scaleX = 0;
+ let scaleY = 0;
+ const clipContextRenderTexture = this.getMaskRenderTexture()[clipContext._bufferIndex];
+ if (this._currentMaskRenderTexture != clipContextRenderTexture && !renderer.isUsingHighPrecisionMask()) {
+ this._currentMaskRenderTexture = clipContextRenderTexture;
+ renderer.preDraw();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this._currentMaskRenderTexture);
+ }
+ if (renderer.isUsingHighPrecisionMask()) {
+ const ppu = model.getPixelsPerUnit();
+ const maskPixelSize = clipContext.getClippingManager()._clippingMaskBufferSize;
+ const physicalMaskWidth = layoutBoundsOnTex01.width * maskPixelSize;
+ const physicalMaskHeight = layoutBoundsOnTex01.height * maskPixelSize;
+ this._tmpBoundsOnModel.setRect(allClipedDrawRect);
+ if (this._tmpBoundsOnModel.width * ppu > physicalMaskWidth) {
+ this._tmpBoundsOnModel.expand(allClipedDrawRect.width * MARGIN, 0);
+ scaleX = layoutBoundsOnTex01.width / this._tmpBoundsOnModel.width;
+ } else {
+ scaleX = ppu / physicalMaskWidth;
+ }
+ if (this._tmpBoundsOnModel.height * ppu > physicalMaskHeight) {
+ this._tmpBoundsOnModel.expand(0, allClipedDrawRect.height * MARGIN);
+ scaleY = layoutBoundsOnTex01.height / this._tmpBoundsOnModel.height;
+ } else {
+ scaleY = ppu / physicalMaskHeight;
+ }
+ } else {
+ this._tmpBoundsOnModel.setRect(allClipedDrawRect);
+ this._tmpBoundsOnModel.expand(allClipedDrawRect.width * MARGIN, allClipedDrawRect.height * MARGIN);
+ scaleX = layoutBoundsOnTex01.width / this._tmpBoundsOnModel.width;
+ scaleY = layoutBoundsOnTex01.height / this._tmpBoundsOnModel.height;
+ }
+ {
+ this._tmpMatrix.loadIdentity();
+ {
+ this._tmpMatrix.translateRelative(-1, -1);
+ this._tmpMatrix.scaleRelative(2, 2);
+ }
+ {
+ this._tmpMatrix.translateRelative(layoutBoundsOnTex01.x, layoutBoundsOnTex01.y);
+ this._tmpMatrix.scaleRelative(scaleX, scaleY);
+ this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x, -this._tmpBoundsOnModel.y);
+ }
+ this._tmpMatrixForMask.setMatrix(this._tmpMatrix.getArray());
+ }
+ {
+ this._tmpMatrix.loadIdentity();
+ {
+ this._tmpMatrix.translateRelative(layoutBoundsOnTex01.x, layoutBoundsOnTex01.y);
+ this._tmpMatrix.scaleRelative(scaleX, scaleY);
+ this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x, -this._tmpBoundsOnModel.y);
+ }
+ this._tmpMatrixForDraw.setMatrix(this._tmpMatrix.getArray());
+ }
+ clipContext._matrixForMask.setMatrix(this._tmpMatrixForMask.getArray());
+ clipContext._matrixForDraw.setMatrix(this._tmpMatrixForDraw.getArray());
+ if (!renderer.isUsingHighPrecisionMask()) {
+ const clipDrawCount = clipContext._clippingIdCount;
+ for (let i = 0; i < clipDrawCount; i++) {
+ const clipDrawIndex = clipContext._clippingIdList[i];
+ if (!model.getDrawableDynamicFlagVertexPositionsDidChange(clipDrawIndex)) {
+ continue;
+ }
+ renderer.setIsCulling(model.getDrawableCulling(clipDrawIndex) != false);
+ if (!this._clearedFrameBufferflags[clipContext._bufferIndex]) {
+ this.gl.clearColor(1, 1, 1, 1);
+ this.gl.clear(this.gl.COLOR_BUFFER_BIT);
+ this._clearedFrameBufferflags[clipContext._bufferIndex] = true;
+ }
+ renderer.setClippingContextBufferForMask(clipContext);
+ renderer.drawMesh(model.getDrawableTextureIndex(clipDrawIndex), model.getDrawableVertexIndexCount(clipDrawIndex), model.getDrawableVertexCount(clipDrawIndex), model.getDrawableVertexIndices(clipDrawIndex), model.getDrawableVertices(clipDrawIndex), model.getDrawableVertexUvs(clipDrawIndex), model.getMultiplyColor(clipDrawIndex), model.getScreenColor(clipDrawIndex), model.getDrawableOpacity(clipDrawIndex), CubismBlendMode.CubismBlendMode_Normal, false);
+ }
+ }
+ }
+ if (!renderer.isUsingHighPrecisionMask()) {
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, s_fbo);
+ renderer.setClippingContextBufferForMask(null);
+ this.gl.viewport(s_viewport[0], s_viewport[1], s_viewport[2], s_viewport[3]);
+ }
+ }
+ }
+ findSameClip(drawableMasks, drawableMaskCounts) {
+ for (let i = 0; i < this._clippingContextListForMask.length; i++) {
+ const clippingContext = this._clippingContextListForMask[i];
+ const count = clippingContext._clippingIdCount;
+ if (count != drawableMaskCounts) {
+ continue;
+ }
+ let sameCount = 0;
+ for (let j = 0; j < count; j++) {
+ const clipId = clippingContext._clippingIdList[j];
+ for (let k = 0; k < count; k++) {
+ if (drawableMasks[k] == clipId) {
+ sameCount++;
+ break;
+ }
+ }
+ }
+ if (sameCount == count) {
+ return clippingContext;
+ }
+ }
+ return null;
+ }
+ setupLayoutBounds(usingClipCount) {
+ const useClippingMaskMaxCount = this._renderTextureCount <= 1 ? ClippingMaskMaxCountOnDefault : ClippingMaskMaxCountOnMultiRenderTexture * this._renderTextureCount;
+ if (usingClipCount <= 0 || usingClipCount > useClippingMaskMaxCount) {
+ if (usingClipCount > useClippingMaskMaxCount) {
+ CubismLogError("not supported mask count : {0}\n[Details] render texture count : {1}, mask count : {2}", usingClipCount - useClippingMaskMaxCount, this._renderTextureCount, usingClipCount);
+ }
+ for (let index = 0; index < this._clippingContextListForMask.length; index++) {
+ const clipContext = this._clippingContextListForMask[index];
+ clipContext._layoutChannelNo = 0;
+ clipContext._layoutBounds.x = 0;
+ clipContext._layoutBounds.y = 0;
+ clipContext._layoutBounds.width = 1;
+ clipContext._layoutBounds.height = 1;
+ clipContext._bufferIndex = 0;
+ }
+ return;
+ }
+ const layoutCountMaxValue = this._renderTextureCount <= 1 ? 9 : 8;
+ let countPerSheetDiv = usingClipCount / this._renderTextureCount;
+ let countPerSheetMod = usingClipCount % this._renderTextureCount;
+ countPerSheetDiv = ~~countPerSheetDiv;
+ countPerSheetMod = ~~countPerSheetMod;
+ let div = countPerSheetDiv / ColorChannelCount;
+ let mod = countPerSheetDiv % ColorChannelCount;
+ div = ~~div;
+ mod = ~~mod;
+ let curClipIndex = 0;
+ for (let renderTextureNo = 0; renderTextureNo < this._renderTextureCount; renderTextureNo++) {
+ for (let channelNo = 0; channelNo < ColorChannelCount; channelNo++) {
+ let layoutCount = div + (channelNo < mod ? 1 : 0);
+ const checkChannelNo = mod + 1 >= ColorChannelCount ? 0 : mod + 1;
+ if (layoutCount < layoutCountMaxValue && channelNo == checkChannelNo) {
+ layoutCount += renderTextureNo < countPerSheetMod ? 1 : 0;
+ }
+ if (layoutCount == 0)
+ ;
+ else if (layoutCount == 1) {
+ const clipContext = this._clippingContextListForMask[curClipIndex++];
+ clipContext._layoutChannelNo = channelNo;
+ clipContext._layoutBounds.x = 0;
+ clipContext._layoutBounds.y = 0;
+ clipContext._layoutBounds.width = 1;
+ clipContext._layoutBounds.height = 1;
+ clipContext._bufferIndex = renderTextureNo;
+ } else if (layoutCount == 2) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 2;
+ xpos = ~~xpos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos * 0.5;
+ cc._layoutBounds.y = 0;
+ cc._layoutBounds.width = 0.5;
+ cc._layoutBounds.height = 1;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else if (layoutCount <= 4) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 2;
+ let ypos = i / 2;
+ xpos = ~~xpos;
+ ypos = ~~ypos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos * 0.5;
+ cc._layoutBounds.y = ypos * 0.5;
+ cc._layoutBounds.width = 0.5;
+ cc._layoutBounds.height = 0.5;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else if (layoutCount <= layoutCountMaxValue) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 3;
+ let ypos = i / 3;
+ xpos = ~~xpos;
+ ypos = ~~ypos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos / 3;
+ cc._layoutBounds.y = ypos / 3;
+ cc._layoutBounds.width = 1 / 3;
+ cc._layoutBounds.height = 1 / 3;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else if (CubismConfig.supportMoreMaskDivisions && layoutCount <= 16) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 4;
+ let ypos = i / 4;
+ xpos = ~~xpos;
+ ypos = ~~ypos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos / 4;
+ cc._layoutBounds.y = ypos / 4;
+ cc._layoutBounds.width = 1 / 4;
+ cc._layoutBounds.height = 1 / 4;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else {
+ CubismLogError("not supported mask count : {0}\n[Details] render texture count : {1}, mask count : {2}", usingClipCount - useClippingMaskMaxCount, this._renderTextureCount, usingClipCount);
+ for (let index = 0; index < layoutCount; index++) {
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = 0;
+ cc._layoutBounds.x = 0;
+ cc._layoutBounds.y = 0;
+ cc._layoutBounds.width = 1;
+ cc._layoutBounds.height = 1;
+ cc._bufferIndex = 0;
+ }
+ }
+ }
+ }
+ }
+ getColorBuffer() {
+ return this._maskColorBuffers;
+ }
+ getClippingContextListForDraw() {
+ return this._clippingContextListForDraw;
+ }
+ getClippingMaskCount() {
+ return this._clippingContextListForMask.length;
+ }
+ setClippingMaskBufferSize(size) {
+ this._clippingMaskBufferSize = size;
+ }
+ getClippingMaskBufferSize() {
+ return this._clippingMaskBufferSize;
+ }
+ getRenderTextureCount() {
+ return this._renderTextureCount;
+ }
+}
+class CubismRenderTextureResource {
+ constructor(frameNo, texture) {
+ this.frameNo = frameNo;
+ this.textures = texture;
+ }
+}
+class CubismClippingContext {
+ constructor(manager, clippingDrawableIndices, clipCount) {
+ this._isUsing = false;
+ this._owner = manager;
+ this._clippingIdList = clippingDrawableIndices;
+ this._clippingIdCount = clipCount;
+ this._allClippedDrawRect = new csmRect();
+ this._layoutBounds = new csmRect();
+ this._clippedDrawableIndexList = [];
+ this._matrixForMask = new CubismMatrix44();
+ this._matrixForDraw = new CubismMatrix44();
+ this._bufferIndex = 0;
+ }
+ release() {
+ const self = this;
+ self._layoutBounds = void 0;
+ self._allClippedDrawRect = void 0;
+ self._clippedDrawableIndexList = void 0;
+ }
+ addClippedDrawable(drawableIndex) {
+ this._clippedDrawableIndexList.push(drawableIndex);
+ }
+ getClippingManager() {
+ return this._owner;
+ }
+ setGl(gl) {
+ this._owner.setGL(gl);
+ }
+}
+class CubismRendererProfile_WebGL {
+ setGlEnable(index, enabled) {
+ if (enabled)
+ this.gl.enable(index);
+ else
+ this.gl.disable(index);
+ }
+ setGlEnableVertexAttribArray(index, enabled) {
+ if (enabled)
+ this.gl.enableVertexAttribArray(index);
+ else
+ this.gl.disableVertexAttribArray(index);
+ }
+ save() {
+ if (this.gl == null) {
+ CubismLogError("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");
+ return;
+ }
+ this._lastArrayBufferBinding = this.gl.getParameter(this.gl.ARRAY_BUFFER_BINDING);
+ this._lastArrayBufferBinding = this.gl.getParameter(this.gl.ELEMENT_ARRAY_BUFFER_BINDING);
+ this._lastProgram = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
+ this._lastActiveTexture = this.gl.getParameter(this.gl.ACTIVE_TEXTURE);
+ this.gl.activeTexture(this.gl.TEXTURE1);
+ this._lastTexture1Binding2D = this.gl.getParameter(this.gl.TEXTURE_BINDING_2D);
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this._lastTexture0Binding2D = this.gl.getParameter(this.gl.TEXTURE_BINDING_2D);
+ this._lastVertexAttribArrayEnabled[0] = this.gl.getVertexAttrib(0, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastVertexAttribArrayEnabled[1] = this.gl.getVertexAttrib(1, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastVertexAttribArrayEnabled[2] = this.gl.getVertexAttrib(2, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastVertexAttribArrayEnabled[3] = this.gl.getVertexAttrib(3, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastScissorTest = this.gl.isEnabled(this.gl.SCISSOR_TEST);
+ this._lastStencilTest = this.gl.isEnabled(this.gl.STENCIL_TEST);
+ this._lastDepthTest = this.gl.isEnabled(this.gl.DEPTH_TEST);
+ this._lastCullFace = this.gl.isEnabled(this.gl.CULL_FACE);
+ this._lastBlend = this.gl.isEnabled(this.gl.BLEND);
+ this._lastFrontFace = this.gl.getParameter(this.gl.FRONT_FACE);
+ this._lastColorMask = this.gl.getParameter(this.gl.COLOR_WRITEMASK);
+ this._lastBlending[0] = this.gl.getParameter(this.gl.BLEND_SRC_RGB);
+ this._lastBlending[1] = this.gl.getParameter(this.gl.BLEND_DST_RGB);
+ this._lastBlending[2] = this.gl.getParameter(this.gl.BLEND_SRC_ALPHA);
+ this._lastBlending[3] = this.gl.getParameter(this.gl.BLEND_DST_ALPHA);
+ this._lastFBO = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING);
+ this._lastViewport = this.gl.getParameter(this.gl.VIEWPORT);
+ }
+ restore() {
+ if (this.gl == null) {
+ CubismLogError("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");
+ return;
+ }
+ this.gl.useProgram(this._lastProgram);
+ this.setGlEnableVertexAttribArray(0, this._lastVertexAttribArrayEnabled[0]);
+ this.setGlEnableVertexAttribArray(1, this._lastVertexAttribArrayEnabled[1]);
+ this.setGlEnableVertexAttribArray(2, this._lastVertexAttribArrayEnabled[2]);
+ this.setGlEnableVertexAttribArray(3, this._lastVertexAttribArrayEnabled[3]);
+ this.setGlEnable(this.gl.SCISSOR_TEST, this._lastScissorTest);
+ this.setGlEnable(this.gl.STENCIL_TEST, this._lastStencilTest);
+ this.setGlEnable(this.gl.DEPTH_TEST, this._lastDepthTest);
+ this.setGlEnable(this.gl.CULL_FACE, this._lastCullFace);
+ this.setGlEnable(this.gl.BLEND, this._lastBlend);
+ this.gl.frontFace(this._lastFrontFace);
+ this.gl.colorMask(this._lastColorMask[0], this._lastColorMask[1], this._lastColorMask[2], this._lastColorMask[3]);
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this._lastArrayBufferBinding);
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this._lastElementArrayBufferBinding);
+ this.gl.activeTexture(this.gl.TEXTURE1);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this._lastTexture1Binding2D);
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this._lastTexture0Binding2D);
+ this.gl.activeTexture(this._lastActiveTexture);
+ this.gl.blendFuncSeparate(this._lastBlending[0], this._lastBlending[1], this._lastBlending[2], this._lastBlending[3]);
+ }
+ setGl(gl) {
+ this.gl = gl;
+ }
+ constructor() {
+ this._lastVertexAttribArrayEnabled = new Array(4);
+ this._lastColorMask = new Array(4);
+ this._lastBlending = new Array(4);
+ this._lastViewport = new Array(4);
+ }
+}
+class CubismShader_WebGL {
+ static getInstance() {
+ if (s_instance == null) {
+ s_instance = new CubismShader_WebGL();
+ return s_instance;
+ }
+ return s_instance;
+ }
+ static deleteInstance() {
+ if (s_instance) {
+ s_instance.release();
+ s_instance = void 0;
+ }
+ }
+ constructor() {
+ this._shaderSets = [];
+ }
+ release() {
+ this.releaseShaderProgram();
+ }
+ setupShaderProgram(renderer, textureId, vertexCount, vertexArray, indexArray, uvArray, bufferData, opacity, colorBlendMode, baseColor, multiplyColor, screenColor, isPremultipliedAlpha, matrix4x4, invertedMask) {
+ if (!isPremultipliedAlpha) {
+ CubismLogError("NoPremultipliedAlpha is not allowed");
+ }
+ if (this._shaderSets.length == 0) {
+ this.generateShaders();
+ }
+ let SRC_COLOR;
+ let DST_COLOR;
+ let SRC_ALPHA;
+ let DST_ALPHA;
+ const clippingContextBufferForMask = renderer.getClippingContextBufferForMask();
+ if (clippingContextBufferForMask != null) {
+ const shaderSet = this._shaderSets[ShaderNames.ShaderNames_SetupMask];
+ this.gl.useProgram(shaderSet.shaderProgram);
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, textureId);
+ this.gl.uniform1i(shaderSet.samplerTexture0Location, 0);
+ if (bufferData.vertex == null) {
+ bufferData.vertex = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.vertex);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, vertexArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributePositionLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributePositionLocation, 2, this.gl.FLOAT, false, 0, 0);
+ if (bufferData.uv == null) {
+ bufferData.uv = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.uv);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, uvArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributeTexCoordLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributeTexCoordLocation, 2, this.gl.FLOAT, false, 0, 0);
+ const channelNo = clippingContextBufferForMask._layoutChannelNo;
+ const colorChannel = clippingContextBufferForMask.getClippingManager().getChannelFlagAsColor(channelNo);
+ this.gl.uniform4f(shaderSet.uniformChannelFlagLocation, colorChannel.R, colorChannel.G, colorChannel.B, colorChannel.A);
+ this.gl.uniformMatrix4fv(shaderSet.uniformClipMatrixLocation, false, clippingContextBufferForMask._matrixForMask.getArray());
+ const rect = clippingContextBufferForMask._layoutBounds;
+ this.gl.uniform4f(shaderSet.uniformBaseColorLocation, rect.x * 2 - 1, rect.y * 2 - 1, rect.getRight() * 2 - 1, rect.getBottom() * 2 - 1);
+ this.gl.uniform4f(shaderSet.uniformMultiplyColorLocation, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A);
+ this.gl.uniform4f(shaderSet.uniformScreenColorLocation, screenColor.R, screenColor.G, screenColor.B, screenColor.A);
+ SRC_COLOR = this.gl.ZERO;
+ DST_COLOR = this.gl.ONE_MINUS_SRC_COLOR;
+ SRC_ALPHA = this.gl.ZERO;
+ DST_ALPHA = this.gl.ONE_MINUS_SRC_ALPHA;
+ } else {
+ const clippingContextBufferForDraw = renderer.getClippingContextBufferForDraw();
+ const masked = clippingContextBufferForDraw != null;
+ const offset = masked ? invertedMask ? 2 : 1 : 0;
+ let shaderSet;
+ switch (colorBlendMode) {
+ case CubismBlendMode.CubismBlendMode_Normal:
+ default:
+ shaderSet = this._shaderSets[ShaderNames.ShaderNames_NormalPremultipliedAlpha + offset];
+ SRC_COLOR = this.gl.ONE;
+ DST_COLOR = this.gl.ONE_MINUS_SRC_ALPHA;
+ SRC_ALPHA = this.gl.ONE;
+ DST_ALPHA = this.gl.ONE_MINUS_SRC_ALPHA;
+ break;
+ case CubismBlendMode.CubismBlendMode_Additive:
+ shaderSet = this._shaderSets[ShaderNames.ShaderNames_AddPremultipliedAlpha + offset];
+ SRC_COLOR = this.gl.ONE;
+ DST_COLOR = this.gl.ONE;
+ SRC_ALPHA = this.gl.ZERO;
+ DST_ALPHA = this.gl.ONE;
+ break;
+ case CubismBlendMode.CubismBlendMode_Multiplicative:
+ shaderSet = this._shaderSets[ShaderNames.ShaderNames_MultPremultipliedAlpha + offset];
+ SRC_COLOR = this.gl.DST_COLOR;
+ DST_COLOR = this.gl.ONE_MINUS_SRC_ALPHA;
+ SRC_ALPHA = this.gl.ZERO;
+ DST_ALPHA = this.gl.ONE;
+ break;
+ }
+ this.gl.useProgram(shaderSet.shaderProgram);
+ if (bufferData.vertex == null) {
+ bufferData.vertex = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.vertex);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, vertexArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributePositionLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributePositionLocation, 2, this.gl.FLOAT, false, 0, 0);
+ if (bufferData.uv == null) {
+ bufferData.uv = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.uv);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, uvArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributeTexCoordLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributeTexCoordLocation, 2, this.gl.FLOAT, false, 0, 0);
+ if (clippingContextBufferForDraw != null) {
+ this.gl.activeTexture(this.gl.TEXTURE1);
+ const tex = clippingContextBufferForDraw.getClippingManager().getColorBuffer()[renderer.getClippingContextBufferForDraw()._bufferIndex];
+ this.gl.bindTexture(this.gl.TEXTURE_2D, tex);
+ this.gl.uniform1i(shaderSet.samplerTexture1Location, 1);
+ this.gl.uniformMatrix4fv(shaderSet.uniformClipMatrixLocation, false, clippingContextBufferForDraw._matrixForDraw.getArray());
+ const channelNo = clippingContextBufferForDraw._layoutChannelNo;
+ const colorChannel = clippingContextBufferForDraw.getClippingManager().getChannelFlagAsColor(channelNo);
+ this.gl.uniform4f(shaderSet.uniformChannelFlagLocation, colorChannel.R, colorChannel.G, colorChannel.B, colorChannel.A);
+ }
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, textureId);
+ this.gl.uniform1i(shaderSet.samplerTexture0Location, 0);
+ this.gl.uniformMatrix4fv(shaderSet.uniformMatrixLocation, false, matrix4x4.getArray());
+ this.gl.uniform4f(shaderSet.uniformBaseColorLocation, baseColor.R, baseColor.G, baseColor.B, baseColor.A);
+ this.gl.uniform4f(shaderSet.uniformMultiplyColorLocation, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A);
+ this.gl.uniform4f(shaderSet.uniformScreenColorLocation, screenColor.R, screenColor.G, screenColor.B, screenColor.A);
+ }
+ if (bufferData.index == null) {
+ bufferData.index = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, bufferData.index);
+ this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, indexArray, this.gl.DYNAMIC_DRAW);
+ this.gl.blendFuncSeparate(SRC_COLOR, DST_COLOR, SRC_ALPHA, DST_ALPHA);
+ }
+ releaseShaderProgram() {
+ for (let i = 0; i < this._shaderSets.length; i++) {
+ this.gl.deleteProgram(this._shaderSets[i].shaderProgram);
+ this._shaderSets[i].shaderProgram = 0;
+ }
+ this._shaderSets = [];
+ }
+ generateShaders() {
+ for (let i = 0; i < ShaderCount; i++) {
+ this._shaderSets.push({});
+ }
+ this._shaderSets[0].shaderProgram = this.loadShaderProgram(vertexShaderSrcSetupMask, fragmentShaderSrcsetupMask);
+ this._shaderSets[1].shaderProgram = this.loadShaderProgram(vertexShaderSrc, fragmentShaderSrcPremultipliedAlpha);
+ this._shaderSets[2].shaderProgram = this.loadShaderProgram(vertexShaderSrcMasked, fragmentShaderSrcMaskPremultipliedAlpha);
+ this._shaderSets[3].shaderProgram = this.loadShaderProgram(vertexShaderSrcMasked, fragmentShaderSrcMaskInvertedPremultipliedAlpha);
+ this._shaderSets[4].shaderProgram = this._shaderSets[1].shaderProgram;
+ this._shaderSets[5].shaderProgram = this._shaderSets[2].shaderProgram;
+ this._shaderSets[6].shaderProgram = this._shaderSets[3].shaderProgram;
+ this._shaderSets[7].shaderProgram = this._shaderSets[1].shaderProgram;
+ this._shaderSets[8].shaderProgram = this._shaderSets[2].shaderProgram;
+ this._shaderSets[9].shaderProgram = this._shaderSets[3].shaderProgram;
+ this._shaderSets[0].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[0].shaderProgram, "a_position");
+ this._shaderSets[0].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[0].shaderProgram, "a_texCoord");
+ this._shaderSets[0].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "s_texture0");
+ this._shaderSets[0].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_clipMatrix");
+ this._shaderSets[0].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_channelFlag");
+ this._shaderSets[0].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_baseColor");
+ this._shaderSets[0].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_multiplyColor");
+ this._shaderSets[0].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_screenColor");
+ this._shaderSets[1].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[1].shaderProgram, "a_position");
+ this._shaderSets[1].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[1].shaderProgram, "a_texCoord");
+ this._shaderSets[1].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "s_texture0");
+ this._shaderSets[1].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_matrix");
+ this._shaderSets[1].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_baseColor");
+ this._shaderSets[1].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_multiplyColor");
+ this._shaderSets[1].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_screenColor");
+ this._shaderSets[2].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[2].shaderProgram, "a_position");
+ this._shaderSets[2].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[2].shaderProgram, "a_texCoord");
+ this._shaderSets[2].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "s_texture0");
+ this._shaderSets[2].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "s_texture1");
+ this._shaderSets[2].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_matrix");
+ this._shaderSets[2].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_clipMatrix");
+ this._shaderSets[2].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_channelFlag");
+ this._shaderSets[2].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_baseColor");
+ this._shaderSets[2].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_multiplyColor");
+ this._shaderSets[2].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_screenColor");
+ this._shaderSets[3].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[3].shaderProgram, "a_position");
+ this._shaderSets[3].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[3].shaderProgram, "a_texCoord");
+ this._shaderSets[3].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "s_texture0");
+ this._shaderSets[3].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "s_texture1");
+ this._shaderSets[3].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_matrix");
+ this._shaderSets[3].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_clipMatrix");
+ this._shaderSets[3].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_channelFlag");
+ this._shaderSets[3].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_baseColor");
+ this._shaderSets[3].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_multiplyColor");
+ this._shaderSets[3].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_screenColor");
+ this._shaderSets[4].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[4].shaderProgram, "a_position");
+ this._shaderSets[4].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[4].shaderProgram, "a_texCoord");
+ this._shaderSets[4].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "s_texture0");
+ this._shaderSets[4].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_matrix");
+ this._shaderSets[4].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_baseColor");
+ this._shaderSets[4].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_multiplyColor");
+ this._shaderSets[4].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_screenColor");
+ this._shaderSets[5].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[5].shaderProgram, "a_position");
+ this._shaderSets[5].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[5].shaderProgram, "a_texCoord");
+ this._shaderSets[5].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "s_texture0");
+ this._shaderSets[5].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "s_texture1");
+ this._shaderSets[5].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_matrix");
+ this._shaderSets[5].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_clipMatrix");
+ this._shaderSets[5].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_channelFlag");
+ this._shaderSets[5].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_baseColor");
+ this._shaderSets[5].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_multiplyColor");
+ this._shaderSets[5].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_screenColor");
+ this._shaderSets[6].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[6].shaderProgram, "a_position");
+ this._shaderSets[6].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[6].shaderProgram, "a_texCoord");
+ this._shaderSets[6].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "s_texture0");
+ this._shaderSets[6].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "s_texture1");
+ this._shaderSets[6].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_matrix");
+ this._shaderSets[6].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_clipMatrix");
+ this._shaderSets[6].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_channelFlag");
+ this._shaderSets[6].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_baseColor");
+ this._shaderSets[6].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_multiplyColor");
+ this._shaderSets[6].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_screenColor");
+ this._shaderSets[7].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[7].shaderProgram, "a_position");
+ this._shaderSets[7].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[7].shaderProgram, "a_texCoord");
+ this._shaderSets[7].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "s_texture0");
+ this._shaderSets[7].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_matrix");
+ this._shaderSets[7].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_baseColor");
+ this._shaderSets[7].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_multiplyColor");
+ this._shaderSets[7].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_screenColor");
+ this._shaderSets[8].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[8].shaderProgram, "a_position");
+ this._shaderSets[8].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[8].shaderProgram, "a_texCoord");
+ this._shaderSets[8].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "s_texture0");
+ this._shaderSets[8].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "s_texture1");
+ this._shaderSets[8].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_matrix");
+ this._shaderSets[8].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_clipMatrix");
+ this._shaderSets[8].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_channelFlag");
+ this._shaderSets[8].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_baseColor");
+ this._shaderSets[8].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_multiplyColor");
+ this._shaderSets[8].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_screenColor");
+ this._shaderSets[9].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[9].shaderProgram, "a_position");
+ this._shaderSets[9].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[9].shaderProgram, "a_texCoord");
+ this._shaderSets[9].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "s_texture0");
+ this._shaderSets[9].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "s_texture1");
+ this._shaderSets[9].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_matrix");
+ this._shaderSets[9].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_clipMatrix");
+ this._shaderSets[9].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_channelFlag");
+ this._shaderSets[9].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_baseColor");
+ this._shaderSets[9].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_multiplyColor");
+ this._shaderSets[9].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_screenColor");
+ }
+ loadShaderProgram(vertexShaderSource, fragmentShaderSource) {
+ const shaderProgram = this.gl.createProgram();
+ const vertShader = this.compileShaderSource(this.gl.VERTEX_SHADER, vertexShaderSource);
+ if (!vertShader) {
+ CubismLogError("Vertex shader compile error!");
+ return 0;
+ }
+ const fragShader = this.compileShaderSource(this.gl.FRAGMENT_SHADER, fragmentShaderSource);
+ if (!fragShader) {
+ CubismLogError("Vertex shader compile error!");
+ return 0;
+ }
+ this.gl.attachShader(shaderProgram, vertShader);
+ this.gl.attachShader(shaderProgram, fragShader);
+ this.gl.linkProgram(shaderProgram);
+ const linkStatus = this.gl.getProgramParameter(shaderProgram, this.gl.LINK_STATUS);
+ if (!linkStatus) {
+ CubismLogError("Failed to link program: {0}", shaderProgram);
+ this.gl.deleteShader(vertShader);
+ this.gl.deleteShader(fragShader);
+ if (shaderProgram) {
+ this.gl.deleteProgram(shaderProgram);
+ }
+ return 0;
+ }
+ this.gl.deleteShader(vertShader);
+ this.gl.deleteShader(fragShader);
+ return shaderProgram;
+ }
+ compileShaderSource(shaderType, shaderSource) {
+ const source = shaderSource;
+ const shader = this.gl.createShader(shaderType);
+ this.gl.shaderSource(shader, source);
+ this.gl.compileShader(shader);
+ if (!shader) {
+ const log = this.gl.getShaderInfoLog(shader);
+ CubismLogError("Shader compile log: {0} ", log);
+ }
+ const status = this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS);
+ if (!status) {
+ this.gl.deleteShader(shader);
+ return null;
+ }
+ return shader;
+ }
+ setGl(gl) {
+ this.gl = gl;
+ }
+}
+var ShaderNames = /* @__PURE__ */ ((ShaderNames2) => {
+ ShaderNames2[ShaderNames2["ShaderNames_SetupMask"] = 0] = "ShaderNames_SetupMask";
+ ShaderNames2[ShaderNames2["ShaderNames_NormalPremultipliedAlpha"] = 1] = "ShaderNames_NormalPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_NormalMaskedPremultipliedAlpha"] = 2] = "ShaderNames_NormalMaskedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_NomralMaskedInvertedPremultipliedAlpha"] = 3] = "ShaderNames_NomralMaskedInvertedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_AddPremultipliedAlpha"] = 4] = "ShaderNames_AddPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_AddMaskedPremultipliedAlpha"] = 5] = "ShaderNames_AddMaskedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_AddMaskedPremultipliedAlphaInverted"] = 6] = "ShaderNames_AddMaskedPremultipliedAlphaInverted";
+ ShaderNames2[ShaderNames2["ShaderNames_MultPremultipliedAlpha"] = 7] = "ShaderNames_MultPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_MultMaskedPremultipliedAlpha"] = 8] = "ShaderNames_MultMaskedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_MultMaskedPremultipliedAlphaInverted"] = 9] = "ShaderNames_MultMaskedPremultipliedAlphaInverted";
+ return ShaderNames2;
+})(ShaderNames || {});
+const vertexShaderSrcSetupMask = "attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_myPos;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_clipMatrix * a_position; v_myPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}";
+const fragmentShaderSrcsetupMask = "precision mediump float;varying vec2 v_texCoord;varying vec4 v_myPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;void main(){ float isInside = step(u_baseColor.x, v_myPos.x/v_myPos.w) * step(u_baseColor.y, v_myPos.y/v_myPos.w) * step(v_myPos.x/v_myPos.w, u_baseColor.z) * step(v_myPos.y/v_myPos.w, u_baseColor.w); gl_FragColor = u_channelFlag * texture2D(s_texture0, v_texCoord).a * isInside;}";
+const vertexShaderSrc = "attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;uniform mat4 u_matrix;void main(){ gl_Position = u_matrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}";
+const vertexShaderSrcMasked = "attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform mat4 u_matrix;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_matrix * a_position; v_clipPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}";
+const fragmentShaderSrcPremultipliedAlpha = "precision mediump float;varying vec2 v_texCoord;uniform vec4 u_baseColor;uniform sampler2D s_texture0;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 color = texColor * u_baseColor; gl_FragColor = vec4(color.rgb, color.a);}";
+const fragmentShaderSrcMaskPremultipliedAlpha = "precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * maskVal; gl_FragColor = col_formask;}";
+const fragmentShaderSrcMaskInvertedPremultipliedAlpha = "precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_channelFlag;uniform vec4 u_baseColor;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * (1.0 - maskVal); gl_FragColor = col_formask;}";
+class CubismRenderer_WebGL extends CubismRenderer {
+ constructor() {
+ super();
+ this._clippingContextBufferForMask = null;
+ this._clippingContextBufferForDraw = null;
+ this._rendererProfile = new CubismRendererProfile_WebGL();
+ this.firstDraw = true;
+ this._textures = {};
+ this._sortedDrawableIndexList = [];
+ this._bufferData = {
+ vertex: null,
+ uv: null,
+ index: null
+ };
+ }
+ initialize(model, maskBufferCount = 1) {
+ if (model.isUsingMasking()) {
+ this._clippingManager = new CubismClippingManager_WebGL();
+ this._clippingManager.initialize(model, model.getDrawableCount(), model.getDrawableMasks(), model.getDrawableMaskCounts(), maskBufferCount);
+ }
+ for (let i = model.getDrawableCount() - 1; i >= 0; i--) {
+ this._sortedDrawableIndexList[i] = 0;
+ }
+ super.initialize(model);
+ }
+ bindTexture(modelTextureNo, glTexture) {
+ this._textures[modelTextureNo] = glTexture;
+ }
+ getBindedTextures() {
+ return this._textures;
+ }
+ setClippingMaskBufferSize(size) {
+ if (!this._model.isUsingMasking()) {
+ return;
+ }
+ const renderTextureCount = this._clippingManager.getRenderTextureCount();
+ this._clippingManager.release();
+ this._clippingManager = new CubismClippingManager_WebGL();
+ this._clippingManager.setClippingMaskBufferSize(size);
+ this._clippingManager.initialize(this.getModel(), this.getModel().getDrawableCount(), this.getModel().getDrawableMasks(), this.getModel().getDrawableMaskCounts(), renderTextureCount);
+ }
+ getClippingMaskBufferSize() {
+ return this._model.isUsingMasking() ? this._clippingManager.getClippingMaskBufferSize() : -1;
+ }
+ getRenderTextureCount() {
+ return this._model.isUsingMasking() ? this._clippingManager.getRenderTextureCount() : -1;
+ }
+ release() {
+ var _a, _b, _c;
+ const self = this;
+ this._clippingManager.release();
+ self._clippingManager = void 0;
+ (_a = this.gl) == null ? void 0 : _a.deleteBuffer(this._bufferData.vertex);
+ this._bufferData.vertex = null;
+ (_b = this.gl) == null ? void 0 : _b.deleteBuffer(this._bufferData.uv);
+ this._bufferData.uv = null;
+ (_c = this.gl) == null ? void 0 : _c.deleteBuffer(this._bufferData.index);
+ this._bufferData.index = null;
+ self._bufferData = void 0;
+ self._textures = void 0;
+ }
+ doDrawModel() {
+ if (this.gl == null) {
+ CubismLogError("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");
+ return;
+ }
+ if (this._clippingManager != null) {
+ this.preDraw();
+ this._clippingManager.setupClippingContext(this.getModel(), this);
+ }
+ this.preDraw();
+ const drawableCount = this.getModel().getDrawableCount();
+ const renderOrder = this.getModel().getDrawableRenderOrders();
+ for (let i = 0; i < drawableCount; ++i) {
+ const order = renderOrder[i];
+ this._sortedDrawableIndexList[order] = i;
+ }
+ for (let i = 0; i < drawableCount; ++i) {
+ const drawableIndex = this._sortedDrawableIndexList[i];
+ if (!this.getModel().getDrawableDynamicFlagIsVisible(drawableIndex)) {
+ continue;
+ }
+ const clipContext = this._clippingManager != null ? this._clippingManager.getClippingContextListForDraw()[drawableIndex] : null;
+ if (clipContext != null && this.isUsingHighPrecisionMask()) {
+ if (clipContext._isUsing) {
+ this.gl.viewport(0, 0, this._clippingManager.getClippingMaskBufferSize(), this._clippingManager.getClippingMaskBufferSize());
+ this.preDraw();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, clipContext.getClippingManager().getMaskRenderTexture()[clipContext._bufferIndex]);
+ this.gl.clearColor(1, 1, 1, 1);
+ this.gl.clear(this.gl.COLOR_BUFFER_BIT);
+ }
+ {
+ const clipDrawCount = clipContext._clippingIdCount;
+ for (let index = 0; index < clipDrawCount; index++) {
+ const clipDrawIndex = clipContext._clippingIdList[index];
+ if (!this._model.getDrawableDynamicFlagVertexPositionsDidChange(clipDrawIndex)) {
+ continue;
+ }
+ this.setIsCulling(this._model.getDrawableCulling(clipDrawIndex) != false);
+ this.setClippingContextBufferForMask(clipContext);
+ this.drawMesh(this.getModel().getDrawableTextureIndex(clipDrawIndex), this.getModel().getDrawableVertexIndexCount(clipDrawIndex), this.getModel().getDrawableVertexCount(clipDrawIndex), this.getModel().getDrawableVertexIndices(clipDrawIndex), this.getModel().getDrawableVertices(clipDrawIndex), this.getModel().getDrawableVertexUvs(clipDrawIndex), this.getModel().getMultiplyColor(clipDrawIndex), this.getModel().getScreenColor(clipDrawIndex), this.getModel().getDrawableOpacity(clipDrawIndex), CubismBlendMode.CubismBlendMode_Normal, false);
+ }
+ }
+ {
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, s_fbo);
+ this.setClippingContextBufferForMask(null);
+ this.gl.viewport(s_viewport[0], s_viewport[1], s_viewport[2], s_viewport[3]);
+ this.preDraw();
+ }
+ }
+ this.setClippingContextBufferForDraw(clipContext);
+ this.setIsCulling(this.getModel().getDrawableCulling(drawableIndex));
+ this.drawMesh(this.getModel().getDrawableTextureIndex(drawableIndex), this.getModel().getDrawableVertexIndexCount(drawableIndex), this.getModel().getDrawableVertexCount(drawableIndex), this.getModel().getDrawableVertexIndices(drawableIndex), this.getModel().getDrawableVertices(drawableIndex), this.getModel().getDrawableVertexUvs(drawableIndex), this.getModel().getMultiplyColor(drawableIndex), this.getModel().getScreenColor(drawableIndex), this.getModel().getDrawableOpacity(drawableIndex), this.getModel().getDrawableBlendMode(drawableIndex), this.getModel().getDrawableInvertedMaskBit(drawableIndex));
+ }
+ }
+ drawMesh(textureNo, indexCount, vertexCount, indexArray, vertexArray, uvArray, multiplyColor, screenColor, opacity, colorBlendMode, invertedMask) {
+ if (this.isCulling()) {
+ this.gl.enable(this.gl.CULL_FACE);
+ } else {
+ this.gl.disable(this.gl.CULL_FACE);
+ }
+ this.gl.frontFace(this.gl.CCW);
+ const modelColorRGBA = this.getModelColor();
+ if (this.getClippingContextBufferForMask() == null) {
+ modelColorRGBA.A *= opacity;
+ if (this.isPremultipliedAlpha()) {
+ modelColorRGBA.R *= modelColorRGBA.A;
+ modelColorRGBA.G *= modelColorRGBA.A;
+ modelColorRGBA.B *= modelColorRGBA.A;
+ }
+ }
+ let drawtexture = null;
+ if (this._textures[textureNo] != null) {
+ drawtexture = this._textures[textureNo];
+ }
+ CubismShader_WebGL.getInstance().setupShaderProgram(this, drawtexture, vertexCount, vertexArray, indexArray, uvArray, this._bufferData, opacity, colorBlendMode, modelColorRGBA, multiplyColor, screenColor, this.isPremultipliedAlpha(), this.getMvpMatrix(), invertedMask);
+ this.gl.drawElements(this.gl.TRIANGLES, indexCount, this.gl.UNSIGNED_SHORT, 0);
+ this.gl.useProgram(null);
+ this.setClippingContextBufferForDraw(null);
+ this.setClippingContextBufferForMask(null);
+ }
+ saveProfile() {
+ this._rendererProfile.save();
+ }
+ restoreProfile() {
+ this._rendererProfile.restore();
+ }
+ static doStaticRelease() {
+ CubismShader_WebGL.deleteInstance();
+ }
+ setRenderState(fbo, viewport) {
+ s_fbo = fbo;
+ s_viewport = viewport;
+ }
+ preDraw() {
+ if (this.firstDraw) {
+ this.firstDraw = false;
+ }
+ this.gl.disable(this.gl.SCISSOR_TEST);
+ this.gl.disable(this.gl.STENCIL_TEST);
+ this.gl.disable(this.gl.DEPTH_TEST);
+ this.gl.frontFace(this.gl.CW);
+ this.gl.enable(this.gl.BLEND);
+ this.gl.colorMask(true, true, true, true);
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);
+ if (this.getAnisotropy() > 0 && this._extension) {
+ for (const tex of Object.entries(this._textures)) {
+ this.gl.bindTexture(this.gl.TEXTURE_2D, tex);
+ this.gl.texParameterf(this.gl.TEXTURE_2D, this._extension.TEXTURE_MAX_ANISOTROPY_EXT, this.getAnisotropy());
+ }
+ }
+ }
+ setClippingContextBufferForMask(clip) {
+ this._clippingContextBufferForMask = clip;
+ }
+ getClippingContextBufferForMask() {
+ return this._clippingContextBufferForMask;
+ }
+ setClippingContextBufferForDraw(clip) {
+ this._clippingContextBufferForDraw = clip;
+ }
+ getClippingContextBufferForDraw() {
+ return this._clippingContextBufferForDraw;
+ }
+ startUp(gl) {
+ this.gl = gl;
+ if (this._clippingManager) {
+ this._clippingManager.setGL(gl);
+ }
+ CubismShader_WebGL.getInstance().setGl(gl);
+ this._rendererProfile.setGl(gl);
+ this._extension = this.gl.getExtension("EXT_texture_filter_anisotropic") || this.gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic") || this.gl.getExtension("MOZ_EXT_texture_filter_anisotropic");
+ }
+}
+CubismRenderer.staticRelease = () => {
+ CubismRenderer_WebGL.doStaticRelease();
+};
+class CubismModelSettingsJson {
+ constructor(json) {
+ this.groups = json.Groups;
+ this.hitAreas = json.HitAreas;
+ this.layout = json.Layout;
+ this.moc = json.FileReferences.Moc;
+ this.expressions = json.FileReferences.Expressions;
+ this.motions = json.FileReferences.Motions;
+ this.textures = json.FileReferences.Textures;
+ this.physics = json.FileReferences.Physics;
+ this.pose = json.FileReferences.Pose;
+ }
+ getEyeBlinkParameters() {
+ var _a, _b;
+ return (_b = (_a = this.groups) == null ? void 0 : _a.find((group) => group.Name === "EyeBlink")) == null ? void 0 : _b.Ids;
+ }
+ getLipSyncParameters() {
+ var _a, _b;
+ return (_b = (_a = this.groups) == null ? void 0 : _a.find((group) => group.Name === "LipSync")) == null ? void 0 : _b.Ids;
+ }
+}
+const HitAreaPrefix = "HitArea";
+const HitAreaHead = "Head";
+const HitAreaBody = "Body";
+const PartsIdCore = "Parts01Core";
+const PartsArmPrefix = "Parts01Arm_";
+const PartsArmLPrefix = "Parts01ArmL_";
+const PartsArmRPrefix = "Parts01ArmR_";
+const ParamAngleX = "ParamAngleX";
+const ParamAngleY = "ParamAngleY";
+const ParamAngleZ = "ParamAngleZ";
+const ParamEyeLOpen = "ParamEyeLOpen";
+const ParamEyeLSmile = "ParamEyeLSmile";
+const ParamEyeROpen = "ParamEyeROpen";
+const ParamEyeRSmile = "ParamEyeRSmile";
+const ParamEyeBallX = "ParamEyeBallX";
+const ParamEyeBallY = "ParamEyeBallY";
+const ParamEyeBallForm = "ParamEyeBallForm";
+const ParamBrowLY = "ParamBrowLY";
+const ParamBrowRY = "ParamBrowRY";
+const ParamBrowLX = "ParamBrowLX";
+const ParamBrowRX = "ParamBrowRX";
+const ParamBrowLAngle = "ParamBrowLAngle";
+const ParamBrowRAngle = "ParamBrowRAngle";
+const ParamBrowLForm = "ParamBrowLForm";
+const ParamBrowRForm = "ParamBrowRForm";
+const ParamMouthForm = "ParamMouthForm";
+const ParamMouthOpenY = "ParamMouthOpenY";
+const ParamCheek = "ParamCheek";
+const ParamBodyAngleX = "ParamBodyAngleX";
+const ParamBodyAngleY = "ParamBodyAngleY";
+const ParamBodyAngleZ = "ParamBodyAngleZ";
+const ParamBreath = "ParamBreath";
+const ParamArmLA = "ParamArmLA";
+const ParamArmRA = "ParamArmRA";
+const ParamArmLB = "ParamArmLB";
+const ParamArmRB = "ParamArmRB";
+const ParamHandL = "ParamHandL";
+const ParamHandR = "ParamHandR";
+const ParamHairFront = "ParamHairFront";
+const ParamHairSide = "ParamHairSide";
+const ParamHairBack = "ParamHairBack";
+const ParamHairFluffy = "ParamHairFluffy";
+const ParamShoulderY = "ParamShoulderY";
+const ParamBustX = "ParamBustX";
+const ParamBustY = "ParamBustY";
+const ParamBaseX = "ParamBaseX";
+const ParamBaseY = "ParamBaseY";
+const ParamNONE = "NONE:";
+const LOGICAL_WIDTH = 2;
+const LOGICAL_HEIGHT = 2;
+var config;
+((config2) => {
+ config2.LOG_LEVEL_VERBOSE = 0;
+ config2.LOG_LEVEL_WARNING = 1;
+ config2.LOG_LEVEL_ERROR = 2;
+ config2.LOG_LEVEL_NONE = 999;
+ config2.logLevel = config2.LOG_LEVEL_WARNING;
+ config2.sound = true;
+ config2.motionSync = true;
+ config2.motionFadingDuration = 500;
+ config2.idleMotionFadingDuration = 2e3;
+ config2.expressionFadingDuration = 500;
+ config2.preserveExpressionOnMotion = true;
+ config2.cubism4 = CubismConfig;
+})(config || (config = {}));
+const VERSION = "0.4.0";
+const logger = {
+ log(tag, ...messages) {
+ if (config.logLevel <= config.LOG_LEVEL_VERBOSE) {
+ console.log(`[${tag}]`, ...messages);
+ }
+ },
+ warn(tag, ...messages) {
+ if (config.logLevel <= config.LOG_LEVEL_WARNING) {
+ console.warn(`[${tag}]`, ...messages);
+ }
+ },
+ error(tag, ...messages) {
+ if (config.logLevel <= config.LOG_LEVEL_ERROR) {
+ console.error(`[${tag}]`, ...messages);
+ }
+ }
+};
+function clamp(num, lower, upper) {
+ return num < lower ? lower : num > upper ? upper : num;
+}
+function rand(min, max) {
+ return Math.random() * (max - min) + min;
+}
+function copyProperty(type, from, to, fromKey, toKey) {
+ const value = from[fromKey];
+ if (value !== null && typeof value === type) {
+ to[toKey] = value;
+ }
+}
+function copyArray(type, from, to, fromKey, toKey) {
+ const array = from[fromKey];
+ if (Array.isArray(array)) {
+ to[toKey] = array.filter((item) => item !== null && typeof item === type);
+ }
+}
+function applyMixins(derivedCtor, baseCtors) {
+ baseCtors.forEach((baseCtor) => {
+ Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
+ if (name !== "constructor") {
+ Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
+ }
+ });
+ });
+}
+function folderName(url2) {
+ let lastSlashIndex = url2.lastIndexOf("/");
+ if (lastSlashIndex != -1) {
+ url2 = url2.slice(0, lastSlashIndex);
+ }
+ lastSlashIndex = url2.lastIndexOf("/");
+ if (lastSlashIndex !== -1) {
+ url2 = url2.slice(lastSlashIndex + 1);
+ }
+ return url2;
+}
+function remove(array, item) {
+ const index = array.indexOf(item);
+ if (index !== -1) {
+ array.splice(index, 1);
+ }
+}
+class ExpressionManager extends EventEmitter {
+ constructor(settings, options) {
+ super();
+ this.expressions = [];
+ this.reserveExpressionIndex = -1;
+ this.destroyed = false;
+ this.settings = settings;
+ this.tag = `ExpressionManager(${settings.name})`;
+ }
+ init() {
+ this.defaultExpression = this.createExpression({}, void 0);
+ this.currentExpression = this.defaultExpression;
+ this.stopAllExpressions();
+ }
+ loadExpression(index) {
+ return __async(this, null, function* () {
+ if (!this.definitions[index]) {
+ logger.warn(this.tag, `Undefined expression at [${index}]`);
+ return void 0;
+ }
+ if (this.expressions[index] === null) {
+ logger.warn(this.tag, `Cannot set expression at [${index}] because it's already failed in loading.`);
+ return void 0;
+ }
+ if (this.expressions[index]) {
+ return this.expressions[index];
+ }
+ const expression = yield this._loadExpression(index);
+ this.expressions[index] = expression;
+ return expression;
+ });
+ }
+ _loadExpression(index) {
+ throw new Error("Not implemented.");
+ }
+ setRandomExpression() {
+ return __async(this, null, function* () {
+ if (this.definitions.length) {
+ const availableIndices = [];
+ for (let i = 0; i < this.definitions.length; i++) {
+ if (this.expressions[i] !== null && this.expressions[i] !== this.currentExpression && i !== this.reserveExpressionIndex) {
+ availableIndices.push(i);
+ }
+ }
+ if (availableIndices.length) {
+ const index = Math.floor(Math.random() * availableIndices.length);
+ return this.setExpression(index);
+ }
+ }
+ return false;
+ });
+ }
+ resetExpression() {
+ this._setExpression(this.defaultExpression);
+ }
+ restoreExpression() {
+ this._setExpression(this.currentExpression);
+ }
+ setExpression(index) {
+ return __async(this, null, function* () {
+ if (typeof index !== "number") {
+ index = this.getExpressionIndex(index);
+ }
+ if (!(index > -1 && index < this.definitions.length)) {
+ return false;
+ }
+ if (index === this.expressions.indexOf(this.currentExpression)) {
+ return false;
+ }
+ this.reserveExpressionIndex = index;
+ const expression = yield this.loadExpression(index);
+ if (!expression || this.reserveExpressionIndex !== index) {
+ return false;
+ }
+ this.reserveExpressionIndex = -1;
+ this.currentExpression = expression;
+ this._setExpression(expression);
+ return true;
+ });
+ }
+ update(model, now) {
+ if (!this.isFinished()) {
+ return this.updateParameters(model, now);
+ }
+ return false;
+ }
+ destroy() {
+ this.destroyed = true;
+ this.emit("destroy");
+ const self = this;
+ self.definitions = void 0;
+ self.expressions = void 0;
+ }
+}
+const EPSILON = 0.01;
+const MAX_SPEED = 40 / 7.5;
+const ACCELERATION_TIME = 1 / (0.15 * 1e3);
+class FocusController {
+ constructor() {
+ this.targetX = 0;
+ this.targetY = 0;
+ this.x = 0;
+ this.y = 0;
+ this.vx = 0;
+ this.vy = 0;
+ }
+ focus(x, y, instant = false) {
+ this.targetX = clamp(x, -1, 1);
+ this.targetY = clamp(y, -1, 1);
+ if (instant) {
+ this.x = this.targetX;
+ this.y = this.targetY;
+ }
+ }
+ update(dt) {
+ const dx = this.targetX - this.x;
+ const dy = this.targetY - this.y;
+ if (Math.abs(dx) < EPSILON && Math.abs(dy) < EPSILON)
+ return;
+ const d = Math.sqrt(__pow(dx, 2) + __pow(dy, 2));
+ const maxSpeed = MAX_SPEED / (1e3 / dt);
+ let ax = maxSpeed * (dx / d) - this.vx;
+ let ay = maxSpeed * (dy / d) - this.vy;
+ const a = Math.sqrt(__pow(ax, 2) + __pow(ay, 2));
+ const maxA = maxSpeed * ACCELERATION_TIME * dt;
+ if (a > maxA) {
+ ax *= maxA / a;
+ ay *= maxA / a;
+ }
+ this.vx += ax;
+ this.vy += ay;
+ const v = Math.sqrt(__pow(this.vx, 2) + __pow(this.vy, 2));
+ const maxV = 0.5 * (Math.sqrt(__pow(maxA, 2) + 8 * maxA * d) - maxA);
+ if (v > maxV) {
+ this.vx *= maxV / v;
+ this.vy *= maxV / v;
+ }
+ this.x += this.vx;
+ this.y += this.vy;
+ }
+}
+class ModelSettings {
+ constructor(json) {
+ this.json = json;
+ let url2 = json.url;
+ if (typeof url2 !== "string") {
+ throw new TypeError("The `url` field in settings JSON must be defined as a string.");
+ }
+ this.url = url2;
+ this.name = folderName(this.url);
+ }
+ resolveURL(path) {
+ return url.resolve(this.url, path);
+ }
+ replaceFiles(replacer) {
+ this.moc = replacer(this.moc, "moc");
+ if (this.pose !== void 0) {
+ this.pose = replacer(this.pose, "pose");
+ }
+ if (this.physics !== void 0) {
+ this.physics = replacer(this.physics, "physics");
+ }
+ for (let i = 0; i < this.textures.length; i++) {
+ this.textures[i] = replacer(this.textures[i], `textures[${i}]`);
+ }
+ }
+ getDefinedFiles() {
+ const files = [];
+ this.replaceFiles((file) => {
+ files.push(file);
+ return file;
+ });
+ return files;
+ }
+ validateFiles(files) {
+ const assertFileExists = (expectedFile, shouldThrow) => {
+ const actualPath = this.resolveURL(expectedFile);
+ if (!files.includes(actualPath)) {
+ if (shouldThrow) {
+ throw new Error(`File "${expectedFile}" is defined in settings, but doesn't exist in given files`);
+ }
+ return false;
+ }
+ return true;
+ };
+ const essentialFiles = [this.moc, ...this.textures];
+ essentialFiles.forEach((texture) => assertFileExists(texture, true));
+ const definedFiles = this.getDefinedFiles();
+ return definedFiles.filter((file) => assertFileExists(file, false));
+ }
+}
+var MotionPriority = /* @__PURE__ */ ((MotionPriority2) => {
+ MotionPriority2[MotionPriority2["NONE"] = 0] = "NONE";
+ MotionPriority2[MotionPriority2["IDLE"] = 1] = "IDLE";
+ MotionPriority2[MotionPriority2["NORMAL"] = 2] = "NORMAL";
+ MotionPriority2[MotionPriority2["FORCE"] = 3] = "FORCE";
+ return MotionPriority2;
+})(MotionPriority || {});
+class MotionState {
+ constructor() {
+ this.debug = false;
+ this.currentPriority = 0;
+ this.reservePriority = 0;
+ }
+ reserve(group, index, priority) {
+ if (priority <= 0) {
+ logger.log(this.tag, `Cannot start a motion with MotionPriority.NONE.`);
+ return false;
+ }
+ if (group === this.currentGroup && index === this.currentIndex) {
+ logger.log(this.tag, `Motion is already playing.`, this.dump(group, index));
+ return false;
+ }
+ if (group === this.reservedGroup && index === this.reservedIndex || group === this.reservedIdleGroup && index === this.reservedIdleIndex) {
+ logger.log(this.tag, `Motion is already reserved.`, this.dump(group, index));
+ return false;
+ }
+ if (priority === 1) {
+ if (this.currentPriority !== 0) {
+ logger.log(this.tag, `Cannot start idle motion because another motion is playing.`, this.dump(group, index));
+ return false;
+ }
+ if (this.reservedIdleGroup !== void 0) {
+ logger.log(this.tag, `Cannot start idle motion because another idle motion has reserved.`, this.dump(group, index));
+ return false;
+ }
+ this.setReservedIdle(group, index);
+ } else {
+ if (priority < 3) {
+ if (priority <= this.currentPriority) {
+ logger.log(this.tag, "Cannot start motion because another motion is playing as an equivalent or higher priority.", this.dump(group, index));
+ return false;
+ }
+ if (priority <= this.reservePriority) {
+ logger.log(this.tag, "Cannot start motion because another motion has reserved as an equivalent or higher priority.", this.dump(group, index));
+ return false;
+ }
+ }
+ this.setReserved(group, index, priority);
+ }
+ return true;
+ }
+ start(motion, group, index, priority) {
+ if (priority === 1) {
+ this.setReservedIdle(void 0, void 0);
+ if (this.currentPriority !== 0) {
+ logger.log(this.tag, "Cannot start idle motion because another motion is playing.", this.dump(group, index));
+ return false;
+ }
+ } else {
+ if (group !== this.reservedGroup || index !== this.reservedIndex) {
+ logger.log(this.tag, "Cannot start motion because another motion has taken the place.", this.dump(group, index));
+ return false;
+ }
+ this.setReserved(void 0, void 0, 0);
+ }
+ if (!motion) {
+ return false;
+ }
+ this.setCurrent(group, index, priority);
+ return true;
+ }
+ complete() {
+ this.setCurrent(void 0, void 0, 0);
+ }
+ setCurrent(group, index, priority) {
+ this.currentPriority = priority;
+ this.currentGroup = group;
+ this.currentIndex = index;
+ }
+ setReserved(group, index, priority) {
+ this.reservePriority = priority;
+ this.reservedGroup = group;
+ this.reservedIndex = index;
+ }
+ setReservedIdle(group, index) {
+ this.reservedIdleGroup = group;
+ this.reservedIdleIndex = index;
+ }
+ isActive(group, index) {
+ return group === this.currentGroup && index === this.currentIndex || group === this.reservedGroup && index === this.reservedIndex || group === this.reservedIdleGroup && index === this.reservedIdleIndex;
+ }
+ reset() {
+ this.setCurrent(void 0, void 0, 0);
+ this.setReserved(void 0, void 0, 0);
+ this.setReservedIdle(void 0, void 0);
+ }
+ shouldRequestIdleMotion() {
+ return this.currentGroup === void 0 && this.reservedIdleGroup === void 0;
+ }
+ shouldOverrideExpression() {
+ return !config.preserveExpressionOnMotion && this.currentPriority > 1;
+ }
+ dump(requestedGroup, requestedIndex) {
+ if (this.debug) {
+ const keys = [
+ "currentPriority",
+ "reservePriority",
+ "currentGroup",
+ "currentIndex",
+ "reservedGroup",
+ "reservedIndex",
+ "reservedIdleGroup",
+ "reservedIdleIndex"
+ ];
+ return `
+ group = "${requestedGroup}", index = ${requestedIndex}
+` + keys.map((key) => "[" + key + "] " + this[key]).join("\n");
+ }
+ return "";
+ }
+}
+const TAG$2 = "SoundManager";
+const VOLUME = 0.9;
+class SoundManager {
+ static get volume() {
+ return this._volume;
+ }
+ static set volume(value) {
+ this._volume = (value > 1 ? 1 : value < 0 ? 0 : value) || 0;
+ this.audios.forEach((audio) => audio.volume = this._volume);
+ }
+ static add(file, onFinish, onError) {
+ const audio = new Audio(file);
+ audio.volume = this._volume;
+ audio.preload = "auto";
+ audio.autoplay = true;
+ audio.crossOrigin = "anonymous";
+ audio.addEventListener("ended", () => {
+ this.dispose(audio);
+ onFinish == null ? void 0 : onFinish();
+ });
+ audio.addEventListener("error", (e) => {
+ this.dispose(audio);
+ logger.warn(TAG$2, `Error occurred on "${file}"`, e.error);
+ onError == null ? void 0 : onError(e.error);
+ });
+ this.audios.push(audio);
+ return audio;
+ }
+ static play(audio) {
+ return new Promise((resolve, reject) => {
+ var _a;
+ (_a = audio.play()) == null ? void 0 : _a.catch((e) => {
+ audio.dispatchEvent(new ErrorEvent("error", { error: e }));
+ reject(e);
+ });
+ if (audio.readyState === audio.HAVE_ENOUGH_DATA) {
+ resolve();
+ } else {
+ audio.addEventListener("canplaythrough", resolve);
+ }
+ });
+ }
+ static addContext(audio) {
+ const context = new AudioContext();
+ this.contexts.push(context);
+ return context;
+ }
+ static addAnalyzer(audio, context) {
+ const source = context.createMediaElementSource(audio);
+ const analyser = context.createAnalyser();
+ analyser.fftSize = 256;
+ analyser.minDecibels = -90;
+ analyser.maxDecibels = -10;
+ analyser.smoothingTimeConstant = 0.85;
+ source.connect(analyser);
+ analyser.connect(context.destination);
+ this.analysers.push(analyser);
+ return analyser;
+ }
+ static analyze(analyser) {
+ if (analyser != void 0) {
+ let pcmData = new Float32Array(analyser.fftSize);
+ let sumSquares = 0;
+ analyser.getFloatTimeDomainData(pcmData);
+ for (const amplitude of pcmData) {
+ sumSquares += amplitude * amplitude;
+ }
+ return parseFloat(Math.sqrt(sumSquares / pcmData.length * 20).toFixed(1));
+ } else {
+ return parseFloat(Math.random().toFixed(1));
+ }
+ }
+ static dispose(audio) {
+ audio.pause();
+ audio.removeAttribute("src");
+ remove(this.audios, audio);
+ }
+ static destroy() {
+ for (let i = this.contexts.length - 1; i >= 0; i--) {
+ this.contexts[i].close();
+ }
+ for (let i = this.audios.length - 1; i >= 0; i--) {
+ this.dispose(this.audios[i]);
+ }
+ }
+}
+SoundManager.audios = [];
+SoundManager.analysers = [];
+SoundManager.contexts = [];
+SoundManager._volume = VOLUME;
+var MotionPreloadStrategy = /* @__PURE__ */ ((MotionPreloadStrategy2) => {
+ MotionPreloadStrategy2["ALL"] = "ALL";
+ MotionPreloadStrategy2["IDLE"] = "IDLE";
+ MotionPreloadStrategy2["NONE"] = "NONE";
+ return MotionPreloadStrategy2;
+})(MotionPreloadStrategy || {});
+class MotionManager extends EventEmitter {
+ constructor(settings, options) {
+ super();
+ this.motionGroups = {};
+ this.state = new MotionState();
+ this.playing = false;
+ this.destroyed = false;
+ this.settings = settings;
+ this.tag = `MotionManager(${settings.name})`;
+ this.state.tag = this.tag;
+ }
+ init(options) {
+ if (options == null ? void 0 : options.idleMotionGroup) {
+ this.groups.idle = options.idleMotionGroup;
+ }
+ this.setupMotions(options);
+ this.stopAllMotions();
+ }
+ setupMotions(options) {
+ for (const group of Object.keys(this.definitions)) {
+ this.motionGroups[group] = [];
+ }
+ let groups;
+ switch (options == null ? void 0 : options.motionPreload) {
+ case "NONE":
+ return;
+ case "ALL":
+ groups = Object.keys(this.definitions);
+ break;
+ case "IDLE":
+ default:
+ groups = [this.groups.idle];
+ break;
+ }
+ for (const group of groups) {
+ if (this.definitions[group]) {
+ for (let i = 0; i < this.definitions[group].length; i++) {
+ this.loadMotion(group, i).then();
+ }
+ }
+ }
+ }
+ loadMotion(group, index) {
+ return __async(this, null, function* () {
+ var _a;
+ if (!((_a = this.definitions[group]) == null ? void 0 : _a[index])) {
+ logger.warn(this.tag, `Undefined motion at "${group}"[${index}]`);
+ return void 0;
+ }
+ if (this.motionGroups[group][index] === null) {
+ logger.warn(this.tag, `Cannot start motion at "${group}"[${index}] because it's already failed in loading.`);
+ return void 0;
+ }
+ if (this.motionGroups[group][index]) {
+ return this.motionGroups[group][index];
+ }
+ const motion = yield this._loadMotion(group, index);
+ if (this.destroyed) {
+ return;
+ }
+ this.motionGroups[group][index] = motion != null ? motion : null;
+ return motion;
+ });
+ }
+ _loadMotion(group, index) {
+ throw new Error("Not implemented.");
+ }
+ speakUp(sound, volume, expression) {
+ return __async(this, null, function* () {
+ if (!config.sound) {
+ return false;
+ }
+ let audio;
+ let analyzer;
+ let context;
+ if (this.currentAudio) {
+ if (!this.currentAudio.ended) {
+ return false;
+ }
+ }
+ let soundURL;
+ const isBase64Content = sound && sound.startsWith("data:audio/wav;base64");
+ if (sound && !isBase64Content) {
+ var A = document.createElement("a");
+ A.href = sound;
+ sound = A.href;
+ soundURL = sound;
+ } else {
+ soundURL = "data:audio/wav;base64";
+ }
+ const isUrlPath = sound && (sound.startsWith("http") || sound.startsWith("blob"));
+ let file;
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ audio = SoundManager.add(file, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ }, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ });
+ this.currentAudio = audio;
+ let _volume = 1;
+ if (volume !== void 0) {
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+ } catch (e) {
+ logger.warn(this.tag, "Failed to create audio", soundURL, e);
+ }
+ }
+ if (audio) {
+ const readyToPlay = SoundManager.play(audio).catch((e) => logger.warn(this.tag, "Failed to play audio", audio.src, e));
+ if (config.motionSync) {
+ yield readyToPlay;
+ }
+ }
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ if (expression && this.expressionManager) {
+ this.expressionManager.setExpression(expression);
+ }
+ this.playing = true;
+ return true;
+ });
+ }
+ startMotion(_0, _1) {
+ return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, sound, volume, expression) {
+ var _a;
+ if (this.currentAudio) {
+ if (!this.currentAudio.ended) {
+ return false;
+ }
+ }
+ if (!this.state.reserve(group, index, priority)) {
+ return false;
+ }
+ const definition = (_a = this.definitions[group]) == null ? void 0 : _a[index];
+ if (!definition) {
+ return false;
+ }
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ }
+ let audio;
+ let analyzer;
+ let context;
+ if (config.sound) {
+ const isBase64Content = sound && sound.startsWith("data:audio/wav;base64");
+ if (sound && !isBase64Content) {
+ var A = document.createElement("a");
+ A.href = sound;
+ sound = A.href;
+ }
+ const isUrlPath = sound && (sound.startsWith("http") || sound.startsWith("blob"));
+ const soundURL = this.getSoundFile(definition);
+ let file = soundURL;
+ if (soundURL) {
+ file = this.settings.resolveURL(soundURL) + "?cache-buster=" + new Date().getTime();
+ }
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ audio = SoundManager.add(file, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ }, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ });
+ this.currentAudio = audio;
+ let _volume = 1;
+ if (volume !== void 0) {
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+ } catch (e) {
+ logger.warn(this.tag, "Failed to create audio", soundURL, e);
+ }
+ }
+ }
+ const motion = yield this.loadMotion(group, index);
+ if (audio) {
+ priority = 3;
+ const readyToPlay = SoundManager.play(audio).catch((e) => logger.warn(this.tag, "Failed to play audio", audio.src, e));
+ if (config.motionSync) {
+ yield readyToPlay;
+ }
+ }
+ if (!this.state.start(motion, group, index, priority)) {
+ if (audio) {
+ SoundManager.dispose(audio);
+ this.currentAudio = void 0;
+ }
+ return false;
+ }
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ logger.log(this.tag, "Start motion:", this.getMotionName(definition));
+ this.emit("motionStart", group, index, audio);
+ if (expression && this.expressionManager) {
+ this.expressionManager.setExpression(expression);
+ }
+ this.playing = true;
+ this._startMotion(motion);
+ return true;
+ });
+ }
+ startRandomMotion(group, priority, sound, volume) {
+ return __async(this, null, function* () {
+ const groupDefs = this.definitions[group];
+ if (groupDefs == null ? void 0 : groupDefs.length) {
+ const availableIndices = [];
+ for (let i = 0; i < groupDefs.length; i++) {
+ if (this.motionGroups[group][i] !== null && !this.state.isActive(group, i)) {
+ availableIndices.push(i);
+ }
+ }
+ if (availableIndices.length) {
+ const index = availableIndices[Math.floor(Math.random() * availableIndices.length)];
+ return this.startMotion(group, index, priority, sound, volume);
+ }
+ }
+ return false;
+ });
+ }
+ stopSpeaking() {
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ this.currentAudio = void 0;
+ }
+ }
+ stopAllMotions() {
+ this._stopAllMotions();
+ this.state.reset();
+ this.stopSpeaking();
+ }
+ update(model, now) {
+ var _a;
+ if (this.isFinished()) {
+ if (this.playing) {
+ this.playing = false;
+ this.emit("motionFinish");
+ }
+ if (this.state.shouldOverrideExpression()) {
+ (_a = this.expressionManager) == null ? void 0 : _a.restoreExpression();
+ }
+ this.state.complete();
+ if (this.state.shouldRequestIdleMotion()) {
+ this.startRandomMotion(this.groups.idle, MotionPriority.IDLE);
+ }
+ }
+ return this.updateParameters(model, now);
+ }
+ mouthSync() {
+ if (this.currentAnalyzer) {
+ return SoundManager.analyze(this.currentAnalyzer);
+ } else {
+ return 0;
+ }
+ }
+ destroy() {
+ var _a;
+ this.destroyed = true;
+ this.emit("destroy");
+ this.stopAllMotions();
+ (_a = this.expressionManager) == null ? void 0 : _a.destroy();
+ const self = this;
+ self.definitions = void 0;
+ self.motionGroups = void 0;
+ }
+}
+const tempBounds = { x: 0, y: 0, width: 0, height: 0 };
+class InternalModel extends EventEmitter {
+ constructor() {
+ super(...arguments);
+ this.focusController = new FocusController();
+ this.originalWidth = 0;
+ this.originalHeight = 0;
+ this.width = 0;
+ this.height = 0;
+ this.localTransform = new Matrix();
+ this.drawingMatrix = new Matrix();
+ this.hitAreas = {};
+ this.textureFlipY = false;
+ this.viewport = [0, 0, 0, 0];
+ this.destroyed = false;
+ }
+ init() {
+ this.setupLayout();
+ this.setupHitAreas();
+ }
+ setupLayout() {
+ const self = this;
+ const size = this.getSize();
+ self.originalWidth = size[0];
+ self.originalHeight = size[1];
+ const layout = Object.assign({
+ width: LOGICAL_WIDTH,
+ height: LOGICAL_HEIGHT
+ }, this.getLayout());
+ this.localTransform.scale(layout.width / LOGICAL_WIDTH, layout.height / LOGICAL_HEIGHT);
+ self.width = this.originalWidth * this.localTransform.a;
+ self.height = this.originalHeight * this.localTransform.d;
+ const offsetX = layout.x !== void 0 && layout.x - layout.width / 2 || layout.centerX !== void 0 && layout.centerX || layout.left !== void 0 && layout.left - layout.width / 2 || layout.right !== void 0 && layout.right + layout.width / 2 || 0;
+ const offsetY = layout.y !== void 0 && layout.y - layout.height / 2 || layout.centerY !== void 0 && layout.centerY || layout.top !== void 0 && layout.top - layout.height / 2 || layout.bottom !== void 0 && layout.bottom + layout.height / 2 || 0;
+ this.localTransform.translate(this.width * offsetX, -this.height * offsetY);
+ }
+ setupHitAreas() {
+ const definitions = this.getHitAreaDefs().filter((hitArea) => hitArea.index >= 0);
+ for (const def of definitions) {
+ this.hitAreas[def.name] = def;
+ }
+ }
+ hitTest(x, y) {
+ return Object.keys(this.hitAreas).filter((hitAreaName) => this.isHit(hitAreaName, x, y));
+ }
+ isHit(hitAreaName, x, y) {
+ if (!this.hitAreas[hitAreaName]) {
+ return false;
+ }
+ const drawIndex = this.hitAreas[hitAreaName].index;
+ const bounds = this.getDrawableBounds(drawIndex, tempBounds);
+ return bounds.x <= x && x <= bounds.x + bounds.width && bounds.y <= y && y <= bounds.y + bounds.height;
+ }
+ getDrawableBounds(index, bounds) {
+ const vertices = this.getDrawableVertices(index);
+ let left = vertices[0];
+ let right = vertices[0];
+ let top = vertices[1];
+ let bottom = vertices[1];
+ for (let i = 0; i < vertices.length; i += 2) {
+ const vx = vertices[i];
+ const vy = vertices[i + 1];
+ left = Math.min(vx, left);
+ right = Math.max(vx, right);
+ top = Math.min(vy, top);
+ bottom = Math.max(vy, bottom);
+ }
+ bounds != null ? bounds : bounds = {};
+ bounds.x = left;
+ bounds.y = top;
+ bounds.width = right - left;
+ bounds.height = bottom - top;
+ return bounds;
+ }
+ updateTransform(transform) {
+ this.drawingMatrix.copyFrom(transform).append(this.localTransform);
+ }
+ update(dt, now) {
+ this.focusController.update(dt);
+ }
+ destroy() {
+ this.destroyed = true;
+ this.emit("destroy");
+ this.motionManager.destroy();
+ this.motionManager = void 0;
+ }
+}
+const TAG$1 = "XHRLoader";
+class NetworkError extends Error {
+ constructor(message, url2, status, aborted = false) {
+ super(message);
+ this.url = url2;
+ this.status = status;
+ this.aborted = aborted;
+ }
+}
+const _XHRLoader = class {
+ static createXHR(target, url2, type, onload, onerror) {
+ const xhr = new XMLHttpRequest();
+ _XHRLoader.allXhrSet.add(xhr);
+ if (target) {
+ let xhrSet = _XHRLoader.xhrMap.get(target);
+ if (!xhrSet) {
+ xhrSet = /* @__PURE__ */ new Set([xhr]);
+ _XHRLoader.xhrMap.set(target, xhrSet);
+ } else {
+ xhrSet.add(xhr);
+ }
+ if (!target.listeners("destroy").includes(_XHRLoader.cancelXHRs)) {
+ target.once("destroy", _XHRLoader.cancelXHRs);
+ }
+ }
+ xhr.open("GET", url2);
+ xhr.responseType = type;
+ xhr.onload = () => {
+ if ((xhr.status === 200 || xhr.status === 0) && xhr.response) {
+ onload(xhr.response);
+ } else {
+ xhr.onerror();
+ }
+ };
+ xhr.onerror = () => {
+ logger.warn(TAG$1, `Failed to load resource as ${xhr.responseType} (Status ${xhr.status}): ${url2}`);
+ onerror(new NetworkError("Network error.", url2, xhr.status));
+ };
+ xhr.onabort = () => onerror(new NetworkError("Aborted.", url2, xhr.status, true));
+ xhr.onloadend = () => {
+ var _a;
+ _XHRLoader.allXhrSet.delete(xhr);
+ if (target) {
+ (_a = _XHRLoader.xhrMap.get(target)) == null ? void 0 : _a.delete(xhr);
+ }
+ };
+ return xhr;
+ }
+ static cancelXHRs() {
+ var _a;
+ (_a = _XHRLoader.xhrMap.get(this)) == null ? void 0 : _a.forEach((xhr) => {
+ xhr.abort();
+ _XHRLoader.allXhrSet.delete(xhr);
+ });
+ _XHRLoader.xhrMap.delete(this);
+ }
+ static release() {
+ _XHRLoader.allXhrSet.forEach((xhr) => xhr.abort());
+ _XHRLoader.allXhrSet.clear();
+ _XHRLoader.xhrMap = /* @__PURE__ */ new WeakMap();
+ }
+};
+let XHRLoader = _XHRLoader;
+XHRLoader.xhrMap = /* @__PURE__ */ new WeakMap();
+XHRLoader.allXhrSet = /* @__PURE__ */ new Set();
+XHRLoader.loader = (context, next) => {
+ return new Promise((resolve, reject) => {
+ const xhr = _XHRLoader.createXHR(context.target, context.settings ? context.settings.resolveURL(context.url) : context.url, context.type, (data) => {
+ context.result = data;
+ resolve();
+ }, reject);
+ xhr.send();
+ });
+};
+function runMiddlewares(middleware, context) {
+ let index = -1;
+ return dispatch(0);
+ function dispatch(i, err) {
+ if (err)
+ return Promise.reject(err);
+ if (i <= index)
+ return Promise.reject(new Error("next() called multiple times"));
+ index = i;
+ const fn = middleware[i];
+ if (!fn)
+ return Promise.resolve();
+ try {
+ return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
+ } catch (err2) {
+ return Promise.reject(err2);
+ }
+ }
+}
+class Live2DLoader {
+ static load(context) {
+ return runMiddlewares(this.middlewares, context).then(() => context.result);
+ }
+}
+Live2DLoader.middlewares = [XHRLoader.loader];
+function createTexture(url2, options = {}) {
+ var _a;
+ const textureOptions = { resourceOptions: { crossorigin: options.crossOrigin } };
+ if (Texture.fromURL) {
+ return Texture.fromURL(url2, textureOptions).catch((e) => {
+ if (e instanceof Error) {
+ throw e;
+ }
+ const err = new Error("Texture loading error");
+ err.event = e;
+ throw err;
+ });
+ }
+ textureOptions.resourceOptions.autoLoad = false;
+ const texture = Texture.from(url2, textureOptions);
+ if (texture.baseTexture.valid) {
+ return Promise.resolve(texture);
+ }
+ const resource = texture.baseTexture.resource;
+ (_a = resource._live2d_load) != null ? _a : resource._live2d_load = new Promise((resolve, reject) => {
+ const errorHandler = (event) => {
+ resource.source.removeEventListener("error", errorHandler);
+ const err = new Error("Texture loading error");
+ err.event = event;
+ reject(err);
+ };
+ resource.source.addEventListener("error", errorHandler);
+ resource.load().then(() => resolve(texture)).catch(errorHandler);
+ });
+ return resource._live2d_load;
+}
+const TAG = "Live2DFactory";
+const urlToJSON = (context, next) => __async(void 0, null, function* () {
+ if (typeof context.source === "string") {
+ const data = yield Live2DLoader.load({
+ url: context.source,
+ type: "json",
+ target: context.live2dModel
+ });
+ data.url = context.source;
+ context.source = data;
+ context.live2dModel.emit("settingsJSONLoaded", data);
+ }
+ return next();
+});
+const jsonToSettings = (context, next) => __async(void 0, null, function* () {
+ if (context.source instanceof ModelSettings) {
+ context.settings = context.source;
+ return next();
+ } else if (typeof context.source === "object") {
+ const runtime = Live2DFactory.findRuntime(context.source);
+ if (runtime) {
+ const settings = runtime.createModelSettings(context.source);
+ context.settings = settings;
+ context.live2dModel.emit("settingsLoaded", settings);
+ return next();
+ }
+ }
+ throw new TypeError("Unknown settings format.");
+});
+const waitUntilReady = (context, next) => {
+ if (context.settings) {
+ const runtime = Live2DFactory.findRuntime(context.settings);
+ if (runtime) {
+ return runtime.ready().then(next);
+ }
+ }
+ return next();
+};
+const setupOptionals = (context, next) => __async(void 0, null, function* () {
+ yield next();
+ const internalModel = context.internalModel;
+ if (internalModel) {
+ const settings = context.settings;
+ const runtime = Live2DFactory.findRuntime(settings);
+ if (runtime) {
+ const tasks = [];
+ if (settings.pose) {
+ tasks.push(Live2DLoader.load({
+ settings,
+ url: settings.pose,
+ type: "json",
+ target: internalModel
+ }).then((data) => {
+ internalModel.pose = runtime.createPose(internalModel.coreModel, data);
+ context.live2dModel.emit("poseLoaded", internalModel.pose);
+ }).catch((e) => {
+ context.live2dModel.emit("poseLoadError", e);
+ logger.warn(TAG, "Failed to load pose.", e);
+ }));
+ }
+ if (settings.physics) {
+ tasks.push(Live2DLoader.load({
+ settings,
+ url: settings.physics,
+ type: "json",
+ target: internalModel
+ }).then((data) => {
+ internalModel.physics = runtime.createPhysics(internalModel.coreModel, data);
+ context.live2dModel.emit("physicsLoaded", internalModel.physics);
+ }).catch((e) => {
+ context.live2dModel.emit("physicsLoadError", e);
+ logger.warn(TAG, "Failed to load physics.", e);
+ }));
+ }
+ if (tasks.length) {
+ yield Promise.all(tasks);
+ }
+ }
+ }
+});
+const setupEssentials = (context, next) => __async(void 0, null, function* () {
+ if (context.settings) {
+ const live2DModel = context.live2dModel;
+ const textureLoadings = context.settings.textures.map((tex) => {
+ const url2 = context.settings.resolveURL(tex);
+ return createTexture(url2, { crossOrigin: context.options.crossOrigin });
+ });
+ yield next();
+ if (context.internalModel) {
+ live2DModel.internalModel = context.internalModel;
+ live2DModel.emit("modelLoaded", context.internalModel);
+ } else {
+ throw new TypeError("Missing internal model.");
+ }
+ live2DModel.textures = yield Promise.all(textureLoadings);
+ live2DModel.emit("textureLoaded", live2DModel.textures);
+ } else {
+ throw new TypeError("Missing settings.");
+ }
+});
+const createInternalModel = (context, next) => __async(void 0, null, function* () {
+ const settings = context.settings;
+ if (settings instanceof ModelSettings) {
+ const runtime = Live2DFactory.findRuntime(settings);
+ if (!runtime) {
+ throw new TypeError("Unknown model settings.");
+ }
+ const modelData = yield Live2DLoader.load({
+ settings,
+ url: settings.moc,
+ type: "arraybuffer",
+ target: context.live2dModel
+ });
+ if (!runtime.isValidMoc(modelData)) {
+ throw new Error("Invalid moc data");
+ }
+ const coreModel = runtime.createCoreModel(modelData);
+ context.internalModel = runtime.createInternalModel(coreModel, settings, context.options);
+ return next();
+ }
+ throw new TypeError("Missing settings.");
+});
+const _Live2DFactory = class {
+ static registerRuntime(runtime) {
+ _Live2DFactory.runtimes.push(runtime);
+ _Live2DFactory.runtimes.sort((a, b) => b.version - a.version);
+ }
+ static findRuntime(source) {
+ for (const runtime of _Live2DFactory.runtimes) {
+ if (runtime.test(source)) {
+ return runtime;
+ }
+ }
+ }
+ static setupLive2DModel(live2dModel, source, options) {
+ return __async(this, null, function* () {
+ const textureLoaded = new Promise((resolve) => live2dModel.once("textureLoaded", resolve));
+ const modelLoaded = new Promise((resolve) => live2dModel.once("modelLoaded", resolve));
+ const readyEventEmitted = Promise.all([textureLoaded, modelLoaded]).then(() => live2dModel.emit("ready"));
+ yield runMiddlewares(_Live2DFactory.live2DModelMiddlewares, {
+ live2dModel,
+ source,
+ options: options || {}
+ });
+ yield readyEventEmitted;
+ live2dModel.emit("load");
+ });
+ }
+ static loadMotion(motionManager, group, index) {
+ var _a, _b;
+ const handleError = (e) => motionManager.emit("motionLoadError", group, index, e);
+ try {
+ const definition = (_a = motionManager.definitions[group]) == null ? void 0 : _a[index];
+ if (!definition) {
+ return Promise.resolve(void 0);
+ }
+ if (!motionManager.listeners("destroy").includes(_Live2DFactory.releaseTasks)) {
+ motionManager.once("destroy", _Live2DFactory.releaseTasks);
+ }
+ let tasks = _Live2DFactory.motionTasksMap.get(motionManager);
+ if (!tasks) {
+ tasks = {};
+ _Live2DFactory.motionTasksMap.set(motionManager, tasks);
+ }
+ let taskGroup = tasks[group];
+ if (!taskGroup) {
+ taskGroup = [];
+ tasks[group] = taskGroup;
+ }
+ const path = motionManager.getMotionFile(definition);
+ (_b = taskGroup[index]) != null ? _b : taskGroup[index] = Live2DLoader.load({
+ url: path,
+ settings: motionManager.settings,
+ type: motionManager.motionDataType,
+ target: motionManager
+ }).then((data) => {
+ var _a2;
+ const taskGroup2 = (_a2 = _Live2DFactory.motionTasksMap.get(motionManager)) == null ? void 0 : _a2[group];
+ if (taskGroup2) {
+ delete taskGroup2[index];
+ }
+ const motion = motionManager.createMotion(data, group, definition);
+ motionManager.emit("motionLoaded", group, index, motion);
+ return motion;
+ }).catch((e) => {
+ logger.warn(motionManager.tag, `Failed to load motion: ${path}
+`, e);
+ handleError(e);
+ });
+ return taskGroup[index];
+ } catch (e) {
+ logger.warn(motionManager.tag, `Failed to load motion at "${group}"[${index}]
+`, e);
+ handleError(e);
+ }
+ return Promise.resolve(void 0);
+ }
+ static loadExpression(expressionManager, index) {
+ var _a;
+ const handleError = (e) => expressionManager.emit("expressionLoadError", index, e);
+ try {
+ const definition = expressionManager.definitions[index];
+ if (!definition) {
+ return Promise.resolve(void 0);
+ }
+ if (!expressionManager.listeners("destroy").includes(_Live2DFactory.releaseTasks)) {
+ expressionManager.once("destroy", _Live2DFactory.releaseTasks);
+ }
+ let tasks = _Live2DFactory.expressionTasksMap.get(expressionManager);
+ if (!tasks) {
+ tasks = [];
+ _Live2DFactory.expressionTasksMap.set(expressionManager, tasks);
+ }
+ const path = expressionManager.getExpressionFile(definition);
+ (_a = tasks[index]) != null ? _a : tasks[index] = Live2DLoader.load({
+ url: path,
+ settings: expressionManager.settings,
+ type: "json",
+ target: expressionManager
+ }).then((data) => {
+ const tasks2 = _Live2DFactory.expressionTasksMap.get(expressionManager);
+ if (tasks2) {
+ delete tasks2[index];
+ }
+ const expression = expressionManager.createExpression(data, definition);
+ expressionManager.emit("expressionLoaded", index, expression);
+ return expression;
+ }).catch((e) => {
+ logger.warn(expressionManager.tag, `Failed to load expression: ${path}
+`, e);
+ handleError(e);
+ });
+ return tasks[index];
+ } catch (e) {
+ logger.warn(expressionManager.tag, `Failed to load expression at [${index}]
+`, e);
+ handleError(e);
+ }
+ return Promise.resolve(void 0);
+ }
+ static releaseTasks() {
+ if (this instanceof MotionManager) {
+ _Live2DFactory.motionTasksMap.delete(this);
+ } else {
+ _Live2DFactory.expressionTasksMap.delete(this);
+ }
+ }
+};
+let Live2DFactory = _Live2DFactory;
+Live2DFactory.runtimes = [];
+Live2DFactory.urlToJSON = urlToJSON;
+Live2DFactory.jsonToSettings = jsonToSettings;
+Live2DFactory.waitUntilReady = waitUntilReady;
+Live2DFactory.setupOptionals = setupOptionals;
+Live2DFactory.setupEssentials = setupEssentials;
+Live2DFactory.createInternalModel = createInternalModel;
+Live2DFactory.live2DModelMiddlewares = [
+ urlToJSON,
+ jsonToSettings,
+ waitUntilReady,
+ setupOptionals,
+ setupEssentials,
+ createInternalModel
+];
+Live2DFactory.motionTasksMap = /* @__PURE__ */ new WeakMap();
+Live2DFactory.expressionTasksMap = /* @__PURE__ */ new WeakMap();
+MotionManager.prototype["_loadMotion"] = function(group, index) {
+ return Live2DFactory.loadMotion(this, group, index);
+};
+ExpressionManager.prototype["_loadExpression"] = function(index) {
+ return Live2DFactory.loadExpression(this, index);
+};
+class InteractionMixin {
+ constructor() {
+ this._autoInteract = false;
+ }
+ get autoInteract() {
+ return this._autoInteract;
+ }
+ set autoInteract(autoInteract) {
+ if (autoInteract !== this._autoInteract) {
+ if (autoInteract) {
+ this.on("pointertap", onTap, this);
+ } else {
+ this.off("pointertap", onTap, this);
+ }
+ this._autoInteract = autoInteract;
+ }
+ }
+ registerInteraction(manager) {
+ if (manager !== this.interactionManager) {
+ this.unregisterInteraction();
+ if (this._autoInteract && manager) {
+ this.interactionManager = manager;
+ manager.on("pointermove", onPointerMove, this);
+ }
+ }
+ }
+ unregisterInteraction() {
+ var _a;
+ if (this.interactionManager) {
+ (_a = this.interactionManager) == null ? void 0 : _a.off("pointermove", onPointerMove, this);
+ this.interactionManager = void 0;
+ }
+ }
+}
+function onTap(event) {
+ this.tap(event.data.global.x, event.data.global.y);
+}
+function onPointerMove(event) {
+ this.focus(event.data.global.x, event.data.global.y);
+}
+class Live2DTransform extends Transform {
+}
+const tempPoint = new Point();
+const tempMatrix$1 = new Matrix();
+let tickerRef;
+class Live2DModel extends Container {
+ constructor(options) {
+ super();
+ this.tag = "Live2DModel(uninitialized)";
+ this.textures = [];
+ this.transform = new Live2DTransform();
+ this.anchor = new ObservablePoint(this.onAnchorChange, this, 0, 0);
+ this.glContextID = -1;
+ this.elapsedTime = performance.now();
+ this.deltaTime = 0;
+ this._autoUpdate = false;
+ this.once("modelLoaded", () => this.init(options));
+ }
+ static from(source, options) {
+ const model = new this(options);
+ return Live2DFactory.setupLive2DModel(model, source, options).then(() => model);
+ }
+ static fromSync(source, options) {
+ const model = new this(options);
+ Live2DFactory.setupLive2DModel(model, source, options).then(options == null ? void 0 : options.onLoad).catch(options == null ? void 0 : options.onError);
+ return model;
+ }
+ static registerTicker(tickerClass) {
+ tickerRef = tickerClass;
+ }
+ get autoUpdate() {
+ return this._autoUpdate;
+ }
+ set autoUpdate(autoUpdate) {
+ var _a;
+ tickerRef || (tickerRef = (_a = window.PIXI) == null ? void 0 : _a.Ticker);
+ if (autoUpdate) {
+ if (!this._destroyed) {
+ if (tickerRef) {
+ tickerRef.shared.add(this.onTickerUpdate, this);
+ this._autoUpdate = true;
+ } else {
+ logger.warn(this.tag, "No Ticker registered, please call Live2DModel.registerTicker(Ticker).");
+ }
+ }
+ } else {
+ tickerRef == null ? void 0 : tickerRef.shared.remove(this.onTickerUpdate, this);
+ this._autoUpdate = false;
+ }
+ }
+ init(options) {
+ this.tag = `Live2DModel(${this.internalModel.settings.name})`;
+ const _options = Object.assign({
+ autoUpdate: true,
+ autoInteract: true
+ }, options);
+ if (_options.autoInteract) {
+ this.interactive = true;
+ }
+ this.autoInteract = _options.autoInteract;
+ this.autoUpdate = _options.autoUpdate;
+ }
+ onAnchorChange() {
+ this.pivot.set(this.anchor.x * this.internalModel.width, this.anchor.y * this.internalModel.height);
+ }
+ motion(group, index, priority, sound, volume, expression) {
+ return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority) : this.internalModel.motionManager.startMotion(group, index, priority, sound, volume, expression);
+ }
+ resetMotions() {
+ return this.internalModel.motionManager.stopAllMotions();
+ }
+ speak(sound, volume, expression) {
+ return this.internalModel.motionManager.speakUp(sound, volume, expression);
+ }
+ stopSpeaking() {
+ return this.internalModel.motionManager.stopSpeaking();
+ }
+ expression(id) {
+ if (this.internalModel.motionManager.expressionManager) {
+ return id === void 0 ? this.internalModel.motionManager.expressionManager.setRandomExpression() : this.internalModel.motionManager.expressionManager.setExpression(id);
+ }
+ return Promise.resolve(false);
+ }
+ focus(x, y, instant = false) {
+ tempPoint.x = x;
+ tempPoint.y = y;
+ this.toModelPosition(tempPoint, tempPoint, true);
+ let tx = tempPoint.x / this.internalModel.originalWidth * 2 - 1;
+ let ty = tempPoint.y / this.internalModel.originalHeight * 2 - 1;
+ let radian = Math.atan2(ty, tx);
+ this.internalModel.focusController.focus(Math.cos(radian), -Math.sin(radian), instant);
+ }
+ tap(x, y) {
+ const hitAreaNames = this.hitTest(x, y);
+ if (hitAreaNames.length) {
+ logger.log(this.tag, `Hit`, hitAreaNames);
+ this.emit("hit", hitAreaNames);
+ }
+ }
+ hitTest(x, y) {
+ tempPoint.x = x;
+ tempPoint.y = y;
+ this.toModelPosition(tempPoint, tempPoint);
+ return this.internalModel.hitTest(tempPoint.x, tempPoint.y);
+ }
+ toModelPosition(position, result = position.clone(), skipUpdate) {
+ if (!skipUpdate) {
+ this._recursivePostUpdateTransform();
+ if (!this.parent) {
+ this.parent = this._tempDisplayObjectParent;
+ this.displayObjectUpdateTransform();
+ this.parent = null;
+ } else {
+ this.displayObjectUpdateTransform();
+ }
+ }
+ this.transform.worldTransform.applyInverse(position, result);
+ this.internalModel.localTransform.applyInverse(result, result);
+ return result;
+ }
+ containsPoint(point) {
+ return this.getBounds(true).contains(point.x, point.y);
+ }
+ _calculateBounds() {
+ this._bounds.addFrame(this.transform, 0, 0, this.internalModel.width, this.internalModel.height);
+ }
+ onTickerUpdate() {
+ this.update(tickerRef.shared.deltaMS);
+ }
+ update(dt) {
+ this.deltaTime += dt;
+ this.elapsedTime += dt;
+ }
+ _render(renderer) {
+ this.registerInteraction(renderer.plugins.interaction);
+ renderer.batch.reset();
+ renderer.geometry.reset();
+ renderer.shader.reset();
+ renderer.state.reset();
+ let shouldUpdateTexture = false;
+ if (this.glContextID !== renderer.CONTEXT_UID) {
+ this.glContextID = renderer.CONTEXT_UID;
+ this.internalModel.updateWebGLContext(renderer.gl, this.glContextID);
+ shouldUpdateTexture = true;
+ }
+ for (let i = 0; i < this.textures.length; i++) {
+ const texture = this.textures[i];
+ if (!texture.valid) {
+ continue;
+ }
+ if (shouldUpdateTexture || !texture.baseTexture._glTextures[this.glContextID]) {
+ renderer.gl.pixelStorei(WebGLRenderingContext.UNPACK_FLIP_Y_WEBGL, this.internalModel.textureFlipY);
+ renderer.texture.bind(texture.baseTexture, 0);
+ }
+ this.internalModel.bindTexture(i, texture.baseTexture._glTextures[this.glContextID].texture);
+ texture.baseTexture.touched = renderer.textureGC.count;
+ }
+ const viewport = renderer.framebuffer.viewport;
+ this.internalModel.viewport = [viewport.x, viewport.y, viewport.width, viewport.height];
+ if (this.deltaTime) {
+ this.internalModel.update(this.deltaTime, this.elapsedTime);
+ this.deltaTime = 0;
+ }
+ const internalTransform = tempMatrix$1.copyFrom(renderer.globalUniforms.uniforms.projectionMatrix).append(this.worldTransform);
+ this.internalModel.updateTransform(internalTransform);
+ this.internalModel.draw(renderer.gl);
+ renderer.state.reset();
+ renderer.texture.reset();
+ }
+ destroy(options) {
+ this.emit("destroy");
+ this.autoUpdate = false;
+ this.unregisterInteraction();
+ if (options == null ? void 0 : options.texture) {
+ this.textures.forEach((texture) => texture.destroy(options.baseTexture));
+ }
+ this.internalModel.destroy();
+ super.destroy(options);
+ }
+}
+applyMixins(Live2DModel, [InteractionMixin]);
+const _FileLoader = class {
+ static resolveURL(settingsURL, filePath) {
+ var _a;
+ const resolved = (_a = _FileLoader.filesMap[settingsURL]) == null ? void 0 : _a[filePath];
+ if (resolved === void 0) {
+ throw new Error("Cannot find this file from uploaded files: " + filePath);
+ }
+ return resolved;
+ }
+ static upload(files, settings) {
+ return __async(this, null, function* () {
+ const fileMap = {};
+ for (const definedFile of settings.getDefinedFiles()) {
+ const actualPath = decodeURI(url.resolve(settings.url, definedFile));
+ const actualFile = files.find((file) => file.webkitRelativePath === actualPath);
+ if (actualFile) {
+ fileMap[definedFile] = URL.createObjectURL(actualFile);
+ }
+ }
+ _FileLoader.filesMap[settings._objectURL] = fileMap;
+ });
+ }
+ static createSettings(files) {
+ return __async(this, null, function* () {
+ const settingsFile = files.find((file) => file.name.endsWith("model.json") || file.name.endsWith("model3.json"));
+ if (!settingsFile) {
+ throw new TypeError("Settings file not found");
+ }
+ const settingsText = yield _FileLoader.readText(settingsFile);
+ const settingsJSON = JSON.parse(settingsText);
+ settingsJSON.url = settingsFile.webkitRelativePath;
+ const runtime = Live2DFactory.findRuntime(settingsJSON);
+ if (!runtime) {
+ throw new Error("Unknown settings JSON");
+ }
+ const settings = runtime.createModelSettings(settingsJSON);
+ settings._objectURL = URL.createObjectURL(settingsFile);
+ return settings;
+ });
+ }
+ static readText(file) {
+ return __async(this, null, function* () {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = () => resolve(reader.result);
+ reader.onerror = reject;
+ reader.readAsText(file, "utf8");
+ });
+ });
+ }
+};
+let FileLoader = _FileLoader;
+FileLoader.filesMap = {};
+FileLoader.factory = (context, next) => __async(void 0, null, function* () {
+ if (Array.isArray(context.source) && context.source[0] instanceof File) {
+ const files = context.source;
+ let settings = files.settings;
+ if (!settings) {
+ settings = yield _FileLoader.createSettings(files);
+ } else if (!settings._objectURL) {
+ throw new Error('"_objectURL" must be specified in ModelSettings');
+ }
+ settings.validateFiles(files.map((file) => encodeURI(file.webkitRelativePath)));
+ yield _FileLoader.upload(files, settings);
+ settings.resolveURL = function(url2) {
+ return _FileLoader.resolveURL(this._objectURL, url2);
+ };
+ context.source = settings;
+ context.live2dModel.once("modelLoaded", (internalModel) => {
+ internalModel.once("destroy", function() {
+ const objectURL = this.settings._objectURL;
+ URL.revokeObjectURL(objectURL);
+ if (_FileLoader.filesMap[objectURL]) {
+ for (const resourceObjectURL of Object.values(_FileLoader.filesMap[objectURL])) {
+ URL.revokeObjectURL(resourceObjectURL);
+ }
+ }
+ delete _FileLoader.filesMap[objectURL];
+ });
+ });
+ }
+ return next();
+});
+Live2DFactory.live2DModelMiddlewares.unshift(FileLoader.factory);
+const _ZipLoader = class {
+ static unzip(reader, settings) {
+ return __async(this, null, function* () {
+ const filePaths = yield _ZipLoader.getFilePaths(reader);
+ const requiredFilePaths = [];
+ for (const definedFile of settings.getDefinedFiles()) {
+ const actualPath = decodeURI(url.resolve(settings.url, definedFile));
+ if (filePaths.includes(actualPath)) {
+ requiredFilePaths.push(actualPath);
+ }
+ }
+ const files = yield _ZipLoader.getFiles(reader, requiredFilePaths);
+ for (let i = 0; i < files.length; i++) {
+ const path = requiredFilePaths[i];
+ const file = files[i];
+ Object.defineProperty(file, "webkitRelativePath", {
+ value: path
+ });
+ }
+ return files;
+ });
+ }
+ static createSettings(reader) {
+ return __async(this, null, function* () {
+ const filePaths = yield _ZipLoader.getFilePaths(reader);
+ const settingsFilePath = filePaths.find((path) => path.endsWith("model.json") || path.endsWith("model3.json"));
+ if (!settingsFilePath) {
+ throw new Error("Settings file not found");
+ }
+ const settingsText = yield _ZipLoader.readText(reader, settingsFilePath);
+ if (!settingsText) {
+ throw new Error("Empty settings file: " + settingsFilePath);
+ }
+ const settingsJSON = JSON.parse(settingsText);
+ settingsJSON.url = settingsFilePath;
+ const runtime = Live2DFactory.findRuntime(settingsJSON);
+ if (!runtime) {
+ throw new Error("Unknown settings JSON");
+ }
+ return runtime.createModelSettings(settingsJSON);
+ });
+ }
+ static zipReader(data, url2) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static getFilePaths(reader) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static getFiles(reader, paths) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static readText(reader, path) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static releaseReader(reader) {
+ }
+};
+let ZipLoader = _ZipLoader;
+ZipLoader.ZIP_PROTOCOL = "zip://";
+ZipLoader.uid = 0;
+ZipLoader.factory = (context, next) => __async(void 0, null, function* () {
+ const source = context.source;
+ let sourceURL;
+ let zipBlob;
+ let settings;
+ if (typeof source === "string" && (source.endsWith(".zip") || source.startsWith(_ZipLoader.ZIP_PROTOCOL))) {
+ if (source.startsWith(_ZipLoader.ZIP_PROTOCOL)) {
+ sourceURL = source.slice(_ZipLoader.ZIP_PROTOCOL.length);
+ } else {
+ sourceURL = source;
+ }
+ zipBlob = yield Live2DLoader.load({
+ url: sourceURL,
+ type: "blob",
+ target: context.live2dModel
+ });
+ } else if (Array.isArray(source) && source.length === 1 && source[0] instanceof File && source[0].name.endsWith(".zip")) {
+ zipBlob = source[0];
+ sourceURL = URL.createObjectURL(zipBlob);
+ settings = source.settings;
+ }
+ if (zipBlob) {
+ if (!zipBlob.size) {
+ throw new Error("Empty zip file");
+ }
+ const reader = yield _ZipLoader.zipReader(zipBlob, sourceURL);
+ if (!settings) {
+ settings = yield _ZipLoader.createSettings(reader);
+ }
+ settings._objectURL = _ZipLoader.ZIP_PROTOCOL + _ZipLoader.uid + "/" + settings.url;
+ const files = yield _ZipLoader.unzip(reader, settings);
+ files.settings = settings;
+ context.source = files;
+ if (sourceURL.startsWith("blob:")) {
+ context.live2dModel.once("modelLoaded", (internalModel) => {
+ internalModel.once("destroy", function() {
+ URL.revokeObjectURL(sourceURL);
+ });
+ });
+ }
+ _ZipLoader.releaseReader(reader);
+ }
+ return next();
+});
+Live2DFactory.live2DModelMiddlewares.unshift(ZipLoader.factory);
+if (!window.Live2DCubismCore) {
+ throw new Error("Could not find Cubism 4 runtime. This plugin requires live2dcubismcore.js to be loaded.");
+}
+class Cubism4ExpressionManager extends ExpressionManager {
+ constructor(settings, options) {
+ var _a;
+ super(settings, options);
+ this.queueManager = new CubismMotionQueueManager();
+ this.definitions = (_a = settings.expressions) != null ? _a : [];
+ this.init();
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ getExpressionIndex(name) {
+ return this.definitions.findIndex((def) => def.Name === name);
+ }
+ getExpressionFile(definition) {
+ return definition.File;
+ }
+ createExpression(data, definition) {
+ return CubismExpressionMotion.create(data);
+ }
+ _setExpression(motion) {
+ return this.queueManager.startMotion(motion, false, performance.now());
+ }
+ stopAllExpressions() {
+ this.queueManager.stopAllMotions();
+ }
+ updateParameters(model, now) {
+ return this.queueManager.doUpdateMotion(model, now);
+ }
+}
+class Cubism4ModelSettings extends ModelSettings {
+ constructor(json) {
+ super(json);
+ if (!Cubism4ModelSettings.isValidJSON(json)) {
+ throw new TypeError("Invalid JSON.");
+ }
+ Object.assign(this, new CubismModelSettingsJson(json));
+ }
+ static isValidJSON(json) {
+ var _a;
+ return !!(json == null ? void 0 : json.FileReferences) && typeof json.FileReferences.Moc === "string" && ((_a = json.FileReferences.Textures) == null ? void 0 : _a.length) > 0 && json.FileReferences.Textures.every((item) => typeof item === "string");
+ }
+ replaceFiles(replace) {
+ super.replaceFiles(replace);
+ if (this.motions) {
+ for (const [group, motions] of Object.entries(this.motions)) {
+ for (let i = 0; i < motions.length; i++) {
+ motions[i].File = replace(motions[i].File, `motions.${group}[${i}].File`);
+ if (motions[i].Sound !== void 0) {
+ motions[i].Sound = replace(motions[i].Sound, `motions.${group}[${i}].Sound`);
+ }
+ }
+ }
+ }
+ if (this.expressions) {
+ for (let i = 0; i < this.expressions.length; i++) {
+ this.expressions[i].File = replace(this.expressions[i].File, `expressions[${i}].File`);
+ }
+ }
+ }
+}
+applyMixins(Cubism4ModelSettings, [CubismModelSettingsJson]);
+class Cubism4MotionManager extends MotionManager {
+ constructor(settings, options) {
+ var _a;
+ super(settings, options);
+ this.groups = { idle: "Idle" };
+ this.motionDataType = "json";
+ this.queueManager = new CubismMotionQueueManager();
+ this.definitions = (_a = settings.motions) != null ? _a : {};
+ this.eyeBlinkIds = settings.getEyeBlinkParameters() || [];
+ this.lipSyncIds = settings.getLipSyncParameters() || [];
+ this.init(options);
+ }
+ init(options) {
+ super.init(options);
+ if (this.settings.expressions) {
+ this.expressionManager = new Cubism4ExpressionManager(this.settings, options);
+ }
+ this.queueManager.setEventCallback((caller, eventValue, customData) => {
+ this.emit("motion:" + eventValue);
+ });
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ _startMotion(motion, onFinish) {
+ motion.setFinishedMotionHandler(onFinish);
+ this.queueManager.stopAllMotions();
+ return this.queueManager.startMotion(motion, false, performance.now());
+ }
+ _stopAllMotions() {
+ this.queueManager.stopAllMotions();
+ }
+ createMotion(data, group, definition) {
+ const motion = CubismMotion.create(data);
+ const json = new CubismMotionJson(data);
+ const defaultFadingDuration = (group === this.groups.idle ? config.idleMotionFadingDuration : config.motionFadingDuration) / 1e3;
+ if (json.getMotionFadeInTime() === void 0) {
+ motion.setFadeInTime(definition.FadeInTime > 0 ? definition.FadeInTime : defaultFadingDuration);
+ }
+ if (json.getMotionFadeOutTime() === void 0) {
+ motion.setFadeOutTime(definition.FadeOutTime > 0 ? definition.FadeOutTime : defaultFadingDuration);
+ }
+ motion.setEffectIds(this.eyeBlinkIds, this.lipSyncIds);
+ return motion;
+ }
+ getMotionFile(definition) {
+ return definition.File;
+ }
+ getMotionName(definition) {
+ return definition.File;
+ }
+ getSoundFile(definition) {
+ return definition.Sound;
+ }
+ updateParameters(model, now) {
+ return this.queueManager.doUpdateMotion(model, now);
+ }
+ destroy() {
+ super.destroy();
+ this.queueManager.release();
+ this.queueManager = void 0;
+ }
+}
+const tempMatrix = new CubismMatrix44();
+class Cubism4InternalModel extends InternalModel {
+ constructor(coreModel, settings, options) {
+ super();
+ this.lipSync = true;
+ this.breath = CubismBreath.create();
+ this.renderer = new CubismRenderer_WebGL();
+ this.idParamAngleX = ParamAngleX;
+ this.idParamAngleY = ParamAngleY;
+ this.idParamAngleZ = ParamAngleZ;
+ this.idParamEyeBallX = ParamEyeBallX;
+ this.idParamEyeBallY = ParamEyeBallY;
+ this.idParamBodyAngleX = ParamBodyAngleX;
+ this.idParamBreath = ParamBreath;
+ this.pixelsPerUnit = 1;
+ this.centeringTransform = new Matrix();
+ this.coreModel = coreModel;
+ this.settings = settings;
+ this.motionManager = new Cubism4MotionManager(settings, options);
+ this.init();
+ }
+ init() {
+ var _a;
+ super.init();
+ if (((_a = this.settings.getEyeBlinkParameters()) == null ? void 0 : _a.length) > 0) {
+ this.eyeBlink = CubismEyeBlink.create(this.settings);
+ }
+ this.breath.setParameters([
+ new BreathParameterData(this.idParamAngleX, 0, 15, 6.5345, 0.5),
+ new BreathParameterData(this.idParamAngleY, 0, 8, 3.5345, 0.5),
+ new BreathParameterData(this.idParamAngleZ, 0, 10, 5.5345, 0.5),
+ new BreathParameterData(this.idParamBodyAngleX, 0, 4, 15.5345, 0.5),
+ new BreathParameterData(this.idParamBreath, 0, 0.5, 3.2345, 0.5)
+ ]);
+ this.renderer.initialize(this.coreModel);
+ this.renderer.setIsPremultipliedAlpha(true);
+ }
+ getSize() {
+ return [this.coreModel.getModel().canvasinfo.CanvasWidth, this.coreModel.getModel().canvasinfo.CanvasHeight];
+ }
+ getLayout() {
+ const layout = {};
+ if (this.settings.layout) {
+ for (const key of Object.keys(this.settings.layout)) {
+ const commonKey = key.charAt(0).toLowerCase() + key.slice(1);
+ layout[commonKey] = this.settings.layout[key];
+ }
+ }
+ return layout;
+ }
+ setupLayout() {
+ super.setupLayout();
+ this.pixelsPerUnit = this.coreModel.getModel().canvasinfo.PixelsPerUnit;
+ this.centeringTransform.scale(this.pixelsPerUnit, this.pixelsPerUnit).translate(this.originalWidth / 2, this.originalHeight / 2);
+ }
+ updateWebGLContext(gl, glContextID) {
+ this.renderer.firstDraw = true;
+ this.renderer._bufferData = {
+ vertex: null,
+ uv: null,
+ index: null
+ };
+ this.renderer.startUp(gl);
+ this.renderer._clippingManager._currentFrameNo = glContextID;
+ this.renderer._clippingManager._maskTexture = void 0;
+ CubismShader_WebGL.getInstance()._shaderSets = [];
+ }
+ bindTexture(index, texture) {
+ this.renderer.bindTexture(index, texture);
+ }
+ getHitAreaDefs() {
+ var _a, _b;
+ return (_b = (_a = this.settings.hitAreas) == null ? void 0 : _a.map((hitArea) => ({
+ id: hitArea.Id,
+ name: hitArea.Name,
+ index: this.coreModel.getDrawableIndex(hitArea.Id)
+ }))) != null ? _b : [];
+ }
+ getDrawableIDs() {
+ return this.coreModel.getDrawableIds();
+ }
+ getDrawableIndex(id) {
+ return this.coreModel.getDrawableIndex(id);
+ }
+ getDrawableVertices(drawIndex) {
+ if (typeof drawIndex === "string") {
+ drawIndex = this.coreModel.getDrawableIndex(drawIndex);
+ if (drawIndex === -1)
+ throw new TypeError("Unable to find drawable ID: " + drawIndex);
+ }
+ const arr = this.coreModel.getDrawableVertices(drawIndex).slice();
+ for (let i = 0; i < arr.length; i += 2) {
+ arr[i] = arr[i] * this.pixelsPerUnit + this.originalWidth / 2;
+ arr[i + 1] = -arr[i + 1] * this.pixelsPerUnit + this.originalHeight / 2;
+ }
+ return arr;
+ }
+ updateTransform(transform) {
+ this.drawingMatrix.copyFrom(this.centeringTransform).prepend(this.localTransform).prepend(transform);
+ }
+ update(dt, now) {
+ var _a, _b, _c, _d;
+ super.update(dt, now);
+ dt /= 1e3;
+ now /= 1e3;
+ const model = this.coreModel;
+ this.emit("beforeMotionUpdate");
+ const motionUpdated = this.motionManager.update(this.coreModel, now);
+ this.emit("afterMotionUpdate");
+ model.saveParameters();
+ (_a = this.motionManager.expressionManager) == null ? void 0 : _a.update(model, now);
+ if (!motionUpdated) {
+ (_b = this.eyeBlink) == null ? void 0 : _b.updateParameters(model, dt);
+ }
+ this.updateFocus();
+ this.updateNaturalMovements(dt * 1e3, now * 1e3);
+ (_c = this.physics) == null ? void 0 : _c.evaluate(model, dt);
+ (_d = this.pose) == null ? void 0 : _d.updateParameters(model, dt);
+ this.emit("beforeModelUpdate");
+ model.update();
+ model.loadParameters();
+ }
+ updateFocus() {
+ this.coreModel.addParameterValueById(this.idParamEyeBallX, this.focusController.x);
+ this.coreModel.addParameterValueById(this.idParamEyeBallY, this.focusController.y);
+ this.coreModel.addParameterValueById(this.idParamAngleX, this.focusController.x * 30);
+ this.coreModel.addParameterValueById(this.idParamAngleY, this.focusController.y * 30);
+ this.coreModel.addParameterValueById(this.idParamAngleZ, this.focusController.x * this.focusController.y * -30);
+ this.coreModel.addParameterValueById(this.idParamBodyAngleX, this.focusController.x * 10);
+ }
+ updateNaturalMovements(dt, now) {
+ var _a;
+ (_a = this.breath) == null ? void 0 : _a.updateParameters(this.coreModel, dt / 1e3);
+ }
+ draw(gl) {
+ const matrix = this.drawingMatrix;
+ const array = tempMatrix.getArray();
+ array[0] = matrix.a;
+ array[1] = matrix.b;
+ array[4] = -matrix.c;
+ array[5] = -matrix.d;
+ array[12] = matrix.tx;
+ array[13] = matrix.ty;
+ this.renderer.setMvpMatrix(tempMatrix);
+ this.renderer.setRenderState(gl.getParameter(gl.FRAMEBUFFER_BINDING), this.viewport);
+ this.renderer.drawModel();
+ }
+ destroy() {
+ super.destroy();
+ this.renderer.release();
+ this.coreModel.release();
+ this.renderer = void 0;
+ this.coreModel = void 0;
+ }
+}
+let startupPromise;
+let startupRetries = 20;
+function cubism4Ready() {
+ if (CubismFramework.isStarted()) {
+ return Promise.resolve();
+ }
+ startupPromise != null ? startupPromise : startupPromise = new Promise((resolve, reject) => {
+ function startUpWithRetry() {
+ try {
+ startUpCubism4();
+ resolve();
+ } catch (e) {
+ startupRetries--;
+ if (startupRetries < 0) {
+ const err = new Error("Failed to start up Cubism 4 framework.");
+ err.cause = e;
+ reject(err);
+ return;
+ }
+ logger.log("Cubism4", "Startup failed, retrying 10ms later...");
+ setTimeout(startUpWithRetry, 10);
+ }
+ }
+ startUpWithRetry();
+ });
+ return startupPromise;
+}
+function startUpCubism4(options) {
+ options = Object.assign({
+ logFunction: console.log,
+ loggingLevel: LogLevel.LogLevel_Verbose
+ }, options);
+ CubismFramework.startUp(options);
+ CubismFramework.initialize();
+}
+Live2DFactory.registerRuntime({
+ version: 4,
+ ready: cubism4Ready,
+ test(source) {
+ return source instanceof Cubism4ModelSettings || Cubism4ModelSettings.isValidJSON(source);
+ },
+ isValidMoc(modelData) {
+ if (modelData.byteLength < 4) {
+ return false;
+ }
+ const view = new Int8Array(modelData, 0, 4);
+ return String.fromCharCode(...view) === "MOC3";
+ },
+ createModelSettings(json) {
+ return new Cubism4ModelSettings(json);
+ },
+ createCoreModel(data, options) {
+ const moc = CubismMoc.create(data, !!(options == null ? void 0 : options.checkMocConsistency));
+ try {
+ const model = moc.createModel();
+ model.__moc = moc;
+ return model;
+ } catch (e) {
+ try {
+ moc.release();
+ } catch (ignored) {
+ }
+ throw e;
+ }
+ },
+ createInternalModel(coreModel, settings, options) {
+ const model = new Cubism4InternalModel(coreModel, settings, options);
+ const coreModelWithMoc = coreModel;
+ if (coreModelWithMoc.__moc) {
+ model.__moc = coreModelWithMoc.__moc;
+ delete coreModelWithMoc.__moc;
+ model.once("destroy", releaseMoc);
+ }
+ return model;
+ },
+ createPhysics(coreModel, data) {
+ return CubismPhysics.create(data);
+ },
+ createPose(coreModel, data) {
+ return CubismPose.create(data);
+ }
+});
+function releaseMoc() {
+ var _a;
+ (_a = this.__moc) == null ? void 0 : _a.release();
+}
+export { ACubismMotion, BreathParameterData, CSM_ASSERT, Constant, Cubism4ExpressionManager, Cubism4InternalModel, Cubism4ModelSettings, Cubism4MotionManager, CubismBlendMode, CubismBreath, CubismClippingContext, CubismClippingManager_WebGL, CubismConfig, CubismDebug, CubismExpressionMotion, CubismEyeBlink, CubismFramework, CubismLogDebug, CubismLogError, CubismLogInfo, CubismLogVerbose, CubismLogWarning, CubismMath, CubismMatrix44, CubismMoc, CubismModel, CubismModelSettingsJson, CubismModelUserData, CubismModelUserDataJson, CubismMotion, CubismMotionCurve, CubismMotionCurveTarget, CubismMotionData, CubismMotionEvent, CubismMotionJson, CubismMotionManager, CubismMotionPoint, CubismMotionQueueEntry, CubismMotionQueueManager, CubismMotionSegment, CubismMotionSegmentType, CubismPhysics, CubismPhysicsInput, CubismPhysicsJson, CubismPhysicsOutput, CubismPhysicsParticle, CubismPhysicsRig, CubismPhysicsSource, CubismPhysicsSubRig, CubismPhysicsTargetType, CubismPose, CubismRenderTextureResource, CubismRenderer, CubismRendererProfile_WebGL, CubismRenderer_WebGL, CubismShader_WebGL, CubismTextureColor, CubismVector2, DrawableColorData, DrawableCullingData, EvaluationOptionFlag, ExpressionBlendType, ExpressionManager, EyeState, FileLoader, FocusController, HitAreaBody, HitAreaHead, HitAreaPrefix, InteractionMixin, InternalModel, InvalidMotionQueueEntryHandleValue, LOGICAL_HEIGHT, LOGICAL_WIDTH, Live2DFactory, Live2DLoader, Live2DModel, Live2DTransform, LogLevel, ModelSettings, MotionManager, MotionPreloadStrategy, MotionPriority, MotionState, Options, ParamAngleX, ParamAngleY, ParamAngleZ, ParamArmLA, ParamArmLB, ParamArmRA, ParamArmRB, ParamBaseX, ParamBaseY, ParamBodyAngleX, ParamBodyAngleY, ParamBodyAngleZ, ParamBreath, ParamBrowLAngle, ParamBrowLForm, ParamBrowLX, ParamBrowLY, ParamBrowRAngle, ParamBrowRForm, ParamBrowRX, ParamBrowRY, ParamBustX, ParamBustY, ParamCheek, ParamEyeBallForm, ParamEyeBallX, ParamEyeBallY, ParamEyeLOpen, ParamEyeLSmile, ParamEyeROpen, ParamEyeRSmile, ParamHairBack, ParamHairFluffy, ParamHairFront, ParamHairSide, ParamHandL, ParamHandR, ParamMouthForm, ParamMouthOpenY, ParamNONE, ParamShoulderY, PartColorData, PartData, PartsArmLPrefix, PartsArmPrefix, PartsArmRPrefix, PartsIdCore, PhysicsJsonEffectiveForces, PhysicsOutput, ShaderNames, SoundManager, VERSION, XHRLoader, ZipLoader, applyMixins, clamp, config, copyArray, copyProperty, csmRect, cubism4Ready, folderName, fragmentShaderSrcMaskInvertedPremultipliedAlpha, fragmentShaderSrcMaskPremultipliedAlpha, fragmentShaderSrcPremultipliedAlpha, fragmentShaderSrcsetupMask, logger, rand, remove, startUpCubism4, vertexShaderSrc, vertexShaderSrcMasked, vertexShaderSrcSetupMask };
diff --git a/dist/cubism4.js b/dist/cubism4.js
new file mode 100644
index 00000000..1034a6e8
--- /dev/null
+++ b/dist/cubism4.js
@@ -0,0 +1,6697 @@
+var __pow = Math.pow;
+var __async = (__this, __arguments, generator) => {
+ return new Promise((resolve, reject) => {
+ var fulfilled = (value) => {
+ try {
+ step(generator.next(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var rejected = (value) => {
+ try {
+ step(generator.throw(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
+ step((generator = generator.apply(__this, __arguments)).next());
+ });
+};
+(function(global, factory) {
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@pixi/utils"), require("@pixi/math"), require("@pixi/core"), require("@pixi/display")) : typeof define === "function" && define.amd ? define(["exports", "@pixi/utils", "@pixi/math", "@pixi/core", "@pixi/display"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory((global.PIXI = global.PIXI || {}, global.PIXI.live2d = global.PIXI.live2d || {}), global.PIXI.utils, global.PIXI, global.PIXI, global.PIXI));
+})(this, function(exports2, utils, math, core, display) {
+ "use strict";
+ class CubismBreath {
+ constructor() {
+ this._breathParameters = [];
+ this._currentTime = 0;
+ }
+ static create() {
+ return new CubismBreath();
+ }
+ setParameters(breathParameters) {
+ this._breathParameters = breathParameters;
+ }
+ getParameters() {
+ return this._breathParameters;
+ }
+ updateParameters(model, deltaTimeSeconds) {
+ this._currentTime += deltaTimeSeconds;
+ const t = this._currentTime * 2 * 3.14159;
+ for (let i = 0; i < this._breathParameters.length; ++i) {
+ const data = this._breathParameters[i];
+ model.addParameterValueById(data.parameterId, data.offset + data.peak * Math.sin(t / data.cycle), data.weight);
+ }
+ }
+ }
+ class BreathParameterData {
+ constructor(parameterId, offset, peak, cycle, weight) {
+ this.parameterId = parameterId == void 0 ? void 0 : parameterId;
+ this.offset = offset == void 0 ? 0 : offset;
+ this.peak = peak == void 0 ? 0 : peak;
+ this.cycle = cycle == void 0 ? 0 : cycle;
+ this.weight = weight == void 0 ? 0 : weight;
+ }
+ }
+ const _CubismEyeBlink = class {
+ static create(modelSetting) {
+ return new _CubismEyeBlink(modelSetting);
+ }
+ setBlinkingInterval(blinkingInterval) {
+ this._blinkingIntervalSeconds = blinkingInterval;
+ }
+ setBlinkingSetting(closing, closed, opening) {
+ this._closingSeconds = closing;
+ this._closedSeconds = closed;
+ this._openingSeconds = opening;
+ }
+ setParameterIds(parameterIds) {
+ this._parameterIds = parameterIds;
+ }
+ getParameterIds() {
+ return this._parameterIds;
+ }
+ updateParameters(model, deltaTimeSeconds) {
+ this._userTimeSeconds += deltaTimeSeconds;
+ let parameterValue;
+ let t = 0;
+ switch (this._blinkingState) {
+ case EyeState.EyeState_Closing:
+ t = (this._userTimeSeconds - this._stateStartTimeSeconds) / this._closingSeconds;
+ if (t >= 1) {
+ t = 1;
+ this._blinkingState = EyeState.EyeState_Closed;
+ this._stateStartTimeSeconds = this._userTimeSeconds;
+ }
+ parameterValue = 1 - t;
+ break;
+ case EyeState.EyeState_Closed:
+ t = (this._userTimeSeconds - this._stateStartTimeSeconds) / this._closedSeconds;
+ if (t >= 1) {
+ this._blinkingState = EyeState.EyeState_Opening;
+ this._stateStartTimeSeconds = this._userTimeSeconds;
+ }
+ parameterValue = 0;
+ break;
+ case EyeState.EyeState_Opening:
+ t = (this._userTimeSeconds - this._stateStartTimeSeconds) / this._openingSeconds;
+ if (t >= 1) {
+ t = 1;
+ this._blinkingState = EyeState.EyeState_Interval;
+ this._nextBlinkingTime = this.determinNextBlinkingTiming();
+ }
+ parameterValue = t;
+ break;
+ case EyeState.EyeState_Interval:
+ if (this._nextBlinkingTime < this._userTimeSeconds) {
+ this._blinkingState = EyeState.EyeState_Closing;
+ this._stateStartTimeSeconds = this._userTimeSeconds;
+ }
+ parameterValue = 1;
+ break;
+ case EyeState.EyeState_First:
+ default:
+ this._blinkingState = EyeState.EyeState_Interval;
+ this._nextBlinkingTime = this.determinNextBlinkingTiming();
+ parameterValue = 1;
+ break;
+ }
+ if (!_CubismEyeBlink.CloseIfZero) {
+ parameterValue = -parameterValue;
+ }
+ for (let i = 0; i < this._parameterIds.length; ++i) {
+ model.setParameterValueById(this._parameterIds[i], parameterValue);
+ }
+ }
+ constructor(modelSetting) {
+ var _a, _b;
+ this._blinkingState = EyeState.EyeState_First;
+ this._nextBlinkingTime = 0;
+ this._stateStartTimeSeconds = 0;
+ this._blinkingIntervalSeconds = 4;
+ this._closingSeconds = 0.1;
+ this._closedSeconds = 0.05;
+ this._openingSeconds = 0.15;
+ this._userTimeSeconds = 0;
+ this._parameterIds = [];
+ if (modelSetting == null) {
+ return;
+ }
+ this._parameterIds = (_b = (_a = modelSetting.getEyeBlinkParameters()) == null ? void 0 : _a.slice()) != null ? _b : this._parameterIds;
+ }
+ determinNextBlinkingTiming() {
+ const r = Math.random();
+ return this._userTimeSeconds + r * (2 * this._blinkingIntervalSeconds - 1);
+ }
+ };
+ let CubismEyeBlink = _CubismEyeBlink;
+ CubismEyeBlink.CloseIfZero = true;
+ var EyeState = /* @__PURE__ */ ((EyeState2) => {
+ EyeState2[EyeState2["EyeState_First"] = 0] = "EyeState_First";
+ EyeState2[EyeState2["EyeState_Interval"] = 1] = "EyeState_Interval";
+ EyeState2[EyeState2["EyeState_Closing"] = 2] = "EyeState_Closing";
+ EyeState2[EyeState2["EyeState_Closed"] = 3] = "EyeState_Closed";
+ EyeState2[EyeState2["EyeState_Opening"] = 4] = "EyeState_Opening";
+ return EyeState2;
+ })(EyeState || {});
+ const Epsilon = 1e-3;
+ const DefaultFadeInSeconds = 0.5;
+ class CubismPose {
+ static create(pose3json) {
+ const ret = new CubismPose();
+ if (typeof pose3json.FadeInTime === "number") {
+ ret._fadeTimeSeconds = pose3json.FadeInTime;
+ if (ret._fadeTimeSeconds <= 0) {
+ ret._fadeTimeSeconds = DefaultFadeInSeconds;
+ }
+ }
+ const poseListInfo = pose3json.Groups;
+ const poseCount = poseListInfo.length;
+ for (let poseIndex = 0; poseIndex < poseCount; ++poseIndex) {
+ const idListInfo = poseListInfo[poseIndex];
+ const idCount = idListInfo.length;
+ let groupCount = 0;
+ for (let groupIndex = 0; groupIndex < idCount; ++groupIndex) {
+ const partInfo = idListInfo[groupIndex];
+ const partData = new PartData();
+ partData.partId = partInfo.Id;
+ const linkListInfo = partInfo.Link;
+ if (linkListInfo) {
+ const linkCount = linkListInfo.length;
+ for (let linkIndex = 0; linkIndex < linkCount; ++linkIndex) {
+ const linkPart = new PartData();
+ linkPart.partId = linkListInfo[linkIndex];
+ partData.link.push(linkPart);
+ }
+ }
+ ret._partGroups.push(partData);
+ ++groupCount;
+ }
+ ret._partGroupCounts.push(groupCount);
+ }
+ return ret;
+ }
+ updateParameters(model, deltaTimeSeconds) {
+ if (model != this._lastModel) {
+ this.reset(model);
+ }
+ this._lastModel = model;
+ if (deltaTimeSeconds < 0) {
+ deltaTimeSeconds = 0;
+ }
+ let beginIndex = 0;
+ for (let i = 0; i < this._partGroupCounts.length; i++) {
+ const partGroupCount = this._partGroupCounts[i];
+ this.doFade(model, deltaTimeSeconds, beginIndex, partGroupCount);
+ beginIndex += partGroupCount;
+ }
+ this.copyPartOpacities(model);
+ }
+ reset(model) {
+ let beginIndex = 0;
+ for (let i = 0; i < this._partGroupCounts.length; ++i) {
+ const groupCount = this._partGroupCounts[i];
+ for (let j = beginIndex; j < beginIndex + groupCount; ++j) {
+ this._partGroups[j].initialize(model);
+ const partsIndex = this._partGroups[j].partIndex;
+ const paramIndex = this._partGroups[j].parameterIndex;
+ if (partsIndex < 0) {
+ continue;
+ }
+ model.setPartOpacityByIndex(partsIndex, j == beginIndex ? 1 : 0);
+ model.setParameterValueByIndex(paramIndex, j == beginIndex ? 1 : 0);
+ for (let k = 0; k < this._partGroups[j].link.length; ++k) {
+ this._partGroups[j].link[k].initialize(model);
+ }
+ }
+ beginIndex += groupCount;
+ }
+ }
+ copyPartOpacities(model) {
+ for (let groupIndex = 0; groupIndex < this._partGroups.length; ++groupIndex) {
+ const partData = this._partGroups[groupIndex];
+ if (partData.link.length == 0) {
+ continue;
+ }
+ const partIndex = this._partGroups[groupIndex].partIndex;
+ const opacity = model.getPartOpacityByIndex(partIndex);
+ for (let linkIndex = 0; linkIndex < partData.link.length; ++linkIndex) {
+ const linkPart = partData.link[linkIndex];
+ const linkPartIndex = linkPart.partIndex;
+ if (linkPartIndex < 0) {
+ continue;
+ }
+ model.setPartOpacityByIndex(linkPartIndex, opacity);
+ }
+ }
+ }
+ doFade(model, deltaTimeSeconds, beginIndex, partGroupCount) {
+ let visiblePartIndex = -1;
+ let newOpacity = 1;
+ const phi = 0.5;
+ const backOpacityThreshold = 0.15;
+ for (let i = beginIndex; i < beginIndex + partGroupCount; ++i) {
+ const partIndex = this._partGroups[i].partIndex;
+ const paramIndex = this._partGroups[i].parameterIndex;
+ if (model.getParameterValueByIndex(paramIndex) > Epsilon) {
+ if (visiblePartIndex >= 0) {
+ break;
+ }
+ visiblePartIndex = i;
+ newOpacity = model.getPartOpacityByIndex(partIndex);
+ newOpacity += deltaTimeSeconds / this._fadeTimeSeconds;
+ if (newOpacity > 1) {
+ newOpacity = 1;
+ }
+ }
+ }
+ if (visiblePartIndex < 0) {
+ visiblePartIndex = 0;
+ newOpacity = 1;
+ }
+ for (let i = beginIndex; i < beginIndex + partGroupCount; ++i) {
+ const partsIndex = this._partGroups[i].partIndex;
+ if (visiblePartIndex == i) {
+ model.setPartOpacityByIndex(partsIndex, newOpacity);
+ } else {
+ let opacity = model.getPartOpacityByIndex(partsIndex);
+ let a1;
+ if (newOpacity < phi) {
+ a1 = newOpacity * (phi - 1) / phi + 1;
+ } else {
+ a1 = (1 - newOpacity) * phi / (1 - phi);
+ }
+ const backOpacity = (1 - a1) * (1 - newOpacity);
+ if (backOpacity > backOpacityThreshold) {
+ a1 = 1 - backOpacityThreshold / (1 - newOpacity);
+ }
+ if (opacity > a1) {
+ opacity = a1;
+ }
+ model.setPartOpacityByIndex(partsIndex, opacity);
+ }
+ }
+ }
+ constructor() {
+ this._fadeTimeSeconds = DefaultFadeInSeconds;
+ this._lastModel = void 0;
+ this._partGroups = [];
+ this._partGroupCounts = [];
+ }
+ }
+ class PartData {
+ constructor(v) {
+ this.parameterIndex = 0;
+ this.partIndex = 0;
+ this.partId = "";
+ this.link = [];
+ if (v != void 0) {
+ this.assignment(v);
+ }
+ }
+ assignment(v) {
+ this.partId = v.partId;
+ this.link = v.link.map((link) => link.clone());
+ return this;
+ }
+ initialize(model) {
+ this.parameterIndex = model.getParameterIndex(this.partId);
+ this.partIndex = model.getPartIndex(this.partId);
+ model.setParameterValueByIndex(this.parameterIndex, 1);
+ }
+ clone() {
+ const clonePartData = new PartData();
+ clonePartData.partId = this.partId;
+ clonePartData.parameterIndex = this.parameterIndex;
+ clonePartData.partIndex = this.partIndex;
+ clonePartData.link = this.link.map((link) => link.clone());
+ return clonePartData;
+ }
+ }
+ class CubismVector2 {
+ constructor(x, y) {
+ this.x = x || 0;
+ this.y = y || 0;
+ }
+ add(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x + vector2.x;
+ ret.y = this.y + vector2.y;
+ return ret;
+ }
+ substract(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x - vector2.x;
+ ret.y = this.y - vector2.y;
+ return ret;
+ }
+ multiply(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x * vector2.x;
+ ret.y = this.y * vector2.y;
+ return ret;
+ }
+ multiplyByScaler(scalar) {
+ return this.multiply(new CubismVector2(scalar, scalar));
+ }
+ division(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x / vector2.x;
+ ret.y = this.y / vector2.y;
+ return ret;
+ }
+ divisionByScalar(scalar) {
+ return this.division(new CubismVector2(scalar, scalar));
+ }
+ getLength() {
+ return Math.sqrt(this.x * this.x + this.y * this.y);
+ }
+ getDistanceWith(a) {
+ return Math.sqrt((this.x - a.x) * (this.x - a.x) + (this.y - a.y) * (this.y - a.y));
+ }
+ dot(a) {
+ return this.x * a.x + this.y * a.y;
+ }
+ normalize() {
+ const length = Math.pow(this.x * this.x + this.y * this.y, 0.5);
+ this.x = this.x / length;
+ this.y = this.y / length;
+ }
+ isEqual(rhs) {
+ return this.x == rhs.x && this.y == rhs.y;
+ }
+ isNotEqual(rhs) {
+ return !this.isEqual(rhs);
+ }
+ }
+ const _CubismMath = class {
+ static range(value, min, max) {
+ if (value < min) {
+ value = min;
+ } else if (value > max) {
+ value = max;
+ }
+ return value;
+ }
+ static sin(x) {
+ return Math.sin(x);
+ }
+ static cos(x) {
+ return Math.cos(x);
+ }
+ static abs(x) {
+ return Math.abs(x);
+ }
+ static sqrt(x) {
+ return Math.sqrt(x);
+ }
+ static cbrt(x) {
+ if (x === 0) {
+ return x;
+ }
+ let cx = x;
+ const isNegativeNumber = cx < 0;
+ if (isNegativeNumber) {
+ cx = -cx;
+ }
+ let ret;
+ if (cx === Infinity) {
+ ret = Infinity;
+ } else {
+ ret = Math.exp(Math.log(cx) / 3);
+ ret = (cx / (ret * ret) + 2 * ret) / 3;
+ }
+ return isNegativeNumber ? -ret : ret;
+ }
+ static getEasingSine(value) {
+ if (value < 0) {
+ return 0;
+ } else if (value > 1) {
+ return 1;
+ }
+ return 0.5 - 0.5 * this.cos(value * Math.PI);
+ }
+ static max(left, right) {
+ return left > right ? left : right;
+ }
+ static min(left, right) {
+ return left > right ? right : left;
+ }
+ static degreesToRadian(degrees) {
+ return degrees / 180 * Math.PI;
+ }
+ static radianToDegrees(radian) {
+ return radian * 180 / Math.PI;
+ }
+ static directionToRadian(from, to) {
+ const q1 = Math.atan2(to.y, to.x);
+ const q2 = Math.atan2(from.y, from.x);
+ let ret = q1 - q2;
+ while (ret < -Math.PI) {
+ ret += Math.PI * 2;
+ }
+ while (ret > Math.PI) {
+ ret -= Math.PI * 2;
+ }
+ return ret;
+ }
+ static directionToDegrees(from, to) {
+ const radian = this.directionToRadian(from, to);
+ let degree = this.radianToDegrees(radian);
+ if (to.x - from.x > 0) {
+ degree = -degree;
+ }
+ return degree;
+ }
+ static radianToDirection(totalAngle) {
+ const ret = new CubismVector2();
+ ret.x = this.sin(totalAngle);
+ ret.y = this.cos(totalAngle);
+ return ret;
+ }
+ static quadraticEquation(a, b, c) {
+ if (this.abs(a) < _CubismMath.Epsilon) {
+ if (this.abs(b) < _CubismMath.Epsilon) {
+ return -c;
+ }
+ return -c / b;
+ }
+ return -(b + this.sqrt(b * b - 4 * a * c)) / (2 * a);
+ }
+ static cardanoAlgorithmForBezier(a, b, c, d) {
+ if (this.sqrt(a) < _CubismMath.Epsilon) {
+ return this.range(this.quadraticEquation(b, c, d), 0, 1);
+ }
+ const ba = b / a;
+ const ca = c / a;
+ const da = d / a;
+ const p = (3 * ca - ba * ba) / 3;
+ const p3 = p / 3;
+ const q = (2 * ba * ba * ba - 9 * ba * ca + 27 * da) / 27;
+ const q2 = q / 2;
+ const discriminant = q2 * q2 + p3 * p3 * p3;
+ const center = 0.5;
+ const threshold = center + 0.01;
+ if (discriminant < 0) {
+ const mp3 = -p / 3;
+ const mp33 = mp3 * mp3 * mp3;
+ const r = this.sqrt(mp33);
+ const t = -q / (2 * r);
+ const cosphi = this.range(t, -1, 1);
+ const phi = Math.acos(cosphi);
+ const crtr = this.cbrt(r);
+ const t1 = 2 * crtr;
+ const root12 = t1 * this.cos(phi / 3) - ba / 3;
+ if (this.abs(root12 - center) < threshold) {
+ return this.range(root12, 0, 1);
+ }
+ const root2 = t1 * this.cos((phi + 2 * Math.PI) / 3) - ba / 3;
+ if (this.abs(root2 - center) < threshold) {
+ return this.range(root2, 0, 1);
+ }
+ const root3 = t1 * this.cos((phi + 4 * Math.PI) / 3) - ba / 3;
+ return this.range(root3, 0, 1);
+ }
+ if (discriminant == 0) {
+ let u12;
+ if (q2 < 0) {
+ u12 = this.cbrt(-q2);
+ } else {
+ u12 = -this.cbrt(q2);
+ }
+ const root12 = 2 * u12 - ba / 3;
+ if (this.abs(root12 - center) < threshold) {
+ return this.range(root12, 0, 1);
+ }
+ const root2 = -u12 - ba / 3;
+ return this.range(root2, 0, 1);
+ }
+ const sd = this.sqrt(discriminant);
+ const u1 = this.cbrt(sd - q2);
+ const v1 = this.cbrt(sd + q2);
+ const root1 = u1 - v1 - ba / 3;
+ return this.range(root1, 0, 1);
+ }
+ constructor() {
+ }
+ };
+ let CubismMath = _CubismMath;
+ CubismMath.Epsilon = 1e-5;
+ class CubismMatrix44 {
+ constructor() {
+ this._tr = new Float32Array(16);
+ this.loadIdentity();
+ }
+ static multiply(a, b, dst) {
+ const c = new Float32Array([
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]);
+ const n = 4;
+ for (let i = 0; i < n; ++i) {
+ for (let j = 0; j < n; ++j) {
+ for (let k = 0; k < n; ++k) {
+ c[j + i * 4] += a[k + i * 4] * b[j + k * 4];
+ }
+ }
+ }
+ for (let i = 0; i < 16; ++i) {
+ dst[i] = c[i];
+ }
+ }
+ loadIdentity() {
+ const c = new Float32Array([
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ]);
+ this.setMatrix(c);
+ }
+ setMatrix(tr) {
+ for (let i = 0; i < 16; ++i) {
+ this._tr[i] = tr[i];
+ }
+ }
+ getArray() {
+ return this._tr;
+ }
+ getScaleX() {
+ return this._tr[0];
+ }
+ getScaleY() {
+ return this._tr[5];
+ }
+ getTranslateX() {
+ return this._tr[12];
+ }
+ getTranslateY() {
+ return this._tr[13];
+ }
+ transformX(src) {
+ return this._tr[0] * src + this._tr[12];
+ }
+ transformY(src) {
+ return this._tr[5] * src + this._tr[13];
+ }
+ invertTransformX(src) {
+ return (src - this._tr[12]) / this._tr[0];
+ }
+ invertTransformY(src) {
+ return (src - this._tr[13]) / this._tr[5];
+ }
+ translateRelative(x, y) {
+ const tr1 = new Float32Array([
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ x,
+ y,
+ 0,
+ 1
+ ]);
+ CubismMatrix44.multiply(tr1, this._tr, this._tr);
+ }
+ translate(x, y) {
+ this._tr[12] = x;
+ this._tr[13] = y;
+ }
+ translateX(x) {
+ this._tr[12] = x;
+ }
+ translateY(y) {
+ this._tr[13] = y;
+ }
+ scaleRelative(x, y) {
+ const tr1 = new Float32Array([
+ x,
+ 0,
+ 0,
+ 0,
+ 0,
+ y,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ]);
+ CubismMatrix44.multiply(tr1, this._tr, this._tr);
+ }
+ scale(x, y) {
+ this._tr[0] = x;
+ this._tr[5] = y;
+ }
+ multiplyByMatrix(m) {
+ CubismMatrix44.multiply(m.getArray(), this._tr, this._tr);
+ }
+ clone() {
+ const cloneMatrix = new CubismMatrix44();
+ for (let i = 0; i < this._tr.length; i++) {
+ cloneMatrix._tr[i] = this._tr[i];
+ }
+ return cloneMatrix;
+ }
+ }
+ class CubismRenderer {
+ initialize(model) {
+ this._model = model;
+ }
+ drawModel() {
+ if (this.getModel() == null)
+ return;
+ this.saveProfile();
+ this.doDrawModel();
+ this.restoreProfile();
+ }
+ setMvpMatrix(matrix44) {
+ this._mvpMatrix4x4.setMatrix(matrix44.getArray());
+ }
+ getMvpMatrix() {
+ return this._mvpMatrix4x4;
+ }
+ setModelColor(red, green, blue, alpha) {
+ if (red < 0) {
+ red = 0;
+ } else if (red > 1) {
+ red = 1;
+ }
+ if (green < 0) {
+ green = 0;
+ } else if (green > 1) {
+ green = 1;
+ }
+ if (blue < 0) {
+ blue = 0;
+ } else if (blue > 1) {
+ blue = 1;
+ }
+ if (alpha < 0) {
+ alpha = 0;
+ } else if (alpha > 1) {
+ alpha = 1;
+ }
+ this._modelColor.R = red;
+ this._modelColor.G = green;
+ this._modelColor.B = blue;
+ this._modelColor.A = alpha;
+ }
+ getModelColor() {
+ return Object.assign({}, this._modelColor);
+ }
+ setIsPremultipliedAlpha(enable) {
+ this._isPremultipliedAlpha = enable;
+ }
+ isPremultipliedAlpha() {
+ return this._isPremultipliedAlpha;
+ }
+ setIsCulling(culling) {
+ this._isCulling = culling;
+ }
+ isCulling() {
+ return this._isCulling;
+ }
+ setAnisotropy(n) {
+ this._anisotropy = n;
+ }
+ getAnisotropy() {
+ return this._anisotropy;
+ }
+ getModel() {
+ return this._model;
+ }
+ useHighPrecisionMask(high) {
+ this._useHighPrecisionMask = high;
+ }
+ isUsingHighPrecisionMask() {
+ return this._useHighPrecisionMask;
+ }
+ constructor() {
+ this._isCulling = false;
+ this._isPremultipliedAlpha = false;
+ this._anisotropy = 0;
+ this._modelColor = new CubismTextureColor();
+ this._useHighPrecisionMask = false;
+ this._mvpMatrix4x4 = new CubismMatrix44();
+ this._mvpMatrix4x4.loadIdentity();
+ }
+ }
+ var CubismBlendMode = /* @__PURE__ */ ((CubismBlendMode2) => {
+ CubismBlendMode2[CubismBlendMode2["CubismBlendMode_Normal"] = 0] = "CubismBlendMode_Normal";
+ CubismBlendMode2[CubismBlendMode2["CubismBlendMode_Additive"] = 1] = "CubismBlendMode_Additive";
+ CubismBlendMode2[CubismBlendMode2["CubismBlendMode_Multiplicative"] = 2] = "CubismBlendMode_Multiplicative";
+ return CubismBlendMode2;
+ })(CubismBlendMode || {});
+ class CubismTextureColor {
+ constructor(r = 1, g = 1, b = 1, a = 1) {
+ this.R = r;
+ this.G = g;
+ this.B = b;
+ this.A = a;
+ }
+ }
+ let s_isStarted = false;
+ let s_isInitialized = false;
+ let s_option = void 0;
+ const Constant = {
+ vertexOffset: 0,
+ vertexStep: 2
+ };
+ class CubismFramework {
+ static startUp(option) {
+ if (s_isStarted) {
+ CubismLogInfo("CubismFramework.startUp() is already done.");
+ return s_isStarted;
+ }
+ if (Live2DCubismCore._isStarted) {
+ s_isStarted = true;
+ return true;
+ }
+ Live2DCubismCore._isStarted = true;
+ s_option = option;
+ if (s_option) {
+ Live2DCubismCore.Logging.csmSetLogFunction(s_option.logFunction);
+ }
+ s_isStarted = true;
+ if (s_isStarted) {
+ const version = Live2DCubismCore.Version.csmGetVersion();
+ const major = (version & 4278190080) >> 24;
+ const minor = (version & 16711680) >> 16;
+ const patch = version & 65535;
+ const versionNumber = version;
+ CubismLogInfo(`Live2D Cubism Core version: {0}.{1}.{2} ({3})`, ("00" + major).slice(-2), ("00" + minor).slice(-2), ("0000" + patch).slice(-4), versionNumber);
+ }
+ CubismLogInfo("CubismFramework.startUp() is complete.");
+ return s_isStarted;
+ }
+ static cleanUp() {
+ s_isStarted = false;
+ s_isInitialized = false;
+ s_option = void 0;
+ }
+ static initialize(memorySize = 0) {
+ if (!s_isStarted) {
+ CubismLogWarning("CubismFramework is not started.");
+ return;
+ }
+ if (s_isInitialized) {
+ CubismLogWarning("CubismFramework.initialize() skipped, already initialized.");
+ return;
+ }
+ Live2DCubismCore.Memory.initializeAmountOfMemory(memorySize);
+ s_isInitialized = true;
+ CubismLogInfo("CubismFramework.initialize() is complete.");
+ }
+ static dispose() {
+ if (!s_isStarted) {
+ CubismLogWarning("CubismFramework is not started.");
+ return;
+ }
+ if (!s_isInitialized) {
+ CubismLogWarning("CubismFramework.dispose() skipped, not initialized.");
+ return;
+ }
+ CubismRenderer.staticRelease();
+ s_isInitialized = false;
+ CubismLogInfo("CubismFramework.dispose() is complete.");
+ }
+ static isStarted() {
+ return s_isStarted;
+ }
+ static isInitialized() {
+ return s_isInitialized;
+ }
+ static coreLogFunction(message) {
+ if (!Live2DCubismCore.Logging.csmGetLogFunction()) {
+ return;
+ }
+ Live2DCubismCore.Logging.csmGetLogFunction()(message);
+ }
+ static getLoggingLevel() {
+ if (s_option != null) {
+ return s_option.loggingLevel;
+ }
+ return LogLevel.LogLevel_Off;
+ }
+ constructor() {
+ }
+ }
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
+ LogLevel2[LogLevel2["LogLevel_Verbose"] = 0] = "LogLevel_Verbose";
+ LogLevel2[LogLevel2["LogLevel_Debug"] = 1] = "LogLevel_Debug";
+ LogLevel2[LogLevel2["LogLevel_Info"] = 2] = "LogLevel_Info";
+ LogLevel2[LogLevel2["LogLevel_Warning"] = 3] = "LogLevel_Warning";
+ LogLevel2[LogLevel2["LogLevel_Error"] = 4] = "LogLevel_Error";
+ LogLevel2[LogLevel2["LogLevel_Off"] = 5] = "LogLevel_Off";
+ return LogLevel2;
+ })(LogLevel || {});
+ const CSM_ASSERT = () => {
+ };
+ function CubismLogVerbose(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Verbose, "[CSM][V]" + fmt + "\n", args);
+ }
+ function CubismLogDebug(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Debug, "[CSM][D]" + fmt + "\n", args);
+ }
+ function CubismLogInfo(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Info, "[CSM][I]" + fmt + "\n", args);
+ }
+ function CubismLogWarning(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Warning, "[CSM][W]" + fmt + "\n", args);
+ }
+ function CubismLogError(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Error, "[CSM][E]" + fmt + "\n", args);
+ }
+ class CubismDebug {
+ static print(logLevel, format, args) {
+ if (logLevel < CubismFramework.getLoggingLevel()) {
+ return;
+ }
+ const logPrint = CubismFramework.coreLogFunction;
+ if (!logPrint)
+ return;
+ const buffer = format.replace(/{(\d+)}/g, (m, k) => {
+ return args[k];
+ });
+ logPrint(buffer);
+ }
+ static dumpBytes(logLevel, data, length) {
+ for (let i = 0; i < length; i++) {
+ if (i % 16 == 0 && i > 0)
+ this.print(logLevel, "\n");
+ else if (i % 8 == 0 && i > 0)
+ this.print(logLevel, " ");
+ this.print(logLevel, "{0} ", [data[i] & 255]);
+ }
+ this.print(logLevel, "\n");
+ }
+ constructor() {
+ }
+ }
+ class DrawableColorData {
+ constructor(isOverwritten = false, color = new CubismTextureColor()) {
+ this.isOverwritten = isOverwritten;
+ this.Color = color;
+ }
+ }
+ class PartColorData {
+ constructor(isOverwritten = false, color = new CubismTextureColor()) {
+ this.isOverwritten = isOverwritten;
+ this.Color = color;
+ }
+ }
+ class DrawableCullingData {
+ constructor(isOverwritten = false, isCulling = false) {
+ this.isOverwritten = isOverwritten;
+ this.isCulling = isCulling;
+ }
+ }
+ class CubismModel {
+ update() {
+ this._model.update();
+ this._model.drawables.resetDynamicFlags();
+ }
+ getPixelsPerUnit() {
+ if (this._model == null) {
+ return 0;
+ }
+ return this._model.canvasinfo.PixelsPerUnit;
+ }
+ getCanvasWidth() {
+ if (this._model == null) {
+ return 0;
+ }
+ return this._model.canvasinfo.CanvasWidth / this._model.canvasinfo.PixelsPerUnit;
+ }
+ getCanvasHeight() {
+ if (this._model == null) {
+ return 0;
+ }
+ return this._model.canvasinfo.CanvasHeight / this._model.canvasinfo.PixelsPerUnit;
+ }
+ saveParameters() {
+ const parameterCount = this._model.parameters.count;
+ const savedParameterCount = this._savedParameters.length;
+ for (let i = 0; i < parameterCount; ++i) {
+ if (i < savedParameterCount) {
+ this._savedParameters[i] = this._parameterValues[i];
+ } else {
+ this._savedParameters.push(this._parameterValues[i]);
+ }
+ }
+ }
+ getMultiplyColor(index) {
+ if (this.getOverwriteFlagForModelMultiplyColors() || this.getOverwriteFlagForDrawableMultiplyColors(index)) {
+ return this._userMultiplyColors[index].Color;
+ }
+ const color = this.getDrawableMultiplyColor(index);
+ return color;
+ }
+ getScreenColor(index) {
+ if (this.getOverwriteFlagForModelScreenColors() || this.getOverwriteFlagForDrawableScreenColors(index)) {
+ return this._userScreenColors[index].Color;
+ }
+ const color = this.getDrawableScreenColor(index);
+ return color;
+ }
+ setMultiplyColorByTextureColor(index, color) {
+ this.setMultiplyColorByRGBA(index, color.R, color.G, color.B, color.A);
+ }
+ setMultiplyColorByRGBA(index, r, g, b, a = 1) {
+ this._userMultiplyColors[index].Color.R = r;
+ this._userMultiplyColors[index].Color.G = g;
+ this._userMultiplyColors[index].Color.B = b;
+ this._userMultiplyColors[index].Color.A = a;
+ }
+ setScreenColorByTextureColor(index, color) {
+ this.setScreenColorByRGBA(index, color.R, color.G, color.B, color.A);
+ }
+ setScreenColorByRGBA(index, r, g, b, a = 1) {
+ this._userScreenColors[index].Color.R = r;
+ this._userScreenColors[index].Color.G = g;
+ this._userScreenColors[index].Color.B = b;
+ this._userScreenColors[index].Color.A = a;
+ }
+ getPartMultiplyColor(partIndex) {
+ return this._userPartMultiplyColors[partIndex].Color;
+ }
+ getPartScreenColor(partIndex) {
+ return this._userPartScreenColors[partIndex].Color;
+ }
+ setPartColor(partIndex, r, g, b, a, partColors, drawableColors) {
+ partColors[partIndex].Color.R = r;
+ partColors[partIndex].Color.G = g;
+ partColors[partIndex].Color.B = b;
+ partColors[partIndex].Color.A = a;
+ if (partColors[partIndex].isOverwritten) {
+ for (let i = 0; i < this._partChildDrawables[partIndex].length; ++i) {
+ const drawableIndex = this._partChildDrawables[partIndex][i];
+ drawableColors[drawableIndex].Color.R = r;
+ drawableColors[drawableIndex].Color.G = g;
+ drawableColors[drawableIndex].Color.B = b;
+ drawableColors[drawableIndex].Color.A = a;
+ }
+ }
+ }
+ setPartMultiplyColorByTextureColor(partIndex, color) {
+ this.setPartMultiplyColorByRGBA(partIndex, color.R, color.G, color.B, color.A);
+ }
+ setPartMultiplyColorByRGBA(partIndex, r, g, b, a) {
+ this.setPartColor(partIndex, r, g, b, a, this._userPartMultiplyColors, this._userMultiplyColors);
+ }
+ setPartScreenColorByTextureColor(partIndex, color) {
+ this.setPartScreenColorByRGBA(partIndex, color.R, color.G, color.B, color.A);
+ }
+ setPartScreenColorByRGBA(partIndex, r, g, b, a) {
+ this.setPartColor(partIndex, r, g, b, a, this._userPartScreenColors, this._userScreenColors);
+ }
+ getOverwriteFlagForModelMultiplyColors() {
+ return this._isOverwrittenModelMultiplyColors;
+ }
+ getOverwriteFlagForModelScreenColors() {
+ return this._isOverwrittenModelScreenColors;
+ }
+ setOverwriteFlagForModelMultiplyColors(value) {
+ this._isOverwrittenModelMultiplyColors = value;
+ }
+ setOverwriteFlagForModelScreenColors(value) {
+ this._isOverwrittenModelScreenColors = value;
+ }
+ getOverwriteFlagForDrawableMultiplyColors(drawableindex) {
+ return this._userMultiplyColors[drawableindex].isOverwritten;
+ }
+ getOverwriteFlagForDrawableScreenColors(drawableindex) {
+ return this._userScreenColors[drawableindex].isOverwritten;
+ }
+ setOverwriteFlagForDrawableMultiplyColors(drawableindex, value) {
+ this._userMultiplyColors[drawableindex].isOverwritten = value;
+ }
+ setOverwriteFlagForDrawableScreenColors(drawableindex, value) {
+ this._userScreenColors[drawableindex].isOverwritten = value;
+ }
+ getOverwriteColorForPartMultiplyColors(partIndex) {
+ return this._userPartMultiplyColors[partIndex].isOverwritten;
+ }
+ getOverwriteColorForPartScreenColors(partIndex) {
+ return this._userPartScreenColors[partIndex].isOverwritten;
+ }
+ setOverwriteColorForPartColors(partIndex, value, partColors, drawableColors) {
+ partColors[partIndex].isOverwritten = value;
+ for (let i = 0; i < this._partChildDrawables[partIndex].length; ++i) {
+ const drawableIndex = this._partChildDrawables[partIndex][i];
+ drawableColors[drawableIndex].isOverwritten = value;
+ if (value) {
+ drawableColors[drawableIndex].Color.R = partColors[partIndex].Color.R;
+ drawableColors[drawableIndex].Color.G = partColors[partIndex].Color.G;
+ drawableColors[drawableIndex].Color.B = partColors[partIndex].Color.B;
+ drawableColors[drawableIndex].Color.A = partColors[partIndex].Color.A;
+ }
+ }
+ }
+ setOverwriteColorForPartMultiplyColors(partIndex, value) {
+ this._userPartMultiplyColors[partIndex].isOverwritten = value;
+ this.setOverwriteColorForPartColors(partIndex, value, this._userPartMultiplyColors, this._userMultiplyColors);
+ }
+ setOverwriteColorForPartScreenColors(partIndex, value) {
+ this._userPartScreenColors[partIndex].isOverwritten = value;
+ this.setOverwriteColorForPartColors(partIndex, value, this._userPartScreenColors, this._userScreenColors);
+ }
+ getDrawableCulling(drawableIndex) {
+ if (this.getOverwriteFlagForModelCullings() || this.getOverwriteFlagForDrawableCullings(drawableIndex)) {
+ return this._userCullings[drawableIndex].isCulling;
+ }
+ const constantFlags = this._model.drawables.constantFlags;
+ return !Live2DCubismCore.Utils.hasIsDoubleSidedBit(constantFlags[drawableIndex]);
+ }
+ setDrawableCulling(drawableIndex, isCulling) {
+ this._userCullings[drawableIndex].isCulling = isCulling;
+ }
+ getOverwriteFlagForModelCullings() {
+ return this._isOverwrittenCullings;
+ }
+ setOverwriteFlagForModelCullings(isOverwrittenCullings) {
+ this._isOverwrittenCullings = isOverwrittenCullings;
+ }
+ getOverwriteFlagForDrawableCullings(drawableIndex) {
+ return this._userCullings[drawableIndex].isOverwritten;
+ }
+ setOverwriteFlagForDrawableCullings(drawableIndex, isOverwrittenCullings) {
+ this._userCullings[drawableIndex].isOverwritten = isOverwrittenCullings;
+ }
+ getModelOapcity() {
+ return this._modelOpacity;
+ }
+ setModelOapcity(value) {
+ this._modelOpacity = value;
+ }
+ getModel() {
+ return this._model;
+ }
+ getPartIndex(partId) {
+ let partIndex;
+ const partCount = this._model.parts.count;
+ for (partIndex = 0; partIndex < partCount; ++partIndex) {
+ if (partId == this._partIds[partIndex]) {
+ return partIndex;
+ }
+ }
+ if (partId in this._notExistPartId) {
+ return this._notExistPartId[partId];
+ }
+ partIndex = partCount + this._notExistPartId.length;
+ this._notExistPartId[partId] = partIndex;
+ this._notExistPartOpacities[partIndex] = 0;
+ return partIndex;
+ }
+ getPartId(partIndex) {
+ return this._model.parts.ids[partIndex];
+ }
+ getPartCount() {
+ return this._model.parts.count;
+ }
+ setPartOpacityByIndex(partIndex, opacity) {
+ if (partIndex in this._notExistPartOpacities) {
+ this._notExistPartOpacities[partIndex] = opacity;
+ return;
+ }
+ CSM_ASSERT(0 <= partIndex && partIndex < this.getPartCount());
+ this._partOpacities[partIndex] = opacity;
+ }
+ setPartOpacityById(partId, opacity) {
+ const index = this.getPartIndex(partId);
+ if (index < 0) {
+ return;
+ }
+ this.setPartOpacityByIndex(index, opacity);
+ }
+ getPartOpacityByIndex(partIndex) {
+ if (partIndex in this._notExistPartOpacities) {
+ return this._notExistPartOpacities[partIndex];
+ }
+ CSM_ASSERT(0 <= partIndex && partIndex < this.getPartCount());
+ return this._partOpacities[partIndex];
+ }
+ getPartOpacityById(partId) {
+ const index = this.getPartIndex(partId);
+ if (index < 0) {
+ return 0;
+ }
+ return this.getPartOpacityByIndex(index);
+ }
+ getParameterIndex(parameterId) {
+ let parameterIndex;
+ const idCount = this._model.parameters.count;
+ for (parameterIndex = 0; parameterIndex < idCount; ++parameterIndex) {
+ if (parameterId != this._parameterIds[parameterIndex]) {
+ continue;
+ }
+ return parameterIndex;
+ }
+ if (parameterId in this._notExistParameterId) {
+ return this._notExistParameterId[parameterId];
+ }
+ parameterIndex = this._model.parameters.count + Object.keys(this._notExistParameterId).length;
+ this._notExistParameterId[parameterId] = parameterIndex;
+ this._notExistParameterValues[parameterIndex] = 0;
+ return parameterIndex;
+ }
+ getParameterCount() {
+ return this._model.parameters.count;
+ }
+ getParameterType(parameterIndex) {
+ return this._model.parameters.types[parameterIndex];
+ }
+ getParameterMaximumValue(parameterIndex) {
+ return this._model.parameters.maximumValues[parameterIndex];
+ }
+ getParameterMinimumValue(parameterIndex) {
+ return this._model.parameters.minimumValues[parameterIndex];
+ }
+ getParameterDefaultValue(parameterIndex) {
+ return this._model.parameters.defaultValues[parameterIndex];
+ }
+ getParameterValueByIndex(parameterIndex) {
+ if (parameterIndex in this._notExistParameterValues) {
+ return this._notExistParameterValues[parameterIndex];
+ }
+ CSM_ASSERT(0 <= parameterIndex && parameterIndex < this.getParameterCount());
+ return this._parameterValues[parameterIndex];
+ }
+ getParameterValueById(parameterId) {
+ const parameterIndex = this.getParameterIndex(parameterId);
+ return this.getParameterValueByIndex(parameterIndex);
+ }
+ setParameterValueByIndex(parameterIndex, value, weight = 1) {
+ if (parameterIndex in this._notExistParameterValues) {
+ this._notExistParameterValues[parameterIndex] = weight == 1 ? value : this._notExistParameterValues[parameterIndex] * (1 - weight) + value * weight;
+ return;
+ }
+ CSM_ASSERT(0 <= parameterIndex && parameterIndex < this.getParameterCount());
+ if (this._model.parameters.maximumValues[parameterIndex] < value) {
+ value = this._model.parameters.maximumValues[parameterIndex];
+ }
+ if (this._model.parameters.minimumValues[parameterIndex] > value) {
+ value = this._model.parameters.minimumValues[parameterIndex];
+ }
+ this._parameterValues[parameterIndex] = weight == 1 ? value : this._parameterValues[parameterIndex] = this._parameterValues[parameterIndex] * (1 - weight) + value * weight;
+ }
+ setParameterValueById(parameterId, value, weight = 1) {
+ const index = this.getParameterIndex(parameterId);
+ this.setParameterValueByIndex(index, value, weight);
+ }
+ addParameterValueByIndex(parameterIndex, value, weight = 1) {
+ this.setParameterValueByIndex(parameterIndex, this.getParameterValueByIndex(parameterIndex) + value * weight);
+ }
+ addParameterValueById(parameterId, value, weight = 1) {
+ const index = this.getParameterIndex(parameterId);
+ this.addParameterValueByIndex(index, value, weight);
+ }
+ multiplyParameterValueById(parameterId, value, weight = 1) {
+ const index = this.getParameterIndex(parameterId);
+ this.multiplyParameterValueByIndex(index, value, weight);
+ }
+ multiplyParameterValueByIndex(parameterIndex, value, weight = 1) {
+ this.setParameterValueByIndex(parameterIndex, this.getParameterValueByIndex(parameterIndex) * (1 + (value - 1) * weight));
+ }
+ getDrawableIds() {
+ return this._drawableIds.slice();
+ }
+ getDrawableIndex(drawableId) {
+ const drawableCount = this._model.drawables.count;
+ for (let drawableIndex = 0; drawableIndex < drawableCount; ++drawableIndex) {
+ if (this._drawableIds[drawableIndex] == drawableId) {
+ return drawableIndex;
+ }
+ }
+ return -1;
+ }
+ getDrawableCount() {
+ return this._model.drawables.count;
+ }
+ getDrawableId(drawableIndex) {
+ return this._model.drawables.ids[drawableIndex];
+ }
+ getDrawableRenderOrders() {
+ return this._model.drawables.renderOrders;
+ }
+ getDrawableTextureIndices(drawableIndex) {
+ return this.getDrawableTextureIndex(drawableIndex);
+ }
+ getDrawableTextureIndex(drawableIndex) {
+ const textureIndices = this._model.drawables.textureIndices;
+ return textureIndices[drawableIndex];
+ }
+ getDrawableDynamicFlagVertexPositionsDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasVertexPositionsDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableVertexIndexCount(drawableIndex) {
+ return this._model.drawables.indexCounts[drawableIndex];
+ }
+ getDrawableVertexCount(drawableIndex) {
+ return this._model.drawables.vertexCounts[drawableIndex];
+ }
+ getDrawableVertices(drawableIndex) {
+ return this.getDrawableVertexPositions(drawableIndex);
+ }
+ getDrawableVertexIndices(drawableIndex) {
+ return this._model.drawables.indices[drawableIndex];
+ }
+ getDrawableVertexPositions(drawableIndex) {
+ return this._model.drawables.vertexPositions[drawableIndex];
+ }
+ getDrawableVertexUvs(drawableIndex) {
+ return this._model.drawables.vertexUvs[drawableIndex];
+ }
+ getDrawableOpacity(drawableIndex) {
+ return this._model.drawables.opacities[drawableIndex];
+ }
+ getDrawableMultiplyColor(drawableIndex) {
+ const multiplyColors = this._model.drawables.multiplyColors;
+ const index = drawableIndex * 4;
+ const multiplyColor = new CubismTextureColor();
+ multiplyColor.R = multiplyColors[index];
+ multiplyColor.G = multiplyColors[index + 1];
+ multiplyColor.B = multiplyColors[index + 2];
+ multiplyColor.A = multiplyColors[index + 3];
+ return multiplyColor;
+ }
+ getDrawableScreenColor(drawableIndex) {
+ const screenColors = this._model.drawables.screenColors;
+ const index = drawableIndex * 4;
+ const screenColor = new CubismTextureColor();
+ screenColor.R = screenColors[index];
+ screenColor.G = screenColors[index + 1];
+ screenColor.B = screenColors[index + 2];
+ screenColor.A = screenColors[index + 3];
+ return screenColor;
+ }
+ getDrawableParentPartIndex(drawableIndex) {
+ return this._model.drawables.parentPartIndices[drawableIndex];
+ }
+ getDrawableBlendMode(drawableIndex) {
+ const constantFlags = this._model.drawables.constantFlags;
+ return Live2DCubismCore.Utils.hasBlendAdditiveBit(constantFlags[drawableIndex]) ? CubismBlendMode.CubismBlendMode_Additive : Live2DCubismCore.Utils.hasBlendMultiplicativeBit(constantFlags[drawableIndex]) ? CubismBlendMode.CubismBlendMode_Multiplicative : CubismBlendMode.CubismBlendMode_Normal;
+ }
+ getDrawableInvertedMaskBit(drawableIndex) {
+ const constantFlags = this._model.drawables.constantFlags;
+ return Live2DCubismCore.Utils.hasIsInvertedMaskBit(constantFlags[drawableIndex]);
+ }
+ getDrawableMasks() {
+ return this._model.drawables.masks;
+ }
+ getDrawableMaskCounts() {
+ return this._model.drawables.maskCounts;
+ }
+ isUsingMasking() {
+ for (let d = 0; d < this._model.drawables.count; ++d) {
+ if (this._model.drawables.maskCounts[d] <= 0) {
+ continue;
+ }
+ return true;
+ }
+ return false;
+ }
+ getDrawableDynamicFlagIsVisible(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasIsVisibleBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagVisibilityDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasVisibilityDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagOpacityDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasOpacityDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagRenderOrderDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasRenderOrderDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagBlendColorDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasBlendColorDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ loadParameters() {
+ let parameterCount = this._model.parameters.count;
+ const savedParameterCount = this._savedParameters.length;
+ if (parameterCount > savedParameterCount) {
+ parameterCount = savedParameterCount;
+ }
+ for (let i = 0; i < parameterCount; ++i) {
+ this._parameterValues[i] = this._savedParameters[i];
+ }
+ }
+ initialize() {
+ this._parameterValues = this._model.parameters.values;
+ this._partOpacities = this._model.parts.opacities;
+ this._parameterMaximumValues = this._model.parameters.maximumValues;
+ this._parameterMinimumValues = this._model.parameters.minimumValues;
+ {
+ const parameterIds = this._model.parameters.ids;
+ const parameterCount = this._model.parameters.count;
+ for (let i = 0; i < parameterCount; ++i) {
+ this._parameterIds.push(parameterIds[i]);
+ }
+ }
+ const partCount = this._model.parts.count;
+ {
+ const partIds = this._model.parts.ids;
+ for (let i = 0; i < partCount; ++i) {
+ this._partIds.push(partIds[i]);
+ }
+ }
+ {
+ const drawableIds = this._model.drawables.ids;
+ const drawableCount = this._model.drawables.count;
+ const userCulling = new DrawableCullingData(false, false);
+ {
+ for (let i = 0; i < partCount; ++i) {
+ const multiplyColor = new CubismTextureColor(1, 1, 1, 1);
+ const screenColor = new CubismTextureColor(0, 0, 0, 1);
+ const userMultiplyColor = new PartColorData(false, multiplyColor);
+ const userScreenColor = new PartColorData(false, screenColor);
+ this._userPartMultiplyColors.push(userMultiplyColor);
+ this._userPartScreenColors.push(userScreenColor);
+ this._partChildDrawables.push([]);
+ }
+ }
+ {
+ for (let i = 0; i < drawableCount; ++i) {
+ const multiplyColor = new CubismTextureColor(1, 1, 1, 1);
+ const screenColor = new CubismTextureColor(0, 0, 0, 1);
+ const userMultiplyColor = new DrawableColorData(false, multiplyColor);
+ const userScreenColor = new DrawableColorData(false, screenColor);
+ this._drawableIds.push(drawableIds[i]);
+ this._userMultiplyColors.push(userMultiplyColor);
+ this._userScreenColors.push(userScreenColor);
+ this._userCullings.push(userCulling);
+ const parentIndex = this.getDrawableParentPartIndex(i);
+ if (parentIndex >= 0) {
+ this._partChildDrawables[parentIndex].push(i);
+ }
+ }
+ }
+ }
+ }
+ constructor(model) {
+ this._model = model;
+ this._savedParameters = [];
+ this._parameterIds = [];
+ this._drawableIds = [];
+ this._partIds = [];
+ this._isOverwrittenModelMultiplyColors = false;
+ this._isOverwrittenModelScreenColors = false;
+ this._isOverwrittenCullings = false;
+ this._modelOpacity = 1;
+ this._userMultiplyColors = [];
+ this._userScreenColors = [];
+ this._userCullings = [];
+ this._userPartMultiplyColors = [];
+ this._userPartScreenColors = [];
+ this._partChildDrawables = [];
+ this._notExistPartId = {};
+ this._notExistParameterId = {};
+ this._notExistParameterValues = {};
+ this._notExistPartOpacities = {};
+ this.initialize();
+ }
+ release() {
+ this._model.release();
+ this._model = void 0;
+ }
+ }
+ class CubismMoc {
+ static create(mocBytes, shouldCheckMocConsistency) {
+ if (shouldCheckMocConsistency) {
+ const consistency = this.hasMocConsistency(mocBytes);
+ if (!consistency) {
+ throw new Error(`Inconsistent MOC3.`);
+ }
+ }
+ const moc = Live2DCubismCore.Moc.fromArrayBuffer(mocBytes);
+ if (moc) {
+ const cubismMoc = new CubismMoc(moc);
+ cubismMoc._mocVersion = Live2DCubismCore.Version.csmGetMocVersion(moc, mocBytes);
+ return cubismMoc;
+ }
+ throw new Error("Failed to CubismMoc.create().");
+ }
+ createModel() {
+ let cubismModel;
+ const model = Live2DCubismCore.Model.fromMoc(this._moc);
+ if (model) {
+ cubismModel = new CubismModel(model);
+ ++this._modelCount;
+ return cubismModel;
+ }
+ throw new Error("Unknown error");
+ }
+ deleteModel(model) {
+ if (model != null) {
+ --this._modelCount;
+ }
+ }
+ constructor(moc) {
+ this._moc = moc;
+ this._modelCount = 0;
+ this._mocVersion = 0;
+ }
+ release() {
+ this._moc._release();
+ this._moc = void 0;
+ }
+ getLatestMocVersion() {
+ return Live2DCubismCore.Version.csmGetLatestMocVersion();
+ }
+ getMocVersion() {
+ return this._mocVersion;
+ }
+ static hasMocConsistency(mocBytes) {
+ const isConsistent = Live2DCubismCore.Moc.prototype.hasMocConsistency(mocBytes);
+ return isConsistent === 1 ? true : false;
+ }
+ }
+ class CubismModelUserDataJson {
+ constructor(json, size) {
+ this._json = json;
+ }
+ release() {
+ this._json = void 0;
+ }
+ getUserDataCount() {
+ return this._json.Meta.UserDataCount;
+ }
+ getTotalUserDataSize() {
+ return this._json.Meta.TotalUserDataSize;
+ }
+ getUserDataTargetType(i) {
+ return this._json.UserData[i].Target;
+ }
+ getUserDataId(i) {
+ return this._json.UserData[i].Id;
+ }
+ getUserDataValue(i) {
+ return this._json.UserData[i].Value;
+ }
+ }
+ const ArtMesh = "ArtMesh";
+ class CubismModelUserData {
+ static create(json, size) {
+ const ret = new CubismModelUserData();
+ ret.parseUserData(json, size);
+ return ret;
+ }
+ getArtMeshUserDatas() {
+ return this._artMeshUserDataNode;
+ }
+ parseUserData(data, size) {
+ const json = new CubismModelUserDataJson(data, size);
+ const typeOfArtMesh = ArtMesh;
+ const nodeCount = json.getUserDataCount();
+ for (let i = 0; i < nodeCount; i++) {
+ const addNode = {
+ targetId: json.getUserDataId(i),
+ targetType: json.getUserDataTargetType(i),
+ value: json.getUserDataValue(i)
+ };
+ this._userDataNodes.push(addNode);
+ if (addNode.targetType == typeOfArtMesh) {
+ this._artMeshUserDataNode.push(addNode);
+ }
+ }
+ json.release();
+ }
+ constructor() {
+ this._userDataNodes = [];
+ this._artMeshUserDataNode = [];
+ }
+ release() {
+ this._userDataNodes = null;
+ }
+ }
+ class ACubismMotion {
+ constructor() {
+ this._fadeInSeconds = -1;
+ this._fadeOutSeconds = -1;
+ this._weight = 1;
+ this._offsetSeconds = 0;
+ this._firedEventValues = [];
+ }
+ release() {
+ this._weight = 0;
+ }
+ updateParameters(model, motionQueueEntry, userTimeSeconds) {
+ if (!motionQueueEntry.isAvailable() || motionQueueEntry.isFinished()) {
+ return;
+ }
+ if (!motionQueueEntry.isStarted()) {
+ motionQueueEntry.setIsStarted(true);
+ motionQueueEntry.setStartTime(userTimeSeconds - this._offsetSeconds);
+ motionQueueEntry.setFadeInStartTime(userTimeSeconds);
+ const duration = this.getDuration();
+ if (motionQueueEntry.getEndTime() < 0) {
+ motionQueueEntry.setEndTime(duration <= 0 ? -1 : motionQueueEntry.getStartTime() + duration);
+ }
+ }
+ let fadeWeight = this._weight;
+ const fadeIn = this._fadeInSeconds == 0 ? 1 : CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / this._fadeInSeconds);
+ const fadeOut = this._fadeOutSeconds == 0 || motionQueueEntry.getEndTime() < 0 ? 1 : CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / this._fadeOutSeconds);
+ fadeWeight = fadeWeight * fadeIn * fadeOut;
+ motionQueueEntry.setState(userTimeSeconds, fadeWeight);
+ this.doUpdateParameters(model, userTimeSeconds, fadeWeight, motionQueueEntry);
+ if (motionQueueEntry.getEndTime() > 0 && motionQueueEntry.getEndTime() < userTimeSeconds) {
+ motionQueueEntry.setIsFinished(true);
+ }
+ }
+ setFadeInTime(fadeInSeconds) {
+ this._fadeInSeconds = fadeInSeconds;
+ }
+ setFadeOutTime(fadeOutSeconds) {
+ this._fadeOutSeconds = fadeOutSeconds;
+ }
+ getFadeOutTime() {
+ return this._fadeOutSeconds;
+ }
+ getFadeInTime() {
+ return this._fadeInSeconds;
+ }
+ setWeight(weight) {
+ this._weight = weight;
+ }
+ getWeight() {
+ return this._weight;
+ }
+ getDuration() {
+ return -1;
+ }
+ getLoopDuration() {
+ return -1;
+ }
+ setOffsetTime(offsetSeconds) {
+ this._offsetSeconds = offsetSeconds;
+ }
+ getFiredEvent(beforeCheckTimeSeconds, motionTimeSeconds) {
+ return this._firedEventValues;
+ }
+ setFinishedMotionHandler(onFinishedMotionHandler) {
+ this._onFinishedMotion = onFinishedMotionHandler;
+ }
+ getFinishedMotionHandler() {
+ return this._onFinishedMotion;
+ }
+ isExistModelOpacity() {
+ return false;
+ }
+ getModelOpacityIndex() {
+ return -1;
+ }
+ getModelOpacityId(index) {
+ return void 0;
+ }
+ getModelOpacityValue() {
+ return 1;
+ }
+ }
+ const DefaultFadeTime = 1;
+ class CubismExpressionMotion extends ACubismMotion {
+ constructor() {
+ super();
+ this._parameters = [];
+ }
+ static create(json) {
+ const expression = new CubismExpressionMotion();
+ expression.parse(json);
+ return expression;
+ }
+ doUpdateParameters(model, userTimeSeconds, weight, motionQueueEntry) {
+ for (let i = 0; i < this._parameters.length; ++i) {
+ const parameter = this._parameters[i];
+ switch (parameter.blendType) {
+ case ExpressionBlendType.ExpressionBlendType_Add: {
+ model.addParameterValueById(parameter.parameterId, parameter.value, weight);
+ break;
+ }
+ case ExpressionBlendType.ExpressionBlendType_Multiply: {
+ model.multiplyParameterValueById(parameter.parameterId, parameter.value, weight);
+ break;
+ }
+ case ExpressionBlendType.ExpressionBlendType_Overwrite: {
+ model.setParameterValueById(parameter.parameterId, parameter.value, weight);
+ break;
+ }
+ }
+ }
+ }
+ parse(json) {
+ this.setFadeInTime(json.FadeInTime != void 0 ? json.FadeInTime : DefaultFadeTime);
+ this.setFadeOutTime(json.FadeOutTime != void 0 ? json.FadeOutTime : DefaultFadeTime);
+ const parameterCount = (json.Parameters || []).length;
+ for (let i = 0; i < parameterCount; ++i) {
+ const param = json.Parameters[i];
+ const parameterId = param.Id;
+ const value = param.Value;
+ let blendType;
+ if (!param.Blend || param.Blend === "Add") {
+ blendType = ExpressionBlendType.ExpressionBlendType_Add;
+ } else if (param.Blend === "Multiply") {
+ blendType = ExpressionBlendType.ExpressionBlendType_Multiply;
+ } else if (param.Blend === "Overwrite") {
+ blendType = ExpressionBlendType.ExpressionBlendType_Overwrite;
+ } else {
+ blendType = ExpressionBlendType.ExpressionBlendType_Add;
+ }
+ const item = {
+ parameterId,
+ blendType,
+ value
+ };
+ this._parameters.push(item);
+ }
+ }
+ }
+ var ExpressionBlendType = /* @__PURE__ */ ((ExpressionBlendType2) => {
+ ExpressionBlendType2[ExpressionBlendType2["ExpressionBlendType_Add"] = 0] = "ExpressionBlendType_Add";
+ ExpressionBlendType2[ExpressionBlendType2["ExpressionBlendType_Multiply"] = 1] = "ExpressionBlendType_Multiply";
+ ExpressionBlendType2[ExpressionBlendType2["ExpressionBlendType_Overwrite"] = 2] = "ExpressionBlendType_Overwrite";
+ return ExpressionBlendType2;
+ })(ExpressionBlendType || {});
+ exports2.CubismConfig = void 0;
+ ((CubismConfig2) => {
+ CubismConfig2.supportMoreMaskDivisions = true;
+ CubismConfig2.setOpacityFromMotion = false;
+ })(exports2.CubismConfig || (exports2.CubismConfig = {}));
+ var CubismMotionCurveTarget = /* @__PURE__ */ ((CubismMotionCurveTarget2) => {
+ CubismMotionCurveTarget2[CubismMotionCurveTarget2["CubismMotionCurveTarget_Model"] = 0] = "CubismMotionCurveTarget_Model";
+ CubismMotionCurveTarget2[CubismMotionCurveTarget2["CubismMotionCurveTarget_Parameter"] = 1] = "CubismMotionCurveTarget_Parameter";
+ CubismMotionCurveTarget2[CubismMotionCurveTarget2["CubismMotionCurveTarget_PartOpacity"] = 2] = "CubismMotionCurveTarget_PartOpacity";
+ return CubismMotionCurveTarget2;
+ })(CubismMotionCurveTarget || {});
+ var CubismMotionSegmentType = /* @__PURE__ */ ((CubismMotionSegmentType2) => {
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_Linear"] = 0] = "CubismMotionSegmentType_Linear";
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_Bezier"] = 1] = "CubismMotionSegmentType_Bezier";
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_Stepped"] = 2] = "CubismMotionSegmentType_Stepped";
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_InverseStepped"] = 3] = "CubismMotionSegmentType_InverseStepped";
+ return CubismMotionSegmentType2;
+ })(CubismMotionSegmentType || {});
+ class CubismMotionPoint {
+ constructor(time = 0, value = 0) {
+ this.time = time;
+ this.value = value;
+ }
+ }
+ class CubismMotionSegment {
+ constructor() {
+ this.basePointIndex = 0;
+ this.segmentType = 0;
+ }
+ }
+ class CubismMotionCurve {
+ constructor() {
+ this.id = "";
+ this.type = 0;
+ this.segmentCount = 0;
+ this.baseSegmentIndex = 0;
+ this.fadeInTime = 0;
+ this.fadeOutTime = 0;
+ }
+ }
+ class CubismMotionEvent {
+ constructor() {
+ this.fireTime = 0;
+ this.value = "";
+ }
+ }
+ class CubismMotionData {
+ constructor() {
+ this.duration = 0;
+ this.loop = false;
+ this.curveCount = 0;
+ this.eventCount = 0;
+ this.fps = 0;
+ this.curves = [];
+ this.segments = [];
+ this.points = [];
+ this.events = [];
+ }
+ }
+ class CubismMotionJson {
+ constructor(json) {
+ this._json = json;
+ }
+ release() {
+ this._json = void 0;
+ }
+ getMotionDuration() {
+ return this._json.Meta.Duration;
+ }
+ isMotionLoop() {
+ return this._json.Meta.Loop || false;
+ }
+ getEvaluationOptionFlag(flagType) {
+ if (EvaluationOptionFlag.EvaluationOptionFlag_AreBeziersRistricted == flagType) {
+ return !!this._json.Meta.AreBeziersRestricted;
+ }
+ return false;
+ }
+ getMotionCurveCount() {
+ return this._json.Meta.CurveCount;
+ }
+ getMotionFps() {
+ return this._json.Meta.Fps;
+ }
+ getMotionTotalSegmentCount() {
+ return this._json.Meta.TotalSegmentCount;
+ }
+ getMotionTotalPointCount() {
+ return this._json.Meta.TotalPointCount;
+ }
+ getMotionFadeInTime() {
+ return this._json.Meta.FadeInTime;
+ }
+ getMotionFadeOutTime() {
+ return this._json.Meta.FadeOutTime;
+ }
+ getMotionCurveTarget(curveIndex) {
+ return this._json.Curves[curveIndex].Target;
+ }
+ getMotionCurveId(curveIndex) {
+ return this._json.Curves[curveIndex].Id;
+ }
+ getMotionCurveFadeInTime(curveIndex) {
+ return this._json.Curves[curveIndex].FadeInTime;
+ }
+ getMotionCurveFadeOutTime(curveIndex) {
+ return this._json.Curves[curveIndex].FadeOutTime;
+ }
+ getMotionCurveSegmentCount(curveIndex) {
+ return this._json.Curves[curveIndex].Segments.length;
+ }
+ getMotionCurveSegment(curveIndex, segmentIndex) {
+ return this._json.Curves[curveIndex].Segments[segmentIndex];
+ }
+ getEventCount() {
+ return this._json.Meta.UserDataCount || 0;
+ }
+ getTotalEventValueSize() {
+ return this._json.Meta.TotalUserDataSize;
+ }
+ getEventTime(userDataIndex) {
+ return this._json.UserData[userDataIndex].Time;
+ }
+ getEventValue(userDataIndex) {
+ return this._json.UserData[userDataIndex].Value;
+ }
+ }
+ var EvaluationOptionFlag = /* @__PURE__ */ ((EvaluationOptionFlag2) => {
+ EvaluationOptionFlag2[EvaluationOptionFlag2["EvaluationOptionFlag_AreBeziersRistricted"] = 0] = "EvaluationOptionFlag_AreBeziersRistricted";
+ return EvaluationOptionFlag2;
+ })(EvaluationOptionFlag || {});
+ const EffectNameEyeBlink = "EyeBlink";
+ const EffectNameLipSync = "LipSync";
+ const TargetNameModel = "Model";
+ const TargetNameParameter = "Parameter";
+ const TargetNamePartOpacity = "PartOpacity";
+ const IdNameOpacity = "Opacity";
+ const UseOldBeziersCurveMotion = false;
+ function lerpPoints(a, b, t) {
+ const result = new CubismMotionPoint();
+ result.time = a.time + (b.time - a.time) * t;
+ result.value = a.value + (b.value - a.value) * t;
+ return result;
+ }
+ function linearEvaluate(points, time) {
+ let t = (time - points[0].time) / (points[1].time - points[0].time);
+ if (t < 0) {
+ t = 0;
+ }
+ return points[0].value + (points[1].value - points[0].value) * t;
+ }
+ function bezierEvaluate(points, time) {
+ let t = (time - points[0].time) / (points[3].time - points[0].time);
+ if (t < 0) {
+ t = 0;
+ }
+ const p01 = lerpPoints(points[0], points[1], t);
+ const p12 = lerpPoints(points[1], points[2], t);
+ const p23 = lerpPoints(points[2], points[3], t);
+ const p012 = lerpPoints(p01, p12, t);
+ const p123 = lerpPoints(p12, p23, t);
+ return lerpPoints(p012, p123, t).value;
+ }
+ function bezierEvaluateCardanoInterpretation(points, time) {
+ const x = time;
+ const x1 = points[0].time;
+ const x2 = points[3].time;
+ const cx1 = points[1].time;
+ const cx2 = points[2].time;
+ const a = x2 - 3 * cx2 + 3 * cx1 - x1;
+ const b = 3 * cx2 - 6 * cx1 + 3 * x1;
+ const c = 3 * cx1 - 3 * x1;
+ const d = x1 - x;
+ const t = CubismMath.cardanoAlgorithmForBezier(a, b, c, d);
+ const p01 = lerpPoints(points[0], points[1], t);
+ const p12 = lerpPoints(points[1], points[2], t);
+ const p23 = lerpPoints(points[2], points[3], t);
+ const p012 = lerpPoints(p01, p12, t);
+ const p123 = lerpPoints(p12, p23, t);
+ return lerpPoints(p012, p123, t).value;
+ }
+ function steppedEvaluate(points, time) {
+ return points[0].value;
+ }
+ function inverseSteppedEvaluate(points, time) {
+ return points[1].value;
+ }
+ function evaluateCurve(motionData, index, time) {
+ const curve = motionData.curves[index];
+ let target = -1;
+ const totalSegmentCount = curve.baseSegmentIndex + curve.segmentCount;
+ let pointPosition = 0;
+ for (let i = curve.baseSegmentIndex; i < totalSegmentCount; ++i) {
+ pointPosition = motionData.segments[i].basePointIndex + (motionData.segments[i].segmentType == CubismMotionSegmentType.CubismMotionSegmentType_Bezier ? 3 : 1);
+ if (motionData.points[pointPosition].time > time) {
+ target = i;
+ break;
+ }
+ }
+ if (target == -1) {
+ return motionData.points[pointPosition].value;
+ }
+ const segment = motionData.segments[target];
+ return segment.evaluate(motionData.points.slice(segment.basePointIndex), time);
+ }
+ class CubismMotion extends ACubismMotion {
+ constructor() {
+ super();
+ this._eyeBlinkParameterIds = [];
+ this._lipSyncParameterIds = [];
+ this._sourceFrameRate = 30;
+ this._loopDurationSeconds = -1;
+ this._isLoop = false;
+ this._isLoopFadeIn = true;
+ this._lastWeight = 0;
+ this._modelOpacity = 1;
+ }
+ static create(json, onFinishedMotionHandler) {
+ const ret = new CubismMotion();
+ ret.parse(json);
+ ret._sourceFrameRate = ret._motionData.fps;
+ ret._loopDurationSeconds = ret._motionData.duration;
+ ret._onFinishedMotion = onFinishedMotionHandler;
+ return ret;
+ }
+ doUpdateParameters(model, userTimeSeconds, fadeWeight, motionQueueEntry) {
+ if (this._modelCurveIdEyeBlink == null) {
+ this._modelCurveIdEyeBlink = EffectNameEyeBlink;
+ }
+ if (this._modelCurveIdLipSync == null) {
+ this._modelCurveIdLipSync = EffectNameLipSync;
+ }
+ if (this._modelCurveIdOpacity == null) {
+ this._modelCurveIdOpacity = IdNameOpacity;
+ }
+ let timeOffsetSeconds = userTimeSeconds - motionQueueEntry.getStartTime();
+ if (timeOffsetSeconds < 0) {
+ timeOffsetSeconds = 0;
+ }
+ let lipSyncValue = Number.MAX_VALUE;
+ let eyeBlinkValue = Number.MAX_VALUE;
+ const MaxTargetSize = 64;
+ let lipSyncFlags = 0;
+ let eyeBlinkFlags = 0;
+ if (this._eyeBlinkParameterIds.length > MaxTargetSize) {
+ CubismLogDebug("too many eye blink targets : {0}", this._eyeBlinkParameterIds.length);
+ }
+ if (this._lipSyncParameterIds.length > MaxTargetSize) {
+ CubismLogDebug("too many lip sync targets : {0}", this._lipSyncParameterIds.length);
+ }
+ const tmpFadeIn = this._fadeInSeconds <= 0 ? 1 : CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / this._fadeInSeconds);
+ const tmpFadeOut = this._fadeOutSeconds <= 0 || motionQueueEntry.getEndTime() < 0 ? 1 : CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / this._fadeOutSeconds);
+ let value;
+ let c, parameterIndex;
+ let time = timeOffsetSeconds;
+ if (this._isLoop) {
+ while (time > this._motionData.duration) {
+ time -= this._motionData.duration;
+ }
+ }
+ const curves = this._motionData.curves;
+ for (c = 0; c < this._motionData.curveCount && curves[c].type == CubismMotionCurveTarget.CubismMotionCurveTarget_Model; ++c) {
+ value = evaluateCurve(this._motionData, c, time);
+ if (curves[c].id == this._modelCurveIdEyeBlink) {
+ eyeBlinkValue = value;
+ } else if (curves[c].id == this._modelCurveIdLipSync) {
+ lipSyncValue = value;
+ } else if (curves[c].id == this._modelCurveIdOpacity) {
+ this._modelOpacity = value;
+ model.setModelOapcity(this.getModelOpacityValue());
+ }
+ }
+ for (; c < this._motionData.curveCount && curves[c].type == CubismMotionCurveTarget.CubismMotionCurveTarget_Parameter; ++c) {
+ parameterIndex = model.getParameterIndex(curves[c].id);
+ if (parameterIndex == -1) {
+ continue;
+ }
+ const sourceValue = model.getParameterValueByIndex(parameterIndex);
+ value = evaluateCurve(this._motionData, c, time);
+ if (eyeBlinkValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._eyeBlinkParameterIds.length && i < MaxTargetSize; ++i) {
+ if (this._eyeBlinkParameterIds[i] == curves[c].id) {
+ value *= eyeBlinkValue;
+ eyeBlinkFlags |= 1 << i;
+ break;
+ }
+ }
+ }
+ if (lipSyncValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._lipSyncParameterIds.length && i < MaxTargetSize; ++i) {
+ if (this._lipSyncParameterIds[i] == curves[c].id) {
+ value += lipSyncValue;
+ lipSyncFlags |= 1 << i;
+ break;
+ }
+ }
+ }
+ let v;
+ if (curves[c].fadeInTime < 0 && curves[c].fadeOutTime < 0) {
+ v = sourceValue + (value - sourceValue) * fadeWeight;
+ } else {
+ let fin;
+ let fout;
+ if (curves[c].fadeInTime < 0) {
+ fin = tmpFadeIn;
+ } else {
+ fin = curves[c].fadeInTime == 0 ? 1 : CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / curves[c].fadeInTime);
+ }
+ if (curves[c].fadeOutTime < 0) {
+ fout = tmpFadeOut;
+ } else {
+ fout = curves[c].fadeOutTime == 0 || motionQueueEntry.getEndTime() < 0 ? 1 : CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / curves[c].fadeOutTime);
+ }
+ const paramWeight = this._weight * fin * fout;
+ v = sourceValue + (value - sourceValue) * paramWeight;
+ }
+ model.setParameterValueByIndex(parameterIndex, v, 1);
+ }
+ {
+ if (eyeBlinkValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._eyeBlinkParameterIds.length && i < MaxTargetSize; ++i) {
+ const sourceValue = model.getParameterValueById(this._eyeBlinkParameterIds[i]);
+ if (eyeBlinkFlags >> i & 1) {
+ continue;
+ }
+ const v = sourceValue + (eyeBlinkValue - sourceValue) * fadeWeight;
+ model.setParameterValueById(this._eyeBlinkParameterIds[i], v);
+ }
+ }
+ if (lipSyncValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._lipSyncParameterIds.length && i < MaxTargetSize; ++i) {
+ const sourceValue = model.getParameterValueById(this._lipSyncParameterIds[i]);
+ if (lipSyncFlags >> i & 1) {
+ continue;
+ }
+ const v = sourceValue + (lipSyncValue - sourceValue) * fadeWeight;
+ model.setParameterValueById(this._lipSyncParameterIds[i], v);
+ }
+ }
+ }
+ for (; c < this._motionData.curveCount && curves[c].type == CubismMotionCurveTarget.CubismMotionCurveTarget_PartOpacity; ++c) {
+ value = evaluateCurve(this._motionData, c, time);
+ if (exports2.CubismConfig.setOpacityFromMotion) {
+ model.setPartOpacityById(curves[c].id, value);
+ } else {
+ parameterIndex = model.getParameterIndex(curves[c].id);
+ if (parameterIndex == -1) {
+ continue;
+ }
+ model.setParameterValueByIndex(parameterIndex, value);
+ }
+ }
+ if (timeOffsetSeconds >= this._motionData.duration) {
+ if (this._isLoop) {
+ motionQueueEntry.setStartTime(userTimeSeconds);
+ if (this._isLoopFadeIn) {
+ motionQueueEntry.setFadeInStartTime(userTimeSeconds);
+ }
+ } else {
+ if (this._onFinishedMotion) {
+ this._onFinishedMotion(this);
+ }
+ motionQueueEntry.setIsFinished(true);
+ }
+ }
+ this._lastWeight = fadeWeight;
+ }
+ setIsLoop(loop) {
+ this._isLoop = loop;
+ }
+ isLoop() {
+ return this._isLoop;
+ }
+ setIsLoopFadeIn(loopFadeIn) {
+ this._isLoopFadeIn = loopFadeIn;
+ }
+ isLoopFadeIn() {
+ return this._isLoopFadeIn;
+ }
+ getDuration() {
+ return this._isLoop ? -1 : this._loopDurationSeconds;
+ }
+ getLoopDuration() {
+ return this._loopDurationSeconds;
+ }
+ setParameterFadeInTime(parameterId, value) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ curves[i].fadeInTime = value;
+ return;
+ }
+ }
+ }
+ setParameterFadeOutTime(parameterId, value) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ curves[i].fadeOutTime = value;
+ return;
+ }
+ }
+ }
+ getParameterFadeInTime(parameterId) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ return curves[i].fadeInTime;
+ }
+ }
+ return -1;
+ }
+ getParameterFadeOutTime(parameterId) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ return curves[i].fadeOutTime;
+ }
+ }
+ return -1;
+ }
+ setEffectIds(eyeBlinkParameterIds, lipSyncParameterIds) {
+ this._eyeBlinkParameterIds = eyeBlinkParameterIds;
+ this._lipSyncParameterIds = lipSyncParameterIds;
+ }
+ release() {
+ this._motionData = void 0;
+ }
+ parse(motionJson) {
+ this._motionData = new CubismMotionData();
+ const json = new CubismMotionJson(motionJson);
+ this._motionData.duration = json.getMotionDuration();
+ this._motionData.loop = json.isMotionLoop();
+ this._motionData.curveCount = json.getMotionCurveCount();
+ this._motionData.fps = json.getMotionFps();
+ this._motionData.eventCount = json.getEventCount();
+ const areBeziersRestructed = json.getEvaluationOptionFlag(EvaluationOptionFlag.EvaluationOptionFlag_AreBeziersRistricted);
+ const fadeInSeconds = json.getMotionFadeInTime();
+ const fadeOutSeconds = json.getMotionFadeOutTime();
+ if (fadeInSeconds !== void 0) {
+ this._fadeInSeconds = fadeInSeconds < 0 ? 1 : fadeInSeconds;
+ } else {
+ this._fadeInSeconds = 1;
+ }
+ if (fadeOutSeconds !== void 0) {
+ this._fadeOutSeconds = fadeOutSeconds < 0 ? 1 : fadeOutSeconds;
+ } else {
+ this._fadeOutSeconds = 1;
+ }
+ this._motionData.curves = Array.from({
+ length: this._motionData.curveCount
+ }).map(() => new CubismMotionCurve());
+ this._motionData.segments = Array.from({
+ length: json.getMotionTotalSegmentCount()
+ }).map(() => new CubismMotionSegment());
+ this._motionData.events = Array.from({
+ length: this._motionData.eventCount
+ }).map(() => new CubismMotionEvent());
+ this._motionData.points = [];
+ let totalPointCount = 0;
+ let totalSegmentCount = 0;
+ for (let curveCount = 0; curveCount < this._motionData.curveCount; ++curveCount) {
+ const curve = this._motionData.curves[curveCount];
+ switch (json.getMotionCurveTarget(curveCount)) {
+ case TargetNameModel:
+ curve.type = CubismMotionCurveTarget.CubismMotionCurveTarget_Model;
+ break;
+ case TargetNameParameter:
+ curve.type = CubismMotionCurveTarget.CubismMotionCurveTarget_Parameter;
+ break;
+ case TargetNamePartOpacity:
+ curve.type = CubismMotionCurveTarget.CubismMotionCurveTarget_PartOpacity;
+ break;
+ default:
+ CubismLogWarning('Warning : Unable to get segment type from Curve! The number of "CurveCount" may be incorrect!');
+ }
+ curve.id = json.getMotionCurveId(curveCount);
+ curve.baseSegmentIndex = totalSegmentCount;
+ const fadeInTime = json.getMotionCurveFadeInTime(curveCount);
+ const fadeOutTime = json.getMotionCurveFadeOutTime(curveCount);
+ curve.fadeInTime = fadeInTime !== void 0 ? fadeInTime : -1;
+ curve.fadeOutTime = fadeOutTime !== void 0 ? fadeOutTime : -1;
+ for (let segmentPosition = 0; segmentPosition < json.getMotionCurveSegmentCount(curveCount); ) {
+ if (segmentPosition == 0) {
+ this._motionData.segments[totalSegmentCount].basePointIndex = totalPointCount;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition), json.getMotionCurveSegment(curveCount, segmentPosition + 1));
+ totalPointCount += 1;
+ segmentPosition += 2;
+ } else {
+ this._motionData.segments[totalSegmentCount].basePointIndex = totalPointCount - 1;
+ }
+ const segment = json.getMotionCurveSegment(curveCount, segmentPosition);
+ switch (segment) {
+ case CubismMotionSegmentType.CubismMotionSegmentType_Linear: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Linear;
+ this._motionData.segments[totalSegmentCount].evaluate = linearEvaluate;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ totalPointCount += 1;
+ segmentPosition += 3;
+ break;
+ }
+ case CubismMotionSegmentType.CubismMotionSegmentType_Bezier: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Bezier;
+ if (areBeziersRestructed || UseOldBeziersCurveMotion) {
+ this._motionData.segments[totalSegmentCount].evaluate = bezierEvaluate;
+ } else {
+ this._motionData.segments[totalSegmentCount].evaluate = bezierEvaluateCardanoInterpretation;
+ }
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ this._motionData.points[totalPointCount + 1] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 3), json.getMotionCurveSegment(curveCount, segmentPosition + 4));
+ this._motionData.points[totalPointCount + 2] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 5), json.getMotionCurveSegment(curveCount, segmentPosition + 6));
+ totalPointCount += 3;
+ segmentPosition += 7;
+ break;
+ }
+ case CubismMotionSegmentType.CubismMotionSegmentType_Stepped: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Stepped;
+ this._motionData.segments[totalSegmentCount].evaluate = steppedEvaluate;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ totalPointCount += 1;
+ segmentPosition += 3;
+ break;
+ }
+ case CubismMotionSegmentType.CubismMotionSegmentType_InverseStepped: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_InverseStepped;
+ this._motionData.segments[totalSegmentCount].evaluate = inverseSteppedEvaluate;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ totalPointCount += 1;
+ segmentPosition += 3;
+ break;
+ }
+ }
+ ++curve.segmentCount;
+ ++totalSegmentCount;
+ }
+ this._motionData.curves.push(curve);
+ }
+ for (let userdatacount = 0; userdatacount < json.getEventCount(); ++userdatacount) {
+ this._motionData.events[userdatacount].fireTime = json.getEventTime(userdatacount);
+ this._motionData.events[userdatacount].value = json.getEventValue(userdatacount);
+ }
+ json.release();
+ }
+ getFiredEvent(beforeCheckTimeSeconds, motionTimeSeconds) {
+ this._firedEventValues.length = 0;
+ for (let u = 0; u < this._motionData.eventCount; ++u) {
+ if (this._motionData.events[u].fireTime > beforeCheckTimeSeconds && this._motionData.events[u].fireTime <= motionTimeSeconds) {
+ this._firedEventValues.push(this._motionData.events[u].value);
+ }
+ }
+ return this._firedEventValues;
+ }
+ isExistModelOpacity() {
+ for (let i = 0; i < this._motionData.curveCount; i++) {
+ const curve = this._motionData.curves[i];
+ if (curve.type != CubismMotionCurveTarget.CubismMotionCurveTarget_Model) {
+ continue;
+ }
+ if (curve.id === IdNameOpacity) {
+ return true;
+ }
+ }
+ return false;
+ }
+ getModelOpacityIndex() {
+ if (this.isExistModelOpacity()) {
+ for (let i = 0; i < this._motionData.curveCount; i++) {
+ const curve = this._motionData.curves[i];
+ if (curve.type != CubismMotionCurveTarget.CubismMotionCurveTarget_Model) {
+ continue;
+ }
+ if (curve.id === IdNameOpacity) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+ getModelOpacityId(index) {
+ if (index != -1) {
+ const curve = this._motionData.curves[index];
+ if (curve.type == CubismMotionCurveTarget.CubismMotionCurveTarget_Model) {
+ if (curve.id === IdNameOpacity) {
+ return curve.id;
+ }
+ }
+ }
+ return void 0;
+ }
+ getModelOpacityValue() {
+ return this._modelOpacity;
+ }
+ }
+ class CubismMotionQueueEntry {
+ constructor() {
+ this._autoDelete = false;
+ this._available = true;
+ this._finished = false;
+ this._started = false;
+ this._startTimeSeconds = -1;
+ this._fadeInStartTimeSeconds = 0;
+ this._endTimeSeconds = -1;
+ this._stateTimeSeconds = 0;
+ this._stateWeight = 0;
+ this._lastEventCheckSeconds = 0;
+ this._motionQueueEntryHandle = this;
+ this._fadeOutSeconds = 0;
+ this._isTriggeredFadeOut = false;
+ }
+ release() {
+ if (this._autoDelete && this._motion) {
+ this._motion.release();
+ }
+ }
+ setFadeOut(fadeOutSeconds) {
+ this._fadeOutSeconds = fadeOutSeconds;
+ this._isTriggeredFadeOut = true;
+ }
+ startFadeOut(fadeOutSeconds, userTimeSeconds) {
+ const newEndTimeSeconds = userTimeSeconds + fadeOutSeconds;
+ this._isTriggeredFadeOut = true;
+ if (this._endTimeSeconds < 0 || newEndTimeSeconds < this._endTimeSeconds) {
+ this._endTimeSeconds = newEndTimeSeconds;
+ }
+ }
+ isFinished() {
+ return this._finished;
+ }
+ isStarted() {
+ return this._started;
+ }
+ getStartTime() {
+ return this._startTimeSeconds;
+ }
+ getFadeInStartTime() {
+ return this._fadeInStartTimeSeconds;
+ }
+ getEndTime() {
+ return this._endTimeSeconds;
+ }
+ setStartTime(startTime) {
+ this._startTimeSeconds = startTime;
+ }
+ setFadeInStartTime(startTime) {
+ this._fadeInStartTimeSeconds = startTime;
+ }
+ setEndTime(endTime) {
+ this._endTimeSeconds = endTime;
+ }
+ setIsFinished(f) {
+ this._finished = f;
+ }
+ setIsStarted(f) {
+ this._started = f;
+ }
+ isAvailable() {
+ return this._available;
+ }
+ setIsAvailable(v) {
+ this._available = v;
+ }
+ setState(timeSeconds, weight) {
+ this._stateTimeSeconds = timeSeconds;
+ this._stateWeight = weight;
+ }
+ getStateTime() {
+ return this._stateTimeSeconds;
+ }
+ getStateWeight() {
+ return this._stateWeight;
+ }
+ getLastCheckEventSeconds() {
+ return this._lastEventCheckSeconds;
+ }
+ setLastCheckEventSeconds(checkSeconds) {
+ this._lastEventCheckSeconds = checkSeconds;
+ }
+ isTriggeredFadeOut() {
+ return this._isTriggeredFadeOut;
+ }
+ getFadeOutSeconds() {
+ return this._fadeOutSeconds;
+ }
+ }
+ class CubismMotionQueueManager {
+ constructor() {
+ this._userTimeSeconds = 0;
+ this._eventCustomData = null;
+ this._motions = [];
+ }
+ release() {
+ for (let i = 0; i < this._motions.length; ++i) {
+ if (this._motions[i]) {
+ this._motions[i].release();
+ }
+ }
+ this._motions = void 0;
+ }
+ startMotion(motion, autoDelete, userTimeSeconds) {
+ if (motion == null) {
+ return InvalidMotionQueueEntryHandleValue;
+ }
+ let motionQueueEntry;
+ for (let i = 0; i < this._motions.length; ++i) {
+ motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ continue;
+ }
+ motionQueueEntry.setFadeOut(motionQueueEntry._motion.getFadeOutTime());
+ }
+ motionQueueEntry = new CubismMotionQueueEntry();
+ motionQueueEntry._autoDelete = autoDelete;
+ motionQueueEntry._motion = motion;
+ this._motions.push(motionQueueEntry);
+ return motionQueueEntry._motionQueueEntryHandle;
+ }
+ isFinished() {
+ let i = 0;
+ while (i < this._motions.length) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ this._motions.splice(i, 1);
+ continue;
+ }
+ const motion = motionQueueEntry._motion;
+ if (motion == null) {
+ motionQueueEntry.release();
+ this._motions.splice(i, 1);
+ continue;
+ }
+ if (!motionQueueEntry.isFinished()) {
+ return false;
+ }
+ i++;
+ }
+ return true;
+ }
+ isFinishedByHandle(motionQueueEntryNumber) {
+ for (let i = 0; i < this._motions.length; i++) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ continue;
+ }
+ if (motionQueueEntry._motionQueueEntryHandle == motionQueueEntryNumber && !motionQueueEntry.isFinished()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ stopAllMotions() {
+ for (let i = 0; i < this._motions.length; i++) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry != null) {
+ motionQueueEntry.release();
+ }
+ }
+ this._motions = [];
+ }
+ getCubismMotionQueueEntry(motionQueueEntryNumber) {
+ return this._motions.find((entry) => entry != null && entry._motionQueueEntryHandle == motionQueueEntryNumber);
+ }
+ setEventCallback(callback, customData = null) {
+ this._eventCallBack = callback;
+ this._eventCustomData = customData;
+ }
+ doUpdateMotion(model, userTimeSeconds) {
+ let updated = false;
+ let i = 0;
+ while (i < this._motions.length) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ this._motions.splice(i, 1);
+ continue;
+ }
+ const motion = motionQueueEntry._motion;
+ if (motion == null) {
+ motionQueueEntry.release();
+ this._motions.splice(i, 1);
+ continue;
+ }
+ motion.updateParameters(model, motionQueueEntry, userTimeSeconds);
+ updated = true;
+ const firedList = motion.getFiredEvent(motionQueueEntry.getLastCheckEventSeconds() - motionQueueEntry.getStartTime(), userTimeSeconds - motionQueueEntry.getStartTime());
+ for (let i2 = 0; i2 < firedList.length; ++i2) {
+ this._eventCallBack(this, firedList[i2], this._eventCustomData);
+ }
+ motionQueueEntry.setLastCheckEventSeconds(userTimeSeconds);
+ if (motionQueueEntry.isFinished()) {
+ motionQueueEntry.release();
+ this._motions.splice(i, 1);
+ } else {
+ if (motionQueueEntry.isTriggeredFadeOut()) {
+ motionQueueEntry.startFadeOut(motionQueueEntry.getFadeOutSeconds(), userTimeSeconds);
+ }
+ i++;
+ }
+ }
+ return updated;
+ }
+ }
+ const InvalidMotionQueueEntryHandleValue = -1;
+ class CubismMotionManager extends CubismMotionQueueManager {
+ constructor() {
+ super();
+ this._currentPriority = 0;
+ this._reservePriority = 0;
+ }
+ getCurrentPriority() {
+ return this._currentPriority;
+ }
+ getReservePriority() {
+ return this._reservePriority;
+ }
+ setReservePriority(val) {
+ this._reservePriority = val;
+ }
+ startMotionPriority(motion, autoDelete, priority) {
+ if (priority == this._reservePriority) {
+ this._reservePriority = 0;
+ }
+ this._currentPriority = priority;
+ return super.startMotion(motion, autoDelete, this._userTimeSeconds);
+ }
+ updateMotion(model, deltaTimeSeconds) {
+ this._userTimeSeconds += deltaTimeSeconds;
+ const updated = super.doUpdateMotion(model, this._userTimeSeconds);
+ if (this.isFinished()) {
+ this._currentPriority = 0;
+ }
+ return updated;
+ }
+ reserveMotion(priority) {
+ if (priority <= this._reservePriority || priority <= this._currentPriority) {
+ return false;
+ }
+ this._reservePriority = priority;
+ return true;
+ }
+ }
+ var CubismPhysicsTargetType = /* @__PURE__ */ ((CubismPhysicsTargetType2) => {
+ CubismPhysicsTargetType2[CubismPhysicsTargetType2["CubismPhysicsTargetType_Parameter"] = 0] = "CubismPhysicsTargetType_Parameter";
+ return CubismPhysicsTargetType2;
+ })(CubismPhysicsTargetType || {});
+ var CubismPhysicsSource = /* @__PURE__ */ ((CubismPhysicsSource2) => {
+ CubismPhysicsSource2[CubismPhysicsSource2["CubismPhysicsSource_X"] = 0] = "CubismPhysicsSource_X";
+ CubismPhysicsSource2[CubismPhysicsSource2["CubismPhysicsSource_Y"] = 1] = "CubismPhysicsSource_Y";
+ CubismPhysicsSource2[CubismPhysicsSource2["CubismPhysicsSource_Angle"] = 2] = "CubismPhysicsSource_Angle";
+ return CubismPhysicsSource2;
+ })(CubismPhysicsSource || {});
+ class PhysicsJsonEffectiveForces {
+ constructor() {
+ this.gravity = new CubismVector2(0, 0);
+ this.wind = new CubismVector2(0, 0);
+ }
+ }
+ class CubismPhysicsParticle {
+ constructor() {
+ this.initialPosition = new CubismVector2(0, 0);
+ this.position = new CubismVector2(0, 0);
+ this.lastPosition = new CubismVector2(0, 0);
+ this.lastGravity = new CubismVector2(0, 0);
+ this.force = new CubismVector2(0, 0);
+ this.velocity = new CubismVector2(0, 0);
+ }
+ }
+ class CubismPhysicsSubRig {
+ constructor() {
+ this.normalizationPosition = {};
+ this.normalizationAngle = {};
+ }
+ }
+ class CubismPhysicsInput {
+ constructor() {
+ this.source = {};
+ }
+ }
+ class CubismPhysicsOutput {
+ constructor() {
+ this.destination = {};
+ this.translationScale = new CubismVector2(0, 0);
+ }
+ }
+ class CubismPhysicsRig {
+ constructor() {
+ this.settings = [];
+ this.inputs = [];
+ this.outputs = [];
+ this.particles = [];
+ this.gravity = new CubismVector2(0, 0);
+ this.wind = new CubismVector2(0, 0);
+ this.fps = 0;
+ }
+ }
+ class CubismPhysicsJson {
+ constructor(json) {
+ this._json = json;
+ }
+ release() {
+ this._json = void 0;
+ }
+ getGravity() {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this._json.Meta.EffectiveForces.Gravity.X;
+ ret.y = this._json.Meta.EffectiveForces.Gravity.Y;
+ return ret;
+ }
+ getWind() {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this._json.Meta.EffectiveForces.Wind.X;
+ ret.y = this._json.Meta.EffectiveForces.Wind.Y;
+ return ret;
+ }
+ getFps() {
+ return this._json.Meta.Fps || 0;
+ }
+ getSubRigCount() {
+ return this._json.Meta.PhysicsSettingCount;
+ }
+ getTotalInputCount() {
+ return this._json.Meta.TotalInputCount;
+ }
+ getTotalOutputCount() {
+ return this._json.Meta.TotalOutputCount;
+ }
+ getVertexCount() {
+ return this._json.Meta.VertexCount;
+ }
+ getNormalizationPositionMinimumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Position.Minimum;
+ }
+ getNormalizationPositionMaximumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Position.Maximum;
+ }
+ getNormalizationPositionDefaultValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Position.Default;
+ }
+ getNormalizationAngleMinimumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Angle.Minimum;
+ }
+ getNormalizationAngleMaximumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Angle.Maximum;
+ }
+ getNormalizationAngleDefaultValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Angle.Default;
+ }
+ getInputCount(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input.length;
+ }
+ getInputWeight(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Weight;
+ }
+ getInputReflect(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Reflect;
+ }
+ getInputType(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Type;
+ }
+ getInputSourceId(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Source.Id;
+ }
+ getOutputCount(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output.length;
+ }
+ getOutputVertexIndex(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].VertexIndex;
+ }
+ getOutputAngleScale(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Scale;
+ }
+ getOutputWeight(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Weight;
+ }
+ getOutputDestinationId(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Destination.Id;
+ }
+ getOutputType(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Type;
+ }
+ getOutputReflect(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Reflect;
+ }
+ getParticleCount(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices.length;
+ }
+ getParticleMobility(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Mobility;
+ }
+ getParticleDelay(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Delay;
+ }
+ getParticleAcceleration(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Acceleration;
+ }
+ getParticleRadius(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Radius;
+ }
+ getParticlePosition(physicsSettingIndex, vertexIndex) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Position.X;
+ ret.y = this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Position.Y;
+ return ret;
+ }
+ }
+ const PhysicsTypeTagX = "X";
+ const PhysicsTypeTagY = "Y";
+ const PhysicsTypeTagAngle = "Angle";
+ const AirResistance = 5;
+ const MaximumWeight = 100;
+ const MovementThreshold = 1e-3;
+ const MaxDeltaTime = 5;
+ class CubismPhysics {
+ static create(json) {
+ const ret = new CubismPhysics();
+ ret.parse(json);
+ ret._physicsRig.gravity.y = 0;
+ return ret;
+ }
+ static delete(physics) {
+ if (physics != null) {
+ physics.release();
+ }
+ }
+ parse(physicsJson) {
+ this._physicsRig = new CubismPhysicsRig();
+ const json = new CubismPhysicsJson(physicsJson);
+ this._physicsRig.gravity = json.getGravity();
+ this._physicsRig.wind = json.getWind();
+ this._physicsRig.subRigCount = json.getSubRigCount();
+ this._physicsRig.fps = json.getFps();
+ this._currentRigOutputs = [];
+ this._previousRigOutputs = [];
+ let inputIndex = 0, outputIndex = 0, particleIndex = 0;
+ for (let i = 0; i < this._physicsRig.subRigCount; ++i) {
+ const setting = new CubismPhysicsSubRig();
+ setting.normalizationPosition.minimum = json.getNormalizationPositionMinimumValue(i);
+ setting.normalizationPosition.maximum = json.getNormalizationPositionMaximumValue(i);
+ setting.normalizationPosition.defalut = json.getNormalizationPositionDefaultValue(i);
+ setting.normalizationAngle.minimum = json.getNormalizationAngleMinimumValue(i);
+ setting.normalizationAngle.maximum = json.getNormalizationAngleMaximumValue(i);
+ setting.normalizationAngle.defalut = json.getNormalizationAngleDefaultValue(i);
+ setting.inputCount = json.getInputCount(i);
+ setting.baseInputIndex = inputIndex;
+ inputIndex += setting.inputCount;
+ for (let j = 0; j < setting.inputCount; ++j) {
+ const input = new CubismPhysicsInput();
+ input.sourceParameterIndex = -1;
+ input.weight = json.getInputWeight(i, j);
+ input.reflect = json.getInputReflect(i, j);
+ switch (json.getInputType(i, j)) {
+ case PhysicsTypeTagX:
+ input.type = CubismPhysicsSource.CubismPhysicsSource_X;
+ input.getNormalizedParameterValue = getInputTranslationXFromNormalizedParameterValue;
+ break;
+ case PhysicsTypeTagY:
+ input.type = CubismPhysicsSource.CubismPhysicsSource_Y;
+ input.getNormalizedParameterValue = getInputTranslationYFromNormalizedParamterValue;
+ break;
+ case PhysicsTypeTagAngle:
+ input.type = CubismPhysicsSource.CubismPhysicsSource_Angle;
+ input.getNormalizedParameterValue = getInputAngleFromNormalizedParameterValue;
+ break;
+ }
+ input.source.targetType = CubismPhysicsTargetType.CubismPhysicsTargetType_Parameter;
+ input.source.id = json.getInputSourceId(i, j);
+ this._physicsRig.inputs.push(input);
+ }
+ setting.outputCount = json.getOutputCount(i);
+ setting.baseOutputIndex = outputIndex;
+ const currentRigOutput = new PhysicsOutput();
+ const previousRigOutput = new PhysicsOutput();
+ for (let j = 0; j < setting.outputCount; ++j) {
+ currentRigOutput.outputs[j] = 0;
+ previousRigOutput.outputs[j] = 0;
+ let output = this._physicsRig.outputs[outputIndex + j];
+ if (!output) {
+ output = new CubismPhysicsOutput();
+ this._physicsRig.outputs[outputIndex + j] = output;
+ }
+ output.destinationParameterIndex = -1;
+ output.vertexIndex = json.getOutputVertexIndex(i, j);
+ output.angleScale = json.getOutputAngleScale(i, j);
+ output.weight = json.getOutputWeight(i, j);
+ output.destination.targetType = CubismPhysicsTargetType.CubismPhysicsTargetType_Parameter;
+ output.destination.id = json.getOutputDestinationId(i, j);
+ switch (json.getOutputType(i, j)) {
+ case PhysicsTypeTagX:
+ output.type = CubismPhysicsSource.CubismPhysicsSource_X;
+ output.getValue = getOutputTranslationX;
+ output.getScale = getOutputScaleTranslationX;
+ break;
+ case PhysicsTypeTagY:
+ output.type = CubismPhysicsSource.CubismPhysicsSource_Y;
+ output.getValue = getOutputTranslationY;
+ output.getScale = getOutputScaleTranslationY;
+ break;
+ case PhysicsTypeTagAngle:
+ output.type = CubismPhysicsSource.CubismPhysicsSource_Angle;
+ output.getValue = getOutputAngle;
+ output.getScale = getOutputScaleAngle;
+ break;
+ }
+ output.reflect = json.getOutputReflect(i, j);
+ }
+ this._currentRigOutputs.push(currentRigOutput);
+ this._previousRigOutputs.push(previousRigOutput);
+ outputIndex += setting.outputCount;
+ setting.particleCount = json.getParticleCount(i);
+ setting.baseParticleIndex = particleIndex;
+ particleIndex += setting.particleCount;
+ for (let j = 0; j < setting.particleCount; ++j) {
+ const particle = new CubismPhysicsParticle();
+ particle.mobility = json.getParticleMobility(i, j);
+ particle.delay = json.getParticleDelay(i, j);
+ particle.acceleration = json.getParticleAcceleration(i, j);
+ particle.radius = json.getParticleRadius(i, j);
+ particle.position = json.getParticlePosition(i, j);
+ this._physicsRig.particles.push(particle);
+ }
+ this._physicsRig.settings.push(setting);
+ }
+ this.initialize();
+ json.release();
+ }
+ stabilization(model) {
+ var _a, _b, _c, _d;
+ let totalAngle;
+ let weight;
+ let radAngle;
+ let outputValue;
+ const totalTranslation = new CubismVector2();
+ let currentSetting;
+ let currentInputs;
+ let currentOutputs;
+ let currentParticles;
+ let parameterValues;
+ let parameterMaximumValues;
+ let parameterMinimumValues;
+ let parameterDefaultValues;
+ parameterValues = model.getModel().parameters.values;
+ parameterMaximumValues = model.getModel().parameters.maximumValues;
+ parameterMinimumValues = model.getModel().parameters.minimumValues;
+ parameterDefaultValues = model.getModel().parameters.defaultValues;
+ if (((_b = (_a = this._parameterCaches) == null ? void 0 : _a.length) != null ? _b : 0) < model.getParameterCount()) {
+ this._parameterCaches = new Float32Array(model.getParameterCount());
+ }
+ if (((_d = (_c = this._parameterInputCaches) == null ? void 0 : _c.length) != null ? _d : 0) < model.getParameterCount()) {
+ this._parameterInputCaches = new Float32Array(model.getParameterCount());
+ }
+ for (let j = 0; j < model.getParameterCount(); ++j) {
+ this._parameterCaches[j] = parameterValues[j];
+ this._parameterInputCaches[j] = parameterValues[j];
+ }
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ totalAngle = { angle: 0 };
+ totalTranslation.x = 0;
+ totalTranslation.y = 0;
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentInputs = this._physicsRig.inputs.slice(currentSetting.baseInputIndex);
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ currentParticles = this._physicsRig.particles.slice(currentSetting.baseParticleIndex);
+ for (let i = 0; i < currentSetting.inputCount; ++i) {
+ weight = currentInputs[i].weight / MaximumWeight;
+ if (currentInputs[i].sourceParameterIndex == -1) {
+ currentInputs[i].sourceParameterIndex = model.getParameterIndex(currentInputs[i].source.id);
+ }
+ currentInputs[i].getNormalizedParameterValue(totalTranslation, totalAngle, parameterValues[currentInputs[i].sourceParameterIndex], parameterMinimumValues[currentInputs[i].sourceParameterIndex], parameterMaximumValues[currentInputs[i].sourceParameterIndex], parameterDefaultValues[currentInputs[i].sourceParameterIndex], currentSetting.normalizationPosition, currentSetting.normalizationAngle, currentInputs[i].reflect, weight);
+ this._parameterCaches[currentInputs[i].sourceParameterIndex] = parameterValues[currentInputs[i].sourceParameterIndex];
+ }
+ radAngle = CubismMath.degreesToRadian(-totalAngle.angle);
+ totalTranslation.x = totalTranslation.x * CubismMath.cos(radAngle) - totalTranslation.y * CubismMath.sin(radAngle);
+ totalTranslation.y = totalTranslation.x * CubismMath.sin(radAngle) + totalTranslation.y * CubismMath.cos(radAngle);
+ updateParticlesForStabilization(currentParticles, currentSetting.particleCount, totalTranslation, totalAngle.angle, this._options.wind, MovementThreshold * currentSetting.normalizationPosition.maximum);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ const particleIndex = currentOutputs[i].vertexIndex;
+ if (currentOutputs[i].destinationParameterIndex == -1) {
+ currentOutputs[i].destinationParameterIndex = model.getParameterIndex(currentOutputs[i].destination.id);
+ }
+ if (particleIndex < 1 || particleIndex >= currentSetting.particleCount) {
+ continue;
+ }
+ let translation = new CubismVector2();
+ translation = currentParticles[particleIndex].position.substract(currentParticles[particleIndex - 1].position);
+ outputValue = currentOutputs[i].getValue(translation, currentParticles, particleIndex, currentOutputs[i].reflect, this._options.gravity);
+ this._currentRigOutputs[settingIndex].outputs[i] = outputValue;
+ this._previousRigOutputs[settingIndex].outputs[i] = outputValue;
+ const destinationParameterIndex = currentOutputs[i].destinationParameterIndex;
+ const outParameterCaches = !Float32Array.prototype.slice && "subarray" in Float32Array.prototype ? JSON.parse(JSON.stringify(parameterValues.subarray(destinationParameterIndex))) : parameterValues.slice(destinationParameterIndex);
+ updateOutputParameterValue(outParameterCaches, parameterMinimumValues[destinationParameterIndex], parameterMaximumValues[destinationParameterIndex], outputValue, currentOutputs[i]);
+ for (let offset = destinationParameterIndex, outParamIndex = 0; offset < this._parameterCaches.length; offset++, outParamIndex++) {
+ parameterValues[offset] = this._parameterCaches[offset] = outParameterCaches[outParamIndex];
+ }
+ }
+ }
+ }
+ evaluate(model, deltaTimeSeconds) {
+ var _a, _b, _c, _d;
+ let totalAngle;
+ let weight;
+ let radAngle;
+ let outputValue;
+ const totalTranslation = new CubismVector2();
+ let currentSetting;
+ let currentInputs;
+ let currentOutputs;
+ let currentParticles;
+ if (0 >= deltaTimeSeconds) {
+ return;
+ }
+ let parameterValues;
+ let parameterMaximumValues;
+ let parameterMinimumValues;
+ let parameterDefaultValues;
+ let physicsDeltaTime;
+ this._currentRemainTime += deltaTimeSeconds;
+ if (this._currentRemainTime > MaxDeltaTime) {
+ this._currentRemainTime = 0;
+ }
+ parameterValues = model.getModel().parameters.values;
+ parameterMaximumValues = model.getModel().parameters.maximumValues;
+ parameterMinimumValues = model.getModel().parameters.minimumValues;
+ parameterDefaultValues = model.getModel().parameters.defaultValues;
+ if (((_b = (_a = this._parameterCaches) == null ? void 0 : _a.length) != null ? _b : 0) < model.getParameterCount()) {
+ this._parameterCaches = new Float32Array(model.getParameterCount());
+ }
+ if (((_d = (_c = this._parameterInputCaches) == null ? void 0 : _c.length) != null ? _d : 0) < model.getParameterCount()) {
+ this._parameterInputCaches = new Float32Array(model.getParameterCount());
+ for (let j = 0; j < model.getParameterCount(); ++j) {
+ this._parameterInputCaches[j] = parameterValues[j];
+ }
+ }
+ if (this._physicsRig.fps > 0) {
+ physicsDeltaTime = 1 / this._physicsRig.fps;
+ } else {
+ physicsDeltaTime = deltaTimeSeconds;
+ }
+ while (this._currentRemainTime >= physicsDeltaTime) {
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ this._previousRigOutputs[settingIndex].outputs[i] = this._currentRigOutputs[settingIndex].outputs[i];
+ }
+ }
+ const inputWeight = physicsDeltaTime / this._currentRemainTime;
+ for (let j = 0; j < model.getParameterCount(); ++j) {
+ this._parameterCaches[j] = this._parameterInputCaches[j] * (1 - inputWeight) + parameterValues[j] * inputWeight;
+ this._parameterInputCaches[j] = this._parameterCaches[j];
+ }
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ totalAngle = { angle: 0 };
+ totalTranslation.x = 0;
+ totalTranslation.y = 0;
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentInputs = this._physicsRig.inputs.slice(currentSetting.baseInputIndex);
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ currentParticles = this._physicsRig.particles.slice(currentSetting.baseParticleIndex);
+ for (let i = 0; i < currentSetting.inputCount; ++i) {
+ weight = currentInputs[i].weight / MaximumWeight;
+ if (currentInputs[i].sourceParameterIndex == -1) {
+ currentInputs[i].sourceParameterIndex = model.getParameterIndex(currentInputs[i].source.id);
+ }
+ currentInputs[i].getNormalizedParameterValue(totalTranslation, totalAngle, this._parameterCaches[currentInputs[i].sourceParameterIndex], parameterMinimumValues[currentInputs[i].sourceParameterIndex], parameterMaximumValues[currentInputs[i].sourceParameterIndex], parameterDefaultValues[currentInputs[i].sourceParameterIndex], currentSetting.normalizationPosition, currentSetting.normalizationAngle, currentInputs[i].reflect, weight);
+ }
+ radAngle = CubismMath.degreesToRadian(-totalAngle.angle);
+ totalTranslation.x = totalTranslation.x * CubismMath.cos(radAngle) - totalTranslation.y * CubismMath.sin(radAngle);
+ totalTranslation.y = totalTranslation.x * CubismMath.sin(radAngle) + totalTranslation.y * CubismMath.cos(radAngle);
+ updateParticles(currentParticles, currentSetting.particleCount, totalTranslation, totalAngle.angle, this._options.wind, MovementThreshold * currentSetting.normalizationPosition.maximum, physicsDeltaTime, AirResistance);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ const particleIndex = currentOutputs[i].vertexIndex;
+ if (currentOutputs[i].destinationParameterIndex == -1) {
+ currentOutputs[i].destinationParameterIndex = model.getParameterIndex(currentOutputs[i].destination.id);
+ }
+ if (particleIndex < 1 || particleIndex >= currentSetting.particleCount) {
+ continue;
+ }
+ const translation = new CubismVector2();
+ translation.x = currentParticles[particleIndex].position.x - currentParticles[particleIndex - 1].position.x;
+ translation.y = currentParticles[particleIndex].position.y - currentParticles[particleIndex - 1].position.y;
+ outputValue = currentOutputs[i].getValue(translation, currentParticles, particleIndex, currentOutputs[i].reflect, this._options.gravity);
+ this._currentRigOutputs[settingIndex].outputs[i] = outputValue;
+ const destinationParameterIndex = currentOutputs[i].destinationParameterIndex;
+ const outParameterCaches = !Float32Array.prototype.slice && "subarray" in Float32Array.prototype ? JSON.parse(JSON.stringify(this._parameterCaches.subarray(destinationParameterIndex))) : this._parameterCaches.slice(destinationParameterIndex);
+ updateOutputParameterValue(outParameterCaches, parameterMinimumValues[destinationParameterIndex], parameterMaximumValues[destinationParameterIndex], outputValue, currentOutputs[i]);
+ for (let offset = destinationParameterIndex, outParamIndex = 0; offset < this._parameterCaches.length; offset++, outParamIndex++) {
+ this._parameterCaches[offset] = outParameterCaches[outParamIndex];
+ }
+ }
+ }
+ this._currentRemainTime -= physicsDeltaTime;
+ }
+ const alpha = this._currentRemainTime / physicsDeltaTime;
+ this.interpolate(model, alpha);
+ }
+ interpolate(model, weight) {
+ let currentOutputs;
+ let currentSetting;
+ let parameterValues;
+ let parameterMaximumValues;
+ let parameterMinimumValues;
+ parameterValues = model.getModel().parameters.values;
+ parameterMaximumValues = model.getModel().parameters.maximumValues;
+ parameterMinimumValues = model.getModel().parameters.minimumValues;
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ if (currentOutputs[i].destinationParameterIndex == -1) {
+ continue;
+ }
+ const destinationParameterIndex = currentOutputs[i].destinationParameterIndex;
+ const outParameterValues = !Float32Array.prototype.slice && "subarray" in Float32Array.prototype ? JSON.parse(JSON.stringify(parameterValues.subarray(destinationParameterIndex))) : parameterValues.slice(destinationParameterIndex);
+ updateOutputParameterValue(outParameterValues, parameterMinimumValues[destinationParameterIndex], parameterMaximumValues[destinationParameterIndex], this._previousRigOutputs[settingIndex].outputs[i] * (1 - weight) + this._currentRigOutputs[settingIndex].outputs[i] * weight, currentOutputs[i]);
+ for (let offset = destinationParameterIndex, outParamIndex = 0; offset < parameterValues.length; offset++, outParamIndex++) {
+ parameterValues[offset] = outParameterValues[outParamIndex];
+ }
+ }
+ }
+ }
+ setOptions(options) {
+ this._options = options;
+ }
+ getOption() {
+ return this._options;
+ }
+ constructor() {
+ this._options = new Options();
+ this._options.gravity.y = -1;
+ this._options.gravity.x = 0;
+ this._options.wind.x = 0;
+ this._options.wind.y = 0;
+ this._currentRigOutputs = [];
+ this._previousRigOutputs = [];
+ this._currentRemainTime = 0;
+ }
+ release() {
+ this._physicsRig = void 0;
+ }
+ initialize() {
+ let strand;
+ let currentSetting;
+ let radius;
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ currentSetting = this._physicsRig.settings[settingIndex];
+ strand = this._physicsRig.particles.slice(currentSetting.baseParticleIndex);
+ strand[0].initialPosition = new CubismVector2(0, 0);
+ strand[0].lastPosition = new CubismVector2(strand[0].initialPosition.x, strand[0].initialPosition.y);
+ strand[0].lastGravity = new CubismVector2(0, -1);
+ strand[0].lastGravity.y *= -1;
+ strand[0].velocity = new CubismVector2(0, 0);
+ strand[0].force = new CubismVector2(0, 0);
+ for (let i = 1; i < currentSetting.particleCount; ++i) {
+ radius = new CubismVector2(0, 0);
+ radius.y = strand[i].radius;
+ strand[i].initialPosition = new CubismVector2(strand[i - 1].initialPosition.x + radius.x, strand[i - 1].initialPosition.y + radius.y);
+ strand[i].position = new CubismVector2(strand[i].initialPosition.x, strand[i].initialPosition.y);
+ strand[i].lastPosition = new CubismVector2(strand[i].initialPosition.x, strand[i].initialPosition.y);
+ strand[i].lastGravity = new CubismVector2(0, -1);
+ strand[i].lastGravity.y *= -1;
+ strand[i].velocity = new CubismVector2(0, 0);
+ strand[i].force = new CubismVector2(0, 0);
+ }
+ }
+ }
+ }
+ class Options {
+ constructor() {
+ this.gravity = new CubismVector2(0, 0);
+ this.wind = new CubismVector2(0, 0);
+ }
+ }
+ class PhysicsOutput {
+ constructor() {
+ this.outputs = [];
+ }
+ }
+ function getInputTranslationXFromNormalizedParameterValue(targetTranslation, targetAngle, value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition, normalizationAngle, isInverted, weight) {
+ targetTranslation.x += normalizeParameterValue(value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition.minimum, normalizationPosition.maximum, normalizationPosition.defalut, isInverted) * weight;
+ }
+ function getInputTranslationYFromNormalizedParamterValue(targetTranslation, targetAngle, value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition, normalizationAngle, isInverted, weight) {
+ targetTranslation.y += normalizeParameterValue(value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition.minimum, normalizationPosition.maximum, normalizationPosition.defalut, isInverted) * weight;
+ }
+ function getInputAngleFromNormalizedParameterValue(targetTranslation, targetAngle, value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizaitionPosition, normalizationAngle, isInverted, weight) {
+ targetAngle.angle += normalizeParameterValue(value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationAngle.minimum, normalizationAngle.maximum, normalizationAngle.defalut, isInverted) * weight;
+ }
+ function getOutputTranslationX(translation, particles, particleIndex, isInverted, parentGravity) {
+ let outputValue = translation.x;
+ if (isInverted) {
+ outputValue *= -1;
+ }
+ return outputValue;
+ }
+ function getOutputTranslationY(translation, particles, particleIndex, isInverted, parentGravity) {
+ let outputValue = translation.y;
+ if (isInverted) {
+ outputValue *= -1;
+ }
+ return outputValue;
+ }
+ function getOutputAngle(translation, particles, particleIndex, isInverted, parentGravity) {
+ let outputValue;
+ if (particleIndex >= 2) {
+ parentGravity = particles[particleIndex - 1].position.substract(particles[particleIndex - 2].position);
+ } else {
+ parentGravity = parentGravity.multiplyByScaler(-1);
+ }
+ outputValue = CubismMath.directionToRadian(parentGravity, translation);
+ if (isInverted) {
+ outputValue *= -1;
+ }
+ return outputValue;
+ }
+ function getRangeValue(min, max) {
+ return Math.abs(Math.max(min, max) - Math.min(min, max));
+ }
+ function getDefaultValue(min, max) {
+ const minValue = Math.min(min, max);
+ return minValue + getRangeValue(min, max) / 2;
+ }
+ function getOutputScaleTranslationX(translationScale, angleScale) {
+ return translationScale.x;
+ }
+ function getOutputScaleTranslationY(translationScale, angleScale) {
+ return translationScale.y;
+ }
+ function getOutputScaleAngle(translationScale, angleScale) {
+ return angleScale;
+ }
+ function updateParticles(strand, strandCount, totalTranslation, totalAngle, windDirection, thresholdValue, deltaTimeSeconds, airResistance) {
+ let totalRadian;
+ let delay;
+ let radian;
+ let currentGravity;
+ let direction = new CubismVector2(0, 0);
+ let velocity = new CubismVector2(0, 0);
+ let force = new CubismVector2(0, 0);
+ let newDirection = new CubismVector2(0, 0);
+ strand[0].position = new CubismVector2(totalTranslation.x, totalTranslation.y);
+ totalRadian = CubismMath.degreesToRadian(totalAngle);
+ currentGravity = CubismMath.radianToDirection(totalRadian);
+ currentGravity.normalize();
+ for (let i = 1; i < strandCount; ++i) {
+ strand[i].force = currentGravity.multiplyByScaler(strand[i].acceleration).add(windDirection);
+ strand[i].lastPosition = new CubismVector2(strand[i].position.x, strand[i].position.y);
+ delay = strand[i].delay * deltaTimeSeconds * 30;
+ direction = strand[i].position.substract(strand[i - 1].position);
+ radian = CubismMath.directionToRadian(strand[i].lastGravity, currentGravity) / airResistance;
+ direction.x = CubismMath.cos(radian) * direction.x - direction.y * CubismMath.sin(radian);
+ direction.y = CubismMath.sin(radian) * direction.x + direction.y * CubismMath.cos(radian);
+ strand[i].position = strand[i - 1].position.add(direction);
+ velocity = strand[i].velocity.multiplyByScaler(delay);
+ force = strand[i].force.multiplyByScaler(delay).multiplyByScaler(delay);
+ strand[i].position = strand[i].position.add(velocity).add(force);
+ newDirection = strand[i].position.substract(strand[i - 1].position);
+ newDirection.normalize();
+ strand[i].position = strand[i - 1].position.add(newDirection.multiplyByScaler(strand[i].radius));
+ if (CubismMath.abs(strand[i].position.x) < thresholdValue) {
+ strand[i].position.x = 0;
+ }
+ if (delay != 0) {
+ strand[i].velocity = strand[i].position.substract(strand[i].lastPosition);
+ strand[i].velocity = strand[i].velocity.divisionByScalar(delay);
+ strand[i].velocity = strand[i].velocity.multiplyByScaler(strand[i].mobility);
+ }
+ strand[i].force = new CubismVector2(0, 0);
+ strand[i].lastGravity = new CubismVector2(currentGravity.x, currentGravity.y);
+ }
+ }
+ function updateParticlesForStabilization(strand, strandCount, totalTranslation, totalAngle, windDirection, thresholdValue) {
+ let totalRadian;
+ let currentGravity;
+ let force = new CubismVector2(0, 0);
+ strand[0].position = new CubismVector2(totalTranslation.x, totalTranslation.y);
+ totalRadian = CubismMath.degreesToRadian(totalAngle);
+ currentGravity = CubismMath.radianToDirection(totalRadian);
+ currentGravity.normalize();
+ for (let i = 1; i < strandCount; ++i) {
+ strand[i].force = currentGravity.multiplyByScaler(strand[i].acceleration).add(windDirection);
+ strand[i].lastPosition = new CubismVector2(strand[i].position.x, strand[i].position.y);
+ strand[i].velocity = new CubismVector2(0, 0);
+ force = strand[i].force;
+ force.normalize();
+ force = force.multiplyByScaler(strand[i].radius);
+ strand[i].position = strand[i - 1].position.add(force);
+ if (CubismMath.abs(strand[i].position.x) < thresholdValue) {
+ strand[i].position.x = 0;
+ }
+ strand[i].force = new CubismVector2(0, 0);
+ strand[i].lastGravity = new CubismVector2(currentGravity.x, currentGravity.y);
+ }
+ }
+ function updateOutputParameterValue(parameterValue, parameterValueMinimum, parameterValueMaximum, translation, output) {
+ let outputScale;
+ let value;
+ let weight;
+ outputScale = output.getScale(output.translationScale, output.angleScale);
+ value = translation * outputScale;
+ if (value < parameterValueMinimum) {
+ if (value < output.valueBelowMinimum) {
+ output.valueBelowMinimum = value;
+ }
+ value = parameterValueMinimum;
+ } else if (value > parameterValueMaximum) {
+ if (value > output.valueExceededMaximum) {
+ output.valueExceededMaximum = value;
+ }
+ value = parameterValueMaximum;
+ }
+ weight = output.weight / MaximumWeight;
+ if (weight >= 1) {
+ parameterValue[0] = value;
+ } else {
+ value = parameterValue[0] * (1 - weight) + value * weight;
+ parameterValue[0] = value;
+ }
+ }
+ function normalizeParameterValue(value, parameterMinimum, parameterMaximum, parameterDefault, normalizedMinimum, normalizedMaximum, normalizedDefault, isInverted) {
+ let result = 0;
+ const maxValue = CubismMath.max(parameterMaximum, parameterMinimum);
+ if (maxValue < value) {
+ value = maxValue;
+ }
+ const minValue = CubismMath.min(parameterMaximum, parameterMinimum);
+ if (minValue > value) {
+ value = minValue;
+ }
+ const minNormValue = CubismMath.min(normalizedMinimum, normalizedMaximum);
+ const maxNormValue = CubismMath.max(normalizedMinimum, normalizedMaximum);
+ const middleNormValue = normalizedDefault;
+ const middleValue = getDefaultValue(minValue, maxValue);
+ const paramValue = value - middleValue;
+ switch (Math.sign(paramValue)) {
+ case 1: {
+ const nLength = maxNormValue - middleNormValue;
+ const pLength = maxValue - middleValue;
+ if (pLength != 0) {
+ result = paramValue * (nLength / pLength);
+ result += middleNormValue;
+ }
+ break;
+ }
+ case -1: {
+ const nLength = minNormValue - middleNormValue;
+ const pLength = minValue - middleValue;
+ if (pLength != 0) {
+ result = paramValue * (nLength / pLength);
+ result += middleNormValue;
+ }
+ break;
+ }
+ case 0: {
+ result = middleNormValue;
+ break;
+ }
+ }
+ return isInverted ? result : result * -1;
+ }
+ class csmRect {
+ constructor(x = 0, y = 0, w = 0, h = 0) {
+ this.x = x;
+ this.y = y;
+ this.width = w;
+ this.height = h;
+ }
+ getCenterX() {
+ return this.x + 0.5 * this.width;
+ }
+ getCenterY() {
+ return this.y + 0.5 * this.height;
+ }
+ getRight() {
+ return this.x + this.width;
+ }
+ getBottom() {
+ return this.y + this.height;
+ }
+ setRect(r) {
+ this.x = r.x;
+ this.y = r.y;
+ this.width = r.width;
+ this.height = r.height;
+ }
+ expand(w, h) {
+ this.x -= w;
+ this.y -= h;
+ this.width += w * 2;
+ this.height += h * 2;
+ }
+ }
+ const ColorChannelCount = 4;
+ const ClippingMaskMaxCountOnDefault = 36;
+ const ClippingMaskMaxCountOnMultiRenderTexture = 32;
+ const ShaderCount = 10;
+ let s_instance;
+ let s_viewport;
+ let s_fbo;
+ class CubismClippingManager_WebGL {
+ getChannelFlagAsColor(channelNo) {
+ return this._channelColors[channelNo];
+ }
+ getMaskRenderTexture() {
+ if (this._maskTexture && this._maskTexture.textures != null) {
+ this._maskTexture.frameNo = this._currentFrameNo;
+ } else {
+ this._maskRenderTextures = [];
+ this._maskColorBuffers = [];
+ const size = this._clippingMaskBufferSize;
+ for (let index = 0; index < this._renderTextureCount; index++) {
+ this._maskColorBuffers.push(this.gl.createTexture());
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this._maskColorBuffers[index]);
+ this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, size, size, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, null);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, null);
+ this._maskRenderTextures.push(this.gl.createFramebuffer());
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this._maskRenderTextures[index]);
+ this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, this._maskColorBuffers[index], 0);
+ }
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, s_fbo);
+ this._maskTexture = new CubismRenderTextureResource(this._currentFrameNo, this._maskRenderTextures);
+ }
+ return this._maskTexture.textures;
+ }
+ setGL(gl) {
+ this.gl = gl;
+ }
+ calcClippedDrawTotalBounds(model, clippingContext) {
+ let clippedDrawTotalMinX = Number.MAX_VALUE;
+ let clippedDrawTotalMinY = Number.MAX_VALUE;
+ let clippedDrawTotalMaxX = Number.MIN_VALUE;
+ let clippedDrawTotalMaxY = Number.MIN_VALUE;
+ const clippedDrawCount = clippingContext._clippedDrawableIndexList.length;
+ for (let clippedDrawableIndex = 0; clippedDrawableIndex < clippedDrawCount; clippedDrawableIndex++) {
+ const drawableIndex = clippingContext._clippedDrawableIndexList[clippedDrawableIndex];
+ const drawableVertexCount = model.getDrawableVertexCount(drawableIndex);
+ const drawableVertexes = model.getDrawableVertices(drawableIndex);
+ let minX = Number.MAX_VALUE;
+ let minY = Number.MAX_VALUE;
+ let maxX = -Number.MAX_VALUE;
+ let maxY = -Number.MAX_VALUE;
+ const loop = drawableVertexCount * Constant.vertexStep;
+ for (let pi = Constant.vertexOffset; pi < loop; pi += Constant.vertexStep) {
+ const x = drawableVertexes[pi];
+ const y = drawableVertexes[pi + 1];
+ if (x < minX) {
+ minX = x;
+ }
+ if (x > maxX) {
+ maxX = x;
+ }
+ if (y < minY) {
+ minY = y;
+ }
+ if (y > maxY) {
+ maxY = y;
+ }
+ }
+ if (minX == Number.MAX_VALUE) {
+ continue;
+ }
+ if (minX < clippedDrawTotalMinX) {
+ clippedDrawTotalMinX = minX;
+ }
+ if (minY < clippedDrawTotalMinY) {
+ clippedDrawTotalMinY = minY;
+ }
+ if (maxX > clippedDrawTotalMaxX) {
+ clippedDrawTotalMaxX = maxX;
+ }
+ if (maxY > clippedDrawTotalMaxY) {
+ clippedDrawTotalMaxY = maxY;
+ }
+ if (clippedDrawTotalMinX == Number.MAX_VALUE) {
+ clippingContext._allClippedDrawRect.x = 0;
+ clippingContext._allClippedDrawRect.y = 0;
+ clippingContext._allClippedDrawRect.width = 0;
+ clippingContext._allClippedDrawRect.height = 0;
+ clippingContext._isUsing = false;
+ } else {
+ clippingContext._isUsing = true;
+ const w = clippedDrawTotalMaxX - clippedDrawTotalMinX;
+ const h = clippedDrawTotalMaxY - clippedDrawTotalMinY;
+ clippingContext._allClippedDrawRect.x = clippedDrawTotalMinX;
+ clippingContext._allClippedDrawRect.y = clippedDrawTotalMinY;
+ clippingContext._allClippedDrawRect.width = w;
+ clippingContext._allClippedDrawRect.height = h;
+ }
+ }
+ }
+ constructor() {
+ this._currentMaskRenderTexture = null;
+ this._currentFrameNo = 0;
+ this._renderTextureCount = 0;
+ this._clippingMaskBufferSize = 256;
+ this._clippingContextListForMask = [];
+ this._clippingContextListForDraw = [];
+ this._channelColors = [];
+ this._tmpBoundsOnModel = new csmRect();
+ this._tmpMatrix = new CubismMatrix44();
+ this._tmpMatrixForMask = new CubismMatrix44();
+ this._tmpMatrixForDraw = new CubismMatrix44();
+ let tmp = new CubismTextureColor();
+ tmp.R = 1;
+ tmp.G = 0;
+ tmp.B = 0;
+ tmp.A = 0;
+ this._channelColors.push(tmp);
+ tmp = new CubismTextureColor();
+ tmp.R = 0;
+ tmp.G = 1;
+ tmp.B = 0;
+ tmp.A = 0;
+ this._channelColors.push(tmp);
+ tmp = new CubismTextureColor();
+ tmp.R = 0;
+ tmp.G = 0;
+ tmp.B = 1;
+ tmp.A = 0;
+ this._channelColors.push(tmp);
+ tmp = new CubismTextureColor();
+ tmp.R = 0;
+ tmp.G = 0;
+ tmp.B = 0;
+ tmp.A = 1;
+ this._channelColors.push(tmp);
+ }
+ release() {
+ var _a;
+ const self2 = this;
+ for (let i = 0; i < this._clippingContextListForMask.length; i++) {
+ if (this._clippingContextListForMask[i]) {
+ (_a = this._clippingContextListForMask[i]) == null ? void 0 : _a.release();
+ }
+ }
+ self2._clippingContextListForMask = void 0;
+ self2._clippingContextListForDraw = void 0;
+ if (this._maskTexture) {
+ for (let i = 0; i < this._maskTexture.textures.length; i++) {
+ this.gl.deleteFramebuffer(this._maskTexture.textures[i]);
+ }
+ this._maskTexture = void 0;
+ }
+ self2._channelColors = void 0;
+ if (this._maskColorBuffers) {
+ for (let index = 0; index < this._maskColorBuffers.length; index++) {
+ this.gl.deleteTexture(this._maskColorBuffers[index]);
+ }
+ }
+ this._maskColorBuffers = void 0;
+ this._maskRenderTextures = void 0;
+ this._clearedFrameBufferflags = void 0;
+ }
+ initialize(model, drawableCount, drawableMasks, drawableMaskCounts, renderTextureCount) {
+ if (renderTextureCount % 1 != 0) {
+ CubismLogWarning("The number of render textures must be specified as an integer. The decimal point is rounded down and corrected to an integer.");
+ renderTextureCount = ~~renderTextureCount;
+ }
+ if (renderTextureCount < 1) {
+ CubismLogWarning("The number of render textures must be an integer greater than or equal to 1. Set the number of render textures to 1.");
+ }
+ this._renderTextureCount = renderTextureCount < 1 ? 1 : renderTextureCount;
+ this._clearedFrameBufferflags = [];
+ for (let i = 0; i < drawableCount; i++) {
+ if (drawableMaskCounts[i] <= 0) {
+ this._clippingContextListForDraw.push(null);
+ continue;
+ }
+ let clippingContext = this.findSameClip(drawableMasks[i], drawableMaskCounts[i]);
+ if (clippingContext == null) {
+ clippingContext = new CubismClippingContext(this, drawableMasks[i], drawableMaskCounts[i]);
+ this._clippingContextListForMask.push(clippingContext);
+ }
+ clippingContext.addClippedDrawable(i);
+ this._clippingContextListForDraw.push(clippingContext);
+ }
+ }
+ setupClippingContext(model, renderer) {
+ this._currentFrameNo++;
+ let usingClipCount = 0;
+ for (let clipIndex = 0; clipIndex < this._clippingContextListForMask.length; clipIndex++) {
+ const cc = this._clippingContextListForMask[clipIndex];
+ this.calcClippedDrawTotalBounds(model, cc);
+ if (cc._isUsing) {
+ usingClipCount++;
+ }
+ }
+ if (usingClipCount > 0) {
+ this.setupLayoutBounds(renderer.isUsingHighPrecisionMask() ? 0 : usingClipCount);
+ if (!renderer.isUsingHighPrecisionMask()) {
+ this.gl.viewport(0, 0, this._clippingMaskBufferSize, this._clippingMaskBufferSize);
+ this._currentMaskRenderTexture = this.getMaskRenderTexture()[0];
+ renderer.preDraw();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this._currentMaskRenderTexture);
+ }
+ if (!this._clearedFrameBufferflags) {
+ this._clearedFrameBufferflags = [];
+ }
+ for (let index = 0; index < this._renderTextureCount; index++) {
+ this._clearedFrameBufferflags[index] = false;
+ }
+ for (let clipIndex = 0; clipIndex < this._clippingContextListForMask.length; clipIndex++) {
+ const clipContext = this._clippingContextListForMask[clipIndex];
+ const allClipedDrawRect = clipContext._allClippedDrawRect;
+ const layoutBoundsOnTex01 = clipContext._layoutBounds;
+ const MARGIN = 0.05;
+ let scaleX = 0;
+ let scaleY = 0;
+ const clipContextRenderTexture = this.getMaskRenderTexture()[clipContext._bufferIndex];
+ if (this._currentMaskRenderTexture != clipContextRenderTexture && !renderer.isUsingHighPrecisionMask()) {
+ this._currentMaskRenderTexture = clipContextRenderTexture;
+ renderer.preDraw();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this._currentMaskRenderTexture);
+ }
+ if (renderer.isUsingHighPrecisionMask()) {
+ const ppu = model.getPixelsPerUnit();
+ const maskPixelSize = clipContext.getClippingManager()._clippingMaskBufferSize;
+ const physicalMaskWidth = layoutBoundsOnTex01.width * maskPixelSize;
+ const physicalMaskHeight = layoutBoundsOnTex01.height * maskPixelSize;
+ this._tmpBoundsOnModel.setRect(allClipedDrawRect);
+ if (this._tmpBoundsOnModel.width * ppu > physicalMaskWidth) {
+ this._tmpBoundsOnModel.expand(allClipedDrawRect.width * MARGIN, 0);
+ scaleX = layoutBoundsOnTex01.width / this._tmpBoundsOnModel.width;
+ } else {
+ scaleX = ppu / physicalMaskWidth;
+ }
+ if (this._tmpBoundsOnModel.height * ppu > physicalMaskHeight) {
+ this._tmpBoundsOnModel.expand(0, allClipedDrawRect.height * MARGIN);
+ scaleY = layoutBoundsOnTex01.height / this._tmpBoundsOnModel.height;
+ } else {
+ scaleY = ppu / physicalMaskHeight;
+ }
+ } else {
+ this._tmpBoundsOnModel.setRect(allClipedDrawRect);
+ this._tmpBoundsOnModel.expand(allClipedDrawRect.width * MARGIN, allClipedDrawRect.height * MARGIN);
+ scaleX = layoutBoundsOnTex01.width / this._tmpBoundsOnModel.width;
+ scaleY = layoutBoundsOnTex01.height / this._tmpBoundsOnModel.height;
+ }
+ {
+ this._tmpMatrix.loadIdentity();
+ {
+ this._tmpMatrix.translateRelative(-1, -1);
+ this._tmpMatrix.scaleRelative(2, 2);
+ }
+ {
+ this._tmpMatrix.translateRelative(layoutBoundsOnTex01.x, layoutBoundsOnTex01.y);
+ this._tmpMatrix.scaleRelative(scaleX, scaleY);
+ this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x, -this._tmpBoundsOnModel.y);
+ }
+ this._tmpMatrixForMask.setMatrix(this._tmpMatrix.getArray());
+ }
+ {
+ this._tmpMatrix.loadIdentity();
+ {
+ this._tmpMatrix.translateRelative(layoutBoundsOnTex01.x, layoutBoundsOnTex01.y);
+ this._tmpMatrix.scaleRelative(scaleX, scaleY);
+ this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x, -this._tmpBoundsOnModel.y);
+ }
+ this._tmpMatrixForDraw.setMatrix(this._tmpMatrix.getArray());
+ }
+ clipContext._matrixForMask.setMatrix(this._tmpMatrixForMask.getArray());
+ clipContext._matrixForDraw.setMatrix(this._tmpMatrixForDraw.getArray());
+ if (!renderer.isUsingHighPrecisionMask()) {
+ const clipDrawCount = clipContext._clippingIdCount;
+ for (let i = 0; i < clipDrawCount; i++) {
+ const clipDrawIndex = clipContext._clippingIdList[i];
+ if (!model.getDrawableDynamicFlagVertexPositionsDidChange(clipDrawIndex)) {
+ continue;
+ }
+ renderer.setIsCulling(model.getDrawableCulling(clipDrawIndex) != false);
+ if (!this._clearedFrameBufferflags[clipContext._bufferIndex]) {
+ this.gl.clearColor(1, 1, 1, 1);
+ this.gl.clear(this.gl.COLOR_BUFFER_BIT);
+ this._clearedFrameBufferflags[clipContext._bufferIndex] = true;
+ }
+ renderer.setClippingContextBufferForMask(clipContext);
+ renderer.drawMesh(model.getDrawableTextureIndex(clipDrawIndex), model.getDrawableVertexIndexCount(clipDrawIndex), model.getDrawableVertexCount(clipDrawIndex), model.getDrawableVertexIndices(clipDrawIndex), model.getDrawableVertices(clipDrawIndex), model.getDrawableVertexUvs(clipDrawIndex), model.getMultiplyColor(clipDrawIndex), model.getScreenColor(clipDrawIndex), model.getDrawableOpacity(clipDrawIndex), CubismBlendMode.CubismBlendMode_Normal, false);
+ }
+ }
+ }
+ if (!renderer.isUsingHighPrecisionMask()) {
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, s_fbo);
+ renderer.setClippingContextBufferForMask(null);
+ this.gl.viewport(s_viewport[0], s_viewport[1], s_viewport[2], s_viewport[3]);
+ }
+ }
+ }
+ findSameClip(drawableMasks, drawableMaskCounts) {
+ for (let i = 0; i < this._clippingContextListForMask.length; i++) {
+ const clippingContext = this._clippingContextListForMask[i];
+ const count = clippingContext._clippingIdCount;
+ if (count != drawableMaskCounts) {
+ continue;
+ }
+ let sameCount = 0;
+ for (let j = 0; j < count; j++) {
+ const clipId = clippingContext._clippingIdList[j];
+ for (let k = 0; k < count; k++) {
+ if (drawableMasks[k] == clipId) {
+ sameCount++;
+ break;
+ }
+ }
+ }
+ if (sameCount == count) {
+ return clippingContext;
+ }
+ }
+ return null;
+ }
+ setupLayoutBounds(usingClipCount) {
+ const useClippingMaskMaxCount = this._renderTextureCount <= 1 ? ClippingMaskMaxCountOnDefault : ClippingMaskMaxCountOnMultiRenderTexture * this._renderTextureCount;
+ if (usingClipCount <= 0 || usingClipCount > useClippingMaskMaxCount) {
+ if (usingClipCount > useClippingMaskMaxCount) {
+ CubismLogError("not supported mask count : {0}\n[Details] render texture count : {1}, mask count : {2}", usingClipCount - useClippingMaskMaxCount, this._renderTextureCount, usingClipCount);
+ }
+ for (let index = 0; index < this._clippingContextListForMask.length; index++) {
+ const clipContext = this._clippingContextListForMask[index];
+ clipContext._layoutChannelNo = 0;
+ clipContext._layoutBounds.x = 0;
+ clipContext._layoutBounds.y = 0;
+ clipContext._layoutBounds.width = 1;
+ clipContext._layoutBounds.height = 1;
+ clipContext._bufferIndex = 0;
+ }
+ return;
+ }
+ const layoutCountMaxValue = this._renderTextureCount <= 1 ? 9 : 8;
+ let countPerSheetDiv = usingClipCount / this._renderTextureCount;
+ let countPerSheetMod = usingClipCount % this._renderTextureCount;
+ countPerSheetDiv = ~~countPerSheetDiv;
+ countPerSheetMod = ~~countPerSheetMod;
+ let div = countPerSheetDiv / ColorChannelCount;
+ let mod = countPerSheetDiv % ColorChannelCount;
+ div = ~~div;
+ mod = ~~mod;
+ let curClipIndex = 0;
+ for (let renderTextureNo = 0; renderTextureNo < this._renderTextureCount; renderTextureNo++) {
+ for (let channelNo = 0; channelNo < ColorChannelCount; channelNo++) {
+ let layoutCount = div + (channelNo < mod ? 1 : 0);
+ const checkChannelNo = mod + 1 >= ColorChannelCount ? 0 : mod + 1;
+ if (layoutCount < layoutCountMaxValue && channelNo == checkChannelNo) {
+ layoutCount += renderTextureNo < countPerSheetMod ? 1 : 0;
+ }
+ if (layoutCount == 0)
+ ;
+ else if (layoutCount == 1) {
+ const clipContext = this._clippingContextListForMask[curClipIndex++];
+ clipContext._layoutChannelNo = channelNo;
+ clipContext._layoutBounds.x = 0;
+ clipContext._layoutBounds.y = 0;
+ clipContext._layoutBounds.width = 1;
+ clipContext._layoutBounds.height = 1;
+ clipContext._bufferIndex = renderTextureNo;
+ } else if (layoutCount == 2) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 2;
+ xpos = ~~xpos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos * 0.5;
+ cc._layoutBounds.y = 0;
+ cc._layoutBounds.width = 0.5;
+ cc._layoutBounds.height = 1;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else if (layoutCount <= 4) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 2;
+ let ypos = i / 2;
+ xpos = ~~xpos;
+ ypos = ~~ypos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos * 0.5;
+ cc._layoutBounds.y = ypos * 0.5;
+ cc._layoutBounds.width = 0.5;
+ cc._layoutBounds.height = 0.5;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else if (layoutCount <= layoutCountMaxValue) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 3;
+ let ypos = i / 3;
+ xpos = ~~xpos;
+ ypos = ~~ypos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos / 3;
+ cc._layoutBounds.y = ypos / 3;
+ cc._layoutBounds.width = 1 / 3;
+ cc._layoutBounds.height = 1 / 3;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else if (exports2.CubismConfig.supportMoreMaskDivisions && layoutCount <= 16) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 4;
+ let ypos = i / 4;
+ xpos = ~~xpos;
+ ypos = ~~ypos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos / 4;
+ cc._layoutBounds.y = ypos / 4;
+ cc._layoutBounds.width = 1 / 4;
+ cc._layoutBounds.height = 1 / 4;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else {
+ CubismLogError("not supported mask count : {0}\n[Details] render texture count : {1}, mask count : {2}", usingClipCount - useClippingMaskMaxCount, this._renderTextureCount, usingClipCount);
+ for (let index = 0; index < layoutCount; index++) {
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = 0;
+ cc._layoutBounds.x = 0;
+ cc._layoutBounds.y = 0;
+ cc._layoutBounds.width = 1;
+ cc._layoutBounds.height = 1;
+ cc._bufferIndex = 0;
+ }
+ }
+ }
+ }
+ }
+ getColorBuffer() {
+ return this._maskColorBuffers;
+ }
+ getClippingContextListForDraw() {
+ return this._clippingContextListForDraw;
+ }
+ getClippingMaskCount() {
+ return this._clippingContextListForMask.length;
+ }
+ setClippingMaskBufferSize(size) {
+ this._clippingMaskBufferSize = size;
+ }
+ getClippingMaskBufferSize() {
+ return this._clippingMaskBufferSize;
+ }
+ getRenderTextureCount() {
+ return this._renderTextureCount;
+ }
+ }
+ class CubismRenderTextureResource {
+ constructor(frameNo, texture) {
+ this.frameNo = frameNo;
+ this.textures = texture;
+ }
+ }
+ class CubismClippingContext {
+ constructor(manager, clippingDrawableIndices, clipCount) {
+ this._isUsing = false;
+ this._owner = manager;
+ this._clippingIdList = clippingDrawableIndices;
+ this._clippingIdCount = clipCount;
+ this._allClippedDrawRect = new csmRect();
+ this._layoutBounds = new csmRect();
+ this._clippedDrawableIndexList = [];
+ this._matrixForMask = new CubismMatrix44();
+ this._matrixForDraw = new CubismMatrix44();
+ this._bufferIndex = 0;
+ }
+ release() {
+ const self2 = this;
+ self2._layoutBounds = void 0;
+ self2._allClippedDrawRect = void 0;
+ self2._clippedDrawableIndexList = void 0;
+ }
+ addClippedDrawable(drawableIndex) {
+ this._clippedDrawableIndexList.push(drawableIndex);
+ }
+ getClippingManager() {
+ return this._owner;
+ }
+ setGl(gl) {
+ this._owner.setGL(gl);
+ }
+ }
+ class CubismRendererProfile_WebGL {
+ setGlEnable(index, enabled) {
+ if (enabled)
+ this.gl.enable(index);
+ else
+ this.gl.disable(index);
+ }
+ setGlEnableVertexAttribArray(index, enabled) {
+ if (enabled)
+ this.gl.enableVertexAttribArray(index);
+ else
+ this.gl.disableVertexAttribArray(index);
+ }
+ save() {
+ if (this.gl == null) {
+ CubismLogError("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");
+ return;
+ }
+ this._lastArrayBufferBinding = this.gl.getParameter(this.gl.ARRAY_BUFFER_BINDING);
+ this._lastArrayBufferBinding = this.gl.getParameter(this.gl.ELEMENT_ARRAY_BUFFER_BINDING);
+ this._lastProgram = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
+ this._lastActiveTexture = this.gl.getParameter(this.gl.ACTIVE_TEXTURE);
+ this.gl.activeTexture(this.gl.TEXTURE1);
+ this._lastTexture1Binding2D = this.gl.getParameter(this.gl.TEXTURE_BINDING_2D);
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this._lastTexture0Binding2D = this.gl.getParameter(this.gl.TEXTURE_BINDING_2D);
+ this._lastVertexAttribArrayEnabled[0] = this.gl.getVertexAttrib(0, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastVertexAttribArrayEnabled[1] = this.gl.getVertexAttrib(1, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastVertexAttribArrayEnabled[2] = this.gl.getVertexAttrib(2, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastVertexAttribArrayEnabled[3] = this.gl.getVertexAttrib(3, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastScissorTest = this.gl.isEnabled(this.gl.SCISSOR_TEST);
+ this._lastStencilTest = this.gl.isEnabled(this.gl.STENCIL_TEST);
+ this._lastDepthTest = this.gl.isEnabled(this.gl.DEPTH_TEST);
+ this._lastCullFace = this.gl.isEnabled(this.gl.CULL_FACE);
+ this._lastBlend = this.gl.isEnabled(this.gl.BLEND);
+ this._lastFrontFace = this.gl.getParameter(this.gl.FRONT_FACE);
+ this._lastColorMask = this.gl.getParameter(this.gl.COLOR_WRITEMASK);
+ this._lastBlending[0] = this.gl.getParameter(this.gl.BLEND_SRC_RGB);
+ this._lastBlending[1] = this.gl.getParameter(this.gl.BLEND_DST_RGB);
+ this._lastBlending[2] = this.gl.getParameter(this.gl.BLEND_SRC_ALPHA);
+ this._lastBlending[3] = this.gl.getParameter(this.gl.BLEND_DST_ALPHA);
+ this._lastFBO = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING);
+ this._lastViewport = this.gl.getParameter(this.gl.VIEWPORT);
+ }
+ restore() {
+ if (this.gl == null) {
+ CubismLogError("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");
+ return;
+ }
+ this.gl.useProgram(this._lastProgram);
+ this.setGlEnableVertexAttribArray(0, this._lastVertexAttribArrayEnabled[0]);
+ this.setGlEnableVertexAttribArray(1, this._lastVertexAttribArrayEnabled[1]);
+ this.setGlEnableVertexAttribArray(2, this._lastVertexAttribArrayEnabled[2]);
+ this.setGlEnableVertexAttribArray(3, this._lastVertexAttribArrayEnabled[3]);
+ this.setGlEnable(this.gl.SCISSOR_TEST, this._lastScissorTest);
+ this.setGlEnable(this.gl.STENCIL_TEST, this._lastStencilTest);
+ this.setGlEnable(this.gl.DEPTH_TEST, this._lastDepthTest);
+ this.setGlEnable(this.gl.CULL_FACE, this._lastCullFace);
+ this.setGlEnable(this.gl.BLEND, this._lastBlend);
+ this.gl.frontFace(this._lastFrontFace);
+ this.gl.colorMask(this._lastColorMask[0], this._lastColorMask[1], this._lastColorMask[2], this._lastColorMask[3]);
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this._lastArrayBufferBinding);
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this._lastElementArrayBufferBinding);
+ this.gl.activeTexture(this.gl.TEXTURE1);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this._lastTexture1Binding2D);
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this._lastTexture0Binding2D);
+ this.gl.activeTexture(this._lastActiveTexture);
+ this.gl.blendFuncSeparate(this._lastBlending[0], this._lastBlending[1], this._lastBlending[2], this._lastBlending[3]);
+ }
+ setGl(gl) {
+ this.gl = gl;
+ }
+ constructor() {
+ this._lastVertexAttribArrayEnabled = new Array(4);
+ this._lastColorMask = new Array(4);
+ this._lastBlending = new Array(4);
+ this._lastViewport = new Array(4);
+ }
+ }
+ class CubismShader_WebGL {
+ static getInstance() {
+ if (s_instance == null) {
+ s_instance = new CubismShader_WebGL();
+ return s_instance;
+ }
+ return s_instance;
+ }
+ static deleteInstance() {
+ if (s_instance) {
+ s_instance.release();
+ s_instance = void 0;
+ }
+ }
+ constructor() {
+ this._shaderSets = [];
+ }
+ release() {
+ this.releaseShaderProgram();
+ }
+ setupShaderProgram(renderer, textureId, vertexCount, vertexArray, indexArray, uvArray, bufferData, opacity, colorBlendMode, baseColor, multiplyColor, screenColor, isPremultipliedAlpha, matrix4x4, invertedMask) {
+ if (!isPremultipliedAlpha) {
+ CubismLogError("NoPremultipliedAlpha is not allowed");
+ }
+ if (this._shaderSets.length == 0) {
+ this.generateShaders();
+ }
+ let SRC_COLOR;
+ let DST_COLOR;
+ let SRC_ALPHA;
+ let DST_ALPHA;
+ const clippingContextBufferForMask = renderer.getClippingContextBufferForMask();
+ if (clippingContextBufferForMask != null) {
+ const shaderSet = this._shaderSets[ShaderNames.ShaderNames_SetupMask];
+ this.gl.useProgram(shaderSet.shaderProgram);
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, textureId);
+ this.gl.uniform1i(shaderSet.samplerTexture0Location, 0);
+ if (bufferData.vertex == null) {
+ bufferData.vertex = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.vertex);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, vertexArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributePositionLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributePositionLocation, 2, this.gl.FLOAT, false, 0, 0);
+ if (bufferData.uv == null) {
+ bufferData.uv = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.uv);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, uvArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributeTexCoordLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributeTexCoordLocation, 2, this.gl.FLOAT, false, 0, 0);
+ const channelNo = clippingContextBufferForMask._layoutChannelNo;
+ const colorChannel = clippingContextBufferForMask.getClippingManager().getChannelFlagAsColor(channelNo);
+ this.gl.uniform4f(shaderSet.uniformChannelFlagLocation, colorChannel.R, colorChannel.G, colorChannel.B, colorChannel.A);
+ this.gl.uniformMatrix4fv(shaderSet.uniformClipMatrixLocation, false, clippingContextBufferForMask._matrixForMask.getArray());
+ const rect = clippingContextBufferForMask._layoutBounds;
+ this.gl.uniform4f(shaderSet.uniformBaseColorLocation, rect.x * 2 - 1, rect.y * 2 - 1, rect.getRight() * 2 - 1, rect.getBottom() * 2 - 1);
+ this.gl.uniform4f(shaderSet.uniformMultiplyColorLocation, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A);
+ this.gl.uniform4f(shaderSet.uniformScreenColorLocation, screenColor.R, screenColor.G, screenColor.B, screenColor.A);
+ SRC_COLOR = this.gl.ZERO;
+ DST_COLOR = this.gl.ONE_MINUS_SRC_COLOR;
+ SRC_ALPHA = this.gl.ZERO;
+ DST_ALPHA = this.gl.ONE_MINUS_SRC_ALPHA;
+ } else {
+ const clippingContextBufferForDraw = renderer.getClippingContextBufferForDraw();
+ const masked = clippingContextBufferForDraw != null;
+ const offset = masked ? invertedMask ? 2 : 1 : 0;
+ let shaderSet;
+ switch (colorBlendMode) {
+ case CubismBlendMode.CubismBlendMode_Normal:
+ default:
+ shaderSet = this._shaderSets[ShaderNames.ShaderNames_NormalPremultipliedAlpha + offset];
+ SRC_COLOR = this.gl.ONE;
+ DST_COLOR = this.gl.ONE_MINUS_SRC_ALPHA;
+ SRC_ALPHA = this.gl.ONE;
+ DST_ALPHA = this.gl.ONE_MINUS_SRC_ALPHA;
+ break;
+ case CubismBlendMode.CubismBlendMode_Additive:
+ shaderSet = this._shaderSets[ShaderNames.ShaderNames_AddPremultipliedAlpha + offset];
+ SRC_COLOR = this.gl.ONE;
+ DST_COLOR = this.gl.ONE;
+ SRC_ALPHA = this.gl.ZERO;
+ DST_ALPHA = this.gl.ONE;
+ break;
+ case CubismBlendMode.CubismBlendMode_Multiplicative:
+ shaderSet = this._shaderSets[ShaderNames.ShaderNames_MultPremultipliedAlpha + offset];
+ SRC_COLOR = this.gl.DST_COLOR;
+ DST_COLOR = this.gl.ONE_MINUS_SRC_ALPHA;
+ SRC_ALPHA = this.gl.ZERO;
+ DST_ALPHA = this.gl.ONE;
+ break;
+ }
+ this.gl.useProgram(shaderSet.shaderProgram);
+ if (bufferData.vertex == null) {
+ bufferData.vertex = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.vertex);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, vertexArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributePositionLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributePositionLocation, 2, this.gl.FLOAT, false, 0, 0);
+ if (bufferData.uv == null) {
+ bufferData.uv = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.uv);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, uvArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributeTexCoordLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributeTexCoordLocation, 2, this.gl.FLOAT, false, 0, 0);
+ if (clippingContextBufferForDraw != null) {
+ this.gl.activeTexture(this.gl.TEXTURE1);
+ const tex = clippingContextBufferForDraw.getClippingManager().getColorBuffer()[renderer.getClippingContextBufferForDraw()._bufferIndex];
+ this.gl.bindTexture(this.gl.TEXTURE_2D, tex);
+ this.gl.uniform1i(shaderSet.samplerTexture1Location, 1);
+ this.gl.uniformMatrix4fv(shaderSet.uniformClipMatrixLocation, false, clippingContextBufferForDraw._matrixForDraw.getArray());
+ const channelNo = clippingContextBufferForDraw._layoutChannelNo;
+ const colorChannel = clippingContextBufferForDraw.getClippingManager().getChannelFlagAsColor(channelNo);
+ this.gl.uniform4f(shaderSet.uniformChannelFlagLocation, colorChannel.R, colorChannel.G, colorChannel.B, colorChannel.A);
+ }
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, textureId);
+ this.gl.uniform1i(shaderSet.samplerTexture0Location, 0);
+ this.gl.uniformMatrix4fv(shaderSet.uniformMatrixLocation, false, matrix4x4.getArray());
+ this.gl.uniform4f(shaderSet.uniformBaseColorLocation, baseColor.R, baseColor.G, baseColor.B, baseColor.A);
+ this.gl.uniform4f(shaderSet.uniformMultiplyColorLocation, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A);
+ this.gl.uniform4f(shaderSet.uniformScreenColorLocation, screenColor.R, screenColor.G, screenColor.B, screenColor.A);
+ }
+ if (bufferData.index == null) {
+ bufferData.index = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, bufferData.index);
+ this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, indexArray, this.gl.DYNAMIC_DRAW);
+ this.gl.blendFuncSeparate(SRC_COLOR, DST_COLOR, SRC_ALPHA, DST_ALPHA);
+ }
+ releaseShaderProgram() {
+ for (let i = 0; i < this._shaderSets.length; i++) {
+ this.gl.deleteProgram(this._shaderSets[i].shaderProgram);
+ this._shaderSets[i].shaderProgram = 0;
+ }
+ this._shaderSets = [];
+ }
+ generateShaders() {
+ for (let i = 0; i < ShaderCount; i++) {
+ this._shaderSets.push({});
+ }
+ this._shaderSets[0].shaderProgram = this.loadShaderProgram(vertexShaderSrcSetupMask, fragmentShaderSrcsetupMask);
+ this._shaderSets[1].shaderProgram = this.loadShaderProgram(vertexShaderSrc, fragmentShaderSrcPremultipliedAlpha);
+ this._shaderSets[2].shaderProgram = this.loadShaderProgram(vertexShaderSrcMasked, fragmentShaderSrcMaskPremultipliedAlpha);
+ this._shaderSets[3].shaderProgram = this.loadShaderProgram(vertexShaderSrcMasked, fragmentShaderSrcMaskInvertedPremultipliedAlpha);
+ this._shaderSets[4].shaderProgram = this._shaderSets[1].shaderProgram;
+ this._shaderSets[5].shaderProgram = this._shaderSets[2].shaderProgram;
+ this._shaderSets[6].shaderProgram = this._shaderSets[3].shaderProgram;
+ this._shaderSets[7].shaderProgram = this._shaderSets[1].shaderProgram;
+ this._shaderSets[8].shaderProgram = this._shaderSets[2].shaderProgram;
+ this._shaderSets[9].shaderProgram = this._shaderSets[3].shaderProgram;
+ this._shaderSets[0].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[0].shaderProgram, "a_position");
+ this._shaderSets[0].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[0].shaderProgram, "a_texCoord");
+ this._shaderSets[0].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "s_texture0");
+ this._shaderSets[0].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_clipMatrix");
+ this._shaderSets[0].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_channelFlag");
+ this._shaderSets[0].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_baseColor");
+ this._shaderSets[0].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_multiplyColor");
+ this._shaderSets[0].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_screenColor");
+ this._shaderSets[1].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[1].shaderProgram, "a_position");
+ this._shaderSets[1].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[1].shaderProgram, "a_texCoord");
+ this._shaderSets[1].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "s_texture0");
+ this._shaderSets[1].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_matrix");
+ this._shaderSets[1].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_baseColor");
+ this._shaderSets[1].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_multiplyColor");
+ this._shaderSets[1].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_screenColor");
+ this._shaderSets[2].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[2].shaderProgram, "a_position");
+ this._shaderSets[2].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[2].shaderProgram, "a_texCoord");
+ this._shaderSets[2].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "s_texture0");
+ this._shaderSets[2].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "s_texture1");
+ this._shaderSets[2].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_matrix");
+ this._shaderSets[2].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_clipMatrix");
+ this._shaderSets[2].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_channelFlag");
+ this._shaderSets[2].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_baseColor");
+ this._shaderSets[2].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_multiplyColor");
+ this._shaderSets[2].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_screenColor");
+ this._shaderSets[3].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[3].shaderProgram, "a_position");
+ this._shaderSets[3].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[3].shaderProgram, "a_texCoord");
+ this._shaderSets[3].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "s_texture0");
+ this._shaderSets[3].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "s_texture1");
+ this._shaderSets[3].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_matrix");
+ this._shaderSets[3].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_clipMatrix");
+ this._shaderSets[3].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_channelFlag");
+ this._shaderSets[3].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_baseColor");
+ this._shaderSets[3].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_multiplyColor");
+ this._shaderSets[3].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_screenColor");
+ this._shaderSets[4].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[4].shaderProgram, "a_position");
+ this._shaderSets[4].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[4].shaderProgram, "a_texCoord");
+ this._shaderSets[4].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "s_texture0");
+ this._shaderSets[4].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_matrix");
+ this._shaderSets[4].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_baseColor");
+ this._shaderSets[4].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_multiplyColor");
+ this._shaderSets[4].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_screenColor");
+ this._shaderSets[5].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[5].shaderProgram, "a_position");
+ this._shaderSets[5].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[5].shaderProgram, "a_texCoord");
+ this._shaderSets[5].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "s_texture0");
+ this._shaderSets[5].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "s_texture1");
+ this._shaderSets[5].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_matrix");
+ this._shaderSets[5].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_clipMatrix");
+ this._shaderSets[5].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_channelFlag");
+ this._shaderSets[5].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_baseColor");
+ this._shaderSets[5].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_multiplyColor");
+ this._shaderSets[5].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_screenColor");
+ this._shaderSets[6].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[6].shaderProgram, "a_position");
+ this._shaderSets[6].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[6].shaderProgram, "a_texCoord");
+ this._shaderSets[6].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "s_texture0");
+ this._shaderSets[6].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "s_texture1");
+ this._shaderSets[6].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_matrix");
+ this._shaderSets[6].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_clipMatrix");
+ this._shaderSets[6].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_channelFlag");
+ this._shaderSets[6].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_baseColor");
+ this._shaderSets[6].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_multiplyColor");
+ this._shaderSets[6].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_screenColor");
+ this._shaderSets[7].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[7].shaderProgram, "a_position");
+ this._shaderSets[7].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[7].shaderProgram, "a_texCoord");
+ this._shaderSets[7].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "s_texture0");
+ this._shaderSets[7].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_matrix");
+ this._shaderSets[7].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_baseColor");
+ this._shaderSets[7].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_multiplyColor");
+ this._shaderSets[7].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_screenColor");
+ this._shaderSets[8].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[8].shaderProgram, "a_position");
+ this._shaderSets[8].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[8].shaderProgram, "a_texCoord");
+ this._shaderSets[8].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "s_texture0");
+ this._shaderSets[8].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "s_texture1");
+ this._shaderSets[8].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_matrix");
+ this._shaderSets[8].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_clipMatrix");
+ this._shaderSets[8].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_channelFlag");
+ this._shaderSets[8].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_baseColor");
+ this._shaderSets[8].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_multiplyColor");
+ this._shaderSets[8].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_screenColor");
+ this._shaderSets[9].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[9].shaderProgram, "a_position");
+ this._shaderSets[9].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[9].shaderProgram, "a_texCoord");
+ this._shaderSets[9].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "s_texture0");
+ this._shaderSets[9].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "s_texture1");
+ this._shaderSets[9].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_matrix");
+ this._shaderSets[9].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_clipMatrix");
+ this._shaderSets[9].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_channelFlag");
+ this._shaderSets[9].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_baseColor");
+ this._shaderSets[9].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_multiplyColor");
+ this._shaderSets[9].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_screenColor");
+ }
+ loadShaderProgram(vertexShaderSource, fragmentShaderSource) {
+ const shaderProgram = this.gl.createProgram();
+ const vertShader = this.compileShaderSource(this.gl.VERTEX_SHADER, vertexShaderSource);
+ if (!vertShader) {
+ CubismLogError("Vertex shader compile error!");
+ return 0;
+ }
+ const fragShader = this.compileShaderSource(this.gl.FRAGMENT_SHADER, fragmentShaderSource);
+ if (!fragShader) {
+ CubismLogError("Vertex shader compile error!");
+ return 0;
+ }
+ this.gl.attachShader(shaderProgram, vertShader);
+ this.gl.attachShader(shaderProgram, fragShader);
+ this.gl.linkProgram(shaderProgram);
+ const linkStatus = this.gl.getProgramParameter(shaderProgram, this.gl.LINK_STATUS);
+ if (!linkStatus) {
+ CubismLogError("Failed to link program: {0}", shaderProgram);
+ this.gl.deleteShader(vertShader);
+ this.gl.deleteShader(fragShader);
+ if (shaderProgram) {
+ this.gl.deleteProgram(shaderProgram);
+ }
+ return 0;
+ }
+ this.gl.deleteShader(vertShader);
+ this.gl.deleteShader(fragShader);
+ return shaderProgram;
+ }
+ compileShaderSource(shaderType, shaderSource) {
+ const source = shaderSource;
+ const shader = this.gl.createShader(shaderType);
+ this.gl.shaderSource(shader, source);
+ this.gl.compileShader(shader);
+ if (!shader) {
+ const log = this.gl.getShaderInfoLog(shader);
+ CubismLogError("Shader compile log: {0} ", log);
+ }
+ const status = this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS);
+ if (!status) {
+ this.gl.deleteShader(shader);
+ return null;
+ }
+ return shader;
+ }
+ setGl(gl) {
+ this.gl = gl;
+ }
+ }
+ var ShaderNames = /* @__PURE__ */ ((ShaderNames2) => {
+ ShaderNames2[ShaderNames2["ShaderNames_SetupMask"] = 0] = "ShaderNames_SetupMask";
+ ShaderNames2[ShaderNames2["ShaderNames_NormalPremultipliedAlpha"] = 1] = "ShaderNames_NormalPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_NormalMaskedPremultipliedAlpha"] = 2] = "ShaderNames_NormalMaskedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_NomralMaskedInvertedPremultipliedAlpha"] = 3] = "ShaderNames_NomralMaskedInvertedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_AddPremultipliedAlpha"] = 4] = "ShaderNames_AddPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_AddMaskedPremultipliedAlpha"] = 5] = "ShaderNames_AddMaskedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_AddMaskedPremultipliedAlphaInverted"] = 6] = "ShaderNames_AddMaskedPremultipliedAlphaInverted";
+ ShaderNames2[ShaderNames2["ShaderNames_MultPremultipliedAlpha"] = 7] = "ShaderNames_MultPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_MultMaskedPremultipliedAlpha"] = 8] = "ShaderNames_MultMaskedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_MultMaskedPremultipliedAlphaInverted"] = 9] = "ShaderNames_MultMaskedPremultipliedAlphaInverted";
+ return ShaderNames2;
+ })(ShaderNames || {});
+ const vertexShaderSrcSetupMask = "attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_myPos;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_clipMatrix * a_position; v_myPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}";
+ const fragmentShaderSrcsetupMask = "precision mediump float;varying vec2 v_texCoord;varying vec4 v_myPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;void main(){ float isInside = step(u_baseColor.x, v_myPos.x/v_myPos.w) * step(u_baseColor.y, v_myPos.y/v_myPos.w) * step(v_myPos.x/v_myPos.w, u_baseColor.z) * step(v_myPos.y/v_myPos.w, u_baseColor.w); gl_FragColor = u_channelFlag * texture2D(s_texture0, v_texCoord).a * isInside;}";
+ const vertexShaderSrc = "attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;uniform mat4 u_matrix;void main(){ gl_Position = u_matrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}";
+ const vertexShaderSrcMasked = "attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform mat4 u_matrix;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_matrix * a_position; v_clipPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}";
+ const fragmentShaderSrcPremultipliedAlpha = "precision mediump float;varying vec2 v_texCoord;uniform vec4 u_baseColor;uniform sampler2D s_texture0;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 color = texColor * u_baseColor; gl_FragColor = vec4(color.rgb, color.a);}";
+ const fragmentShaderSrcMaskPremultipliedAlpha = "precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * maskVal; gl_FragColor = col_formask;}";
+ const fragmentShaderSrcMaskInvertedPremultipliedAlpha = "precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_channelFlag;uniform vec4 u_baseColor;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * (1.0 - maskVal); gl_FragColor = col_formask;}";
+ class CubismRenderer_WebGL extends CubismRenderer {
+ constructor() {
+ super();
+ this._clippingContextBufferForMask = null;
+ this._clippingContextBufferForDraw = null;
+ this._rendererProfile = new CubismRendererProfile_WebGL();
+ this.firstDraw = true;
+ this._textures = {};
+ this._sortedDrawableIndexList = [];
+ this._bufferData = {
+ vertex: null,
+ uv: null,
+ index: null
+ };
+ }
+ initialize(model, maskBufferCount = 1) {
+ if (model.isUsingMasking()) {
+ this._clippingManager = new CubismClippingManager_WebGL();
+ this._clippingManager.initialize(model, model.getDrawableCount(), model.getDrawableMasks(), model.getDrawableMaskCounts(), maskBufferCount);
+ }
+ for (let i = model.getDrawableCount() - 1; i >= 0; i--) {
+ this._sortedDrawableIndexList[i] = 0;
+ }
+ super.initialize(model);
+ }
+ bindTexture(modelTextureNo, glTexture) {
+ this._textures[modelTextureNo] = glTexture;
+ }
+ getBindedTextures() {
+ return this._textures;
+ }
+ setClippingMaskBufferSize(size) {
+ if (!this._model.isUsingMasking()) {
+ return;
+ }
+ const renderTextureCount = this._clippingManager.getRenderTextureCount();
+ this._clippingManager.release();
+ this._clippingManager = new CubismClippingManager_WebGL();
+ this._clippingManager.setClippingMaskBufferSize(size);
+ this._clippingManager.initialize(this.getModel(), this.getModel().getDrawableCount(), this.getModel().getDrawableMasks(), this.getModel().getDrawableMaskCounts(), renderTextureCount);
+ }
+ getClippingMaskBufferSize() {
+ return this._model.isUsingMasking() ? this._clippingManager.getClippingMaskBufferSize() : -1;
+ }
+ getRenderTextureCount() {
+ return this._model.isUsingMasking() ? this._clippingManager.getRenderTextureCount() : -1;
+ }
+ release() {
+ var _a, _b, _c;
+ const self2 = this;
+ this._clippingManager.release();
+ self2._clippingManager = void 0;
+ (_a = this.gl) == null ? void 0 : _a.deleteBuffer(this._bufferData.vertex);
+ this._bufferData.vertex = null;
+ (_b = this.gl) == null ? void 0 : _b.deleteBuffer(this._bufferData.uv);
+ this._bufferData.uv = null;
+ (_c = this.gl) == null ? void 0 : _c.deleteBuffer(this._bufferData.index);
+ this._bufferData.index = null;
+ self2._bufferData = void 0;
+ self2._textures = void 0;
+ }
+ doDrawModel() {
+ if (this.gl == null) {
+ CubismLogError("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");
+ return;
+ }
+ if (this._clippingManager != null) {
+ this.preDraw();
+ this._clippingManager.setupClippingContext(this.getModel(), this);
+ }
+ this.preDraw();
+ const drawableCount = this.getModel().getDrawableCount();
+ const renderOrder = this.getModel().getDrawableRenderOrders();
+ for (let i = 0; i < drawableCount; ++i) {
+ const order = renderOrder[i];
+ this._sortedDrawableIndexList[order] = i;
+ }
+ for (let i = 0; i < drawableCount; ++i) {
+ const drawableIndex = this._sortedDrawableIndexList[i];
+ if (!this.getModel().getDrawableDynamicFlagIsVisible(drawableIndex)) {
+ continue;
+ }
+ const clipContext = this._clippingManager != null ? this._clippingManager.getClippingContextListForDraw()[drawableIndex] : null;
+ if (clipContext != null && this.isUsingHighPrecisionMask()) {
+ if (clipContext._isUsing) {
+ this.gl.viewport(0, 0, this._clippingManager.getClippingMaskBufferSize(), this._clippingManager.getClippingMaskBufferSize());
+ this.preDraw();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, clipContext.getClippingManager().getMaskRenderTexture()[clipContext._bufferIndex]);
+ this.gl.clearColor(1, 1, 1, 1);
+ this.gl.clear(this.gl.COLOR_BUFFER_BIT);
+ }
+ {
+ const clipDrawCount = clipContext._clippingIdCount;
+ for (let index = 0; index < clipDrawCount; index++) {
+ const clipDrawIndex = clipContext._clippingIdList[index];
+ if (!this._model.getDrawableDynamicFlagVertexPositionsDidChange(clipDrawIndex)) {
+ continue;
+ }
+ this.setIsCulling(this._model.getDrawableCulling(clipDrawIndex) != false);
+ this.setClippingContextBufferForMask(clipContext);
+ this.drawMesh(this.getModel().getDrawableTextureIndex(clipDrawIndex), this.getModel().getDrawableVertexIndexCount(clipDrawIndex), this.getModel().getDrawableVertexCount(clipDrawIndex), this.getModel().getDrawableVertexIndices(clipDrawIndex), this.getModel().getDrawableVertices(clipDrawIndex), this.getModel().getDrawableVertexUvs(clipDrawIndex), this.getModel().getMultiplyColor(clipDrawIndex), this.getModel().getScreenColor(clipDrawIndex), this.getModel().getDrawableOpacity(clipDrawIndex), CubismBlendMode.CubismBlendMode_Normal, false);
+ }
+ }
+ {
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, s_fbo);
+ this.setClippingContextBufferForMask(null);
+ this.gl.viewport(s_viewport[0], s_viewport[1], s_viewport[2], s_viewport[3]);
+ this.preDraw();
+ }
+ }
+ this.setClippingContextBufferForDraw(clipContext);
+ this.setIsCulling(this.getModel().getDrawableCulling(drawableIndex));
+ this.drawMesh(this.getModel().getDrawableTextureIndex(drawableIndex), this.getModel().getDrawableVertexIndexCount(drawableIndex), this.getModel().getDrawableVertexCount(drawableIndex), this.getModel().getDrawableVertexIndices(drawableIndex), this.getModel().getDrawableVertices(drawableIndex), this.getModel().getDrawableVertexUvs(drawableIndex), this.getModel().getMultiplyColor(drawableIndex), this.getModel().getScreenColor(drawableIndex), this.getModel().getDrawableOpacity(drawableIndex), this.getModel().getDrawableBlendMode(drawableIndex), this.getModel().getDrawableInvertedMaskBit(drawableIndex));
+ }
+ }
+ drawMesh(textureNo, indexCount, vertexCount, indexArray, vertexArray, uvArray, multiplyColor, screenColor, opacity, colorBlendMode, invertedMask) {
+ if (this.isCulling()) {
+ this.gl.enable(this.gl.CULL_FACE);
+ } else {
+ this.gl.disable(this.gl.CULL_FACE);
+ }
+ this.gl.frontFace(this.gl.CCW);
+ const modelColorRGBA = this.getModelColor();
+ if (this.getClippingContextBufferForMask() == null) {
+ modelColorRGBA.A *= opacity;
+ if (this.isPremultipliedAlpha()) {
+ modelColorRGBA.R *= modelColorRGBA.A;
+ modelColorRGBA.G *= modelColorRGBA.A;
+ modelColorRGBA.B *= modelColorRGBA.A;
+ }
+ }
+ let drawtexture = null;
+ if (this._textures[textureNo] != null) {
+ drawtexture = this._textures[textureNo];
+ }
+ CubismShader_WebGL.getInstance().setupShaderProgram(this, drawtexture, vertexCount, vertexArray, indexArray, uvArray, this._bufferData, opacity, colorBlendMode, modelColorRGBA, multiplyColor, screenColor, this.isPremultipliedAlpha(), this.getMvpMatrix(), invertedMask);
+ this.gl.drawElements(this.gl.TRIANGLES, indexCount, this.gl.UNSIGNED_SHORT, 0);
+ this.gl.useProgram(null);
+ this.setClippingContextBufferForDraw(null);
+ this.setClippingContextBufferForMask(null);
+ }
+ saveProfile() {
+ this._rendererProfile.save();
+ }
+ restoreProfile() {
+ this._rendererProfile.restore();
+ }
+ static doStaticRelease() {
+ CubismShader_WebGL.deleteInstance();
+ }
+ setRenderState(fbo, viewport) {
+ s_fbo = fbo;
+ s_viewport = viewport;
+ }
+ preDraw() {
+ if (this.firstDraw) {
+ this.firstDraw = false;
+ }
+ this.gl.disable(this.gl.SCISSOR_TEST);
+ this.gl.disable(this.gl.STENCIL_TEST);
+ this.gl.disable(this.gl.DEPTH_TEST);
+ this.gl.frontFace(this.gl.CW);
+ this.gl.enable(this.gl.BLEND);
+ this.gl.colorMask(true, true, true, true);
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);
+ if (this.getAnisotropy() > 0 && this._extension) {
+ for (const tex of Object.entries(this._textures)) {
+ this.gl.bindTexture(this.gl.TEXTURE_2D, tex);
+ this.gl.texParameterf(this.gl.TEXTURE_2D, this._extension.TEXTURE_MAX_ANISOTROPY_EXT, this.getAnisotropy());
+ }
+ }
+ }
+ setClippingContextBufferForMask(clip) {
+ this._clippingContextBufferForMask = clip;
+ }
+ getClippingContextBufferForMask() {
+ return this._clippingContextBufferForMask;
+ }
+ setClippingContextBufferForDraw(clip) {
+ this._clippingContextBufferForDraw = clip;
+ }
+ getClippingContextBufferForDraw() {
+ return this._clippingContextBufferForDraw;
+ }
+ startUp(gl) {
+ this.gl = gl;
+ if (this._clippingManager) {
+ this._clippingManager.setGL(gl);
+ }
+ CubismShader_WebGL.getInstance().setGl(gl);
+ this._rendererProfile.setGl(gl);
+ this._extension = this.gl.getExtension("EXT_texture_filter_anisotropic") || this.gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic") || this.gl.getExtension("MOZ_EXT_texture_filter_anisotropic");
+ }
+ }
+ CubismRenderer.staticRelease = () => {
+ CubismRenderer_WebGL.doStaticRelease();
+ };
+ class CubismModelSettingsJson {
+ constructor(json) {
+ this.groups = json.Groups;
+ this.hitAreas = json.HitAreas;
+ this.layout = json.Layout;
+ this.moc = json.FileReferences.Moc;
+ this.expressions = json.FileReferences.Expressions;
+ this.motions = json.FileReferences.Motions;
+ this.textures = json.FileReferences.Textures;
+ this.physics = json.FileReferences.Physics;
+ this.pose = json.FileReferences.Pose;
+ }
+ getEyeBlinkParameters() {
+ var _a, _b;
+ return (_b = (_a = this.groups) == null ? void 0 : _a.find((group) => group.Name === "EyeBlink")) == null ? void 0 : _b.Ids;
+ }
+ getLipSyncParameters() {
+ var _a, _b;
+ return (_b = (_a = this.groups) == null ? void 0 : _a.find((group) => group.Name === "LipSync")) == null ? void 0 : _b.Ids;
+ }
+ }
+ const HitAreaPrefix = "HitArea";
+ const HitAreaHead = "Head";
+ const HitAreaBody = "Body";
+ const PartsIdCore = "Parts01Core";
+ const PartsArmPrefix = "Parts01Arm_";
+ const PartsArmLPrefix = "Parts01ArmL_";
+ const PartsArmRPrefix = "Parts01ArmR_";
+ const ParamAngleX = "ParamAngleX";
+ const ParamAngleY = "ParamAngleY";
+ const ParamAngleZ = "ParamAngleZ";
+ const ParamEyeLOpen = "ParamEyeLOpen";
+ const ParamEyeLSmile = "ParamEyeLSmile";
+ const ParamEyeROpen = "ParamEyeROpen";
+ const ParamEyeRSmile = "ParamEyeRSmile";
+ const ParamEyeBallX = "ParamEyeBallX";
+ const ParamEyeBallY = "ParamEyeBallY";
+ const ParamEyeBallForm = "ParamEyeBallForm";
+ const ParamBrowLY = "ParamBrowLY";
+ const ParamBrowRY = "ParamBrowRY";
+ const ParamBrowLX = "ParamBrowLX";
+ const ParamBrowRX = "ParamBrowRX";
+ const ParamBrowLAngle = "ParamBrowLAngle";
+ const ParamBrowRAngle = "ParamBrowRAngle";
+ const ParamBrowLForm = "ParamBrowLForm";
+ const ParamBrowRForm = "ParamBrowRForm";
+ const ParamMouthForm = "ParamMouthForm";
+ const ParamMouthOpenY = "ParamMouthOpenY";
+ const ParamCheek = "ParamCheek";
+ const ParamBodyAngleX = "ParamBodyAngleX";
+ const ParamBodyAngleY = "ParamBodyAngleY";
+ const ParamBodyAngleZ = "ParamBodyAngleZ";
+ const ParamBreath = "ParamBreath";
+ const ParamArmLA = "ParamArmLA";
+ const ParamArmRA = "ParamArmRA";
+ const ParamArmLB = "ParamArmLB";
+ const ParamArmRB = "ParamArmRB";
+ const ParamHandL = "ParamHandL";
+ const ParamHandR = "ParamHandR";
+ const ParamHairFront = "ParamHairFront";
+ const ParamHairSide = "ParamHairSide";
+ const ParamHairBack = "ParamHairBack";
+ const ParamHairFluffy = "ParamHairFluffy";
+ const ParamShoulderY = "ParamShoulderY";
+ const ParamBustX = "ParamBustX";
+ const ParamBustY = "ParamBustY";
+ const ParamBaseX = "ParamBaseX";
+ const ParamBaseY = "ParamBaseY";
+ const ParamNONE = "NONE:";
+ const LOGICAL_WIDTH = 2;
+ const LOGICAL_HEIGHT = 2;
+ exports2.config = void 0;
+ ((config2) => {
+ config2.LOG_LEVEL_VERBOSE = 0;
+ config2.LOG_LEVEL_WARNING = 1;
+ config2.LOG_LEVEL_ERROR = 2;
+ config2.LOG_LEVEL_NONE = 999;
+ config2.logLevel = config2.LOG_LEVEL_WARNING;
+ config2.sound = true;
+ config2.motionSync = true;
+ config2.motionFadingDuration = 500;
+ config2.idleMotionFadingDuration = 2e3;
+ config2.expressionFadingDuration = 500;
+ config2.preserveExpressionOnMotion = true;
+ config2.cubism4 = exports2.CubismConfig;
+ })(exports2.config || (exports2.config = {}));
+ const VERSION = "0.4.0";
+ const logger = {
+ log(tag, ...messages) {
+ if (exports2.config.logLevel <= exports2.config.LOG_LEVEL_VERBOSE) {
+ console.log(`[${tag}]`, ...messages);
+ }
+ },
+ warn(tag, ...messages) {
+ if (exports2.config.logLevel <= exports2.config.LOG_LEVEL_WARNING) {
+ console.warn(`[${tag}]`, ...messages);
+ }
+ },
+ error(tag, ...messages) {
+ if (exports2.config.logLevel <= exports2.config.LOG_LEVEL_ERROR) {
+ console.error(`[${tag}]`, ...messages);
+ }
+ }
+ };
+ function clamp(num, lower, upper) {
+ return num < lower ? lower : num > upper ? upper : num;
+ }
+ function rand(min, max) {
+ return Math.random() * (max - min) + min;
+ }
+ function copyProperty(type, from, to, fromKey, toKey) {
+ const value = from[fromKey];
+ if (value !== null && typeof value === type) {
+ to[toKey] = value;
+ }
+ }
+ function copyArray(type, from, to, fromKey, toKey) {
+ const array = from[fromKey];
+ if (Array.isArray(array)) {
+ to[toKey] = array.filter((item) => item !== null && typeof item === type);
+ }
+ }
+ function applyMixins(derivedCtor, baseCtors) {
+ baseCtors.forEach((baseCtor) => {
+ Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
+ if (name !== "constructor") {
+ Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
+ }
+ });
+ });
+ }
+ function folderName(url) {
+ let lastSlashIndex = url.lastIndexOf("/");
+ if (lastSlashIndex != -1) {
+ url = url.slice(0, lastSlashIndex);
+ }
+ lastSlashIndex = url.lastIndexOf("/");
+ if (lastSlashIndex !== -1) {
+ url = url.slice(lastSlashIndex + 1);
+ }
+ return url;
+ }
+ function remove(array, item) {
+ const index = array.indexOf(item);
+ if (index !== -1) {
+ array.splice(index, 1);
+ }
+ }
+ class ExpressionManager extends utils.EventEmitter {
+ constructor(settings, options) {
+ super();
+ this.expressions = [];
+ this.reserveExpressionIndex = -1;
+ this.destroyed = false;
+ this.settings = settings;
+ this.tag = `ExpressionManager(${settings.name})`;
+ }
+ init() {
+ this.defaultExpression = this.createExpression({}, void 0);
+ this.currentExpression = this.defaultExpression;
+ this.stopAllExpressions();
+ }
+ loadExpression(index) {
+ return __async(this, null, function* () {
+ if (!this.definitions[index]) {
+ logger.warn(this.tag, `Undefined expression at [${index}]`);
+ return void 0;
+ }
+ if (this.expressions[index] === null) {
+ logger.warn(this.tag, `Cannot set expression at [${index}] because it's already failed in loading.`);
+ return void 0;
+ }
+ if (this.expressions[index]) {
+ return this.expressions[index];
+ }
+ const expression = yield this._loadExpression(index);
+ this.expressions[index] = expression;
+ return expression;
+ });
+ }
+ _loadExpression(index) {
+ throw new Error("Not implemented.");
+ }
+ setRandomExpression() {
+ return __async(this, null, function* () {
+ if (this.definitions.length) {
+ const availableIndices = [];
+ for (let i = 0; i < this.definitions.length; i++) {
+ if (this.expressions[i] !== null && this.expressions[i] !== this.currentExpression && i !== this.reserveExpressionIndex) {
+ availableIndices.push(i);
+ }
+ }
+ if (availableIndices.length) {
+ const index = Math.floor(Math.random() * availableIndices.length);
+ return this.setExpression(index);
+ }
+ }
+ return false;
+ });
+ }
+ resetExpression() {
+ this._setExpression(this.defaultExpression);
+ }
+ restoreExpression() {
+ this._setExpression(this.currentExpression);
+ }
+ setExpression(index) {
+ return __async(this, null, function* () {
+ if (typeof index !== "number") {
+ index = this.getExpressionIndex(index);
+ }
+ if (!(index > -1 && index < this.definitions.length)) {
+ return false;
+ }
+ if (index === this.expressions.indexOf(this.currentExpression)) {
+ return false;
+ }
+ this.reserveExpressionIndex = index;
+ const expression = yield this.loadExpression(index);
+ if (!expression || this.reserveExpressionIndex !== index) {
+ return false;
+ }
+ this.reserveExpressionIndex = -1;
+ this.currentExpression = expression;
+ this._setExpression(expression);
+ return true;
+ });
+ }
+ update(model, now) {
+ if (!this.isFinished()) {
+ return this.updateParameters(model, now);
+ }
+ return false;
+ }
+ destroy() {
+ this.destroyed = true;
+ this.emit("destroy");
+ const self2 = this;
+ self2.definitions = void 0;
+ self2.expressions = void 0;
+ }
+ }
+ const EPSILON = 0.01;
+ const MAX_SPEED = 40 / 7.5;
+ const ACCELERATION_TIME = 1 / (0.15 * 1e3);
+ class FocusController {
+ constructor() {
+ this.targetX = 0;
+ this.targetY = 0;
+ this.x = 0;
+ this.y = 0;
+ this.vx = 0;
+ this.vy = 0;
+ }
+ focus(x, y, instant = false) {
+ this.targetX = clamp(x, -1, 1);
+ this.targetY = clamp(y, -1, 1);
+ if (instant) {
+ this.x = this.targetX;
+ this.y = this.targetY;
+ }
+ }
+ update(dt) {
+ const dx = this.targetX - this.x;
+ const dy = this.targetY - this.y;
+ if (Math.abs(dx) < EPSILON && Math.abs(dy) < EPSILON)
+ return;
+ const d = Math.sqrt(__pow(dx, 2) + __pow(dy, 2));
+ const maxSpeed = MAX_SPEED / (1e3 / dt);
+ let ax = maxSpeed * (dx / d) - this.vx;
+ let ay = maxSpeed * (dy / d) - this.vy;
+ const a = Math.sqrt(__pow(ax, 2) + __pow(ay, 2));
+ const maxA = maxSpeed * ACCELERATION_TIME * dt;
+ if (a > maxA) {
+ ax *= maxA / a;
+ ay *= maxA / a;
+ }
+ this.vx += ax;
+ this.vy += ay;
+ const v = Math.sqrt(__pow(this.vx, 2) + __pow(this.vy, 2));
+ const maxV = 0.5 * (Math.sqrt(__pow(maxA, 2) + 8 * maxA * d) - maxA);
+ if (v > maxV) {
+ this.vx *= maxV / v;
+ this.vy *= maxV / v;
+ }
+ this.x += this.vx;
+ this.y += this.vy;
+ }
+ }
+ class ModelSettings {
+ constructor(json) {
+ this.json = json;
+ let url2 = json.url;
+ if (typeof url2 !== "string") {
+ throw new TypeError("The `url` field in settings JSON must be defined as a string.");
+ }
+ this.url = url2;
+ this.name = folderName(this.url);
+ }
+ resolveURL(path) {
+ return utils.url.resolve(this.url, path);
+ }
+ replaceFiles(replacer) {
+ this.moc = replacer(this.moc, "moc");
+ if (this.pose !== void 0) {
+ this.pose = replacer(this.pose, "pose");
+ }
+ if (this.physics !== void 0) {
+ this.physics = replacer(this.physics, "physics");
+ }
+ for (let i = 0; i < this.textures.length; i++) {
+ this.textures[i] = replacer(this.textures[i], `textures[${i}]`);
+ }
+ }
+ getDefinedFiles() {
+ const files = [];
+ this.replaceFiles((file) => {
+ files.push(file);
+ return file;
+ });
+ return files;
+ }
+ validateFiles(files) {
+ const assertFileExists = (expectedFile, shouldThrow) => {
+ const actualPath = this.resolveURL(expectedFile);
+ if (!files.includes(actualPath)) {
+ if (shouldThrow) {
+ throw new Error(`File "${expectedFile}" is defined in settings, but doesn't exist in given files`);
+ }
+ return false;
+ }
+ return true;
+ };
+ const essentialFiles = [this.moc, ...this.textures];
+ essentialFiles.forEach((texture) => assertFileExists(texture, true));
+ const definedFiles = this.getDefinedFiles();
+ return definedFiles.filter((file) => assertFileExists(file, false));
+ }
+ }
+ var MotionPriority = /* @__PURE__ */ ((MotionPriority2) => {
+ MotionPriority2[MotionPriority2["NONE"] = 0] = "NONE";
+ MotionPriority2[MotionPriority2["IDLE"] = 1] = "IDLE";
+ MotionPriority2[MotionPriority2["NORMAL"] = 2] = "NORMAL";
+ MotionPriority2[MotionPriority2["FORCE"] = 3] = "FORCE";
+ return MotionPriority2;
+ })(MotionPriority || {});
+ class MotionState {
+ constructor() {
+ this.debug = false;
+ this.currentPriority = 0;
+ this.reservePriority = 0;
+ }
+ reserve(group, index, priority) {
+ if (priority <= 0) {
+ logger.log(this.tag, `Cannot start a motion with MotionPriority.NONE.`);
+ return false;
+ }
+ if (group === this.currentGroup && index === this.currentIndex) {
+ logger.log(this.tag, `Motion is already playing.`, this.dump(group, index));
+ return false;
+ }
+ if (group === this.reservedGroup && index === this.reservedIndex || group === this.reservedIdleGroup && index === this.reservedIdleIndex) {
+ logger.log(this.tag, `Motion is already reserved.`, this.dump(group, index));
+ return false;
+ }
+ if (priority === 1) {
+ if (this.currentPriority !== 0) {
+ logger.log(this.tag, `Cannot start idle motion because another motion is playing.`, this.dump(group, index));
+ return false;
+ }
+ if (this.reservedIdleGroup !== void 0) {
+ logger.log(this.tag, `Cannot start idle motion because another idle motion has reserved.`, this.dump(group, index));
+ return false;
+ }
+ this.setReservedIdle(group, index);
+ } else {
+ if (priority < 3) {
+ if (priority <= this.currentPriority) {
+ logger.log(this.tag, "Cannot start motion because another motion is playing as an equivalent or higher priority.", this.dump(group, index));
+ return false;
+ }
+ if (priority <= this.reservePriority) {
+ logger.log(this.tag, "Cannot start motion because another motion has reserved as an equivalent or higher priority.", this.dump(group, index));
+ return false;
+ }
+ }
+ this.setReserved(group, index, priority);
+ }
+ return true;
+ }
+ start(motion, group, index, priority) {
+ if (priority === 1) {
+ this.setReservedIdle(void 0, void 0);
+ if (this.currentPriority !== 0) {
+ logger.log(this.tag, "Cannot start idle motion because another motion is playing.", this.dump(group, index));
+ return false;
+ }
+ } else {
+ if (group !== this.reservedGroup || index !== this.reservedIndex) {
+ logger.log(this.tag, "Cannot start motion because another motion has taken the place.", this.dump(group, index));
+ return false;
+ }
+ this.setReserved(void 0, void 0, 0);
+ }
+ if (!motion) {
+ return false;
+ }
+ this.setCurrent(group, index, priority);
+ return true;
+ }
+ complete() {
+ this.setCurrent(void 0, void 0, 0);
+ }
+ setCurrent(group, index, priority) {
+ this.currentPriority = priority;
+ this.currentGroup = group;
+ this.currentIndex = index;
+ }
+ setReserved(group, index, priority) {
+ this.reservePriority = priority;
+ this.reservedGroup = group;
+ this.reservedIndex = index;
+ }
+ setReservedIdle(group, index) {
+ this.reservedIdleGroup = group;
+ this.reservedIdleIndex = index;
+ }
+ isActive(group, index) {
+ return group === this.currentGroup && index === this.currentIndex || group === this.reservedGroup && index === this.reservedIndex || group === this.reservedIdleGroup && index === this.reservedIdleIndex;
+ }
+ reset() {
+ this.setCurrent(void 0, void 0, 0);
+ this.setReserved(void 0, void 0, 0);
+ this.setReservedIdle(void 0, void 0);
+ }
+ shouldRequestIdleMotion() {
+ return this.currentGroup === void 0 && this.reservedIdleGroup === void 0;
+ }
+ shouldOverrideExpression() {
+ return !exports2.config.preserveExpressionOnMotion && this.currentPriority > 1;
+ }
+ dump(requestedGroup, requestedIndex) {
+ if (this.debug) {
+ const keys = [
+ "currentPriority",
+ "reservePriority",
+ "currentGroup",
+ "currentIndex",
+ "reservedGroup",
+ "reservedIndex",
+ "reservedIdleGroup",
+ "reservedIdleIndex"
+ ];
+ return `
+ group = "${requestedGroup}", index = ${requestedIndex}
+` + keys.map((key) => "[" + key + "] " + this[key]).join("\n");
+ }
+ return "";
+ }
+ }
+ const TAG$2 = "SoundManager";
+ const VOLUME = 0.9;
+ class SoundManager {
+ static get volume() {
+ return this._volume;
+ }
+ static set volume(value) {
+ this._volume = (value > 1 ? 1 : value < 0 ? 0 : value) || 0;
+ this.audios.forEach((audio) => audio.volume = this._volume);
+ }
+ static add(file, onFinish, onError) {
+ const audio = new Audio(file);
+ audio.volume = this._volume;
+ audio.preload = "auto";
+ audio.autoplay = true;
+ audio.crossOrigin = "anonymous";
+ audio.addEventListener("ended", () => {
+ this.dispose(audio);
+ onFinish == null ? void 0 : onFinish();
+ });
+ audio.addEventListener("error", (e) => {
+ this.dispose(audio);
+ logger.warn(TAG$2, `Error occurred on "${file}"`, e.error);
+ onError == null ? void 0 : onError(e.error);
+ });
+ this.audios.push(audio);
+ return audio;
+ }
+ static play(audio) {
+ return new Promise((resolve, reject) => {
+ var _a;
+ (_a = audio.play()) == null ? void 0 : _a.catch((e) => {
+ audio.dispatchEvent(new ErrorEvent("error", { error: e }));
+ reject(e);
+ });
+ if (audio.readyState === audio.HAVE_ENOUGH_DATA) {
+ resolve();
+ } else {
+ audio.addEventListener("canplaythrough", resolve);
+ }
+ });
+ }
+ static addContext(audio) {
+ const context = new AudioContext();
+ this.contexts.push(context);
+ return context;
+ }
+ static addAnalyzer(audio, context) {
+ const source = context.createMediaElementSource(audio);
+ const analyser = context.createAnalyser();
+ analyser.fftSize = 256;
+ analyser.minDecibels = -90;
+ analyser.maxDecibels = -10;
+ analyser.smoothingTimeConstant = 0.85;
+ source.connect(analyser);
+ analyser.connect(context.destination);
+ this.analysers.push(analyser);
+ return analyser;
+ }
+ static analyze(analyser) {
+ if (analyser != void 0) {
+ let pcmData = new Float32Array(analyser.fftSize);
+ let sumSquares = 0;
+ analyser.getFloatTimeDomainData(pcmData);
+ for (const amplitude of pcmData) {
+ sumSquares += amplitude * amplitude;
+ }
+ return parseFloat(Math.sqrt(sumSquares / pcmData.length * 20).toFixed(1));
+ } else {
+ return parseFloat(Math.random().toFixed(1));
+ }
+ }
+ static dispose(audio) {
+ audio.pause();
+ audio.removeAttribute("src");
+ remove(this.audios, audio);
+ }
+ static destroy() {
+ for (let i = this.contexts.length - 1; i >= 0; i--) {
+ this.contexts[i].close();
+ }
+ for (let i = this.audios.length - 1; i >= 0; i--) {
+ this.dispose(this.audios[i]);
+ }
+ }
+ }
+ SoundManager.audios = [];
+ SoundManager.analysers = [];
+ SoundManager.contexts = [];
+ SoundManager._volume = VOLUME;
+ var MotionPreloadStrategy = /* @__PURE__ */ ((MotionPreloadStrategy2) => {
+ MotionPreloadStrategy2["ALL"] = "ALL";
+ MotionPreloadStrategy2["IDLE"] = "IDLE";
+ MotionPreloadStrategy2["NONE"] = "NONE";
+ return MotionPreloadStrategy2;
+ })(MotionPreloadStrategy || {});
+ class MotionManager extends utils.EventEmitter {
+ constructor(settings, options) {
+ super();
+ this.motionGroups = {};
+ this.state = new MotionState();
+ this.playing = false;
+ this.destroyed = false;
+ this.settings = settings;
+ this.tag = `MotionManager(${settings.name})`;
+ this.state.tag = this.tag;
+ }
+ init(options) {
+ if (options == null ? void 0 : options.idleMotionGroup) {
+ this.groups.idle = options.idleMotionGroup;
+ }
+ this.setupMotions(options);
+ this.stopAllMotions();
+ }
+ setupMotions(options) {
+ for (const group of Object.keys(this.definitions)) {
+ this.motionGroups[group] = [];
+ }
+ let groups;
+ switch (options == null ? void 0 : options.motionPreload) {
+ case "NONE":
+ return;
+ case "ALL":
+ groups = Object.keys(this.definitions);
+ break;
+ case "IDLE":
+ default:
+ groups = [this.groups.idle];
+ break;
+ }
+ for (const group of groups) {
+ if (this.definitions[group]) {
+ for (let i = 0; i < this.definitions[group].length; i++) {
+ this.loadMotion(group, i).then();
+ }
+ }
+ }
+ }
+ loadMotion(group, index) {
+ return __async(this, null, function* () {
+ var _a;
+ if (!((_a = this.definitions[group]) == null ? void 0 : _a[index])) {
+ logger.warn(this.tag, `Undefined motion at "${group}"[${index}]`);
+ return void 0;
+ }
+ if (this.motionGroups[group][index] === null) {
+ logger.warn(this.tag, `Cannot start motion at "${group}"[${index}] because it's already failed in loading.`);
+ return void 0;
+ }
+ if (this.motionGroups[group][index]) {
+ return this.motionGroups[group][index];
+ }
+ const motion = yield this._loadMotion(group, index);
+ if (this.destroyed) {
+ return;
+ }
+ this.motionGroups[group][index] = motion != null ? motion : null;
+ return motion;
+ });
+ }
+ _loadMotion(group, index) {
+ throw new Error("Not implemented.");
+ }
+ speakUp(sound, volume, expression) {
+ return __async(this, null, function* () {
+ if (!exports2.config.sound) {
+ return false;
+ }
+ let audio;
+ let analyzer;
+ let context;
+ if (this.currentAudio) {
+ if (!this.currentAudio.ended) {
+ return false;
+ }
+ }
+ let soundURL;
+ const isBase64Content = sound && sound.startsWith("data:audio/wav;base64");
+ if (sound && !isBase64Content) {
+ var A = document.createElement("a");
+ A.href = sound;
+ sound = A.href;
+ soundURL = sound;
+ } else {
+ soundURL = "data:audio/wav;base64";
+ }
+ const isUrlPath = sound && (sound.startsWith("http") || sound.startsWith("blob"));
+ let file;
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ audio = SoundManager.add(file, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ }, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ });
+ this.currentAudio = audio;
+ let _volume = 1;
+ if (volume !== void 0) {
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+ } catch (e) {
+ logger.warn(this.tag, "Failed to create audio", soundURL, e);
+ }
+ }
+ if (audio) {
+ const readyToPlay = SoundManager.play(audio).catch((e) => logger.warn(this.tag, "Failed to play audio", audio.src, e));
+ if (exports2.config.motionSync) {
+ yield readyToPlay;
+ }
+ }
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ if (expression && this.expressionManager) {
+ this.expressionManager.setExpression(expression);
+ }
+ this.playing = true;
+ return true;
+ });
+ }
+ startMotion(_0, _1) {
+ return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, sound, volume, expression) {
+ var _a;
+ if (this.currentAudio) {
+ if (!this.currentAudio.ended) {
+ return false;
+ }
+ }
+ if (!this.state.reserve(group, index, priority)) {
+ return false;
+ }
+ const definition = (_a = this.definitions[group]) == null ? void 0 : _a[index];
+ if (!definition) {
+ return false;
+ }
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ }
+ let audio;
+ let analyzer;
+ let context;
+ if (exports2.config.sound) {
+ const isBase64Content = sound && sound.startsWith("data:audio/wav;base64");
+ if (sound && !isBase64Content) {
+ var A = document.createElement("a");
+ A.href = sound;
+ sound = A.href;
+ }
+ const isUrlPath = sound && (sound.startsWith("http") || sound.startsWith("blob"));
+ const soundURL = this.getSoundFile(definition);
+ let file = soundURL;
+ if (soundURL) {
+ file = this.settings.resolveURL(soundURL) + "?cache-buster=" + new Date().getTime();
+ }
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ audio = SoundManager.add(file, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ }, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ });
+ this.currentAudio = audio;
+ let _volume = 1;
+ if (volume !== void 0) {
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+ } catch (e) {
+ logger.warn(this.tag, "Failed to create audio", soundURL, e);
+ }
+ }
+ }
+ const motion = yield this.loadMotion(group, index);
+ if (audio) {
+ priority = 3;
+ const readyToPlay = SoundManager.play(audio).catch((e) => logger.warn(this.tag, "Failed to play audio", audio.src, e));
+ if (exports2.config.motionSync) {
+ yield readyToPlay;
+ }
+ }
+ if (!this.state.start(motion, group, index, priority)) {
+ if (audio) {
+ SoundManager.dispose(audio);
+ this.currentAudio = void 0;
+ }
+ return false;
+ }
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ logger.log(this.tag, "Start motion:", this.getMotionName(definition));
+ this.emit("motionStart", group, index, audio);
+ if (expression && this.expressionManager) {
+ this.expressionManager.setExpression(expression);
+ }
+ this.playing = true;
+ this._startMotion(motion);
+ return true;
+ });
+ }
+ startRandomMotion(group, priority, sound, volume) {
+ return __async(this, null, function* () {
+ const groupDefs = this.definitions[group];
+ if (groupDefs == null ? void 0 : groupDefs.length) {
+ const availableIndices = [];
+ for (let i = 0; i < groupDefs.length; i++) {
+ if (this.motionGroups[group][i] !== null && !this.state.isActive(group, i)) {
+ availableIndices.push(i);
+ }
+ }
+ if (availableIndices.length) {
+ const index = availableIndices[Math.floor(Math.random() * availableIndices.length)];
+ return this.startMotion(group, index, priority, sound, volume);
+ }
+ }
+ return false;
+ });
+ }
+ stopSpeaking() {
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ this.currentAudio = void 0;
+ }
+ }
+ stopAllMotions() {
+ this._stopAllMotions();
+ this.state.reset();
+ this.stopSpeaking();
+ }
+ update(model, now) {
+ var _a;
+ if (this.isFinished()) {
+ if (this.playing) {
+ this.playing = false;
+ this.emit("motionFinish");
+ }
+ if (this.state.shouldOverrideExpression()) {
+ (_a = this.expressionManager) == null ? void 0 : _a.restoreExpression();
+ }
+ this.state.complete();
+ if (this.state.shouldRequestIdleMotion()) {
+ this.startRandomMotion(this.groups.idle, MotionPriority.IDLE);
+ }
+ }
+ return this.updateParameters(model, now);
+ }
+ mouthSync() {
+ if (this.currentAnalyzer) {
+ return SoundManager.analyze(this.currentAnalyzer);
+ } else {
+ return 0;
+ }
+ }
+ destroy() {
+ var _a;
+ this.destroyed = true;
+ this.emit("destroy");
+ this.stopAllMotions();
+ (_a = this.expressionManager) == null ? void 0 : _a.destroy();
+ const self2 = this;
+ self2.definitions = void 0;
+ self2.motionGroups = void 0;
+ }
+ }
+ const tempBounds = { x: 0, y: 0, width: 0, height: 0 };
+ class InternalModel extends utils.EventEmitter {
+ constructor() {
+ super(...arguments);
+ this.focusController = new FocusController();
+ this.originalWidth = 0;
+ this.originalHeight = 0;
+ this.width = 0;
+ this.height = 0;
+ this.localTransform = new math.Matrix();
+ this.drawingMatrix = new math.Matrix();
+ this.hitAreas = {};
+ this.textureFlipY = false;
+ this.viewport = [0, 0, 0, 0];
+ this.destroyed = false;
+ }
+ init() {
+ this.setupLayout();
+ this.setupHitAreas();
+ }
+ setupLayout() {
+ const self2 = this;
+ const size = this.getSize();
+ self2.originalWidth = size[0];
+ self2.originalHeight = size[1];
+ const layout = Object.assign({
+ width: LOGICAL_WIDTH,
+ height: LOGICAL_HEIGHT
+ }, this.getLayout());
+ this.localTransform.scale(layout.width / LOGICAL_WIDTH, layout.height / LOGICAL_HEIGHT);
+ self2.width = this.originalWidth * this.localTransform.a;
+ self2.height = this.originalHeight * this.localTransform.d;
+ const offsetX = layout.x !== void 0 && layout.x - layout.width / 2 || layout.centerX !== void 0 && layout.centerX || layout.left !== void 0 && layout.left - layout.width / 2 || layout.right !== void 0 && layout.right + layout.width / 2 || 0;
+ const offsetY = layout.y !== void 0 && layout.y - layout.height / 2 || layout.centerY !== void 0 && layout.centerY || layout.top !== void 0 && layout.top - layout.height / 2 || layout.bottom !== void 0 && layout.bottom + layout.height / 2 || 0;
+ this.localTransform.translate(this.width * offsetX, -this.height * offsetY);
+ }
+ setupHitAreas() {
+ const definitions = this.getHitAreaDefs().filter((hitArea) => hitArea.index >= 0);
+ for (const def of definitions) {
+ this.hitAreas[def.name] = def;
+ }
+ }
+ hitTest(x, y) {
+ return Object.keys(this.hitAreas).filter((hitAreaName) => this.isHit(hitAreaName, x, y));
+ }
+ isHit(hitAreaName, x, y) {
+ if (!this.hitAreas[hitAreaName]) {
+ return false;
+ }
+ const drawIndex = this.hitAreas[hitAreaName].index;
+ const bounds = this.getDrawableBounds(drawIndex, tempBounds);
+ return bounds.x <= x && x <= bounds.x + bounds.width && bounds.y <= y && y <= bounds.y + bounds.height;
+ }
+ getDrawableBounds(index, bounds) {
+ const vertices = this.getDrawableVertices(index);
+ let left = vertices[0];
+ let right = vertices[0];
+ let top = vertices[1];
+ let bottom = vertices[1];
+ for (let i = 0; i < vertices.length; i += 2) {
+ const vx = vertices[i];
+ const vy = vertices[i + 1];
+ left = Math.min(vx, left);
+ right = Math.max(vx, right);
+ top = Math.min(vy, top);
+ bottom = Math.max(vy, bottom);
+ }
+ bounds != null ? bounds : bounds = {};
+ bounds.x = left;
+ bounds.y = top;
+ bounds.width = right - left;
+ bounds.height = bottom - top;
+ return bounds;
+ }
+ updateTransform(transform) {
+ this.drawingMatrix.copyFrom(transform).append(this.localTransform);
+ }
+ update(dt, now) {
+ this.focusController.update(dt);
+ }
+ destroy() {
+ this.destroyed = true;
+ this.emit("destroy");
+ this.motionManager.destroy();
+ this.motionManager = void 0;
+ }
+ }
+ const TAG$1 = "XHRLoader";
+ class NetworkError extends Error {
+ constructor(message, url, status, aborted = false) {
+ super(message);
+ this.url = url;
+ this.status = status;
+ this.aborted = aborted;
+ }
+ }
+ const _XHRLoader = class {
+ static createXHR(target, url, type, onload, onerror) {
+ const xhr = new XMLHttpRequest();
+ _XHRLoader.allXhrSet.add(xhr);
+ if (target) {
+ let xhrSet = _XHRLoader.xhrMap.get(target);
+ if (!xhrSet) {
+ xhrSet = /* @__PURE__ */ new Set([xhr]);
+ _XHRLoader.xhrMap.set(target, xhrSet);
+ } else {
+ xhrSet.add(xhr);
+ }
+ if (!target.listeners("destroy").includes(_XHRLoader.cancelXHRs)) {
+ target.once("destroy", _XHRLoader.cancelXHRs);
+ }
+ }
+ xhr.open("GET", url);
+ xhr.responseType = type;
+ xhr.onload = () => {
+ if ((xhr.status === 200 || xhr.status === 0) && xhr.response) {
+ onload(xhr.response);
+ } else {
+ xhr.onerror();
+ }
+ };
+ xhr.onerror = () => {
+ logger.warn(TAG$1, `Failed to load resource as ${xhr.responseType} (Status ${xhr.status}): ${url}`);
+ onerror(new NetworkError("Network error.", url, xhr.status));
+ };
+ xhr.onabort = () => onerror(new NetworkError("Aborted.", url, xhr.status, true));
+ xhr.onloadend = () => {
+ var _a;
+ _XHRLoader.allXhrSet.delete(xhr);
+ if (target) {
+ (_a = _XHRLoader.xhrMap.get(target)) == null ? void 0 : _a.delete(xhr);
+ }
+ };
+ return xhr;
+ }
+ static cancelXHRs() {
+ var _a;
+ (_a = _XHRLoader.xhrMap.get(this)) == null ? void 0 : _a.forEach((xhr) => {
+ xhr.abort();
+ _XHRLoader.allXhrSet.delete(xhr);
+ });
+ _XHRLoader.xhrMap.delete(this);
+ }
+ static release() {
+ _XHRLoader.allXhrSet.forEach((xhr) => xhr.abort());
+ _XHRLoader.allXhrSet.clear();
+ _XHRLoader.xhrMap = /* @__PURE__ */ new WeakMap();
+ }
+ };
+ let XHRLoader = _XHRLoader;
+ XHRLoader.xhrMap = /* @__PURE__ */ new WeakMap();
+ XHRLoader.allXhrSet = /* @__PURE__ */ new Set();
+ XHRLoader.loader = (context, next) => {
+ return new Promise((resolve, reject) => {
+ const xhr = _XHRLoader.createXHR(context.target, context.settings ? context.settings.resolveURL(context.url) : context.url, context.type, (data) => {
+ context.result = data;
+ resolve();
+ }, reject);
+ xhr.send();
+ });
+ };
+ function runMiddlewares(middleware, context) {
+ let index = -1;
+ return dispatch(0);
+ function dispatch(i, err) {
+ if (err)
+ return Promise.reject(err);
+ if (i <= index)
+ return Promise.reject(new Error("next() called multiple times"));
+ index = i;
+ const fn = middleware[i];
+ if (!fn)
+ return Promise.resolve();
+ try {
+ return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
+ } catch (err2) {
+ return Promise.reject(err2);
+ }
+ }
+ }
+ class Live2DLoader {
+ static load(context) {
+ return runMiddlewares(this.middlewares, context).then(() => context.result);
+ }
+ }
+ Live2DLoader.middlewares = [XHRLoader.loader];
+ function createTexture(url, options = {}) {
+ var _a;
+ const textureOptions = { resourceOptions: { crossorigin: options.crossOrigin } };
+ if (core.Texture.fromURL) {
+ return core.Texture.fromURL(url, textureOptions).catch((e) => {
+ if (e instanceof Error) {
+ throw e;
+ }
+ const err = new Error("Texture loading error");
+ err.event = e;
+ throw err;
+ });
+ }
+ textureOptions.resourceOptions.autoLoad = false;
+ const texture = core.Texture.from(url, textureOptions);
+ if (texture.baseTexture.valid) {
+ return Promise.resolve(texture);
+ }
+ const resource = texture.baseTexture.resource;
+ (_a = resource._live2d_load) != null ? _a : resource._live2d_load = new Promise((resolve, reject) => {
+ const errorHandler = (event) => {
+ resource.source.removeEventListener("error", errorHandler);
+ const err = new Error("Texture loading error");
+ err.event = event;
+ reject(err);
+ };
+ resource.source.addEventListener("error", errorHandler);
+ resource.load().then(() => resolve(texture)).catch(errorHandler);
+ });
+ return resource._live2d_load;
+ }
+ const TAG = "Live2DFactory";
+ const urlToJSON = (context, next) => __async(this, null, function* () {
+ if (typeof context.source === "string") {
+ const data = yield Live2DLoader.load({
+ url: context.source,
+ type: "json",
+ target: context.live2dModel
+ });
+ data.url = context.source;
+ context.source = data;
+ context.live2dModel.emit("settingsJSONLoaded", data);
+ }
+ return next();
+ });
+ const jsonToSettings = (context, next) => __async(this, null, function* () {
+ if (context.source instanceof ModelSettings) {
+ context.settings = context.source;
+ return next();
+ } else if (typeof context.source === "object") {
+ const runtime = Live2DFactory.findRuntime(context.source);
+ if (runtime) {
+ const settings = runtime.createModelSettings(context.source);
+ context.settings = settings;
+ context.live2dModel.emit("settingsLoaded", settings);
+ return next();
+ }
+ }
+ throw new TypeError("Unknown settings format.");
+ });
+ const waitUntilReady = (context, next) => {
+ if (context.settings) {
+ const runtime = Live2DFactory.findRuntime(context.settings);
+ if (runtime) {
+ return runtime.ready().then(next);
+ }
+ }
+ return next();
+ };
+ const setupOptionals = (context, next) => __async(this, null, function* () {
+ yield next();
+ const internalModel = context.internalModel;
+ if (internalModel) {
+ const settings = context.settings;
+ const runtime = Live2DFactory.findRuntime(settings);
+ if (runtime) {
+ const tasks = [];
+ if (settings.pose) {
+ tasks.push(Live2DLoader.load({
+ settings,
+ url: settings.pose,
+ type: "json",
+ target: internalModel
+ }).then((data) => {
+ internalModel.pose = runtime.createPose(internalModel.coreModel, data);
+ context.live2dModel.emit("poseLoaded", internalModel.pose);
+ }).catch((e) => {
+ context.live2dModel.emit("poseLoadError", e);
+ logger.warn(TAG, "Failed to load pose.", e);
+ }));
+ }
+ if (settings.physics) {
+ tasks.push(Live2DLoader.load({
+ settings,
+ url: settings.physics,
+ type: "json",
+ target: internalModel
+ }).then((data) => {
+ internalModel.physics = runtime.createPhysics(internalModel.coreModel, data);
+ context.live2dModel.emit("physicsLoaded", internalModel.physics);
+ }).catch((e) => {
+ context.live2dModel.emit("physicsLoadError", e);
+ logger.warn(TAG, "Failed to load physics.", e);
+ }));
+ }
+ if (tasks.length) {
+ yield Promise.all(tasks);
+ }
+ }
+ }
+ });
+ const setupEssentials = (context, next) => __async(this, null, function* () {
+ if (context.settings) {
+ const live2DModel = context.live2dModel;
+ const textureLoadings = context.settings.textures.map((tex) => {
+ const url = context.settings.resolveURL(tex);
+ return createTexture(url, { crossOrigin: context.options.crossOrigin });
+ });
+ yield next();
+ if (context.internalModel) {
+ live2DModel.internalModel = context.internalModel;
+ live2DModel.emit("modelLoaded", context.internalModel);
+ } else {
+ throw new TypeError("Missing internal model.");
+ }
+ live2DModel.textures = yield Promise.all(textureLoadings);
+ live2DModel.emit("textureLoaded", live2DModel.textures);
+ } else {
+ throw new TypeError("Missing settings.");
+ }
+ });
+ const createInternalModel = (context, next) => __async(this, null, function* () {
+ const settings = context.settings;
+ if (settings instanceof ModelSettings) {
+ const runtime = Live2DFactory.findRuntime(settings);
+ if (!runtime) {
+ throw new TypeError("Unknown model settings.");
+ }
+ const modelData = yield Live2DLoader.load({
+ settings,
+ url: settings.moc,
+ type: "arraybuffer",
+ target: context.live2dModel
+ });
+ if (!runtime.isValidMoc(modelData)) {
+ throw new Error("Invalid moc data");
+ }
+ const coreModel = runtime.createCoreModel(modelData);
+ context.internalModel = runtime.createInternalModel(coreModel, settings, context.options);
+ return next();
+ }
+ throw new TypeError("Missing settings.");
+ });
+ const _Live2DFactory = class {
+ static registerRuntime(runtime) {
+ _Live2DFactory.runtimes.push(runtime);
+ _Live2DFactory.runtimes.sort((a, b) => b.version - a.version);
+ }
+ static findRuntime(source) {
+ for (const runtime of _Live2DFactory.runtimes) {
+ if (runtime.test(source)) {
+ return runtime;
+ }
+ }
+ }
+ static setupLive2DModel(live2dModel, source, options) {
+ return __async(this, null, function* () {
+ const textureLoaded = new Promise((resolve) => live2dModel.once("textureLoaded", resolve));
+ const modelLoaded = new Promise((resolve) => live2dModel.once("modelLoaded", resolve));
+ const readyEventEmitted = Promise.all([textureLoaded, modelLoaded]).then(() => live2dModel.emit("ready"));
+ yield runMiddlewares(_Live2DFactory.live2DModelMiddlewares, {
+ live2dModel,
+ source,
+ options: options || {}
+ });
+ yield readyEventEmitted;
+ live2dModel.emit("load");
+ });
+ }
+ static loadMotion(motionManager, group, index) {
+ var _a, _b;
+ const handleError = (e) => motionManager.emit("motionLoadError", group, index, e);
+ try {
+ const definition = (_a = motionManager.definitions[group]) == null ? void 0 : _a[index];
+ if (!definition) {
+ return Promise.resolve(void 0);
+ }
+ if (!motionManager.listeners("destroy").includes(_Live2DFactory.releaseTasks)) {
+ motionManager.once("destroy", _Live2DFactory.releaseTasks);
+ }
+ let tasks = _Live2DFactory.motionTasksMap.get(motionManager);
+ if (!tasks) {
+ tasks = {};
+ _Live2DFactory.motionTasksMap.set(motionManager, tasks);
+ }
+ let taskGroup = tasks[group];
+ if (!taskGroup) {
+ taskGroup = [];
+ tasks[group] = taskGroup;
+ }
+ const path = motionManager.getMotionFile(definition);
+ (_b = taskGroup[index]) != null ? _b : taskGroup[index] = Live2DLoader.load({
+ url: path,
+ settings: motionManager.settings,
+ type: motionManager.motionDataType,
+ target: motionManager
+ }).then((data) => {
+ var _a2;
+ const taskGroup2 = (_a2 = _Live2DFactory.motionTasksMap.get(motionManager)) == null ? void 0 : _a2[group];
+ if (taskGroup2) {
+ delete taskGroup2[index];
+ }
+ const motion = motionManager.createMotion(data, group, definition);
+ motionManager.emit("motionLoaded", group, index, motion);
+ return motion;
+ }).catch((e) => {
+ logger.warn(motionManager.tag, `Failed to load motion: ${path}
+`, e);
+ handleError(e);
+ });
+ return taskGroup[index];
+ } catch (e) {
+ logger.warn(motionManager.tag, `Failed to load motion at "${group}"[${index}]
+`, e);
+ handleError(e);
+ }
+ return Promise.resolve(void 0);
+ }
+ static loadExpression(expressionManager, index) {
+ var _a;
+ const handleError = (e) => expressionManager.emit("expressionLoadError", index, e);
+ try {
+ const definition = expressionManager.definitions[index];
+ if (!definition) {
+ return Promise.resolve(void 0);
+ }
+ if (!expressionManager.listeners("destroy").includes(_Live2DFactory.releaseTasks)) {
+ expressionManager.once("destroy", _Live2DFactory.releaseTasks);
+ }
+ let tasks = _Live2DFactory.expressionTasksMap.get(expressionManager);
+ if (!tasks) {
+ tasks = [];
+ _Live2DFactory.expressionTasksMap.set(expressionManager, tasks);
+ }
+ const path = expressionManager.getExpressionFile(definition);
+ (_a = tasks[index]) != null ? _a : tasks[index] = Live2DLoader.load({
+ url: path,
+ settings: expressionManager.settings,
+ type: "json",
+ target: expressionManager
+ }).then((data) => {
+ const tasks2 = _Live2DFactory.expressionTasksMap.get(expressionManager);
+ if (tasks2) {
+ delete tasks2[index];
+ }
+ const expression = expressionManager.createExpression(data, definition);
+ expressionManager.emit("expressionLoaded", index, expression);
+ return expression;
+ }).catch((e) => {
+ logger.warn(expressionManager.tag, `Failed to load expression: ${path}
+`, e);
+ handleError(e);
+ });
+ return tasks[index];
+ } catch (e) {
+ logger.warn(expressionManager.tag, `Failed to load expression at [${index}]
+`, e);
+ handleError(e);
+ }
+ return Promise.resolve(void 0);
+ }
+ static releaseTasks() {
+ if (this instanceof MotionManager) {
+ _Live2DFactory.motionTasksMap.delete(this);
+ } else {
+ _Live2DFactory.expressionTasksMap.delete(this);
+ }
+ }
+ };
+ let Live2DFactory = _Live2DFactory;
+ Live2DFactory.runtimes = [];
+ Live2DFactory.urlToJSON = urlToJSON;
+ Live2DFactory.jsonToSettings = jsonToSettings;
+ Live2DFactory.waitUntilReady = waitUntilReady;
+ Live2DFactory.setupOptionals = setupOptionals;
+ Live2DFactory.setupEssentials = setupEssentials;
+ Live2DFactory.createInternalModel = createInternalModel;
+ Live2DFactory.live2DModelMiddlewares = [
+ urlToJSON,
+ jsonToSettings,
+ waitUntilReady,
+ setupOptionals,
+ setupEssentials,
+ createInternalModel
+ ];
+ Live2DFactory.motionTasksMap = /* @__PURE__ */ new WeakMap();
+ Live2DFactory.expressionTasksMap = /* @__PURE__ */ new WeakMap();
+ MotionManager.prototype["_loadMotion"] = function(group, index) {
+ return Live2DFactory.loadMotion(this, group, index);
+ };
+ ExpressionManager.prototype["_loadExpression"] = function(index) {
+ return Live2DFactory.loadExpression(this, index);
+ };
+ class InteractionMixin {
+ constructor() {
+ this._autoInteract = false;
+ }
+ get autoInteract() {
+ return this._autoInteract;
+ }
+ set autoInteract(autoInteract) {
+ if (autoInteract !== this._autoInteract) {
+ if (autoInteract) {
+ this.on("pointertap", onTap, this);
+ } else {
+ this.off("pointertap", onTap, this);
+ }
+ this._autoInteract = autoInteract;
+ }
+ }
+ registerInteraction(manager) {
+ if (manager !== this.interactionManager) {
+ this.unregisterInteraction();
+ if (this._autoInteract && manager) {
+ this.interactionManager = manager;
+ manager.on("pointermove", onPointerMove, this);
+ }
+ }
+ }
+ unregisterInteraction() {
+ var _a;
+ if (this.interactionManager) {
+ (_a = this.interactionManager) == null ? void 0 : _a.off("pointermove", onPointerMove, this);
+ this.interactionManager = void 0;
+ }
+ }
+ }
+ function onTap(event) {
+ this.tap(event.data.global.x, event.data.global.y);
+ }
+ function onPointerMove(event) {
+ this.focus(event.data.global.x, event.data.global.y);
+ }
+ class Live2DTransform extends math.Transform {
+ }
+ const tempPoint = new math.Point();
+ const tempMatrix$1 = new math.Matrix();
+ let tickerRef;
+ class Live2DModel extends display.Container {
+ constructor(options) {
+ super();
+ this.tag = "Live2DModel(uninitialized)";
+ this.textures = [];
+ this.transform = new Live2DTransform();
+ this.anchor = new math.ObservablePoint(this.onAnchorChange, this, 0, 0);
+ this.glContextID = -1;
+ this.elapsedTime = performance.now();
+ this.deltaTime = 0;
+ this._autoUpdate = false;
+ this.once("modelLoaded", () => this.init(options));
+ }
+ static from(source, options) {
+ const model = new this(options);
+ return Live2DFactory.setupLive2DModel(model, source, options).then(() => model);
+ }
+ static fromSync(source, options) {
+ const model = new this(options);
+ Live2DFactory.setupLive2DModel(model, source, options).then(options == null ? void 0 : options.onLoad).catch(options == null ? void 0 : options.onError);
+ return model;
+ }
+ static registerTicker(tickerClass) {
+ tickerRef = tickerClass;
+ }
+ get autoUpdate() {
+ return this._autoUpdate;
+ }
+ set autoUpdate(autoUpdate) {
+ var _a;
+ tickerRef || (tickerRef = (_a = window.PIXI) == null ? void 0 : _a.Ticker);
+ if (autoUpdate) {
+ if (!this._destroyed) {
+ if (tickerRef) {
+ tickerRef.shared.add(this.onTickerUpdate, this);
+ this._autoUpdate = true;
+ } else {
+ logger.warn(this.tag, "No Ticker registered, please call Live2DModel.registerTicker(Ticker).");
+ }
+ }
+ } else {
+ tickerRef == null ? void 0 : tickerRef.shared.remove(this.onTickerUpdate, this);
+ this._autoUpdate = false;
+ }
+ }
+ init(options) {
+ this.tag = `Live2DModel(${this.internalModel.settings.name})`;
+ const _options = Object.assign({
+ autoUpdate: true,
+ autoInteract: true
+ }, options);
+ if (_options.autoInteract) {
+ this.interactive = true;
+ }
+ this.autoInteract = _options.autoInteract;
+ this.autoUpdate = _options.autoUpdate;
+ }
+ onAnchorChange() {
+ this.pivot.set(this.anchor.x * this.internalModel.width, this.anchor.y * this.internalModel.height);
+ }
+ motion(group, index, priority, sound, volume, expression) {
+ return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority) : this.internalModel.motionManager.startMotion(group, index, priority, sound, volume, expression);
+ }
+ resetMotions() {
+ return this.internalModel.motionManager.stopAllMotions();
+ }
+ speak(sound, volume, expression) {
+ return this.internalModel.motionManager.speakUp(sound, volume, expression);
+ }
+ stopSpeaking() {
+ return this.internalModel.motionManager.stopSpeaking();
+ }
+ expression(id) {
+ if (this.internalModel.motionManager.expressionManager) {
+ return id === void 0 ? this.internalModel.motionManager.expressionManager.setRandomExpression() : this.internalModel.motionManager.expressionManager.setExpression(id);
+ }
+ return Promise.resolve(false);
+ }
+ focus(x, y, instant = false) {
+ tempPoint.x = x;
+ tempPoint.y = y;
+ this.toModelPosition(tempPoint, tempPoint, true);
+ let tx = tempPoint.x / this.internalModel.originalWidth * 2 - 1;
+ let ty = tempPoint.y / this.internalModel.originalHeight * 2 - 1;
+ let radian = Math.atan2(ty, tx);
+ this.internalModel.focusController.focus(Math.cos(radian), -Math.sin(radian), instant);
+ }
+ tap(x, y) {
+ const hitAreaNames = this.hitTest(x, y);
+ if (hitAreaNames.length) {
+ logger.log(this.tag, `Hit`, hitAreaNames);
+ this.emit("hit", hitAreaNames);
+ }
+ }
+ hitTest(x, y) {
+ tempPoint.x = x;
+ tempPoint.y = y;
+ this.toModelPosition(tempPoint, tempPoint);
+ return this.internalModel.hitTest(tempPoint.x, tempPoint.y);
+ }
+ toModelPosition(position, result = position.clone(), skipUpdate) {
+ if (!skipUpdate) {
+ this._recursivePostUpdateTransform();
+ if (!this.parent) {
+ this.parent = this._tempDisplayObjectParent;
+ this.displayObjectUpdateTransform();
+ this.parent = null;
+ } else {
+ this.displayObjectUpdateTransform();
+ }
+ }
+ this.transform.worldTransform.applyInverse(position, result);
+ this.internalModel.localTransform.applyInverse(result, result);
+ return result;
+ }
+ containsPoint(point) {
+ return this.getBounds(true).contains(point.x, point.y);
+ }
+ _calculateBounds() {
+ this._bounds.addFrame(this.transform, 0, 0, this.internalModel.width, this.internalModel.height);
+ }
+ onTickerUpdate() {
+ this.update(tickerRef.shared.deltaMS);
+ }
+ update(dt) {
+ this.deltaTime += dt;
+ this.elapsedTime += dt;
+ }
+ _render(renderer) {
+ this.registerInteraction(renderer.plugins.interaction);
+ renderer.batch.reset();
+ renderer.geometry.reset();
+ renderer.shader.reset();
+ renderer.state.reset();
+ let shouldUpdateTexture = false;
+ if (this.glContextID !== renderer.CONTEXT_UID) {
+ this.glContextID = renderer.CONTEXT_UID;
+ this.internalModel.updateWebGLContext(renderer.gl, this.glContextID);
+ shouldUpdateTexture = true;
+ }
+ for (let i = 0; i < this.textures.length; i++) {
+ const texture = this.textures[i];
+ if (!texture.valid) {
+ continue;
+ }
+ if (shouldUpdateTexture || !texture.baseTexture._glTextures[this.glContextID]) {
+ renderer.gl.pixelStorei(WebGLRenderingContext.UNPACK_FLIP_Y_WEBGL, this.internalModel.textureFlipY);
+ renderer.texture.bind(texture.baseTexture, 0);
+ }
+ this.internalModel.bindTexture(i, texture.baseTexture._glTextures[this.glContextID].texture);
+ texture.baseTexture.touched = renderer.textureGC.count;
+ }
+ const viewport = renderer.framebuffer.viewport;
+ this.internalModel.viewport = [viewport.x, viewport.y, viewport.width, viewport.height];
+ if (this.deltaTime) {
+ this.internalModel.update(this.deltaTime, this.elapsedTime);
+ this.deltaTime = 0;
+ }
+ const internalTransform = tempMatrix$1.copyFrom(renderer.globalUniforms.uniforms.projectionMatrix).append(this.worldTransform);
+ this.internalModel.updateTransform(internalTransform);
+ this.internalModel.draw(renderer.gl);
+ renderer.state.reset();
+ renderer.texture.reset();
+ }
+ destroy(options) {
+ this.emit("destroy");
+ this.autoUpdate = false;
+ this.unregisterInteraction();
+ if (options == null ? void 0 : options.texture) {
+ this.textures.forEach((texture) => texture.destroy(options.baseTexture));
+ }
+ this.internalModel.destroy();
+ super.destroy(options);
+ }
+ }
+ applyMixins(Live2DModel, [InteractionMixin]);
+ const _FileLoader = class {
+ static resolveURL(settingsURL, filePath) {
+ var _a;
+ const resolved = (_a = _FileLoader.filesMap[settingsURL]) == null ? void 0 : _a[filePath];
+ if (resolved === void 0) {
+ throw new Error("Cannot find this file from uploaded files: " + filePath);
+ }
+ return resolved;
+ }
+ static upload(files, settings) {
+ return __async(this, null, function* () {
+ const fileMap = {};
+ for (const definedFile of settings.getDefinedFiles()) {
+ const actualPath = decodeURI(utils.url.resolve(settings.url, definedFile));
+ const actualFile = files.find((file) => file.webkitRelativePath === actualPath);
+ if (actualFile) {
+ fileMap[definedFile] = URL.createObjectURL(actualFile);
+ }
+ }
+ _FileLoader.filesMap[settings._objectURL] = fileMap;
+ });
+ }
+ static createSettings(files) {
+ return __async(this, null, function* () {
+ const settingsFile = files.find((file) => file.name.endsWith("model.json") || file.name.endsWith("model3.json"));
+ if (!settingsFile) {
+ throw new TypeError("Settings file not found");
+ }
+ const settingsText = yield _FileLoader.readText(settingsFile);
+ const settingsJSON = JSON.parse(settingsText);
+ settingsJSON.url = settingsFile.webkitRelativePath;
+ const runtime = Live2DFactory.findRuntime(settingsJSON);
+ if (!runtime) {
+ throw new Error("Unknown settings JSON");
+ }
+ const settings = runtime.createModelSettings(settingsJSON);
+ settings._objectURL = URL.createObjectURL(settingsFile);
+ return settings;
+ });
+ }
+ static readText(file) {
+ return __async(this, null, function* () {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = () => resolve(reader.result);
+ reader.onerror = reject;
+ reader.readAsText(file, "utf8");
+ });
+ });
+ }
+ };
+ let FileLoader = _FileLoader;
+ FileLoader.filesMap = {};
+ FileLoader.factory = (context, next) => __async(this, null, function* () {
+ if (Array.isArray(context.source) && context.source[0] instanceof File) {
+ const files = context.source;
+ let settings = files.settings;
+ if (!settings) {
+ settings = yield _FileLoader.createSettings(files);
+ } else if (!settings._objectURL) {
+ throw new Error('"_objectURL" must be specified in ModelSettings');
+ }
+ settings.validateFiles(files.map((file) => encodeURI(file.webkitRelativePath)));
+ yield _FileLoader.upload(files, settings);
+ settings.resolveURL = function(url) {
+ return _FileLoader.resolveURL(this._objectURL, url);
+ };
+ context.source = settings;
+ context.live2dModel.once("modelLoaded", (internalModel) => {
+ internalModel.once("destroy", function() {
+ const objectURL = this.settings._objectURL;
+ URL.revokeObjectURL(objectURL);
+ if (_FileLoader.filesMap[objectURL]) {
+ for (const resourceObjectURL of Object.values(_FileLoader.filesMap[objectURL])) {
+ URL.revokeObjectURL(resourceObjectURL);
+ }
+ }
+ delete _FileLoader.filesMap[objectURL];
+ });
+ });
+ }
+ return next();
+ });
+ Live2DFactory.live2DModelMiddlewares.unshift(FileLoader.factory);
+ const _ZipLoader = class {
+ static unzip(reader, settings) {
+ return __async(this, null, function* () {
+ const filePaths = yield _ZipLoader.getFilePaths(reader);
+ const requiredFilePaths = [];
+ for (const definedFile of settings.getDefinedFiles()) {
+ const actualPath = decodeURI(utils.url.resolve(settings.url, definedFile));
+ if (filePaths.includes(actualPath)) {
+ requiredFilePaths.push(actualPath);
+ }
+ }
+ const files = yield _ZipLoader.getFiles(reader, requiredFilePaths);
+ for (let i = 0; i < files.length; i++) {
+ const path = requiredFilePaths[i];
+ const file = files[i];
+ Object.defineProperty(file, "webkitRelativePath", {
+ value: path
+ });
+ }
+ return files;
+ });
+ }
+ static createSettings(reader) {
+ return __async(this, null, function* () {
+ const filePaths = yield _ZipLoader.getFilePaths(reader);
+ const settingsFilePath = filePaths.find((path) => path.endsWith("model.json") || path.endsWith("model3.json"));
+ if (!settingsFilePath) {
+ throw new Error("Settings file not found");
+ }
+ const settingsText = yield _ZipLoader.readText(reader, settingsFilePath);
+ if (!settingsText) {
+ throw new Error("Empty settings file: " + settingsFilePath);
+ }
+ const settingsJSON = JSON.parse(settingsText);
+ settingsJSON.url = settingsFilePath;
+ const runtime = Live2DFactory.findRuntime(settingsJSON);
+ if (!runtime) {
+ throw new Error("Unknown settings JSON");
+ }
+ return runtime.createModelSettings(settingsJSON);
+ });
+ }
+ static zipReader(data, url) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static getFilePaths(reader) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static getFiles(reader, paths) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static readText(reader, path) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static releaseReader(reader) {
+ }
+ };
+ let ZipLoader = _ZipLoader;
+ ZipLoader.ZIP_PROTOCOL = "zip://";
+ ZipLoader.uid = 0;
+ ZipLoader.factory = (context, next) => __async(this, null, function* () {
+ const source = context.source;
+ let sourceURL;
+ let zipBlob;
+ let settings;
+ if (typeof source === "string" && (source.endsWith(".zip") || source.startsWith(_ZipLoader.ZIP_PROTOCOL))) {
+ if (source.startsWith(_ZipLoader.ZIP_PROTOCOL)) {
+ sourceURL = source.slice(_ZipLoader.ZIP_PROTOCOL.length);
+ } else {
+ sourceURL = source;
+ }
+ zipBlob = yield Live2DLoader.load({
+ url: sourceURL,
+ type: "blob",
+ target: context.live2dModel
+ });
+ } else if (Array.isArray(source) && source.length === 1 && source[0] instanceof File && source[0].name.endsWith(".zip")) {
+ zipBlob = source[0];
+ sourceURL = URL.createObjectURL(zipBlob);
+ settings = source.settings;
+ }
+ if (zipBlob) {
+ if (!zipBlob.size) {
+ throw new Error("Empty zip file");
+ }
+ const reader = yield _ZipLoader.zipReader(zipBlob, sourceURL);
+ if (!settings) {
+ settings = yield _ZipLoader.createSettings(reader);
+ }
+ settings._objectURL = _ZipLoader.ZIP_PROTOCOL + _ZipLoader.uid + "/" + settings.url;
+ const files = yield _ZipLoader.unzip(reader, settings);
+ files.settings = settings;
+ context.source = files;
+ if (sourceURL.startsWith("blob:")) {
+ context.live2dModel.once("modelLoaded", (internalModel) => {
+ internalModel.once("destroy", function() {
+ URL.revokeObjectURL(sourceURL);
+ });
+ });
+ }
+ _ZipLoader.releaseReader(reader);
+ }
+ return next();
+ });
+ Live2DFactory.live2DModelMiddlewares.unshift(ZipLoader.factory);
+ if (!window.Live2DCubismCore) {
+ throw new Error("Could not find Cubism 4 runtime. This plugin requires live2dcubismcore.js to be loaded.");
+ }
+ class Cubism4ExpressionManager extends ExpressionManager {
+ constructor(settings, options) {
+ var _a;
+ super(settings, options);
+ this.queueManager = new CubismMotionQueueManager();
+ this.definitions = (_a = settings.expressions) != null ? _a : [];
+ this.init();
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ getExpressionIndex(name) {
+ return this.definitions.findIndex((def) => def.Name === name);
+ }
+ getExpressionFile(definition) {
+ return definition.File;
+ }
+ createExpression(data, definition) {
+ return CubismExpressionMotion.create(data);
+ }
+ _setExpression(motion) {
+ return this.queueManager.startMotion(motion, false, performance.now());
+ }
+ stopAllExpressions() {
+ this.queueManager.stopAllMotions();
+ }
+ updateParameters(model, now) {
+ return this.queueManager.doUpdateMotion(model, now);
+ }
+ }
+ class Cubism4ModelSettings extends ModelSettings {
+ constructor(json) {
+ super(json);
+ if (!Cubism4ModelSettings.isValidJSON(json)) {
+ throw new TypeError("Invalid JSON.");
+ }
+ Object.assign(this, new CubismModelSettingsJson(json));
+ }
+ static isValidJSON(json) {
+ var _a;
+ return !!(json == null ? void 0 : json.FileReferences) && typeof json.FileReferences.Moc === "string" && ((_a = json.FileReferences.Textures) == null ? void 0 : _a.length) > 0 && json.FileReferences.Textures.every((item) => typeof item === "string");
+ }
+ replaceFiles(replace) {
+ super.replaceFiles(replace);
+ if (this.motions) {
+ for (const [group, motions] of Object.entries(this.motions)) {
+ for (let i = 0; i < motions.length; i++) {
+ motions[i].File = replace(motions[i].File, `motions.${group}[${i}].File`);
+ if (motions[i].Sound !== void 0) {
+ motions[i].Sound = replace(motions[i].Sound, `motions.${group}[${i}].Sound`);
+ }
+ }
+ }
+ }
+ if (this.expressions) {
+ for (let i = 0; i < this.expressions.length; i++) {
+ this.expressions[i].File = replace(this.expressions[i].File, `expressions[${i}].File`);
+ }
+ }
+ }
+ }
+ applyMixins(Cubism4ModelSettings, [CubismModelSettingsJson]);
+ class Cubism4MotionManager extends MotionManager {
+ constructor(settings, options) {
+ var _a;
+ super(settings, options);
+ this.groups = { idle: "Idle" };
+ this.motionDataType = "json";
+ this.queueManager = new CubismMotionQueueManager();
+ this.definitions = (_a = settings.motions) != null ? _a : {};
+ this.eyeBlinkIds = settings.getEyeBlinkParameters() || [];
+ this.lipSyncIds = settings.getLipSyncParameters() || [];
+ this.init(options);
+ }
+ init(options) {
+ super.init(options);
+ if (this.settings.expressions) {
+ this.expressionManager = new Cubism4ExpressionManager(this.settings, options);
+ }
+ this.queueManager.setEventCallback((caller, eventValue, customData) => {
+ this.emit("motion:" + eventValue);
+ });
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ _startMotion(motion, onFinish) {
+ motion.setFinishedMotionHandler(onFinish);
+ this.queueManager.stopAllMotions();
+ return this.queueManager.startMotion(motion, false, performance.now());
+ }
+ _stopAllMotions() {
+ this.queueManager.stopAllMotions();
+ }
+ createMotion(data, group, definition) {
+ const motion = CubismMotion.create(data);
+ const json = new CubismMotionJson(data);
+ const defaultFadingDuration = (group === this.groups.idle ? exports2.config.idleMotionFadingDuration : exports2.config.motionFadingDuration) / 1e3;
+ if (json.getMotionFadeInTime() === void 0) {
+ motion.setFadeInTime(definition.FadeInTime > 0 ? definition.FadeInTime : defaultFadingDuration);
+ }
+ if (json.getMotionFadeOutTime() === void 0) {
+ motion.setFadeOutTime(definition.FadeOutTime > 0 ? definition.FadeOutTime : defaultFadingDuration);
+ }
+ motion.setEffectIds(this.eyeBlinkIds, this.lipSyncIds);
+ return motion;
+ }
+ getMotionFile(definition) {
+ return definition.File;
+ }
+ getMotionName(definition) {
+ return definition.File;
+ }
+ getSoundFile(definition) {
+ return definition.Sound;
+ }
+ updateParameters(model, now) {
+ return this.queueManager.doUpdateMotion(model, now);
+ }
+ destroy() {
+ super.destroy();
+ this.queueManager.release();
+ this.queueManager = void 0;
+ }
+ }
+ const tempMatrix = new CubismMatrix44();
+ class Cubism4InternalModel extends InternalModel {
+ constructor(coreModel, settings, options) {
+ super();
+ this.lipSync = true;
+ this.breath = CubismBreath.create();
+ this.renderer = new CubismRenderer_WebGL();
+ this.idParamAngleX = ParamAngleX;
+ this.idParamAngleY = ParamAngleY;
+ this.idParamAngleZ = ParamAngleZ;
+ this.idParamEyeBallX = ParamEyeBallX;
+ this.idParamEyeBallY = ParamEyeBallY;
+ this.idParamBodyAngleX = ParamBodyAngleX;
+ this.idParamBreath = ParamBreath;
+ this.pixelsPerUnit = 1;
+ this.centeringTransform = new math.Matrix();
+ this.coreModel = coreModel;
+ this.settings = settings;
+ this.motionManager = new Cubism4MotionManager(settings, options);
+ this.init();
+ }
+ init() {
+ var _a;
+ super.init();
+ if (((_a = this.settings.getEyeBlinkParameters()) == null ? void 0 : _a.length) > 0) {
+ this.eyeBlink = CubismEyeBlink.create(this.settings);
+ }
+ this.breath.setParameters([
+ new BreathParameterData(this.idParamAngleX, 0, 15, 6.5345, 0.5),
+ new BreathParameterData(this.idParamAngleY, 0, 8, 3.5345, 0.5),
+ new BreathParameterData(this.idParamAngleZ, 0, 10, 5.5345, 0.5),
+ new BreathParameterData(this.idParamBodyAngleX, 0, 4, 15.5345, 0.5),
+ new BreathParameterData(this.idParamBreath, 0, 0.5, 3.2345, 0.5)
+ ]);
+ this.renderer.initialize(this.coreModel);
+ this.renderer.setIsPremultipliedAlpha(true);
+ }
+ getSize() {
+ return [this.coreModel.getModel().canvasinfo.CanvasWidth, this.coreModel.getModel().canvasinfo.CanvasHeight];
+ }
+ getLayout() {
+ const layout = {};
+ if (this.settings.layout) {
+ for (const key of Object.keys(this.settings.layout)) {
+ const commonKey = key.charAt(0).toLowerCase() + key.slice(1);
+ layout[commonKey] = this.settings.layout[key];
+ }
+ }
+ return layout;
+ }
+ setupLayout() {
+ super.setupLayout();
+ this.pixelsPerUnit = this.coreModel.getModel().canvasinfo.PixelsPerUnit;
+ this.centeringTransform.scale(this.pixelsPerUnit, this.pixelsPerUnit).translate(this.originalWidth / 2, this.originalHeight / 2);
+ }
+ updateWebGLContext(gl, glContextID) {
+ this.renderer.firstDraw = true;
+ this.renderer._bufferData = {
+ vertex: null,
+ uv: null,
+ index: null
+ };
+ this.renderer.startUp(gl);
+ this.renderer._clippingManager._currentFrameNo = glContextID;
+ this.renderer._clippingManager._maskTexture = void 0;
+ CubismShader_WebGL.getInstance()._shaderSets = [];
+ }
+ bindTexture(index, texture) {
+ this.renderer.bindTexture(index, texture);
+ }
+ getHitAreaDefs() {
+ var _a, _b;
+ return (_b = (_a = this.settings.hitAreas) == null ? void 0 : _a.map((hitArea) => ({
+ id: hitArea.Id,
+ name: hitArea.Name,
+ index: this.coreModel.getDrawableIndex(hitArea.Id)
+ }))) != null ? _b : [];
+ }
+ getDrawableIDs() {
+ return this.coreModel.getDrawableIds();
+ }
+ getDrawableIndex(id) {
+ return this.coreModel.getDrawableIndex(id);
+ }
+ getDrawableVertices(drawIndex) {
+ if (typeof drawIndex === "string") {
+ drawIndex = this.coreModel.getDrawableIndex(drawIndex);
+ if (drawIndex === -1)
+ throw new TypeError("Unable to find drawable ID: " + drawIndex);
+ }
+ const arr = this.coreModel.getDrawableVertices(drawIndex).slice();
+ for (let i = 0; i < arr.length; i += 2) {
+ arr[i] = arr[i] * this.pixelsPerUnit + this.originalWidth / 2;
+ arr[i + 1] = -arr[i + 1] * this.pixelsPerUnit + this.originalHeight / 2;
+ }
+ return arr;
+ }
+ updateTransform(transform) {
+ this.drawingMatrix.copyFrom(this.centeringTransform).prepend(this.localTransform).prepend(transform);
+ }
+ update(dt, now) {
+ var _a, _b, _c, _d;
+ super.update(dt, now);
+ dt /= 1e3;
+ now /= 1e3;
+ const model = this.coreModel;
+ this.emit("beforeMotionUpdate");
+ const motionUpdated = this.motionManager.update(this.coreModel, now);
+ this.emit("afterMotionUpdate");
+ model.saveParameters();
+ (_a = this.motionManager.expressionManager) == null ? void 0 : _a.update(model, now);
+ if (!motionUpdated) {
+ (_b = this.eyeBlink) == null ? void 0 : _b.updateParameters(model, dt);
+ }
+ this.updateFocus();
+ this.updateNaturalMovements(dt * 1e3, now * 1e3);
+ (_c = this.physics) == null ? void 0 : _c.evaluate(model, dt);
+ (_d = this.pose) == null ? void 0 : _d.updateParameters(model, dt);
+ this.emit("beforeModelUpdate");
+ model.update();
+ model.loadParameters();
+ }
+ updateFocus() {
+ this.coreModel.addParameterValueById(this.idParamEyeBallX, this.focusController.x);
+ this.coreModel.addParameterValueById(this.idParamEyeBallY, this.focusController.y);
+ this.coreModel.addParameterValueById(this.idParamAngleX, this.focusController.x * 30);
+ this.coreModel.addParameterValueById(this.idParamAngleY, this.focusController.y * 30);
+ this.coreModel.addParameterValueById(this.idParamAngleZ, this.focusController.x * this.focusController.y * -30);
+ this.coreModel.addParameterValueById(this.idParamBodyAngleX, this.focusController.x * 10);
+ }
+ updateNaturalMovements(dt, now) {
+ var _a;
+ (_a = this.breath) == null ? void 0 : _a.updateParameters(this.coreModel, dt / 1e3);
+ }
+ draw(gl) {
+ const matrix = this.drawingMatrix;
+ const array = tempMatrix.getArray();
+ array[0] = matrix.a;
+ array[1] = matrix.b;
+ array[4] = -matrix.c;
+ array[5] = -matrix.d;
+ array[12] = matrix.tx;
+ array[13] = matrix.ty;
+ this.renderer.setMvpMatrix(tempMatrix);
+ this.renderer.setRenderState(gl.getParameter(gl.FRAMEBUFFER_BINDING), this.viewport);
+ this.renderer.drawModel();
+ }
+ destroy() {
+ super.destroy();
+ this.renderer.release();
+ this.coreModel.release();
+ this.renderer = void 0;
+ this.coreModel = void 0;
+ }
+ }
+ let startupPromise;
+ let startupRetries = 20;
+ function cubism4Ready() {
+ if (CubismFramework.isStarted()) {
+ return Promise.resolve();
+ }
+ startupPromise != null ? startupPromise : startupPromise = new Promise((resolve, reject) => {
+ function startUpWithRetry() {
+ try {
+ startUpCubism4();
+ resolve();
+ } catch (e) {
+ startupRetries--;
+ if (startupRetries < 0) {
+ const err = new Error("Failed to start up Cubism 4 framework.");
+ err.cause = e;
+ reject(err);
+ return;
+ }
+ logger.log("Cubism4", "Startup failed, retrying 10ms later...");
+ setTimeout(startUpWithRetry, 10);
+ }
+ }
+ startUpWithRetry();
+ });
+ return startupPromise;
+ }
+ function startUpCubism4(options) {
+ options = Object.assign({
+ logFunction: console.log,
+ loggingLevel: LogLevel.LogLevel_Verbose
+ }, options);
+ CubismFramework.startUp(options);
+ CubismFramework.initialize();
+ }
+ Live2DFactory.registerRuntime({
+ version: 4,
+ ready: cubism4Ready,
+ test(source) {
+ return source instanceof Cubism4ModelSettings || Cubism4ModelSettings.isValidJSON(source);
+ },
+ isValidMoc(modelData) {
+ if (modelData.byteLength < 4) {
+ return false;
+ }
+ const view = new Int8Array(modelData, 0, 4);
+ return String.fromCharCode(...view) === "MOC3";
+ },
+ createModelSettings(json) {
+ return new Cubism4ModelSettings(json);
+ },
+ createCoreModel(data, options) {
+ const moc = CubismMoc.create(data, !!(options == null ? void 0 : options.checkMocConsistency));
+ try {
+ const model = moc.createModel();
+ model.__moc = moc;
+ return model;
+ } catch (e) {
+ try {
+ moc.release();
+ } catch (ignored) {
+ }
+ throw e;
+ }
+ },
+ createInternalModel(coreModel, settings, options) {
+ const model = new Cubism4InternalModel(coreModel, settings, options);
+ const coreModelWithMoc = coreModel;
+ if (coreModelWithMoc.__moc) {
+ model.__moc = coreModelWithMoc.__moc;
+ delete coreModelWithMoc.__moc;
+ model.once("destroy", releaseMoc);
+ }
+ return model;
+ },
+ createPhysics(coreModel, data) {
+ return CubismPhysics.create(data);
+ },
+ createPose(coreModel, data) {
+ return CubismPose.create(data);
+ }
+ });
+ function releaseMoc() {
+ var _a;
+ (_a = this.__moc) == null ? void 0 : _a.release();
+ }
+ exports2.ACubismMotion = ACubismMotion;
+ exports2.BreathParameterData = BreathParameterData;
+ exports2.CSM_ASSERT = CSM_ASSERT;
+ exports2.Constant = Constant;
+ exports2.Cubism4ExpressionManager = Cubism4ExpressionManager;
+ exports2.Cubism4InternalModel = Cubism4InternalModel;
+ exports2.Cubism4ModelSettings = Cubism4ModelSettings;
+ exports2.Cubism4MotionManager = Cubism4MotionManager;
+ exports2.CubismBlendMode = CubismBlendMode;
+ exports2.CubismBreath = CubismBreath;
+ exports2.CubismClippingContext = CubismClippingContext;
+ exports2.CubismClippingManager_WebGL = CubismClippingManager_WebGL;
+ exports2.CubismDebug = CubismDebug;
+ exports2.CubismExpressionMotion = CubismExpressionMotion;
+ exports2.CubismEyeBlink = CubismEyeBlink;
+ exports2.CubismFramework = CubismFramework;
+ exports2.CubismLogDebug = CubismLogDebug;
+ exports2.CubismLogError = CubismLogError;
+ exports2.CubismLogInfo = CubismLogInfo;
+ exports2.CubismLogVerbose = CubismLogVerbose;
+ exports2.CubismLogWarning = CubismLogWarning;
+ exports2.CubismMath = CubismMath;
+ exports2.CubismMatrix44 = CubismMatrix44;
+ exports2.CubismMoc = CubismMoc;
+ exports2.CubismModel = CubismModel;
+ exports2.CubismModelSettingsJson = CubismModelSettingsJson;
+ exports2.CubismModelUserData = CubismModelUserData;
+ exports2.CubismModelUserDataJson = CubismModelUserDataJson;
+ exports2.CubismMotion = CubismMotion;
+ exports2.CubismMotionCurve = CubismMotionCurve;
+ exports2.CubismMotionCurveTarget = CubismMotionCurveTarget;
+ exports2.CubismMotionData = CubismMotionData;
+ exports2.CubismMotionEvent = CubismMotionEvent;
+ exports2.CubismMotionJson = CubismMotionJson;
+ exports2.CubismMotionManager = CubismMotionManager;
+ exports2.CubismMotionPoint = CubismMotionPoint;
+ exports2.CubismMotionQueueEntry = CubismMotionQueueEntry;
+ exports2.CubismMotionQueueManager = CubismMotionQueueManager;
+ exports2.CubismMotionSegment = CubismMotionSegment;
+ exports2.CubismMotionSegmentType = CubismMotionSegmentType;
+ exports2.CubismPhysics = CubismPhysics;
+ exports2.CubismPhysicsInput = CubismPhysicsInput;
+ exports2.CubismPhysicsJson = CubismPhysicsJson;
+ exports2.CubismPhysicsOutput = CubismPhysicsOutput;
+ exports2.CubismPhysicsParticle = CubismPhysicsParticle;
+ exports2.CubismPhysicsRig = CubismPhysicsRig;
+ exports2.CubismPhysicsSource = CubismPhysicsSource;
+ exports2.CubismPhysicsSubRig = CubismPhysicsSubRig;
+ exports2.CubismPhysicsTargetType = CubismPhysicsTargetType;
+ exports2.CubismPose = CubismPose;
+ exports2.CubismRenderTextureResource = CubismRenderTextureResource;
+ exports2.CubismRenderer = CubismRenderer;
+ exports2.CubismRendererProfile_WebGL = CubismRendererProfile_WebGL;
+ exports2.CubismRenderer_WebGL = CubismRenderer_WebGL;
+ exports2.CubismShader_WebGL = CubismShader_WebGL;
+ exports2.CubismTextureColor = CubismTextureColor;
+ exports2.CubismVector2 = CubismVector2;
+ exports2.DrawableColorData = DrawableColorData;
+ exports2.DrawableCullingData = DrawableCullingData;
+ exports2.EvaluationOptionFlag = EvaluationOptionFlag;
+ exports2.ExpressionBlendType = ExpressionBlendType;
+ exports2.ExpressionManager = ExpressionManager;
+ exports2.EyeState = EyeState;
+ exports2.FileLoader = FileLoader;
+ exports2.FocusController = FocusController;
+ exports2.HitAreaBody = HitAreaBody;
+ exports2.HitAreaHead = HitAreaHead;
+ exports2.HitAreaPrefix = HitAreaPrefix;
+ exports2.InteractionMixin = InteractionMixin;
+ exports2.InternalModel = InternalModel;
+ exports2.InvalidMotionQueueEntryHandleValue = InvalidMotionQueueEntryHandleValue;
+ exports2.LOGICAL_HEIGHT = LOGICAL_HEIGHT;
+ exports2.LOGICAL_WIDTH = LOGICAL_WIDTH;
+ exports2.Live2DFactory = Live2DFactory;
+ exports2.Live2DLoader = Live2DLoader;
+ exports2.Live2DModel = Live2DModel;
+ exports2.Live2DTransform = Live2DTransform;
+ exports2.LogLevel = LogLevel;
+ exports2.ModelSettings = ModelSettings;
+ exports2.MotionManager = MotionManager;
+ exports2.MotionPreloadStrategy = MotionPreloadStrategy;
+ exports2.MotionPriority = MotionPriority;
+ exports2.MotionState = MotionState;
+ exports2.Options = Options;
+ exports2.ParamAngleX = ParamAngleX;
+ exports2.ParamAngleY = ParamAngleY;
+ exports2.ParamAngleZ = ParamAngleZ;
+ exports2.ParamArmLA = ParamArmLA;
+ exports2.ParamArmLB = ParamArmLB;
+ exports2.ParamArmRA = ParamArmRA;
+ exports2.ParamArmRB = ParamArmRB;
+ exports2.ParamBaseX = ParamBaseX;
+ exports2.ParamBaseY = ParamBaseY;
+ exports2.ParamBodyAngleX = ParamBodyAngleX;
+ exports2.ParamBodyAngleY = ParamBodyAngleY;
+ exports2.ParamBodyAngleZ = ParamBodyAngleZ;
+ exports2.ParamBreath = ParamBreath;
+ exports2.ParamBrowLAngle = ParamBrowLAngle;
+ exports2.ParamBrowLForm = ParamBrowLForm;
+ exports2.ParamBrowLX = ParamBrowLX;
+ exports2.ParamBrowLY = ParamBrowLY;
+ exports2.ParamBrowRAngle = ParamBrowRAngle;
+ exports2.ParamBrowRForm = ParamBrowRForm;
+ exports2.ParamBrowRX = ParamBrowRX;
+ exports2.ParamBrowRY = ParamBrowRY;
+ exports2.ParamBustX = ParamBustX;
+ exports2.ParamBustY = ParamBustY;
+ exports2.ParamCheek = ParamCheek;
+ exports2.ParamEyeBallForm = ParamEyeBallForm;
+ exports2.ParamEyeBallX = ParamEyeBallX;
+ exports2.ParamEyeBallY = ParamEyeBallY;
+ exports2.ParamEyeLOpen = ParamEyeLOpen;
+ exports2.ParamEyeLSmile = ParamEyeLSmile;
+ exports2.ParamEyeROpen = ParamEyeROpen;
+ exports2.ParamEyeRSmile = ParamEyeRSmile;
+ exports2.ParamHairBack = ParamHairBack;
+ exports2.ParamHairFluffy = ParamHairFluffy;
+ exports2.ParamHairFront = ParamHairFront;
+ exports2.ParamHairSide = ParamHairSide;
+ exports2.ParamHandL = ParamHandL;
+ exports2.ParamHandR = ParamHandR;
+ exports2.ParamMouthForm = ParamMouthForm;
+ exports2.ParamMouthOpenY = ParamMouthOpenY;
+ exports2.ParamNONE = ParamNONE;
+ exports2.ParamShoulderY = ParamShoulderY;
+ exports2.PartColorData = PartColorData;
+ exports2.PartData = PartData;
+ exports2.PartsArmLPrefix = PartsArmLPrefix;
+ exports2.PartsArmPrefix = PartsArmPrefix;
+ exports2.PartsArmRPrefix = PartsArmRPrefix;
+ exports2.PartsIdCore = PartsIdCore;
+ exports2.PhysicsJsonEffectiveForces = PhysicsJsonEffectiveForces;
+ exports2.PhysicsOutput = PhysicsOutput;
+ exports2.ShaderNames = ShaderNames;
+ exports2.SoundManager = SoundManager;
+ exports2.VERSION = VERSION;
+ exports2.XHRLoader = XHRLoader;
+ exports2.ZipLoader = ZipLoader;
+ exports2.applyMixins = applyMixins;
+ exports2.clamp = clamp;
+ exports2.copyArray = copyArray;
+ exports2.copyProperty = copyProperty;
+ exports2.csmRect = csmRect;
+ exports2.cubism4Ready = cubism4Ready;
+ exports2.folderName = folderName;
+ exports2.fragmentShaderSrcMaskInvertedPremultipliedAlpha = fragmentShaderSrcMaskInvertedPremultipliedAlpha;
+ exports2.fragmentShaderSrcMaskPremultipliedAlpha = fragmentShaderSrcMaskPremultipliedAlpha;
+ exports2.fragmentShaderSrcPremultipliedAlpha = fragmentShaderSrcPremultipliedAlpha;
+ exports2.fragmentShaderSrcsetupMask = fragmentShaderSrcsetupMask;
+ exports2.logger = logger;
+ exports2.rand = rand;
+ exports2.remove = remove;
+ exports2.startUpCubism4 = startUpCubism4;
+ exports2.vertexShaderSrc = vertexShaderSrc;
+ exports2.vertexShaderSrcMasked = vertexShaderSrcMasked;
+ exports2.vertexShaderSrcSetupMask = vertexShaderSrcSetupMask;
+ Object.defineProperties(exports2, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
+});
diff --git a/dist/cubism4.min.js b/dist/cubism4.min.js
new file mode 100644
index 00000000..4f1c6e1f
--- /dev/null
+++ b/dist/cubism4.min.js
@@ -0,0 +1 @@
+var __pow=Math.pow,__async=(t,e,i)=>new Promise(((s,r)=>{var o=t=>{try{n(i.next(t))}catch(e){r(e)}},a=t=>{try{n(i.throw(t))}catch(e){r(e)}},n=t=>t.done?s(t.value):Promise.resolve(t.value).then(o,a);n((i=i.apply(t,e)).next())}));!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@pixi/utils"),require("@pixi/math"),require("@pixi/core"),require("@pixi/display")):"function"==typeof define&&define.amd?define(["exports","@pixi/utils","@pixi/math","@pixi/core","@pixi/display"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).PIXI=t.PIXI||{},t.PIXI.live2d=t.PIXI.live2d||{}),t.PIXI.utils,t.PIXI,t.PIXI,t.PIXI)}(this,(function(t,e,i,s,r){"use strict";class o{constructor(){this._breathParameters=[],this._currentTime=0}static create(){return new o}setParameters(t){this._breathParameters=t}getParameters(){return this._breathParameters}updateParameters(t,e){this._currentTime+=e;const i=2*this._currentTime*3.14159;for(let s=0;s=1&&(s=1,this._blinkingState=h.EyeState_Closed,this._stateStartTimeSeconds=this._userTimeSeconds),i=1-s;break;case h.EyeState_Closed:s=(this._userTimeSeconds-this._stateStartTimeSeconds)/this._closedSeconds,s>=1&&(this._blinkingState=h.EyeState_Opening,this._stateStartTimeSeconds=this._userTimeSeconds),i=0;break;case h.EyeState_Opening:s=(this._userTimeSeconds-this._stateStartTimeSeconds)/this._openingSeconds,s>=1&&(s=1,this._blinkingState=h.EyeState_Interval,this._nextBlinkingTime=this.determinNextBlinkingTiming()),i=s;break;case h.EyeState_Interval:this._nextBlinkingTime(t[t.EyeState_First=0]="EyeState_First",t[t.EyeState_Interval=1]="EyeState_Interval",t[t.EyeState_Closing=2]="EyeState_Closing",t[t.EyeState_Closed=3]="EyeState_Closed",t[t.EyeState_Opening=4]="EyeState_Opening",t))(h||{});class u{static create(t){const e=new u;"number"==typeof t.FadeInTime&&(e._fadeTimeSeconds=t.FadeInTime,e._fadeTimeSeconds<=0&&(e._fadeTimeSeconds=.5));const i=t.Groups,s=i.length;for(let r=0;r.001){if(r>=0)break;r=n,o=t.getPartOpacityByIndex(i),o+=e/this._fadeTimeSeconds,o>1&&(o=1)}}r<0&&(r=0,o=1);for(let n=i;n.15&&(i=1-.15/(1-o)),s>i&&(s=i),t.setPartOpacityByIndex(e,s)}}}constructor(){this._fadeTimeSeconds=.5,this._lastModel=void 0,this._partGroups=[],this._partGroupCounts=[]}}class d{constructor(t){this.parameterIndex=0,this.partIndex=0,this.partId="",this.link=[],null!=t&&this.assignment(t)}assignment(t){return this.partId=t.partId,this.link=t.link.map((t=>t.clone())),this}initialize(t){this.parameterIndex=t.getParameterIndex(this.partId),this.partIndex=t.getPartIndex(this.partId),t.setParameterValueByIndex(this.parameterIndex,1)}clone(){const t=new d;return t.partId=this.partId,t.parameterIndex=this.parameterIndex,t.partIndex=this.partIndex,t.link=this.link.map((t=>t.clone())),t}}class c{constructor(t,e){this.x=t||0,this.y=e||0}add(t){const e=new c(0,0);return e.x=this.x+t.x,e.y=this.y+t.y,e}substract(t){const e=new c(0,0);return e.x=this.x-t.x,e.y=this.y-t.y,e}multiply(t){const e=new c(0,0);return e.x=this.x*t.x,e.y=this.y*t.y,e}multiplyByScaler(t){return this.multiply(new c(t,t))}division(t){const e=new c(0,0);return e.x=this.x/t.x,e.y=this.y/t.y,e}divisionByScalar(t){return this.division(new c(t,t))}getLength(){return Math.sqrt(this.x*this.x+this.y*this.y)}getDistanceWith(t){return Math.sqrt((this.x-t.x)*(this.x-t.x)+(this.y-t.y)*(this.y-t.y))}dot(t){return this.x*t.x+this.y*t.y}normalize(){const t=Math.pow(this.x*this.x+this.y*this.y,.5);this.x=this.x/t,this.y=this.y/t}isEqual(t){return this.x==t.x&&this.y==t.y}isNotEqual(t){return!this.isEqual(t)}}const g=class{static range(t,e,i){return ti&&(t=i),t}static sin(t){return Math.sin(t)}static cos(t){return Math.cos(t)}static abs(t){return Math.abs(t)}static sqrt(t){return Math.sqrt(t)}static cbrt(t){if(0===t)return t;let e=t;const i=e<0;let s;return i&&(e=-e),e===1/0?s=1/0:(s=Math.exp(Math.log(e)/3),s=(e/(s*s)+2*s)/3),i?-s:s}static getEasingSine(t){return t<0?0:t>1?1:.5-.5*this.cos(t*Math.PI)}static max(t,e){return t>e?t:e}static min(t,e){return t>e?e:t}static degreesToRadian(t){return t/180*Math.PI}static radianToDegrees(t){return 180*t/Math.PI}static directionToRadian(t,e){let i=Math.atan2(e.y,e.x)-Math.atan2(t.y,t.x);for(;i<-Math.PI;)i+=2*Math.PI;for(;i>Math.PI;)i-=2*Math.PI;return i}static directionToDegrees(t,e){const i=this.directionToRadian(t,e);let s=this.radianToDegrees(i);return e.x-t.x>0&&(s=-s),s}static radianToDirection(t){const e=new c;return e.x=this.sin(t),e.y=this.cos(t),e}static quadraticEquation(t,e,i){return this.abs(t)1&&(t=1),e<0?e=0:e>1&&(e=1),i<0?i=0:i>1&&(i=1),s<0?s=0:s>1&&(s=1),this._modelColor.R=t,this._modelColor.G=e,this._modelColor.B=i,this._modelColor.A=s}getModelColor(){return Object.assign({},this._modelColor)}setIsPremultipliedAlpha(t){this._isPremultipliedAlpha=t}isPremultipliedAlpha(){return this._isPremultipliedAlpha}setIsCulling(t){this._isCulling=t}isCulling(){return this._isCulling}setAnisotropy(t){this._anisotropy=t}getAnisotropy(){return this._anisotropy}getModel(){return this._model}useHighPrecisionMask(t){this._useHighPrecisionMask=t}isUsingHighPrecisionMask(){return this._useHighPrecisionMask}constructor(){this._isCulling=!1,this._isPremultipliedAlpha=!1,this._anisotropy=0,this._modelColor=new y,this._useHighPrecisionMask=!1,this._mvpMatrix4x4=new _,this._mvpMatrix4x4.loadIdentity()}}var f=(t=>(t[t.CubismBlendMode_Normal=0]="CubismBlendMode_Normal",t[t.CubismBlendMode_Additive=1]="CubismBlendMode_Additive",t[t.CubismBlendMode_Multiplicative=2]="CubismBlendMode_Multiplicative",t))(f||{});class y{constructor(t=1,e=1,i=1,s=1){this.R=t,this.G=e,this.B=i,this.A=s}}let C,x=!1,M=!1;const v={vertexOffset:0,vertexStep:2};class P{static startUp(t){if(x)return T("CubismFramework.startUp() is already done."),x;if(Live2DCubismCore._isStarted)return x=!0,!0;if(Live2DCubismCore._isStarted=!0,C=t,C&&Live2DCubismCore.Logging.csmSetLogFunction(C.logFunction),x=!0,x){const t=Live2DCubismCore.Version.csmGetVersion(),e=(16711680&t)>>16,i=65535&t,s=t;T("Live2D Cubism Core version: {0}.{1}.{2} ({3})",("00"+((4278190080&t)>>24)).slice(-2),("00"+e).slice(-2),("0000"+i).slice(-4),s)}return T("CubismFramework.startUp() is complete."),x}static cleanUp(){x=!1,M=!1,C=void 0}static initialize(t=0){x?M?I("CubismFramework.initialize() skipped, already initialized."):(Live2DCubismCore.Memory.initializeAmountOfMemory(t),M=!0,T("CubismFramework.initialize() is complete.")):I("CubismFramework is not started.")}static dispose(){x?M?(p.staticRelease(),M=!1,T("CubismFramework.dispose() is complete.")):I("CubismFramework.dispose() skipped, not initialized."):I("CubismFramework is not started.")}static isStarted(){return x}static isInitialized(){return M}static coreLogFunction(t){Live2DCubismCore.Logging.csmGetLogFunction()&&Live2DCubismCore.Logging.csmGetLogFunction()(t)}static getLoggingLevel(){return null!=C?C.loggingLevel:b.LogLevel_Off}constructor(){}}var b=(t=>(t[t.LogLevel_Verbose=0]="LogLevel_Verbose",t[t.LogLevel_Debug=1]="LogLevel_Debug",t[t.LogLevel_Info=2]="LogLevel_Info",t[t.LogLevel_Warning=3]="LogLevel_Warning",t[t.LogLevel_Error=4]="LogLevel_Error",t[t.LogLevel_Off=5]="LogLevel_Off",t))(b||{});const S=()=>{};function w(t,...e){E.print(b.LogLevel_Debug,"[CSM][D]"+t+"\n",e)}function T(t,...e){E.print(b.LogLevel_Info,"[CSM][I]"+t+"\n",e)}function I(t,...e){E.print(b.LogLevel_Warning,"[CSM][W]"+t+"\n",e)}function L(t,...e){E.print(b.LogLevel_Error,"[CSM][E]"+t+"\n",e)}class E{static print(t,e,i){if(ti[e])))}static dumpBytes(t,e,i){for(let s=0;s0?this.print(t,"\n"):s%8==0&&s>0&&this.print(t," "),this.print(t,"{0} ",[255&e[s]]);this.print(t,"\n")}constructor(){}}class A{constructor(t=!1,e=new y){this.isOverwritten=t,this.Color=e}}class F{constructor(t=!1,e=new y){this.isOverwritten=t,this.Color=e}}class D{constructor(t=!1,e=!1){this.isOverwritten=t,this.isCulling=e}}class B{update(){this._model.update(),this._model.drawables.resetDynamicFlags()}getPixelsPerUnit(){return null==this._model?0:this._model.canvasinfo.PixelsPerUnit}getCanvasWidth(){return null==this._model?0:this._model.canvasinfo.CanvasWidth/this._model.canvasinfo.PixelsPerUnit}getCanvasHeight(){return null==this._model?0:this._model.canvasinfo.CanvasHeight/this._model.canvasinfo.PixelsPerUnit}saveParameters(){const t=this._model.parameters.count,e=this._savedParameters.length;for(let i=0;ie&&(e=this._model.parameters.minimumValues[t]),this._parameterValues[t]=1==i?e:this._parameterValues[t]=this._parameterValues[t]*(1-i)+e*i)}setParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.setParameterValueByIndex(s,e,i)}addParameterValueByIndex(t,e,i=1){this.setParameterValueByIndex(t,this.getParameterValueByIndex(t)+e*i)}addParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.addParameterValueByIndex(s,e,i)}multiplyParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.multiplyParameterValueByIndex(s,e,i)}multiplyParameterValueByIndex(t,e,i=1){this.setParameterValueByIndex(t,this.getParameterValueByIndex(t)*(1+(e-1)*i))}getDrawableIds(){return this._drawableIds.slice()}getDrawableIndex(t){const e=this._model.drawables.count;for(let i=0;ie&&(t=e);for(let i=0;i=0&&this._partChildDrawables[n].push(t)}}}constructor(t){this._model=t,this._savedParameters=[],this._parameterIds=[],this._drawableIds=[],this._partIds=[],this._isOverwrittenModelMultiplyColors=!1,this._isOverwrittenModelScreenColors=!1,this._isOverwrittenCullings=!1,this._modelOpacity=1,this._userMultiplyColors=[],this._userScreenColors=[],this._userCullings=[],this._userPartMultiplyColors=[],this._userPartScreenColors=[],this._partChildDrawables=[],this._notExistPartId={},this._notExistParameterId={},this._notExistParameterValues={},this._notExistPartOpacities={},this.initialize()}release(){this._model.release(),this._model=void 0}}class R{static create(t,e){if(e){if(!this.hasMocConsistency(t))throw new Error("Inconsistent MOC3.")}const i=Live2DCubismCore.Moc.fromArrayBuffer(t);if(i){const e=new R(i);return e._mocVersion=Live2DCubismCore.Version.csmGetMocVersion(i,t),e}throw new Error("Failed to CubismMoc.create().")}createModel(){let t;const e=Live2DCubismCore.Model.fromMoc(this._moc);if(e)return t=new B(e),++this._modelCount,t;throw new Error("Unknown error")}deleteModel(t){null!=t&&--this._modelCount}constructor(t){this._moc=t,this._modelCount=0,this._mocVersion=0}release(){this._moc._release(),this._moc=void 0}getLatestMocVersion(){return Live2DCubismCore.Version.csmGetLatestMocVersion()}getMocVersion(){return this._mocVersion}static hasMocConsistency(t){return 1===Live2DCubismCore.Moc.prototype.hasMocConsistency(t)}}class O{constructor(t,e){this._json=t}release(){this._json=void 0}getUserDataCount(){return this._json.Meta.UserDataCount}getTotalUserDataSize(){return this._json.Meta.TotalUserDataSize}getUserDataTargetType(t){return this._json.UserData[t].Target}getUserDataId(t){return this._json.UserData[t].Id}getUserDataValue(t){return this._json.UserData[t].Value}}class k{static create(t,e){const i=new k;return i.parseUserData(t,e),i}getArtMeshUserDatas(){return this._artMeshUserDataNode}parseUserData(t,e){const i=new O(t,e),s=i.getUserDataCount();for(let r=0;r0&&e.getEndTime()(t[t.ExpressionBlendType_Add=0]="ExpressionBlendType_Add",t[t.ExpressionBlendType_Multiply=1]="ExpressionBlendType_Multiply",t[t.ExpressionBlendType_Overwrite=2]="ExpressionBlendType_Overwrite",t))(G||{});t.CubismConfig=void 0,(N=t.CubismConfig||(t.CubismConfig={})).supportMoreMaskDivisions=!0,N.setOpacityFromMotion=!1;var X=(t=>(t[t.CubismMotionCurveTarget_Model=0]="CubismMotionCurveTarget_Model",t[t.CubismMotionCurveTarget_Parameter=1]="CubismMotionCurveTarget_Parameter",t[t.CubismMotionCurveTarget_PartOpacity=2]="CubismMotionCurveTarget_PartOpacity",t))(X||{}),z=(t=>(t[t.CubismMotionSegmentType_Linear=0]="CubismMotionSegmentType_Linear",t[t.CubismMotionSegmentType_Bezier=1]="CubismMotionSegmentType_Bezier",t[t.CubismMotionSegmentType_Stepped=2]="CubismMotionSegmentType_Stepped",t[t.CubismMotionSegmentType_InverseStepped=3]="CubismMotionSegmentType_InverseStepped",t))(z||{});class j{constructor(t=0,e=0){this.time=t,this.value=e}}class W{constructor(){this.basePointIndex=0,this.segmentType=0}}class H{constructor(){this.id="",this.type=0,this.segmentCount=0,this.baseSegmentIndex=0,this.fadeInTime=0,this.fadeOutTime=0}}class Y{constructor(){this.fireTime=0,this.value=""}}class q{constructor(){this.duration=0,this.loop=!1,this.curveCount=0,this.eventCount=0,this.fps=0,this.curves=[],this.segments=[],this.points=[],this.events=[]}}class ${constructor(t){this._json=t}release(){this._json=void 0}getMotionDuration(){return this._json.Meta.Duration}isMotionLoop(){return this._json.Meta.Loop||!1}getEvaluationOptionFlag(t){return J.EvaluationOptionFlag_AreBeziersRistricted==t&&!!this._json.Meta.AreBeziersRestricted}getMotionCurveCount(){return this._json.Meta.CurveCount}getMotionFps(){return this._json.Meta.Fps}getMotionTotalSegmentCount(){return this._json.Meta.TotalSegmentCount}getMotionTotalPointCount(){return this._json.Meta.TotalPointCount}getMotionFadeInTime(){return this._json.Meta.FadeInTime}getMotionFadeOutTime(){return this._json.Meta.FadeOutTime}getMotionCurveTarget(t){return this._json.Curves[t].Target}getMotionCurveId(t){return this._json.Curves[t].Id}getMotionCurveFadeInTime(t){return this._json.Curves[t].FadeInTime}getMotionCurveFadeOutTime(t){return this._json.Curves[t].FadeOutTime}getMotionCurveSegmentCount(t){return this._json.Curves[t].Segments.length}getMotionCurveSegment(t,e){return this._json.Curves[t].Segments[e]}getEventCount(){return this._json.Meta.UserDataCount||0}getTotalEventValueSize(){return this._json.Meta.TotalUserDataSize}getEventTime(t){return this._json.UserData[t].Time}getEventValue(t){return this._json.UserData[t].Value}}var J=(t=>(t[t.EvaluationOptionFlag_AreBeziersRistricted=0]="EvaluationOptionFlag_AreBeziersRistricted",t))(J||{});const Z="Opacity";function Q(t,e,i){const s=new j;return s.time=t.time+(e.time-t.time)*i,s.value=t.value+(e.value-t.value)*i,s}function K(t,e){let i=(e-t[0].time)/(t[1].time-t[0].time);return i<0&&(i=0),t[0].value+(t[1].value-t[0].value)*i}function tt(t,e){let i=(e-t[0].time)/(t[3].time-t[0].time);i<0&&(i=0);const s=Q(t[0],t[1],i),r=Q(t[1],t[2],i),o=Q(t[2],t[3],i),a=Q(s,r,i),n=Q(r,o,i);return Q(a,n,i).value}function et(t,e){const i=e,s=t[0].time,r=t[3].time,o=t[1].time,a=t[2].time,n=r-3*a+3*o-s,l=3*a-6*o+3*s,h=3*o-3*s,u=s-i,d=m.cardanoAlgorithmForBezier(n,l,h,u),c=Q(t[0],t[1],d),g=Q(t[1],t[2],d),_=Q(t[2],t[3],d),p=Q(c,g,d),f=Q(g,_,d);return Q(p,f,d).value}function it(t,e){return t[0].value}function st(t,e){return t[1].value}function rt(t,e,i){const s=t.curves[e];let r=-1;const o=s.baseSegmentIndex+s.segmentCount;let a=0;for(let l=s.baseSegmentIndex;li){r=l;break}if(-1==r)return t.points[a].value;const n=t.segments[r];return n.evaluate(t.points.slice(n.basePointIndex),i)}class ot extends U{constructor(){super(),this._eyeBlinkParameterIds=[],this._lipSyncParameterIds=[],this._sourceFrameRate=30,this._loopDurationSeconds=-1,this._isLoop=!1,this._isLoopFadeIn=!0,this._lastWeight=0,this._modelOpacity=1}static create(t,e){const i=new ot;return i.parse(t),i._sourceFrameRate=i._motionData.fps,i._loopDurationSeconds=i._motionData.duration,i._onFinishedMotion=e,i}doUpdateParameters(e,i,s,r){null==this._modelCurveIdEyeBlink&&(this._modelCurveIdEyeBlink="EyeBlink"),null==this._modelCurveIdLipSync&&(this._modelCurveIdLipSync="LipSync"),null==this._modelCurveIdOpacity&&(this._modelCurveIdOpacity=Z);let o=i-r.getStartTime();o<0&&(o=0);let a=Number.MAX_VALUE,n=Number.MAX_VALUE;const l=64;let h=0,u=0;this._eyeBlinkParameterIds.length>l&&w("too many eye blink targets : {0}",this._eyeBlinkParameterIds.length),this._lipSyncParameterIds.length>l&&w("too many lip sync targets : {0}",this._lipSyncParameterIds.length);const d=this._fadeInSeconds<=0?1:m.getEasingSine((i-r.getFadeInStartTime())/this._fadeInSeconds),c=this._fadeOutSeconds<=0||r.getEndTime()<0?1:m.getEasingSine((r.getEndTime()-i)/this._fadeOutSeconds);let g,_,p,f=o;if(this._isLoop)for(;f>this._motionData.duration;)f-=this._motionData.duration;const y=this._motionData.curves;for(_=0;_>t&1)continue;const r=i+(n-i)*s;e.setParameterValueById(this._eyeBlinkParameterIds[t],r)}if(a!=Number.MAX_VALUE)for(let t=0;t>t&1)continue;const r=i+(a-i)*s;e.setParameterValueById(this._lipSyncParameterIds[t],r)}for(;_=this._motionData.duration&&(this._isLoop?(r.setStartTime(i),this._isLoopFadeIn&&r.setFadeInStartTime(i)):(this._onFinishedMotion&&this._onFinishedMotion(this),r.setIsFinished(!0))),this._lastWeight=s}setIsLoop(t){this._isLoop=t}isLoop(){return this._isLoop}setIsLoopFadeIn(t){this._isLoopFadeIn=t}isLoopFadeIn(){return this._isLoopFadeIn}getDuration(){return this._isLoop?-1:this._loopDurationSeconds}getLoopDuration(){return this._loopDurationSeconds}setParameterFadeInTime(t,e){const i=this._motionData.curves;for(let s=0;snew H)),this._motionData.segments=Array.from({length:e.getMotionTotalSegmentCount()}).map((()=>new W)),this._motionData.events=Array.from({length:this._motionData.eventCount}).map((()=>new Y)),this._motionData.points=[];let o=0,a=0;for(let n=0;nt&&this._motionData.events[i].fireTime<=e&&this._firedEventValues.push(this._motionData.events[i].value);return this._firedEventValues}isExistModelOpacity(){for(let t=0;tnull!=e&&e._motionQueueEntryHandle==t))}setEventCallback(t,e=null){this._eventCallBack=t,this._eventCustomData=e}doUpdateMotion(t,e){let i=!1,s=0;for(;s(t[t.CubismPhysicsTargetType_Parameter=0]="CubismPhysicsTargetType_Parameter",t))(ht||{}),ut=(t=>(t[t.CubismPhysicsSource_X=0]="CubismPhysicsSource_X",t[t.CubismPhysicsSource_Y=1]="CubismPhysicsSource_Y",t[t.CubismPhysicsSource_Angle=2]="CubismPhysicsSource_Angle",t))(ut||{});class dt{constructor(){this.initialPosition=new c(0,0),this.position=new c(0,0),this.lastPosition=new c(0,0),this.lastGravity=new c(0,0),this.force=new c(0,0),this.velocity=new c(0,0)}}class ct{constructor(){this.normalizationPosition={},this.normalizationAngle={}}}class gt{constructor(){this.source={}}}class mt{constructor(){this.destination={},this.translationScale=new c(0,0)}}class _t{constructor(){this.settings=[],this.inputs=[],this.outputs=[],this.particles=[],this.gravity=new c(0,0),this.wind=new c(0,0),this.fps=0}}class pt{constructor(t){this._json=t}release(){this._json=void 0}getGravity(){const t=new c(0,0);return t.x=this._json.Meta.EffectiveForces.Gravity.X,t.y=this._json.Meta.EffectiveForces.Gravity.Y,t}getWind(){const t=new c(0,0);return t.x=this._json.Meta.EffectiveForces.Wind.X,t.y=this._json.Meta.EffectiveForces.Wind.Y,t}getFps(){return this._json.Meta.Fps||0}getSubRigCount(){return this._json.Meta.PhysicsSettingCount}getTotalInputCount(){return this._json.Meta.TotalInputCount}getTotalOutputCount(){return this._json.Meta.TotalOutputCount}getVertexCount(){return this._json.Meta.VertexCount}getNormalizationPositionMinimumValue(t){return this._json.PhysicsSettings[t].Normalization.Position.Minimum}getNormalizationPositionMaximumValue(t){return this._json.PhysicsSettings[t].Normalization.Position.Maximum}getNormalizationPositionDefaultValue(t){return this._json.PhysicsSettings[t].Normalization.Position.Default}getNormalizationAngleMinimumValue(t){return this._json.PhysicsSettings[t].Normalization.Angle.Minimum}getNormalizationAngleMaximumValue(t){return this._json.PhysicsSettings[t].Normalization.Angle.Maximum}getNormalizationAngleDefaultValue(t){return this._json.PhysicsSettings[t].Normalization.Angle.Default}getInputCount(t){return this._json.PhysicsSettings[t].Input.length}getInputWeight(t,e){return this._json.PhysicsSettings[t].Input[e].Weight}getInputReflect(t,e){return this._json.PhysicsSettings[t].Input[e].Reflect}getInputType(t,e){return this._json.PhysicsSettings[t].Input[e].Type}getInputSourceId(t,e){return this._json.PhysicsSettings[t].Input[e].Source.Id}getOutputCount(t){return this._json.PhysicsSettings[t].Output.length}getOutputVertexIndex(t,e){return this._json.PhysicsSettings[t].Output[e].VertexIndex}getOutputAngleScale(t,e){return this._json.PhysicsSettings[t].Output[e].Scale}getOutputWeight(t,e){return this._json.PhysicsSettings[t].Output[e].Weight}getOutputDestinationId(t,e){return this._json.PhysicsSettings[t].Output[e].Destination.Id}getOutputType(t,e){return this._json.PhysicsSettings[t].Output[e].Type}getOutputReflect(t,e){return this._json.PhysicsSettings[t].Output[e].Reflect}getParticleCount(t){return this._json.PhysicsSettings[t].Vertices.length}getParticleMobility(t,e){return this._json.PhysicsSettings[t].Vertices[e].Mobility}getParticleDelay(t,e){return this._json.PhysicsSettings[t].Vertices[e].Delay}getParticleAcceleration(t,e){return this._json.PhysicsSettings[t].Vertices[e].Acceleration}getParticleRadius(t,e){return this._json.PhysicsSettings[t].Vertices[e].Radius}getParticlePosition(t,e){const i=new c(0,0);return i.x=this._json.PhysicsSettings[t].Vertices[e].Position.X,i.y=this._json.PhysicsSettings[t].Vertices[e].Position.Y,i}}const ft="Angle";class yt{static create(t){const e=new yt;return e.parse(t),e._physicsRig.gravity.y=0,e}static delete(t){null!=t&&t.release()}parse(t){this._physicsRig=new _t;const e=new pt(t);this._physicsRig.gravity=e.getGravity(),this._physicsRig.wind=e.getWind(),this._physicsRig.subRigCount=e.getSubRigCount(),this._physicsRig.fps=e.getFps(),this._currentRigOutputs=[],this._previousRigOutputs=[];let i=0,s=0,r=0;for(let o=0;o=u.particleCount)continue;let s=new c;s=_[i].position.substract(_[i-1].position),l=g[e].getValue(s,_,i,g[e].reflect,this._options.gravity),this._currentRigOutputs[x].outputs[e]=l,this._previousRigOutputs[x].outputs[e]=l;const r=g[e].destinationParameterIndex,o=!Float32Array.prototype.slice&&"subarray"in Float32Array.prototype?JSON.parse(JSON.stringify(p.subarray(r))):p.slice(r);Dt(o,y[r],f[r],l,g[e]);for(let t=r,e=0;t=e)return;if(this._currentRemainTime+=e,this._currentRemainTime>5&&(this._currentRemainTime=0),f=t.getModel().parameters.values,y=t.getModel().parameters.maximumValues,C=t.getModel().parameters.minimumValues,x=t.getModel().parameters.defaultValues,(null!=(s=null==(i=this._parameterCaches)?void 0:i.length)?s:0)0?1/this._physicsRig.fps:e;this._currentRemainTime>=M;){for(let t=0;t=d.particleCount)continue;const r=new c;r.x=p[s].position.x-p[s-1].position.x,r.y=p[s].position.y-p[s-1].position.y,h=_[e].getValue(r,p,s,_[e].reflect,this._options.gravity),this._currentRigOutputs[i].outputs[e]=h;const o=_[e].destinationParameterIndex,a=!Float32Array.prototype.slice&&"subarray"in Float32Array.prototype?JSON.parse(JSON.stringify(this._parameterCaches.subarray(o))):this._parameterCaches.slice(o);Dt(a,C[o],y[o],h,_[e]);for(let t=o,e=0;t=2?e[i-1].position.substract(e[i-2].position):r.multiplyByScaler(-1),o=m.directionToRadian(r,t),s&&(o*=-1),o}function Tt(t,e){return Math.min(t,e)+function(t,e){return Math.abs(Math.max(t,e)-Math.min(t,e))}(t,e)/2}function It(t,e){return t.x}function Lt(t,e){return t.y}function Et(t,e){return e}function At(t,e,i,s,r,o,a,n){let l,h,u,d,g=new c(0,0),_=new c(0,0),p=new c(0,0),f=new c(0,0);t[0].position=new c(i.x,i.y),l=m.degreesToRadian(s),d=m.radianToDirection(l),d.normalize();for(let y=1;yi&&(a>r.valueExceededMaximum&&(r.valueExceededMaximum=a),a=i),n=r.weight/100,n>=1||(a=t[0]*(1-n)+a*n),t[0]=a}function Bt(t,e,i,s,r,o,a,n){let l=0;const h=m.max(i,e);ht&&(t=u);const d=m.min(r,o),c=m.max(r,o),g=a,_=Tt(u,h),p=t-_;switch(Math.sign(p)){case 1:{const t=c-g,e=h-_;0!=e&&(l=p*(t/e),l+=g);break}case-1:{const t=d-g,e=u-_;0!=e&&(l=p*(t/e),l+=g);break}case 0:l=g}return n?l:-1*l}class Rt{constructor(t=0,e=0,i=0,s=0){this.x=t,this.y=e,this.width=i,this.height=s}getCenterX(){return this.x+.5*this.width}getCenterY(){return this.y+.5*this.height}getRight(){return this.x+this.width}getBottom(){return this.y+this.height}setRect(t){this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height}expand(t,e){this.x-=t,this.y-=e,this.width+=2*t,this.height+=2*e}}let Ot,kt,Ut;class Vt{getChannelFlagAsColor(t){return this._channelColors[t]}getMaskRenderTexture(){if(this._maskTexture&&null!=this._maskTexture.textures)this._maskTexture.frameNo=this._currentFrameNo;else{this._maskRenderTextures=[],this._maskColorBuffers=[];const t=this._clippingMaskBufferSize;for(let e=0;ec&&(c=e),ig&&(g=i)}if(u!=Number.MAX_VALUE)if(ur&&(r=c),g>o&&(o=g),i==Number.MAX_VALUE)e._allClippedDrawRect.x=0,e._allClippedDrawRect.y=0,e._allClippedDrawRect.width=0,e._allClippedDrawRect.height=0,e._isUsing=!1;else{e._isUsing=!0;const t=r-i,a=o-s;e._allClippedDrawRect.x=i,e._allClippedDrawRect.y=s,e._allClippedDrawRect.width=t,e._allClippedDrawRect.height=a}}}constructor(){this._currentMaskRenderTexture=null,this._currentFrameNo=0,this._renderTextureCount=0,this._clippingMaskBufferSize=256,this._clippingContextListForMask=[],this._clippingContextListForDraw=[],this._channelColors=[],this._tmpBoundsOnModel=new Rt,this._tmpMatrix=new _,this._tmpMatrixForMask=new _,this._tmpMatrixForDraw=new _;let t=new y;t.R=1,t.G=0,t.B=0,t.A=0,this._channelColors.push(t),t=new y,t.R=0,t.G=1,t.B=0,t.A=0,this._channelColors.push(t),t=new y,t.R=0,t.G=0,t.B=1,t.A=0,this._channelColors.push(t),t=new y,t.R=0,t.G=0,t.B=0,t.A=1,this._channelColors.push(t)}release(){var t;const e=this;for(let i=0;i0){this.setupLayoutBounds(e.isUsingHighPrecisionMask()?0:i),e.isUsingHighPrecisionMask()||(this.gl.viewport(0,0,this._clippingMaskBufferSize,this._clippingMaskBufferSize),this._currentMaskRenderTexture=this.getMaskRenderTexture()[0],e.preDraw(),this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,this._currentMaskRenderTexture)),this._clearedFrameBufferflags||(this._clearedFrameBufferflags=[]);for(let t=0;th?(this._tmpBoundsOnModel.expand(r.width*a,0),n=o.width/this._tmpBoundsOnModel.width):n=e/h,this._tmpBoundsOnModel.height*e>u?(this._tmpBoundsOnModel.expand(0,r.height*a),l=o.height/this._tmpBoundsOnModel.height):l=e/u}else this._tmpBoundsOnModel.setRect(r),this._tmpBoundsOnModel.expand(r.width*a,r.height*a),n=o.width/this._tmpBoundsOnModel.width,l=o.height/this._tmpBoundsOnModel.height;if(this._tmpMatrix.loadIdentity(),this._tmpMatrix.translateRelative(-1,-1),this._tmpMatrix.scaleRelative(2,2),this._tmpMatrix.translateRelative(o.x,o.y),this._tmpMatrix.scaleRelative(n,l),this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x,-this._tmpBoundsOnModel.y),this._tmpMatrixForMask.setMatrix(this._tmpMatrix.getArray()),this._tmpMatrix.loadIdentity(),this._tmpMatrix.translateRelative(o.x,o.y),this._tmpMatrix.scaleRelative(n,l),this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x,-this._tmpBoundsOnModel.y),this._tmpMatrixForDraw.setMatrix(this._tmpMatrix.getArray()),s._matrixForMask.setMatrix(this._tmpMatrixForMask.getArray()),s._matrixForDraw.setMatrix(this._tmpMatrixForDraw.getArray()),!e.isUsingHighPrecisionMask()){const i=s._clippingIdCount;for(let r=0;ri){e>i&&L("not supported mask count : {0}\n[Details] render texture count : {1}, mask count : {2}",e-i,this._renderTextureCount,e);for(let t=0;t=4?0:n+1;if(u(t[t.ShaderNames_SetupMask=0]="ShaderNames_SetupMask",t[t.ShaderNames_NormalPremultipliedAlpha=1]="ShaderNames_NormalPremultipliedAlpha",t[t.ShaderNames_NormalMaskedPremultipliedAlpha=2]="ShaderNames_NormalMaskedPremultipliedAlpha",t[t.ShaderNames_NomralMaskedInvertedPremultipliedAlpha=3]="ShaderNames_NomralMaskedInvertedPremultipliedAlpha",t[t.ShaderNames_AddPremultipliedAlpha=4]="ShaderNames_AddPremultipliedAlpha",t[t.ShaderNames_AddMaskedPremultipliedAlpha=5]="ShaderNames_AddMaskedPremultipliedAlpha",t[t.ShaderNames_AddMaskedPremultipliedAlphaInverted=6]="ShaderNames_AddMaskedPremultipliedAlphaInverted",t[t.ShaderNames_MultPremultipliedAlpha=7]="ShaderNames_MultPremultipliedAlpha",t[t.ShaderNames_MultMaskedPremultipliedAlpha=8]="ShaderNames_MultMaskedPremultipliedAlpha",t[t.ShaderNames_MultMaskedPremultipliedAlphaInverted=9]="ShaderNames_MultMaskedPremultipliedAlphaInverted",t))(jt||{});const Wt="attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_myPos;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_clipMatrix * a_position; v_myPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}",Ht="precision mediump float;varying vec2 v_texCoord;varying vec4 v_myPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;void main(){ float isInside = step(u_baseColor.x, v_myPos.x/v_myPos.w) * step(u_baseColor.y, v_myPos.y/v_myPos.w) * step(v_myPos.x/v_myPos.w, u_baseColor.z) * step(v_myPos.y/v_myPos.w, u_baseColor.w); gl_FragColor = u_channelFlag * texture2D(s_texture0, v_texCoord).a * isInside;}",Yt="attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;uniform mat4 u_matrix;void main(){ gl_Position = u_matrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}",qt="attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform mat4 u_matrix;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_matrix * a_position; v_clipPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}",$t="precision mediump float;varying vec2 v_texCoord;uniform vec4 u_baseColor;uniform sampler2D s_texture0;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 color = texColor * u_baseColor; gl_FragColor = vec4(color.rgb, color.a);}",Jt="precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * maskVal; gl_FragColor = col_formask;}",Zt="precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_channelFlag;uniform vec4 u_baseColor;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * (1.0 - maskVal); gl_FragColor = col_formask;}";class Qt extends p{constructor(){super(),this._clippingContextBufferForMask=null,this._clippingContextBufferForDraw=null,this._rendererProfile=new Xt,this.firstDraw=!0,this._textures={},this._sortedDrawableIndexList=[],this._bufferData={vertex:null,uv:null,index:null}}initialize(t,e=1){t.isUsingMasking()&&(this._clippingManager=new Vt,this._clippingManager.initialize(t,t.getDrawableCount(),t.getDrawableMasks(),t.getDrawableMaskCounts(),e));for(let i=t.getDrawableCount()-1;i>=0;i--)this._sortedDrawableIndexList[i]=0;super.initialize(t)}bindTexture(t,e){this._textures[t]=e}getBindedTextures(){return this._textures}setClippingMaskBufferSize(t){if(!this._model.isUsingMasking())return;const e=this._clippingManager.getRenderTextureCount();this._clippingManager.release(),this._clippingManager=new Vt,this._clippingManager.setClippingMaskBufferSize(t),this._clippingManager.initialize(this.getModel(),this.getModel().getDrawableCount(),this.getModel().getDrawableMasks(),this.getModel().getDrawableMaskCounts(),e)}getClippingMaskBufferSize(){return this._model.isUsingMasking()?this._clippingManager.getClippingMaskBufferSize():-1}getRenderTextureCount(){return this._model.isUsingMasking()?this._clippingManager.getRenderTextureCount():-1}release(){var t,e,i;const s=this;this._clippingManager.release(),s._clippingManager=void 0,null==(t=this.gl)||t.deleteBuffer(this._bufferData.vertex),this._bufferData.vertex=null,null==(e=this.gl)||e.deleteBuffer(this._bufferData.uv),this._bufferData.uv=null,null==(i=this.gl)||i.deleteBuffer(this._bufferData.index),this._bufferData.index=null,s._bufferData=void 0,s._textures=void 0}doDrawModel(){if(null==this.gl)return void L("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");null!=this._clippingManager&&(this.preDraw(),this._clippingManager.setupClippingContext(this.getModel(),this)),this.preDraw();const t=this.getModel().getDrawableCount(),e=this.getModel().getDrawableRenderOrders();for(let i=0;i0&&this._extension)for(const t of Object.entries(this._textures))this.gl.bindTexture(this.gl.TEXTURE_2D,t),this.gl.texParameterf(this.gl.TEXTURE_2D,this._extension.TEXTURE_MAX_ANISOTROPY_EXT,this.getAnisotropy())}setClippingContextBufferForMask(t){this._clippingContextBufferForMask=t}getClippingContextBufferForMask(){return this._clippingContextBufferForMask}setClippingContextBufferForDraw(t){this._clippingContextBufferForDraw=t}getClippingContextBufferForDraw(){return this._clippingContextBufferForDraw}startUp(t){this.gl=t,this._clippingManager&&this._clippingManager.setGL(t),zt.getInstance().setGl(t),this._rendererProfile.setGl(t),this._extension=this.gl.getExtension("EXT_texture_filter_anisotropic")||this.gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic")||this.gl.getExtension("MOZ_EXT_texture_filter_anisotropic")}}p.staticRelease=()=>{Qt.doStaticRelease()};class Kt{constructor(t){this.groups=t.Groups,this.hitAreas=t.HitAreas,this.layout=t.Layout,this.moc=t.FileReferences.Moc,this.expressions=t.FileReferences.Expressions,this.motions=t.FileReferences.Motions,this.textures=t.FileReferences.Textures,this.physics=t.FileReferences.Physics,this.pose=t.FileReferences.Pose}getEyeBlinkParameters(){var t,e;return null==(e=null==(t=this.groups)?void 0:t.find((t=>"EyeBlink"===t.Name)))?void 0:e.Ids}getLipSyncParameters(){var t,e;return null==(e=null==(t=this.groups)?void 0:t.find((t=>"LipSync"===t.Name)))?void 0:e.Ids}}const te="ParamAngleX",ee="ParamAngleY",ie="ParamAngleZ",se="ParamEyeBallX",re="ParamEyeBallY",oe="ParamBodyAngleX",ae="ParamBreath";var ne;t.config=void 0,(ne=t.config||(t.config={})).LOG_LEVEL_VERBOSE=0,ne.LOG_LEVEL_WARNING=1,ne.LOG_LEVEL_ERROR=2,ne.LOG_LEVEL_NONE=999,ne.logLevel=ne.LOG_LEVEL_WARNING,ne.sound=!0,ne.motionSync=!0,ne.motionFadingDuration=500,ne.idleMotionFadingDuration=2e3,ne.expressionFadingDuration=500,ne.preserveExpressionOnMotion=!0,ne.cubism4=t.CubismConfig;const le={log(e,...i){t.config.logLevel<=t.config.LOG_LEVEL_VERBOSE&&console.log(`[${e}]`,...i)},warn(e,...i){t.config.logLevel<=t.config.LOG_LEVEL_WARNING&&console.warn(`[${e}]`,...i)},error(e,...i){t.config.logLevel<=t.config.LOG_LEVEL_ERROR&&console.error(`[${e}]`,...i)}};function he(t,e,i){return ti?i:t}function ue(t,e){e.forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((i=>{"constructor"!==i&&Object.defineProperty(t.prototype,i,Object.getOwnPropertyDescriptor(e.prototype,i))}))}))}function de(t){let e=t.lastIndexOf("/");return-1!=e&&(t=t.slice(0,e)),e=t.lastIndexOf("/"),-1!==e&&(t=t.slice(e+1)),t}function ce(t,e){const i=t.indexOf(e);-1!==i&&t.splice(i,1)}class ge extends e.EventEmitter{constructor(t,e){super(),this.expressions=[],this.reserveExpressionIndex=-1,this.destroyed=!1,this.settings=t,this.tag=`ExpressionManager(${t.name})`}init(){this.defaultExpression=this.createExpression({},void 0),this.currentExpression=this.defaultExpression,this.stopAllExpressions()}loadExpression(t){return __async(this,null,(function*(){if(!this.definitions[t])return void le.warn(this.tag,`Undefined expression at [${t}]`);if(null===this.expressions[t])return void le.warn(this.tag,`Cannot set expression at [${t}] because it's already failed in loading.`);if(this.expressions[t])return this.expressions[t];const e=yield this._loadExpression(t);return this.expressions[t]=e,e}))}_loadExpression(t){throw new Error("Not implemented.")}setRandomExpression(){return __async(this,null,(function*(){if(this.definitions.length){const t=[];for(let e=0;e-1&&tl&&(o*=l/n,a*=l/n),this.vx+=o,this.vy+=a;const h=Math.sqrt(__pow(this.vx,2)+__pow(this.vy,2)),u=.5*(Math.sqrt(__pow(l,2)+8*l*s)-l);h>u&&(this.vx*=u/h,this.vy*=u/h),this.x+=this.vx,this.y+=this.vy}}class _e{constructor(t){this.json=t;let e=t.url;if("string"!=typeof e)throw new TypeError("The `url` field in settings JSON must be defined as a string.");this.url=e,this.name=de(this.url)}resolveURL(t){return e.url.resolve(this.url,t)}replaceFiles(t){this.moc=t(this.moc,"moc"),void 0!==this.pose&&(this.pose=t(this.pose,"pose")),void 0!==this.physics&&(this.physics=t(this.physics,"physics"));for(let e=0;e(t.push(e),e))),t}validateFiles(t){const e=(e,i)=>{const s=this.resolveURL(e);if(!t.includes(s)){if(i)throw new Error(`File "${e}" is defined in settings, but doesn't exist in given files`);return!1}return!0};[this.moc,...this.textures].forEach((t=>e(t,!0)));return this.getDefinedFiles().filter((t=>e(t,!1)))}}var pe=(t=>(t[t.NONE=0]="NONE",t[t.IDLE=1]="IDLE",t[t.NORMAL=2]="NORMAL",t[t.FORCE=3]="FORCE",t))(pe||{});class fe{constructor(){this.debug=!1,this.currentPriority=0,this.reservePriority=0}reserve(t,e,i){if(i<=0)return le.log(this.tag,"Cannot start a motion with MotionPriority.NONE."),!1;if(t===this.currentGroup&&e===this.currentIndex)return le.log(this.tag,"Motion is already playing.",this.dump(t,e)),!1;if(t===this.reservedGroup&&e===this.reservedIndex||t===this.reservedIdleGroup&&e===this.reservedIdleIndex)return le.log(this.tag,"Motion is already reserved.",this.dump(t,e)),!1;if(1===i){if(0!==this.currentPriority)return le.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(t,e)),!1;if(void 0!==this.reservedIdleGroup)return le.log(this.tag,"Cannot start idle motion because another idle motion has reserved.",this.dump(t,e)),!1;this.setReservedIdle(t,e)}else{if(i<3){if(i<=this.currentPriority)return le.log(this.tag,"Cannot start motion because another motion is playing as an equivalent or higher priority.",this.dump(t,e)),!1;if(i<=this.reservePriority)return le.log(this.tag,"Cannot start motion because another motion has reserved as an equivalent or higher priority.",this.dump(t,e)),!1}this.setReserved(t,e,i)}return!0}start(t,e,i,s){if(1===s){if(this.setReservedIdle(void 0,void 0),0!==this.currentPriority)return le.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(e,i)),!1}else{if(e!==this.reservedGroup||i!==this.reservedIndex)return le.log(this.tag,"Cannot start motion because another motion has taken the place.",this.dump(e,i)),!1;this.setReserved(void 0,void 0,0)}return!!t&&(this.setCurrent(e,i,s),!0)}complete(){this.setCurrent(void 0,void 0,0)}setCurrent(t,e,i){this.currentPriority=i,this.currentGroup=t,this.currentIndex=e}setReserved(t,e,i){this.reservePriority=i,this.reservedGroup=t,this.reservedIndex=e}setReservedIdle(t,e){this.reservedIdleGroup=t,this.reservedIdleIndex=e}isActive(t,e){return t===this.currentGroup&&e===this.currentIndex||t===this.reservedGroup&&e===this.reservedIndex||t===this.reservedIdleGroup&&e===this.reservedIdleIndex}reset(){this.setCurrent(void 0,void 0,0),this.setReserved(void 0,void 0,0),this.setReservedIdle(void 0,void 0)}shouldRequestIdleMotion(){return void 0===this.currentGroup&&void 0===this.reservedIdleGroup}shouldOverrideExpression(){return!t.config.preserveExpressionOnMotion&&this.currentPriority>1}dump(t,e){if(this.debug){return`\n group = "${t}", index = ${e}\n`+["currentPriority","reservePriority","currentGroup","currentIndex","reservedGroup","reservedIndex","reservedIdleGroup","reservedIdleIndex"].map((t=>"["+t+"] "+this[t])).join("\n")}return""}}class ye{static get volume(){return this._volume}static set volume(t){this._volume=(t>1?1:t<0?0:t)||0,this.audios.forEach((t=>t.volume=this._volume))}static add(t,e,i){const s=new Audio(t);return s.volume=this._volume,s.preload="auto",s.autoplay=!0,s.crossOrigin="anonymous",s.addEventListener("ended",(()=>{this.dispose(s),null==e||e()})),s.addEventListener("error",(e=>{this.dispose(s),le.warn("SoundManager",`Error occurred on "${t}"`,e.error),null==i||i(e.error)})),this.audios.push(s),s}static play(t){return new Promise(((e,i)=>{var s;null==(s=t.play())||s.catch((e=>{t.dispatchEvent(new ErrorEvent("error",{error:e})),i(e)})),t.readyState===t.HAVE_ENOUGH_DATA?e():t.addEventListener("canplaythrough",e)}))}static addContext(t){const e=new AudioContext;return this.contexts.push(e),e}static addAnalyzer(t,e){const i=e.createMediaElementSource(t),s=e.createAnalyser();return s.fftSize=256,s.minDecibels=-90,s.maxDecibels=-10,s.smoothingTimeConstant=.85,i.connect(s),s.connect(e.destination),this.analysers.push(s),s}static analyze(t){if(null!=t){let e=new Float32Array(t.fftSize),i=0;t.getFloatTimeDomainData(e);for(const t of e)i+=t*t;return parseFloat(Math.sqrt(i/e.length*20).toFixed(1))}return parseFloat(Math.random().toFixed(1))}static dispose(t){t.pause(),t.removeAttribute("src"),ce(this.audios,t)}static destroy(){for(let t=this.contexts.length-1;t>=0;t--)this.contexts[t].close();for(let t=this.audios.length-1;t>=0;t--)this.dispose(this.audios[t])}}ye.audios=[],ye.analysers=[],ye.contexts=[],ye._volume=.9;var Ce=(t=>(t.ALL="ALL",t.IDLE="IDLE",t.NONE="NONE",t))(Ce||{});class xe extends e.EventEmitter{constructor(t,e){super(),this.motionGroups={},this.state=new fe,this.playing=!1,this.destroyed=!1,this.settings=t,this.tag=`MotionManager(${t.name})`,this.state.tag=this.tag}init(t){(null==t?void 0:t.idleMotionGroup)&&(this.groups.idle=t.idleMotionGroup),this.setupMotions(t),this.stopAllMotions()}setupMotions(t){for(const i of Object.keys(this.definitions))this.motionGroups[i]=[];let e;switch(null==t?void 0:t.motionPreload){case"NONE":return;case"ALL":e=Object.keys(this.definitions);break;default:e=[this.groups.idle]}for(const i of e)if(this.definitions[i])for(let t=0;t{s&&d.expressionManager&&d.expressionManager.resetExpression(),d.currentAudio=void 0}),(()=>{s&&d.expressionManager&&d.expressionManager.resetExpression(),d.currentAudio=void 0})),this.currentAudio=r;let t=1;void 0!==i&&(t=i),ye.volume=t,a=ye.addContext(this.currentAudio),this.currentContext=a,o=ye.addAnalyzer(this.currentAudio,this.currentContext),this.currentAnalyzer=o}catch(c){le.warn(this.tag,"Failed to create audio",n,c)}if(r){const e=ye.play(r).catch((t=>le.warn(this.tag,"Failed to play audio",r.src,t)));t.config.motionSync&&(yield e)}return this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),s&&this.expressionManager&&this.expressionManager.setExpression(s),this.playing=!0,!0}))}startMotion(e,i){return __async(this,arguments,(function*(e,i,s=pe.NORMAL,r,o,a){var n;if(this.currentAudio&&!this.currentAudio.ended)return!1;if(!this.state.reserve(e,i,s))return!1;const l=null==(n=this.definitions[e])?void 0:n[i];if(!l)return!1;let h,u,d;if(this.currentAudio&&ye.dispose(this.currentAudio),t.config.sound){const t=r&&r.startsWith("data:audio/wav;base64");if(r&&!t){var c=document.createElement("a");c.href=r,r=c.href}const e=r&&(r.startsWith("http")||r.startsWith("blob")),i=this.getSoundFile(l);let s=i;i&&(s=this.settings.resolveURL(i)+"?cache-buster="+(new Date).getTime()),(e||t)&&(s=r);const n=this;if(s)try{h=ye.add(s,(()=>{a&&n.expressionManager&&n.expressionManager.resetExpression(),n.currentAudio=void 0}),(()=>{a&&n.expressionManager&&n.expressionManager.resetExpression(),n.currentAudio=void 0})),this.currentAudio=h;let t=1;void 0!==o&&(t=o),ye.volume=t,d=ye.addContext(this.currentAudio),this.currentContext=d,u=ye.addAnalyzer(this.currentAudio,this.currentContext),this.currentAnalyzer=u}catch(m){le.warn(this.tag,"Failed to create audio",i,m)}}const g=yield this.loadMotion(e,i);if(h){s=3;const e=ye.play(h).catch((t=>le.warn(this.tag,"Failed to play audio",h.src,t)));t.config.motionSync&&(yield e)}return this.state.start(g,e,i,s)?(this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),le.log(this.tag,"Start motion:",this.getMotionName(l)),this.emit("motionStart",e,i,h),a&&this.expressionManager&&this.expressionManager.setExpression(a),this.playing=!0,this._startMotion(g),!0):(h&&(ye.dispose(h),this.currentAudio=void 0),!1)}))}startRandomMotion(t,e,i,s){return __async(this,null,(function*(){const r=this.definitions[t];if(null==r?void 0:r.length){const o=[];for(let e=0;et.index>=0));for(const e of t)this.hitAreas[e.name]=e}hitTest(t,e){return Object.keys(this.hitAreas).filter((i=>this.isHit(i,t,e)))}isHit(t,e,i){if(!this.hitAreas[t])return!1;const s=this.hitAreas[t].index,r=this.getDrawableBounds(s,Me);return r.x<=e&&e<=r.x+r.width&&r.y<=i&&i<=r.y+r.height}getDrawableBounds(t,e){const i=this.getDrawableVertices(t);let s=i[0],r=i[0],o=i[1],a=i[1];for(let n=0;n{200!==o.status&&0!==o.status||!o.response?o.onerror():s(o.response)},o.onerror=()=>{le.warn("XHRLoader",`Failed to load resource as ${o.responseType} (Status ${o.status}): ${e}`),r(new Pe("Network error.",e,o.status))},o.onabort=()=>r(new Pe("Aborted.",e,o.status,!0)),o.onloadend=()=>{var e;be.allXhrSet.delete(o),t&&(null==(e=be.xhrMap.get(t))||e.delete(o))},o}static cancelXHRs(){var t;null==(t=be.xhrMap.get(this))||t.forEach((t=>{t.abort(),be.allXhrSet.delete(t)})),be.xhrMap.delete(this)}static release(){be.allXhrSet.forEach((t=>t.abort())),be.allXhrSet.clear(),be.xhrMap=new WeakMap}};let Se=be;function we(t,e){let i=-1;return function s(r,o){if(o)return Promise.reject(o);if(r<=i)return Promise.reject(new Error("next() called multiple times"));i=r;const a=t[r];if(!a)return Promise.resolve();try{return Promise.resolve(a(e,s.bind(null,r+1)))}catch(n){return Promise.reject(n)}}(0)}Se.xhrMap=new WeakMap,Se.allXhrSet=new Set,Se.loader=(t,e)=>new Promise(((e,i)=>{be.createXHR(t.target,t.settings?t.settings.resolveURL(t.url):t.url,t.type,(i=>{t.result=i,e()}),i).send()}));class Te{static load(t){return we(this.middlewares,t).then((()=>t.result))}}Te.middlewares=[Se.loader];const Ie="Live2DFactory",Le=(t,e)=>__async(this,null,(function*(){if("string"==typeof t.source){const e=yield Te.load({url:t.source,type:"json",target:t.live2dModel});e.url=t.source,t.source=e,t.live2dModel.emit("settingsJSONLoaded",e)}return e()})),Ee=(t,e)=>__async(this,null,(function*(){if(t.source instanceof _e)return t.settings=t.source,e();if("object"==typeof t.source){const i=Oe.findRuntime(t.source);if(i){const s=i.createModelSettings(t.source);return t.settings=s,t.live2dModel.emit("settingsLoaded",s),e()}}throw new TypeError("Unknown settings format.")})),Ae=(t,e)=>{if(t.settings){const i=Oe.findRuntime(t.settings);if(i)return i.ready().then(e)}return e()},Fe=(t,e)=>__async(this,null,(function*(){yield e();const i=t.internalModel;if(i){const e=t.settings,s=Oe.findRuntime(e);if(s){const r=[];e.pose&&r.push(Te.load({settings:e,url:e.pose,type:"json",target:i}).then((e=>{i.pose=s.createPose(i.coreModel,e),t.live2dModel.emit("poseLoaded",i.pose)})).catch((e=>{t.live2dModel.emit("poseLoadError",e),le.warn(Ie,"Failed to load pose.",e)}))),e.physics&&r.push(Te.load({settings:e,url:e.physics,type:"json",target:i}).then((e=>{i.physics=s.createPhysics(i.coreModel,e),t.live2dModel.emit("physicsLoaded",i.physics)})).catch((e=>{t.live2dModel.emit("physicsLoadError",e),le.warn(Ie,"Failed to load physics.",e)}))),r.length&&(yield Promise.all(r))}}})),De=(t,e)=>__async(this,null,(function*(){if(!t.settings)throw new TypeError("Missing settings.");{const i=t.live2dModel,r=t.settings.textures.map((e=>function(t,e={}){const i={resourceOptions:{crossorigin:e.crossOrigin}};if(s.Texture.fromURL)return s.Texture.fromURL(t,i).catch((t=>{if(t instanceof Error)throw t;const e=new Error("Texture loading error");throw e.event=t,e}));i.resourceOptions.autoLoad=!1;const r=s.Texture.from(t,i);if(r.baseTexture.valid)return Promise.resolve(r);const o=r.baseTexture.resource;return null!=o._live2d_load||(o._live2d_load=new Promise(((t,e)=>{const i=t=>{o.source.removeEventListener("error",i);const s=new Error("Texture loading error");s.event=t,e(s)};o.source.addEventListener("error",i),o.load().then((()=>t(r))).catch(i)}))),o._live2d_load}(t.settings.resolveURL(e),{crossOrigin:t.options.crossOrigin})));if(yield e(),!t.internalModel)throw new TypeError("Missing internal model.");i.internalModel=t.internalModel,i.emit("modelLoaded",t.internalModel),i.textures=yield Promise.all(r),i.emit("textureLoaded",i.textures)}})),Be=(t,e)=>__async(this,null,(function*(){const i=t.settings;if(i instanceof _e){const s=Oe.findRuntime(i);if(!s)throw new TypeError("Unknown model settings.");const r=yield Te.load({settings:i,url:i.moc,type:"arraybuffer",target:t.live2dModel});if(!s.isValidMoc(r))throw new Error("Invalid moc data");const o=s.createCoreModel(r);return t.internalModel=s.createInternalModel(o,i,t.options),e()}throw new TypeError("Missing settings.")})),Re=class{static registerRuntime(t){Re.runtimes.push(t),Re.runtimes.sort(((t,e)=>e.version-t.version))}static findRuntime(t){for(const e of Re.runtimes)if(e.test(t))return e}static setupLive2DModel(t,e,i){return __async(this,null,(function*(){const s=new Promise((e=>t.once("textureLoaded",e))),r=new Promise((e=>t.once("modelLoaded",e))),o=Promise.all([s,r]).then((()=>t.emit("ready")));yield we(Re.live2DModelMiddlewares,{live2dModel:t,source:e,options:i||{}}),yield o,t.emit("load")}))}static loadMotion(t,e,i){var s;const r=s=>t.emit("motionLoadError",e,i,s);try{const o=null==(s=t.definitions[e])?void 0:s[i];if(!o)return Promise.resolve(void 0);t.listeners("destroy").includes(Re.releaseTasks)||t.once("destroy",Re.releaseTasks);let a=Re.motionTasksMap.get(t);a||(a={},Re.motionTasksMap.set(t,a));let n=a[e];n||(n=[],a[e]=n);const l=t.getMotionFile(o);return null!=n[i]||(n[i]=Te.load({url:l,settings:t.settings,type:t.motionDataType,target:t}).then((s=>{var r;const a=null==(r=Re.motionTasksMap.get(t))?void 0:r[e];a&&delete a[i];const n=t.createMotion(s,e,o);return t.emit("motionLoaded",e,i,n),n})).catch((e=>{le.warn(t.tag,`Failed to load motion: ${l}\n`,e),r(e)}))),n[i]}catch(o){le.warn(t.tag,`Failed to load motion at "${e}"[${i}]\n`,o),r(o)}return Promise.resolve(void 0)}static loadExpression(t,e){const i=i=>t.emit("expressionLoadError",e,i);try{const s=t.definitions[e];if(!s)return Promise.resolve(void 0);t.listeners("destroy").includes(Re.releaseTasks)||t.once("destroy",Re.releaseTasks);let r=Re.expressionTasksMap.get(t);r||(r=[],Re.expressionTasksMap.set(t,r));const o=t.getExpressionFile(s);return null!=r[e]||(r[e]=Te.load({url:o,settings:t.settings,type:"json",target:t}).then((i=>{const r=Re.expressionTasksMap.get(t);r&&delete r[e];const o=t.createExpression(i,s);return t.emit("expressionLoaded",e,o),o})).catch((e=>{le.warn(t.tag,`Failed to load expression: ${o}\n`,e),i(e)}))),r[e]}catch(s){le.warn(t.tag,`Failed to load expression at [${e}]\n`,s),i(s)}return Promise.resolve(void 0)}static releaseTasks(){this instanceof xe?Re.motionTasksMap.delete(this):Re.expressionTasksMap.delete(this)}};let Oe=Re;Oe.runtimes=[],Oe.urlToJSON=Le,Oe.jsonToSettings=Ee,Oe.waitUntilReady=Ae,Oe.setupOptionals=Fe,Oe.setupEssentials=De,Oe.createInternalModel=Be,Oe.live2DModelMiddlewares=[Le,Ee,Ae,Fe,De,Be],Oe.motionTasksMap=new WeakMap,Oe.expressionTasksMap=new WeakMap,xe.prototype._loadMotion=function(t,e){return Oe.loadMotion(this,t,e)},ge.prototype._loadExpression=function(t){return Oe.loadExpression(this,t)};class ke{constructor(){this._autoInteract=!1}get autoInteract(){return this._autoInteract}set autoInteract(t){t!==this._autoInteract&&(t?this.on("pointertap",Ue,this):this.off("pointertap",Ue,this),this._autoInteract=t)}registerInteraction(t){t!==this.interactionManager&&(this.unregisterInteraction(),this._autoInteract&&t&&(this.interactionManager=t,t.on("pointermove",Ve,this)))}unregisterInteraction(){var t;this.interactionManager&&(null==(t=this.interactionManager)||t.off("pointermove",Ve,this),this.interactionManager=void 0)}}function Ue(t){this.tap(t.data.global.x,t.data.global.y)}function Ve(t){this.focus(t.data.global.x,t.data.global.y)}class Ne extends i.Transform{}const Ge=new i.Point,Xe=new i.Matrix;let ze;class je extends r.Container{constructor(t){super(),this.tag="Live2DModel(uninitialized)",this.textures=[],this.transform=new Ne,this.anchor=new i.ObservablePoint(this.onAnchorChange,this,0,0),this.glContextID=-1,this.elapsedTime=performance.now(),this.deltaTime=0,this._autoUpdate=!1,this.once("modelLoaded",(()=>this.init(t)))}static from(t,e){const i=new this(e);return Oe.setupLive2DModel(i,t,e).then((()=>i))}static fromSync(t,e){const i=new this(e);return Oe.setupLive2DModel(i,t,e).then(null==e?void 0:e.onLoad).catch(null==e?void 0:e.onError),i}static registerTicker(t){ze=t}get autoUpdate(){return this._autoUpdate}set autoUpdate(t){var e;ze||(ze=null==(e=window.PIXI)?void 0:e.Ticker),t?this._destroyed||(ze?(ze.shared.add(this.onTickerUpdate,this),this._autoUpdate=!0):le.warn(this.tag,"No Ticker registered, please call Live2DModel.registerTicker(Ticker).")):(null==ze||ze.shared.remove(this.onTickerUpdate,this),this._autoUpdate=!1)}init(t){this.tag=`Live2DModel(${this.internalModel.settings.name})`;const e=Object.assign({autoUpdate:!0,autoInteract:!0},t);e.autoInteract&&(this.interactive=!0),this.autoInteract=e.autoInteract,this.autoUpdate=e.autoUpdate}onAnchorChange(){this.pivot.set(this.anchor.x*this.internalModel.width,this.anchor.y*this.internalModel.height)}motion(t,e,i,s,r,o){return void 0===e?this.internalModel.motionManager.startRandomMotion(t,i):this.internalModel.motionManager.startMotion(t,e,i,s,r,o)}resetMotions(){return this.internalModel.motionManager.stopAllMotions()}speak(t,e,i){return this.internalModel.motionManager.speakUp(t,e,i)}stopSpeaking(){return this.internalModel.motionManager.stopSpeaking()}expression(t){return this.internalModel.motionManager.expressionManager?void 0===t?this.internalModel.motionManager.expressionManager.setRandomExpression():this.internalModel.motionManager.expressionManager.setExpression(t):Promise.resolve(!1)}focus(t,e,i=!1){Ge.x=t,Ge.y=e,this.toModelPosition(Ge,Ge,!0);let s=Ge.x/this.internalModel.originalWidth*2-1,r=Ge.y/this.internalModel.originalHeight*2-1,o=Math.atan2(r,s);this.internalModel.focusController.focus(Math.cos(o),-Math.sin(o),i)}tap(t,e){const i=this.hitTest(t,e);i.length&&(le.log(this.tag,"Hit",i),this.emit("hit",i))}hitTest(t,e){return Ge.x=t,Ge.y=e,this.toModelPosition(Ge,Ge),this.internalModel.hitTest(Ge.x,Ge.y)}toModelPosition(t,e=t.clone(),i){return i||(this._recursivePostUpdateTransform(),this.parent?this.displayObjectUpdateTransform():(this.parent=this._tempDisplayObjectParent,this.displayObjectUpdateTransform(),this.parent=null)),this.transform.worldTransform.applyInverse(t,e),this.internalModel.localTransform.applyInverse(e,e),e}containsPoint(t){return this.getBounds(!0).contains(t.x,t.y)}_calculateBounds(){this._bounds.addFrame(this.transform,0,0,this.internalModel.width,this.internalModel.height)}onTickerUpdate(){this.update(ze.shared.deltaMS)}update(t){this.deltaTime+=t,this.elapsedTime+=t}_render(t){this.registerInteraction(t.plugins.interaction),t.batch.reset(),t.geometry.reset(),t.shader.reset(),t.state.reset();let e=!1;this.glContextID!==t.CONTEXT_UID&&(this.glContextID=t.CONTEXT_UID,this.internalModel.updateWebGLContext(t.gl,this.glContextID),e=!0);for(let r=0;re.destroy(t.baseTexture))),this.internalModel.destroy(),super.destroy(t)}}ue(je,[ke]);const We=class{static resolveURL(t,e){var i;const s=null==(i=We.filesMap[t])?void 0:i[e];if(void 0===s)throw new Error("Cannot find this file from uploaded files: "+e);return s}static upload(t,i){return __async(this,null,(function*(){const s={};for(const r of i.getDefinedFiles()){const o=decodeURI(e.url.resolve(i.url,r)),a=t.find((t=>t.webkitRelativePath===o));a&&(s[r]=URL.createObjectURL(a))}We.filesMap[i._objectURL]=s}))}static createSettings(t){return __async(this,null,(function*(){const e=t.find((t=>t.name.endsWith("model.json")||t.name.endsWith("model3.json")));if(!e)throw new TypeError("Settings file not found");const i=yield We.readText(e),s=JSON.parse(i);s.url=e.webkitRelativePath;const r=Oe.findRuntime(s);if(!r)throw new Error("Unknown settings JSON");const o=r.createModelSettings(s);return o._objectURL=URL.createObjectURL(e),o}))}static readText(t){return __async(this,null,(function*(){return new Promise(((e,i)=>{const s=new FileReader;s.onload=()=>e(s.result),s.onerror=i,s.readAsText(t,"utf8")}))}))}};let He=We;He.filesMap={},He.factory=(t,e)=>__async(this,null,(function*(){if(Array.isArray(t.source)&&t.source[0]instanceof File){const e=t.source;let i=e.settings;if(i){if(!i._objectURL)throw new Error('"_objectURL" must be specified in ModelSettings')}else i=yield We.createSettings(e);i.validateFiles(e.map((t=>encodeURI(t.webkitRelativePath)))),yield We.upload(e,i),i.resolveURL=function(t){return We.resolveURL(this._objectURL,t)},t.source=i,t.live2dModel.once("modelLoaded",(t=>{t.once("destroy",(function(){const t=this.settings._objectURL;if(URL.revokeObjectURL(t),We.filesMap[t])for(const e of Object.values(We.filesMap[t]))URL.revokeObjectURL(e);delete We.filesMap[t]}))}))}return e()})),Oe.live2DModelMiddlewares.unshift(He.factory);const Ye=class{static unzip(t,i){return __async(this,null,(function*(){const s=yield Ye.getFilePaths(t),r=[];for(const t of i.getDefinedFiles()){const o=decodeURI(e.url.resolve(i.url,t));s.includes(o)&&r.push(o)}const o=yield Ye.getFiles(t,r);for(let t=0;tt.endsWith("model.json")||t.endsWith("model3.json")));if(!e)throw new Error("Settings file not found");const i=yield Ye.readText(t,e);if(!i)throw new Error("Empty settings file: "+e);const s=JSON.parse(i);s.url=e;const r=Oe.findRuntime(s);if(!r)throw new Error("Unknown settings JSON");return r.createModelSettings(s)}))}static zipReader(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFilePaths(t){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFiles(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static readText(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static releaseReader(t){}};let qe=Ye;if(qe.ZIP_PROTOCOL="zip://",qe.uid=0,qe.factory=(t,e)=>__async(this,null,(function*(){const i=t.source;let s,r,o;if("string"==typeof i&&(i.endsWith(".zip")||i.startsWith(Ye.ZIP_PROTOCOL))?(s=i.startsWith(Ye.ZIP_PROTOCOL)?i.slice(Ye.ZIP_PROTOCOL.length):i,r=yield Te.load({url:s,type:"blob",target:t.live2dModel})):Array.isArray(i)&&1===i.length&&i[0]instanceof File&&i[0].name.endsWith(".zip")&&(r=i[0],s=URL.createObjectURL(r),o=i.settings),r){if(!r.size)throw new Error("Empty zip file");const e=yield Ye.zipReader(r,s);o||(o=yield Ye.createSettings(e)),o._objectURL=Ye.ZIP_PROTOCOL+Ye.uid+"/"+o.url;const i=yield Ye.unzip(e,o);i.settings=o,t.source=i,s.startsWith("blob:")&&t.live2dModel.once("modelLoaded",(t=>{t.once("destroy",(function(){URL.revokeObjectURL(s)}))})),Ye.releaseReader(e)}return e()})),Oe.live2DModelMiddlewares.unshift(qe.factory),!window.Live2DCubismCore)throw new Error("Could not find Cubism 4 runtime. This plugin requires live2dcubismcore.js to be loaded.");class $e extends ge{constructor(t,e){var i;super(t,e),this.queueManager=new nt,this.definitions=null!=(i=t.expressions)?i:[],this.init()}isFinished(){return this.queueManager.isFinished()}getExpressionIndex(t){return this.definitions.findIndex((e=>e.Name===t))}getExpressionFile(t){return t.File}createExpression(t,e){return V.create(t)}_setExpression(t){return this.queueManager.startMotion(t,!1,performance.now())}stopAllExpressions(){this.queueManager.stopAllMotions()}updateParameters(t,e){return this.queueManager.doUpdateMotion(t,e)}}class Je extends _e{constructor(t){if(super(t),!Je.isValidJSON(t))throw new TypeError("Invalid JSON.");Object.assign(this,new Kt(t))}static isValidJSON(t){var e;return!!(null==t?void 0:t.FileReferences)&&"string"==typeof t.FileReferences.Moc&&(null==(e=t.FileReferences.Textures)?void 0:e.length)>0&&t.FileReferences.Textures.every((t=>"string"==typeof t))}replaceFiles(t){if(super.replaceFiles(t),this.motions)for(const[e,i]of Object.entries(this.motions))for(let s=0;s{this.emit("motion:"+e)}))}isFinished(){return this.queueManager.isFinished()}_startMotion(t,e){return t.setFinishedMotionHandler(e),this.queueManager.stopAllMotions(),this.queueManager.startMotion(t,!1,performance.now())}_stopAllMotions(){this.queueManager.stopAllMotions()}createMotion(e,i,s){const r=ot.create(e),o=new $(e),a=(i===this.groups.idle?t.config.idleMotionFadingDuration:t.config.motionFadingDuration)/1e3;return void 0===o.getMotionFadeInTime()&&r.setFadeInTime(s.FadeInTime>0?s.FadeInTime:a),void 0===o.getMotionFadeOutTime()&&r.setFadeOutTime(s.FadeOutTime>0?s.FadeOutTime:a),r.setEffectIds(this.eyeBlinkIds,this.lipSyncIds),r}getMotionFile(t){return t.File}getMotionName(t){return t.File}getSoundFile(t){return t.Sound}updateParameters(t,e){return this.queueManager.doUpdateMotion(t,e)}destroy(){super.destroy(),this.queueManager.release(),this.queueManager=void 0}}const Qe=new _;class Ke extends ve{constructor(t,e,s){super(),this.lipSync=!0,this.breath=o.create(),this.renderer=new Qt,this.idParamAngleX=te,this.idParamAngleY=ee,this.idParamAngleZ=ie,this.idParamEyeBallX=se,this.idParamEyeBallY=re,this.idParamBodyAngleX=oe,this.idParamBreath=ae,this.pixelsPerUnit=1,this.centeringTransform=new i.Matrix,this.coreModel=t,this.settings=e,this.motionManager=new Ze(e,s),this.init()}init(){var t;super.init(),(null==(t=this.settings.getEyeBlinkParameters())?void 0:t.length)>0&&(this.eyeBlink=l.create(this.settings)),this.breath.setParameters([new a(this.idParamAngleX,0,15,6.5345,.5),new a(this.idParamAngleY,0,8,3.5345,.5),new a(this.idParamAngleZ,0,10,5.5345,.5),new a(this.idParamBodyAngleX,0,4,15.5345,.5),new a(this.idParamBreath,0,.5,3.2345,.5)]),this.renderer.initialize(this.coreModel),this.renderer.setIsPremultipliedAlpha(!0)}getSize(){return[this.coreModel.getModel().canvasinfo.CanvasWidth,this.coreModel.getModel().canvasinfo.CanvasHeight]}getLayout(){const t={};if(this.settings.layout)for(const e of Object.keys(this.settings.layout)){t[e.charAt(0).toLowerCase()+e.slice(1)]=this.settings.layout[e]}return t}setupLayout(){super.setupLayout(),this.pixelsPerUnit=this.coreModel.getModel().canvasinfo.PixelsPerUnit,this.centeringTransform.scale(this.pixelsPerUnit,this.pixelsPerUnit).translate(this.originalWidth/2,this.originalHeight/2)}updateWebGLContext(t,e){this.renderer.firstDraw=!0,this.renderer._bufferData={vertex:null,uv:null,index:null},this.renderer.startUp(t),this.renderer._clippingManager._currentFrameNo=e,this.renderer._clippingManager._maskTexture=void 0,zt.getInstance()._shaderSets=[]}bindTexture(t,e){this.renderer.bindTexture(t,e)}getHitAreaDefs(){var t,e;return null!=(e=null==(t=this.settings.hitAreas)?void 0:t.map((t=>({id:t.Id,name:t.Name,index:this.coreModel.getDrawableIndex(t.Id)}))))?e:[]}getDrawableIDs(){return this.coreModel.getDrawableIds()}getDrawableIndex(t){return this.coreModel.getDrawableIndex(t)}getDrawableVertices(t){if("string"==typeof t&&-1===(t=this.coreModel.getDrawableIndex(t)))throw new TypeError("Unable to find drawable ID: "+t);const e=this.coreModel.getDrawableVertices(t).slice();for(let i=0;i{!function i(){try{si(),t()}catch(s){if(ei--,ei<0){const t=new Error("Failed to start up Cubism 4 framework.");return t.cause=s,void e(t)}le.log("Cubism4","Startup failed, retrying 10ms later..."),setTimeout(i,10)}}()}))),ti)}function si(t){t=Object.assign({logFunction:console.log,loggingLevel:b.LogLevel_Verbose},t),P.startUp(t),P.initialize()}function ri(){var t;null==(t=this.__moc)||t.release()}Oe.registerRuntime({version:4,ready:ii,test:t=>t instanceof Je||Je.isValidJSON(t),isValidMoc(t){if(t.byteLength<4)return!1;const e=new Int8Array(t,0,4);return"MOC3"===String.fromCharCode(...e)},createModelSettings:t=>new Je(t),createCoreModel(t,e){const i=R.create(t,!!(null==e?void 0:e.checkMocConsistency));try{const t=i.createModel();return t.__moc=i,t}catch(s){try{i.release()}catch(r){}throw s}},createInternalModel(t,e,i){const s=new Ke(t,e,i),r=t;return r.__moc&&(s.__moc=r.__moc,delete r.__moc,s.once("destroy",ri)),s},createPhysics:(t,e)=>yt.create(e),createPose:(t,e)=>u.create(e)}),t.ACubismMotion=U,t.BreathParameterData=a,t.CSM_ASSERT=S,t.Constant=v,t.Cubism4ExpressionManager=$e,t.Cubism4InternalModel=Ke,t.Cubism4ModelSettings=Je,t.Cubism4MotionManager=Ze,t.CubismBlendMode=f,t.CubismBreath=o,t.CubismClippingContext=Gt,t.CubismClippingManager_WebGL=Vt,t.CubismDebug=E,t.CubismExpressionMotion=V,t.CubismEyeBlink=l,t.CubismFramework=P,t.CubismLogDebug=w,t.CubismLogError=L,t.CubismLogInfo=T,t.CubismLogVerbose=function(t,...e){E.print(b.LogLevel_Verbose,"[CSM][V]"+t+"\n",e)},t.CubismLogWarning=I,t.CubismMath=m,t.CubismMatrix44=_,t.CubismMoc=R,t.CubismModel=B,t.CubismModelSettingsJson=Kt,t.CubismModelUserData=k,t.CubismModelUserDataJson=O,t.CubismMotion=ot,t.CubismMotionCurve=H,t.CubismMotionCurveTarget=X,t.CubismMotionData=q,t.CubismMotionEvent=Y,t.CubismMotionJson=$,t.CubismMotionManager=class extends nt{constructor(){super(),this._currentPriority=0,this._reservePriority=0}getCurrentPriority(){return this._currentPriority}getReservePriority(){return this._reservePriority}setReservePriority(t){this._reservePriority=t}startMotionPriority(t,e,i){return i==this._reservePriority&&(this._reservePriority=0),this._currentPriority=i,super.startMotion(t,e,this._userTimeSeconds)}updateMotion(t,e){this._userTimeSeconds+=e;const i=super.doUpdateMotion(t,this._userTimeSeconds);return this.isFinished()&&(this._currentPriority=0),i}reserveMotion(t){return!(t<=this._reservePriority||t<=this._currentPriority)&&(this._reservePriority=t,!0)}},t.CubismMotionPoint=j,t.CubismMotionQueueEntry=at,t.CubismMotionQueueManager=nt,t.CubismMotionSegment=W,t.CubismMotionSegmentType=z,t.CubismPhysics=yt,t.CubismPhysicsInput=gt,t.CubismPhysicsJson=pt,t.CubismPhysicsOutput=mt,t.CubismPhysicsParticle=dt,t.CubismPhysicsRig=_t,t.CubismPhysicsSource=ut,t.CubismPhysicsSubRig=ct,t.CubismPhysicsTargetType=ht,t.CubismPose=u,t.CubismRenderTextureResource=Nt,t.CubismRenderer=p,t.CubismRendererProfile_WebGL=Xt,t.CubismRenderer_WebGL=Qt,t.CubismShader_WebGL=zt,t.CubismTextureColor=y,t.CubismVector2=c,t.DrawableColorData=A,t.DrawableCullingData=D,t.EvaluationOptionFlag=J,t.ExpressionBlendType=G,t.ExpressionManager=ge,t.EyeState=h,t.FileLoader=He,t.FocusController=me,t.HitAreaBody="Body",t.HitAreaHead="Head",t.HitAreaPrefix="HitArea",t.InteractionMixin=ke,t.InternalModel=ve,t.InvalidMotionQueueEntryHandleValue=lt,t.LOGICAL_HEIGHT=2,t.LOGICAL_WIDTH=2,t.Live2DFactory=Oe,t.Live2DLoader=Te,t.Live2DModel=je,t.Live2DTransform=Ne,t.LogLevel=b,t.ModelSettings=_e,t.MotionManager=xe,t.MotionPreloadStrategy=Ce,t.MotionPriority=pe,t.MotionState=fe,t.Options=Ct,t.ParamAngleX=te,t.ParamAngleY=ee,t.ParamAngleZ=ie,t.ParamArmLA="ParamArmLA",t.ParamArmLB="ParamArmLB",t.ParamArmRA="ParamArmRA",t.ParamArmRB="ParamArmRB",t.ParamBaseX="ParamBaseX",t.ParamBaseY="ParamBaseY",t.ParamBodyAngleX=oe,t.ParamBodyAngleY="ParamBodyAngleY",t.ParamBodyAngleZ="ParamBodyAngleZ",t.ParamBreath=ae,t.ParamBrowLAngle="ParamBrowLAngle",t.ParamBrowLForm="ParamBrowLForm",t.ParamBrowLX="ParamBrowLX",t.ParamBrowLY="ParamBrowLY",t.ParamBrowRAngle="ParamBrowRAngle",t.ParamBrowRForm="ParamBrowRForm",t.ParamBrowRX="ParamBrowRX",t.ParamBrowRY="ParamBrowRY",t.ParamBustX="ParamBustX",t.ParamBustY="ParamBustY",t.ParamCheek="ParamCheek",t.ParamEyeBallForm="ParamEyeBallForm",t.ParamEyeBallX=se,t.ParamEyeBallY=re,t.ParamEyeLOpen="ParamEyeLOpen",t.ParamEyeLSmile="ParamEyeLSmile",t.ParamEyeROpen="ParamEyeROpen",t.ParamEyeRSmile="ParamEyeRSmile",t.ParamHairBack="ParamHairBack",t.ParamHairFluffy="ParamHairFluffy",t.ParamHairFront="ParamHairFront",t.ParamHairSide="ParamHairSide",t.ParamHandL="ParamHandL",t.ParamHandR="ParamHandR",t.ParamMouthForm="ParamMouthForm",t.ParamMouthOpenY="ParamMouthOpenY",t.ParamNONE="NONE:",t.ParamShoulderY="ParamShoulderY",t.PartColorData=F,t.PartData=d,t.PartsArmLPrefix="Parts01ArmL_",t.PartsArmPrefix="Parts01Arm_",t.PartsArmRPrefix="Parts01ArmR_",t.PartsIdCore="Parts01Core",t.PhysicsJsonEffectiveForces=class{constructor(){this.gravity=new c(0,0),this.wind=new c(0,0)}},t.PhysicsOutput=xt,t.ShaderNames=jt,t.SoundManager=ye,t.VERSION="0.4.0",t.XHRLoader=Se,t.ZipLoader=qe,t.applyMixins=ue,t.clamp=he,t.copyArray=function(t,e,i,s,r){const o=e[s];Array.isArray(o)&&(i[r]=o.filter((e=>null!==e&&typeof e===t)))},t.copyProperty=function(t,e,i,s,r){const o=e[s];null!==o&&typeof o===t&&(i[r]=o)},t.csmRect=Rt,t.cubism4Ready=ii,t.folderName=de,t.fragmentShaderSrcMaskInvertedPremultipliedAlpha=Zt,t.fragmentShaderSrcMaskPremultipliedAlpha=Jt,t.fragmentShaderSrcPremultipliedAlpha=$t,t.fragmentShaderSrcsetupMask=Ht,t.logger=le,t.rand=function(t,e){return Math.random()*(e-t)+t},t.remove=ce,t.startUpCubism4=si,t.vertexShaderSrc=Yt,t.vertexShaderSrcMasked=qt,t.vertexShaderSrcSetupMask=Wt,Object.defineProperties(t,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
diff --git a/dist/extra.es.js b/dist/extra.es.js
new file mode 100644
index 00000000..27187582
--- /dev/null
+++ b/dist/extra.es.js
@@ -0,0 +1,61 @@
+var __pow = Math.pow;
+import { Graphics } from "@pixi/graphics";
+import { TextStyle, Text } from "@pixi/text";
+import { Rectangle } from "@pixi/math";
+const tempBounds = new Rectangle();
+class HitAreaFrames extends Graphics {
+ constructor() {
+ super();
+ this.initialized = false;
+ this.texts = [];
+ this.strokeWidth = 4;
+ this.normalColor = 14883354;
+ this.activeColor = 2017330;
+ this.interactive = true;
+ this.on("added", this.init).on("pointermove", this.onPointerMove);
+ }
+ init() {
+ const internalModel = this.parent.internalModel;
+ const textStyle = new TextStyle({
+ fontSize: 24,
+ fill: "#ffffff",
+ stroke: "#000000",
+ strokeThickness: 4
+ });
+ this.texts = Object.keys(internalModel.hitAreas).map((hitAreaName) => {
+ const text = new Text(hitAreaName, textStyle);
+ text.visible = false;
+ this.addChild(text);
+ return text;
+ });
+ }
+ onPointerMove(e) {
+ const hitAreaNames = this.parent.hitTest(e.data.global.x, e.data.global.y);
+ this.texts.forEach((text) => {
+ text.visible = hitAreaNames.includes(text.text);
+ });
+ }
+ _render(renderer) {
+ const internalModel = this.parent.internalModel;
+ const scale = 1 / Math.sqrt(__pow(this.transform.worldTransform.a, 2) + __pow(this.transform.worldTransform.b, 2));
+ this.texts.forEach((text) => {
+ this.lineStyle({
+ width: this.strokeWidth * scale,
+ color: text.visible ? this.activeColor : this.normalColor
+ });
+ const bounds = internalModel.getDrawableBounds(internalModel.hitAreas[text.text].index, tempBounds);
+ const transform = internalModel.localTransform;
+ bounds.x = bounds.x * transform.a + transform.tx;
+ bounds.y = bounds.y * transform.d + transform.ty;
+ bounds.width = bounds.width * transform.a;
+ bounds.height = bounds.height * transform.d;
+ this.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
+ text.x = bounds.x + this.strokeWidth * scale;
+ text.y = bounds.y + this.strokeWidth * scale;
+ text.scale.set(scale);
+ });
+ super._render(renderer);
+ this.clear();
+ }
+}
+export { HitAreaFrames };
diff --git a/dist/extra.js b/dist/extra.js
new file mode 100644
index 00000000..53d8e796
--- /dev/null
+++ b/dist/extra.js
@@ -0,0 +1,64 @@
+var __pow = Math.pow;
+(function(global, factory) {
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@pixi/graphics"), require("@pixi/text"), require("@pixi/math")) : typeof define === "function" && define.amd ? define(["exports", "@pixi/graphics", "@pixi/text", "@pixi/math"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory((global.PIXI = global.PIXI || {}, global.PIXI.live2d = global.PIXI.live2d || {}), global.PIXI, global.PIXI, global.PIXI));
+})(this, function(exports2, graphics, text, math) {
+ "use strict";
+ const tempBounds = new math.Rectangle();
+ class HitAreaFrames extends graphics.Graphics {
+ constructor() {
+ super();
+ this.initialized = false;
+ this.texts = [];
+ this.strokeWidth = 4;
+ this.normalColor = 14883354;
+ this.activeColor = 2017330;
+ this.interactive = true;
+ this.on("added", this.init).on("pointermove", this.onPointerMove);
+ }
+ init() {
+ const internalModel = this.parent.internalModel;
+ const textStyle = new text.TextStyle({
+ fontSize: 24,
+ fill: "#ffffff",
+ stroke: "#000000",
+ strokeThickness: 4
+ });
+ this.texts = Object.keys(internalModel.hitAreas).map((hitAreaName) => {
+ const text$1 = new text.Text(hitAreaName, textStyle);
+ text$1.visible = false;
+ this.addChild(text$1);
+ return text$1;
+ });
+ }
+ onPointerMove(e) {
+ const hitAreaNames = this.parent.hitTest(e.data.global.x, e.data.global.y);
+ this.texts.forEach((text2) => {
+ text2.visible = hitAreaNames.includes(text2.text);
+ });
+ }
+ _render(renderer) {
+ const internalModel = this.parent.internalModel;
+ const scale = 1 / Math.sqrt(__pow(this.transform.worldTransform.a, 2) + __pow(this.transform.worldTransform.b, 2));
+ this.texts.forEach((text2) => {
+ this.lineStyle({
+ width: this.strokeWidth * scale,
+ color: text2.visible ? this.activeColor : this.normalColor
+ });
+ const bounds = internalModel.getDrawableBounds(internalModel.hitAreas[text2.text].index, tempBounds);
+ const transform = internalModel.localTransform;
+ bounds.x = bounds.x * transform.a + transform.tx;
+ bounds.y = bounds.y * transform.d + transform.ty;
+ bounds.width = bounds.width * transform.a;
+ bounds.height = bounds.height * transform.d;
+ this.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
+ text2.x = bounds.x + this.strokeWidth * scale;
+ text2.y = bounds.y + this.strokeWidth * scale;
+ text2.scale.set(scale);
+ });
+ super._render(renderer);
+ this.clear();
+ }
+ }
+ exports2.HitAreaFrames = HitAreaFrames;
+ Object.defineProperties(exports2, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
+});
diff --git a/dist/extra.min.js b/dist/extra.min.js
new file mode 100644
index 00000000..4541d9c5
--- /dev/null
+++ b/dist/extra.min.js
@@ -0,0 +1 @@
+var __pow=Math.pow;!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@pixi/graphics"),require("@pixi/text"),require("@pixi/math")):"function"==typeof define&&define.amd?define(["exports","@pixi/graphics","@pixi/text","@pixi/math"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).PIXI=t.PIXI||{},t.PIXI.live2d=t.PIXI.live2d||{}),t.PIXI,t.PIXI,t.PIXI)}(this,(function(t,e,i,s){"use strict";const o=new s.Rectangle;class r extends e.Graphics{constructor(){super(),this.initialized=!1,this.texts=[],this.strokeWidth=4,this.normalColor=14883354,this.activeColor=2017330,this.interactive=!0,this.on("added",this.init).on("pointermove",this.onPointerMove)}init(){const t=this.parent.internalModel,e=new i.TextStyle({fontSize:24,fill:"#ffffff",stroke:"#000000",strokeThickness:4});this.texts=Object.keys(t.hitAreas).map((t=>{const s=new i.Text(t,e);return s.visible=!1,this.addChild(s),s}))}onPointerMove(t){const e=this.parent.hitTest(t.data.global.x,t.data.global.y);this.texts.forEach((t=>{t.visible=e.includes(t.text)}))}_render(t){const e=this.parent.internalModel,i=1/Math.sqrt(__pow(this.transform.worldTransform.a,2)+__pow(this.transform.worldTransform.b,2));this.texts.forEach((t=>{this.lineStyle({width:this.strokeWidth*i,color:t.visible?this.activeColor:this.normalColor});const s=e.getDrawableBounds(e.hitAreas[t.text].index,o),r=e.localTransform;s.x=s.x*r.a+r.tx,s.y=s.y*r.d+r.ty,s.width=s.width*r.a,s.height=s.height*r.d,this.drawRect(s.x,s.y,s.width,s.height),t.x=s.x+this.strokeWidth*i,t.y=s.y+this.strokeWidth*i,t.scale.set(i)})),super._render(t),this.clear()}}t.HitAreaFrames=r,Object.defineProperties(t,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
diff --git a/dist/index.es.js b/dist/index.es.js
new file mode 100644
index 00000000..277f0196
--- /dev/null
+++ b/dist/index.es.js
@@ -0,0 +1,6967 @@
+var __pow = Math.pow;
+var __async = (__this, __arguments, generator) => {
+ return new Promise((resolve, reject) => {
+ var fulfilled = (value) => {
+ try {
+ step(generator.next(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var rejected = (value) => {
+ try {
+ step(generator.throw(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
+ step((generator = generator.apply(__this, __arguments)).next());
+ });
+};
+import { EventEmitter, url } from "@pixi/utils";
+import { Matrix, Transform, Point, ObservablePoint } from "@pixi/math";
+import { Texture } from "@pixi/core";
+import { Container } from "@pixi/display";
+const LOGICAL_WIDTH = 2;
+const LOGICAL_HEIGHT = 2;
+var CubismConfig;
+((CubismConfig2) => {
+ CubismConfig2.supportMoreMaskDivisions = true;
+ CubismConfig2.setOpacityFromMotion = false;
+})(CubismConfig || (CubismConfig = {}));
+var config;
+((config2) => {
+ config2.LOG_LEVEL_VERBOSE = 0;
+ config2.LOG_LEVEL_WARNING = 1;
+ config2.LOG_LEVEL_ERROR = 2;
+ config2.LOG_LEVEL_NONE = 999;
+ config2.logLevel = config2.LOG_LEVEL_WARNING;
+ config2.sound = true;
+ config2.motionSync = true;
+ config2.motionFadingDuration = 500;
+ config2.idleMotionFadingDuration = 2e3;
+ config2.expressionFadingDuration = 500;
+ config2.preserveExpressionOnMotion = true;
+ config2.cubism4 = CubismConfig;
+})(config || (config = {}));
+const VERSION = "0.4.0";
+const logger = {
+ log(tag, ...messages) {
+ if (config.logLevel <= config.LOG_LEVEL_VERBOSE) {
+ console.log(`[${tag}]`, ...messages);
+ }
+ },
+ warn(tag, ...messages) {
+ if (config.logLevel <= config.LOG_LEVEL_WARNING) {
+ console.warn(`[${tag}]`, ...messages);
+ }
+ },
+ error(tag, ...messages) {
+ if (config.logLevel <= config.LOG_LEVEL_ERROR) {
+ console.error(`[${tag}]`, ...messages);
+ }
+ }
+};
+function clamp(num, lower, upper) {
+ return num < lower ? lower : num > upper ? upper : num;
+}
+function rand(min, max) {
+ return Math.random() * (max - min) + min;
+}
+function copyProperty(type, from, to, fromKey, toKey) {
+ const value = from[fromKey];
+ if (value !== null && typeof value === type) {
+ to[toKey] = value;
+ }
+}
+function copyArray(type, from, to, fromKey, toKey) {
+ const array = from[fromKey];
+ if (Array.isArray(array)) {
+ to[toKey] = array.filter((item) => item !== null && typeof item === type);
+ }
+}
+function applyMixins(derivedCtor, baseCtors) {
+ baseCtors.forEach((baseCtor) => {
+ Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
+ if (name !== "constructor") {
+ Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
+ }
+ });
+ });
+}
+function folderName(url2) {
+ let lastSlashIndex = url2.lastIndexOf("/");
+ if (lastSlashIndex != -1) {
+ url2 = url2.slice(0, lastSlashIndex);
+ }
+ lastSlashIndex = url2.lastIndexOf("/");
+ if (lastSlashIndex !== -1) {
+ url2 = url2.slice(lastSlashIndex + 1);
+ }
+ return url2;
+}
+function remove(array, item) {
+ const index = array.indexOf(item);
+ if (index !== -1) {
+ array.splice(index, 1);
+ }
+}
+class ExpressionManager extends EventEmitter {
+ constructor(settings, options) {
+ super();
+ this.expressions = [];
+ this.reserveExpressionIndex = -1;
+ this.destroyed = false;
+ this.settings = settings;
+ this.tag = `ExpressionManager(${settings.name})`;
+ }
+ init() {
+ this.defaultExpression = this.createExpression({}, void 0);
+ this.currentExpression = this.defaultExpression;
+ this.stopAllExpressions();
+ }
+ loadExpression(index) {
+ return __async(this, null, function* () {
+ if (!this.definitions[index]) {
+ logger.warn(this.tag, `Undefined expression at [${index}]`);
+ return void 0;
+ }
+ if (this.expressions[index] === null) {
+ logger.warn(this.tag, `Cannot set expression at [${index}] because it's already failed in loading.`);
+ return void 0;
+ }
+ if (this.expressions[index]) {
+ return this.expressions[index];
+ }
+ const expression = yield this._loadExpression(index);
+ this.expressions[index] = expression;
+ return expression;
+ });
+ }
+ _loadExpression(index) {
+ throw new Error("Not implemented.");
+ }
+ setRandomExpression() {
+ return __async(this, null, function* () {
+ if (this.definitions.length) {
+ const availableIndices = [];
+ for (let i = 0; i < this.definitions.length; i++) {
+ if (this.expressions[i] !== null && this.expressions[i] !== this.currentExpression && i !== this.reserveExpressionIndex) {
+ availableIndices.push(i);
+ }
+ }
+ if (availableIndices.length) {
+ const index = Math.floor(Math.random() * availableIndices.length);
+ return this.setExpression(index);
+ }
+ }
+ return false;
+ });
+ }
+ resetExpression() {
+ this._setExpression(this.defaultExpression);
+ }
+ restoreExpression() {
+ this._setExpression(this.currentExpression);
+ }
+ setExpression(index) {
+ return __async(this, null, function* () {
+ if (typeof index !== "number") {
+ index = this.getExpressionIndex(index);
+ }
+ if (!(index > -1 && index < this.definitions.length)) {
+ return false;
+ }
+ if (index === this.expressions.indexOf(this.currentExpression)) {
+ return false;
+ }
+ this.reserveExpressionIndex = index;
+ const expression = yield this.loadExpression(index);
+ if (!expression || this.reserveExpressionIndex !== index) {
+ return false;
+ }
+ this.reserveExpressionIndex = -1;
+ this.currentExpression = expression;
+ this._setExpression(expression);
+ return true;
+ });
+ }
+ update(model, now) {
+ if (!this.isFinished()) {
+ return this.updateParameters(model, now);
+ }
+ return false;
+ }
+ destroy() {
+ this.destroyed = true;
+ this.emit("destroy");
+ const self = this;
+ self.definitions = void 0;
+ self.expressions = void 0;
+ }
+}
+const EPSILON = 0.01;
+const MAX_SPEED = 40 / 7.5;
+const ACCELERATION_TIME = 1 / (0.15 * 1e3);
+class FocusController {
+ constructor() {
+ this.targetX = 0;
+ this.targetY = 0;
+ this.x = 0;
+ this.y = 0;
+ this.vx = 0;
+ this.vy = 0;
+ }
+ focus(x, y, instant = false) {
+ this.targetX = clamp(x, -1, 1);
+ this.targetY = clamp(y, -1, 1);
+ if (instant) {
+ this.x = this.targetX;
+ this.y = this.targetY;
+ }
+ }
+ update(dt) {
+ const dx = this.targetX - this.x;
+ const dy = this.targetY - this.y;
+ if (Math.abs(dx) < EPSILON && Math.abs(dy) < EPSILON)
+ return;
+ const d = Math.sqrt(__pow(dx, 2) + __pow(dy, 2));
+ const maxSpeed = MAX_SPEED / (1e3 / dt);
+ let ax = maxSpeed * (dx / d) - this.vx;
+ let ay = maxSpeed * (dy / d) - this.vy;
+ const a = Math.sqrt(__pow(ax, 2) + __pow(ay, 2));
+ const maxA = maxSpeed * ACCELERATION_TIME * dt;
+ if (a > maxA) {
+ ax *= maxA / a;
+ ay *= maxA / a;
+ }
+ this.vx += ax;
+ this.vy += ay;
+ const v = Math.sqrt(__pow(this.vx, 2) + __pow(this.vy, 2));
+ const maxV = 0.5 * (Math.sqrt(__pow(maxA, 2) + 8 * maxA * d) - maxA);
+ if (v > maxV) {
+ this.vx *= maxV / v;
+ this.vy *= maxV / v;
+ }
+ this.x += this.vx;
+ this.y += this.vy;
+ }
+}
+class ModelSettings {
+ constructor(json) {
+ this.json = json;
+ let url2 = json.url;
+ if (typeof url2 !== "string") {
+ throw new TypeError("The `url` field in settings JSON must be defined as a string.");
+ }
+ this.url = url2;
+ this.name = folderName(this.url);
+ }
+ resolveURL(path) {
+ return url.resolve(this.url, path);
+ }
+ replaceFiles(replacer) {
+ this.moc = replacer(this.moc, "moc");
+ if (this.pose !== void 0) {
+ this.pose = replacer(this.pose, "pose");
+ }
+ if (this.physics !== void 0) {
+ this.physics = replacer(this.physics, "physics");
+ }
+ for (let i = 0; i < this.textures.length; i++) {
+ this.textures[i] = replacer(this.textures[i], `textures[${i}]`);
+ }
+ }
+ getDefinedFiles() {
+ const files = [];
+ this.replaceFiles((file) => {
+ files.push(file);
+ return file;
+ });
+ return files;
+ }
+ validateFiles(files) {
+ const assertFileExists = (expectedFile, shouldThrow) => {
+ const actualPath = this.resolveURL(expectedFile);
+ if (!files.includes(actualPath)) {
+ if (shouldThrow) {
+ throw new Error(`File "${expectedFile}" is defined in settings, but doesn't exist in given files`);
+ }
+ return false;
+ }
+ return true;
+ };
+ const essentialFiles = [this.moc, ...this.textures];
+ essentialFiles.forEach((texture) => assertFileExists(texture, true));
+ const definedFiles = this.getDefinedFiles();
+ return definedFiles.filter((file) => assertFileExists(file, false));
+ }
+}
+var MotionPriority = /* @__PURE__ */ ((MotionPriority2) => {
+ MotionPriority2[MotionPriority2["NONE"] = 0] = "NONE";
+ MotionPriority2[MotionPriority2["IDLE"] = 1] = "IDLE";
+ MotionPriority2[MotionPriority2["NORMAL"] = 2] = "NORMAL";
+ MotionPriority2[MotionPriority2["FORCE"] = 3] = "FORCE";
+ return MotionPriority2;
+})(MotionPriority || {});
+class MotionState {
+ constructor() {
+ this.debug = false;
+ this.currentPriority = 0;
+ this.reservePriority = 0;
+ }
+ reserve(group, index, priority) {
+ if (priority <= 0) {
+ logger.log(this.tag, `Cannot start a motion with MotionPriority.NONE.`);
+ return false;
+ }
+ if (group === this.currentGroup && index === this.currentIndex) {
+ logger.log(this.tag, `Motion is already playing.`, this.dump(group, index));
+ return false;
+ }
+ if (group === this.reservedGroup && index === this.reservedIndex || group === this.reservedIdleGroup && index === this.reservedIdleIndex) {
+ logger.log(this.tag, `Motion is already reserved.`, this.dump(group, index));
+ return false;
+ }
+ if (priority === 1) {
+ if (this.currentPriority !== 0) {
+ logger.log(this.tag, `Cannot start idle motion because another motion is playing.`, this.dump(group, index));
+ return false;
+ }
+ if (this.reservedIdleGroup !== void 0) {
+ logger.log(this.tag, `Cannot start idle motion because another idle motion has reserved.`, this.dump(group, index));
+ return false;
+ }
+ this.setReservedIdle(group, index);
+ } else {
+ if (priority < 3) {
+ if (priority <= this.currentPriority) {
+ logger.log(this.tag, "Cannot start motion because another motion is playing as an equivalent or higher priority.", this.dump(group, index));
+ return false;
+ }
+ if (priority <= this.reservePriority) {
+ logger.log(this.tag, "Cannot start motion because another motion has reserved as an equivalent or higher priority.", this.dump(group, index));
+ return false;
+ }
+ }
+ this.setReserved(group, index, priority);
+ }
+ return true;
+ }
+ start(motion, group, index, priority) {
+ if (priority === 1) {
+ this.setReservedIdle(void 0, void 0);
+ if (this.currentPriority !== 0) {
+ logger.log(this.tag, "Cannot start idle motion because another motion is playing.", this.dump(group, index));
+ return false;
+ }
+ } else {
+ if (group !== this.reservedGroup || index !== this.reservedIndex) {
+ logger.log(this.tag, "Cannot start motion because another motion has taken the place.", this.dump(group, index));
+ return false;
+ }
+ this.setReserved(void 0, void 0, 0);
+ }
+ if (!motion) {
+ return false;
+ }
+ this.setCurrent(group, index, priority);
+ return true;
+ }
+ complete() {
+ this.setCurrent(void 0, void 0, 0);
+ }
+ setCurrent(group, index, priority) {
+ this.currentPriority = priority;
+ this.currentGroup = group;
+ this.currentIndex = index;
+ }
+ setReserved(group, index, priority) {
+ this.reservePriority = priority;
+ this.reservedGroup = group;
+ this.reservedIndex = index;
+ }
+ setReservedIdle(group, index) {
+ this.reservedIdleGroup = group;
+ this.reservedIdleIndex = index;
+ }
+ isActive(group, index) {
+ return group === this.currentGroup && index === this.currentIndex || group === this.reservedGroup && index === this.reservedIndex || group === this.reservedIdleGroup && index === this.reservedIdleIndex;
+ }
+ reset() {
+ this.setCurrent(void 0, void 0, 0);
+ this.setReserved(void 0, void 0, 0);
+ this.setReservedIdle(void 0, void 0);
+ }
+ shouldRequestIdleMotion() {
+ return this.currentGroup === void 0 && this.reservedIdleGroup === void 0;
+ }
+ shouldOverrideExpression() {
+ return !config.preserveExpressionOnMotion && this.currentPriority > 1;
+ }
+ dump(requestedGroup, requestedIndex) {
+ if (this.debug) {
+ const keys = [
+ "currentPriority",
+ "reservePriority",
+ "currentGroup",
+ "currentIndex",
+ "reservedGroup",
+ "reservedIndex",
+ "reservedIdleGroup",
+ "reservedIdleIndex"
+ ];
+ return `
+ group = "${requestedGroup}", index = ${requestedIndex}
+` + keys.map((key) => "[" + key + "] " + this[key]).join("\n");
+ }
+ return "";
+ }
+}
+const TAG$2 = "SoundManager";
+const VOLUME = 0.9;
+class SoundManager {
+ static get volume() {
+ return this._volume;
+ }
+ static set volume(value) {
+ this._volume = (value > 1 ? 1 : value < 0 ? 0 : value) || 0;
+ this.audios.forEach((audio) => audio.volume = this._volume);
+ }
+ static add(file, onFinish, onError) {
+ const audio = new Audio(file);
+ audio.volume = this._volume;
+ audio.preload = "auto";
+ audio.autoplay = true;
+ audio.crossOrigin = "anonymous";
+ audio.addEventListener("ended", () => {
+ this.dispose(audio);
+ onFinish == null ? void 0 : onFinish();
+ });
+ audio.addEventListener("error", (e) => {
+ this.dispose(audio);
+ logger.warn(TAG$2, `Error occurred on "${file}"`, e.error);
+ onError == null ? void 0 : onError(e.error);
+ });
+ this.audios.push(audio);
+ return audio;
+ }
+ static play(audio) {
+ return new Promise((resolve, reject) => {
+ var _a;
+ (_a = audio.play()) == null ? void 0 : _a.catch((e) => {
+ audio.dispatchEvent(new ErrorEvent("error", { error: e }));
+ reject(e);
+ });
+ if (audio.readyState === audio.HAVE_ENOUGH_DATA) {
+ resolve();
+ } else {
+ audio.addEventListener("canplaythrough", resolve);
+ }
+ });
+ }
+ static addContext(audio) {
+ const context = new AudioContext();
+ this.contexts.push(context);
+ return context;
+ }
+ static addAnalyzer(audio, context) {
+ const source = context.createMediaElementSource(audio);
+ const analyser = context.createAnalyser();
+ analyser.fftSize = 256;
+ analyser.minDecibels = -90;
+ analyser.maxDecibels = -10;
+ analyser.smoothingTimeConstant = 0.85;
+ source.connect(analyser);
+ analyser.connect(context.destination);
+ this.analysers.push(analyser);
+ return analyser;
+ }
+ static analyze(analyser) {
+ if (analyser != void 0) {
+ let pcmData = new Float32Array(analyser.fftSize);
+ let sumSquares = 0;
+ analyser.getFloatTimeDomainData(pcmData);
+ for (const amplitude of pcmData) {
+ sumSquares += amplitude * amplitude;
+ }
+ return parseFloat(Math.sqrt(sumSquares / pcmData.length * 20).toFixed(1));
+ } else {
+ return parseFloat(Math.random().toFixed(1));
+ }
+ }
+ static dispose(audio) {
+ audio.pause();
+ audio.removeAttribute("src");
+ remove(this.audios, audio);
+ }
+ static destroy() {
+ for (let i = this.contexts.length - 1; i >= 0; i--) {
+ this.contexts[i].close();
+ }
+ for (let i = this.audios.length - 1; i >= 0; i--) {
+ this.dispose(this.audios[i]);
+ }
+ }
+}
+SoundManager.audios = [];
+SoundManager.analysers = [];
+SoundManager.contexts = [];
+SoundManager._volume = VOLUME;
+var MotionPreloadStrategy = /* @__PURE__ */ ((MotionPreloadStrategy2) => {
+ MotionPreloadStrategy2["ALL"] = "ALL";
+ MotionPreloadStrategy2["IDLE"] = "IDLE";
+ MotionPreloadStrategy2["NONE"] = "NONE";
+ return MotionPreloadStrategy2;
+})(MotionPreloadStrategy || {});
+class MotionManager extends EventEmitter {
+ constructor(settings, options) {
+ super();
+ this.motionGroups = {};
+ this.state = new MotionState();
+ this.playing = false;
+ this.destroyed = false;
+ this.settings = settings;
+ this.tag = `MotionManager(${settings.name})`;
+ this.state.tag = this.tag;
+ }
+ init(options) {
+ if (options == null ? void 0 : options.idleMotionGroup) {
+ this.groups.idle = options.idleMotionGroup;
+ }
+ this.setupMotions(options);
+ this.stopAllMotions();
+ }
+ setupMotions(options) {
+ for (const group of Object.keys(this.definitions)) {
+ this.motionGroups[group] = [];
+ }
+ let groups;
+ switch (options == null ? void 0 : options.motionPreload) {
+ case "NONE":
+ return;
+ case "ALL":
+ groups = Object.keys(this.definitions);
+ break;
+ case "IDLE":
+ default:
+ groups = [this.groups.idle];
+ break;
+ }
+ for (const group of groups) {
+ if (this.definitions[group]) {
+ for (let i = 0; i < this.definitions[group].length; i++) {
+ this.loadMotion(group, i).then();
+ }
+ }
+ }
+ }
+ loadMotion(group, index) {
+ return __async(this, null, function* () {
+ var _a;
+ if (!((_a = this.definitions[group]) == null ? void 0 : _a[index])) {
+ logger.warn(this.tag, `Undefined motion at "${group}"[${index}]`);
+ return void 0;
+ }
+ if (this.motionGroups[group][index] === null) {
+ logger.warn(this.tag, `Cannot start motion at "${group}"[${index}] because it's already failed in loading.`);
+ return void 0;
+ }
+ if (this.motionGroups[group][index]) {
+ return this.motionGroups[group][index];
+ }
+ const motion = yield this._loadMotion(group, index);
+ if (this.destroyed) {
+ return;
+ }
+ this.motionGroups[group][index] = motion != null ? motion : null;
+ return motion;
+ });
+ }
+ _loadMotion(group, index) {
+ throw new Error("Not implemented.");
+ }
+ speakUp(sound, volume, expression) {
+ return __async(this, null, function* () {
+ if (!config.sound) {
+ return false;
+ }
+ let audio;
+ let analyzer;
+ let context;
+ if (this.currentAudio) {
+ if (!this.currentAudio.ended) {
+ return false;
+ }
+ }
+ let soundURL;
+ const isBase64Content = sound && sound.startsWith("data:audio/wav;base64");
+ if (sound && !isBase64Content) {
+ var A = document.createElement("a");
+ A.href = sound;
+ sound = A.href;
+ soundURL = sound;
+ } else {
+ soundURL = "data:audio/wav;base64";
+ }
+ const isUrlPath = sound && (sound.startsWith("http") || sound.startsWith("blob"));
+ let file;
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ audio = SoundManager.add(file, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ }, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ });
+ this.currentAudio = audio;
+ let _volume = 1;
+ if (volume !== void 0) {
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+ } catch (e) {
+ logger.warn(this.tag, "Failed to create audio", soundURL, e);
+ }
+ }
+ if (audio) {
+ const readyToPlay = SoundManager.play(audio).catch((e) => logger.warn(this.tag, "Failed to play audio", audio.src, e));
+ if (config.motionSync) {
+ yield readyToPlay;
+ }
+ }
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ if (expression && this.expressionManager) {
+ this.expressionManager.setExpression(expression);
+ }
+ this.playing = true;
+ return true;
+ });
+ }
+ startMotion(_0, _1) {
+ return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, sound, volume, expression) {
+ var _a;
+ if (this.currentAudio) {
+ if (!this.currentAudio.ended) {
+ return false;
+ }
+ }
+ if (!this.state.reserve(group, index, priority)) {
+ return false;
+ }
+ const definition = (_a = this.definitions[group]) == null ? void 0 : _a[index];
+ if (!definition) {
+ return false;
+ }
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ }
+ let audio;
+ let analyzer;
+ let context;
+ if (config.sound) {
+ const isBase64Content = sound && sound.startsWith("data:audio/wav;base64");
+ if (sound && !isBase64Content) {
+ var A = document.createElement("a");
+ A.href = sound;
+ sound = A.href;
+ }
+ const isUrlPath = sound && (sound.startsWith("http") || sound.startsWith("blob"));
+ const soundURL = this.getSoundFile(definition);
+ let file = soundURL;
+ if (soundURL) {
+ file = this.settings.resolveURL(soundURL) + "?cache-buster=" + new Date().getTime();
+ }
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ audio = SoundManager.add(file, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ }, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ });
+ this.currentAudio = audio;
+ let _volume = 1;
+ if (volume !== void 0) {
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+ } catch (e) {
+ logger.warn(this.tag, "Failed to create audio", soundURL, e);
+ }
+ }
+ }
+ const motion = yield this.loadMotion(group, index);
+ if (audio) {
+ priority = 3;
+ const readyToPlay = SoundManager.play(audio).catch((e) => logger.warn(this.tag, "Failed to play audio", audio.src, e));
+ if (config.motionSync) {
+ yield readyToPlay;
+ }
+ }
+ if (!this.state.start(motion, group, index, priority)) {
+ if (audio) {
+ SoundManager.dispose(audio);
+ this.currentAudio = void 0;
+ }
+ return false;
+ }
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ logger.log(this.tag, "Start motion:", this.getMotionName(definition));
+ this.emit("motionStart", group, index, audio);
+ if (expression && this.expressionManager) {
+ this.expressionManager.setExpression(expression);
+ }
+ this.playing = true;
+ this._startMotion(motion);
+ return true;
+ });
+ }
+ startRandomMotion(group, priority, sound, volume) {
+ return __async(this, null, function* () {
+ const groupDefs = this.definitions[group];
+ if (groupDefs == null ? void 0 : groupDefs.length) {
+ const availableIndices = [];
+ for (let i = 0; i < groupDefs.length; i++) {
+ if (this.motionGroups[group][i] !== null && !this.state.isActive(group, i)) {
+ availableIndices.push(i);
+ }
+ }
+ if (availableIndices.length) {
+ const index = availableIndices[Math.floor(Math.random() * availableIndices.length)];
+ return this.startMotion(group, index, priority, sound, volume);
+ }
+ }
+ return false;
+ });
+ }
+ stopSpeaking() {
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ this.currentAudio = void 0;
+ }
+ }
+ stopAllMotions() {
+ this._stopAllMotions();
+ this.state.reset();
+ this.stopSpeaking();
+ }
+ update(model, now) {
+ var _a;
+ if (this.isFinished()) {
+ if (this.playing) {
+ this.playing = false;
+ this.emit("motionFinish");
+ }
+ if (this.state.shouldOverrideExpression()) {
+ (_a = this.expressionManager) == null ? void 0 : _a.restoreExpression();
+ }
+ this.state.complete();
+ if (this.state.shouldRequestIdleMotion()) {
+ this.startRandomMotion(this.groups.idle, MotionPriority.IDLE);
+ }
+ }
+ return this.updateParameters(model, now);
+ }
+ mouthSync() {
+ if (this.currentAnalyzer) {
+ return SoundManager.analyze(this.currentAnalyzer);
+ } else {
+ return 0;
+ }
+ }
+ destroy() {
+ var _a;
+ this.destroyed = true;
+ this.emit("destroy");
+ this.stopAllMotions();
+ (_a = this.expressionManager) == null ? void 0 : _a.destroy();
+ const self = this;
+ self.definitions = void 0;
+ self.motionGroups = void 0;
+ }
+}
+const tempBounds = { x: 0, y: 0, width: 0, height: 0 };
+class InternalModel extends EventEmitter {
+ constructor() {
+ super(...arguments);
+ this.focusController = new FocusController();
+ this.originalWidth = 0;
+ this.originalHeight = 0;
+ this.width = 0;
+ this.height = 0;
+ this.localTransform = new Matrix();
+ this.drawingMatrix = new Matrix();
+ this.hitAreas = {};
+ this.textureFlipY = false;
+ this.viewport = [0, 0, 0, 0];
+ this.destroyed = false;
+ }
+ init() {
+ this.setupLayout();
+ this.setupHitAreas();
+ }
+ setupLayout() {
+ const self = this;
+ const size = this.getSize();
+ self.originalWidth = size[0];
+ self.originalHeight = size[1];
+ const layout = Object.assign({
+ width: LOGICAL_WIDTH,
+ height: LOGICAL_HEIGHT
+ }, this.getLayout());
+ this.localTransform.scale(layout.width / LOGICAL_WIDTH, layout.height / LOGICAL_HEIGHT);
+ self.width = this.originalWidth * this.localTransform.a;
+ self.height = this.originalHeight * this.localTransform.d;
+ const offsetX = layout.x !== void 0 && layout.x - layout.width / 2 || layout.centerX !== void 0 && layout.centerX || layout.left !== void 0 && layout.left - layout.width / 2 || layout.right !== void 0 && layout.right + layout.width / 2 || 0;
+ const offsetY = layout.y !== void 0 && layout.y - layout.height / 2 || layout.centerY !== void 0 && layout.centerY || layout.top !== void 0 && layout.top - layout.height / 2 || layout.bottom !== void 0 && layout.bottom + layout.height / 2 || 0;
+ this.localTransform.translate(this.width * offsetX, -this.height * offsetY);
+ }
+ setupHitAreas() {
+ const definitions = this.getHitAreaDefs().filter((hitArea) => hitArea.index >= 0);
+ for (const def of definitions) {
+ this.hitAreas[def.name] = def;
+ }
+ }
+ hitTest(x, y) {
+ return Object.keys(this.hitAreas).filter((hitAreaName) => this.isHit(hitAreaName, x, y));
+ }
+ isHit(hitAreaName, x, y) {
+ if (!this.hitAreas[hitAreaName]) {
+ return false;
+ }
+ const drawIndex = this.hitAreas[hitAreaName].index;
+ const bounds = this.getDrawableBounds(drawIndex, tempBounds);
+ return bounds.x <= x && x <= bounds.x + bounds.width && bounds.y <= y && y <= bounds.y + bounds.height;
+ }
+ getDrawableBounds(index, bounds) {
+ const vertices = this.getDrawableVertices(index);
+ let left = vertices[0];
+ let right = vertices[0];
+ let top = vertices[1];
+ let bottom = vertices[1];
+ for (let i = 0; i < vertices.length; i += 2) {
+ const vx = vertices[i];
+ const vy = vertices[i + 1];
+ left = Math.min(vx, left);
+ right = Math.max(vx, right);
+ top = Math.min(vy, top);
+ bottom = Math.max(vy, bottom);
+ }
+ bounds != null ? bounds : bounds = {};
+ bounds.x = left;
+ bounds.y = top;
+ bounds.width = right - left;
+ bounds.height = bottom - top;
+ return bounds;
+ }
+ updateTransform(transform) {
+ this.drawingMatrix.copyFrom(transform).append(this.localTransform);
+ }
+ update(dt, now) {
+ this.focusController.update(dt);
+ }
+ destroy() {
+ this.destroyed = true;
+ this.emit("destroy");
+ this.motionManager.destroy();
+ this.motionManager = void 0;
+ }
+}
+const TAG$1 = "XHRLoader";
+class NetworkError extends Error {
+ constructor(message, url2, status, aborted = false) {
+ super(message);
+ this.url = url2;
+ this.status = status;
+ this.aborted = aborted;
+ }
+}
+const _XHRLoader = class {
+ static createXHR(target, url2, type, onload, onerror) {
+ const xhr = new XMLHttpRequest();
+ _XHRLoader.allXhrSet.add(xhr);
+ if (target) {
+ let xhrSet = _XHRLoader.xhrMap.get(target);
+ if (!xhrSet) {
+ xhrSet = /* @__PURE__ */ new Set([xhr]);
+ _XHRLoader.xhrMap.set(target, xhrSet);
+ } else {
+ xhrSet.add(xhr);
+ }
+ if (!target.listeners("destroy").includes(_XHRLoader.cancelXHRs)) {
+ target.once("destroy", _XHRLoader.cancelXHRs);
+ }
+ }
+ xhr.open("GET", url2);
+ xhr.responseType = type;
+ xhr.onload = () => {
+ if ((xhr.status === 200 || xhr.status === 0) && xhr.response) {
+ onload(xhr.response);
+ } else {
+ xhr.onerror();
+ }
+ };
+ xhr.onerror = () => {
+ logger.warn(TAG$1, `Failed to load resource as ${xhr.responseType} (Status ${xhr.status}): ${url2}`);
+ onerror(new NetworkError("Network error.", url2, xhr.status));
+ };
+ xhr.onabort = () => onerror(new NetworkError("Aborted.", url2, xhr.status, true));
+ xhr.onloadend = () => {
+ var _a;
+ _XHRLoader.allXhrSet.delete(xhr);
+ if (target) {
+ (_a = _XHRLoader.xhrMap.get(target)) == null ? void 0 : _a.delete(xhr);
+ }
+ };
+ return xhr;
+ }
+ static cancelXHRs() {
+ var _a;
+ (_a = _XHRLoader.xhrMap.get(this)) == null ? void 0 : _a.forEach((xhr) => {
+ xhr.abort();
+ _XHRLoader.allXhrSet.delete(xhr);
+ });
+ _XHRLoader.xhrMap.delete(this);
+ }
+ static release() {
+ _XHRLoader.allXhrSet.forEach((xhr) => xhr.abort());
+ _XHRLoader.allXhrSet.clear();
+ _XHRLoader.xhrMap = /* @__PURE__ */ new WeakMap();
+ }
+};
+let XHRLoader = _XHRLoader;
+XHRLoader.xhrMap = /* @__PURE__ */ new WeakMap();
+XHRLoader.allXhrSet = /* @__PURE__ */ new Set();
+XHRLoader.loader = (context, next) => {
+ return new Promise((resolve, reject) => {
+ const xhr = _XHRLoader.createXHR(context.target, context.settings ? context.settings.resolveURL(context.url) : context.url, context.type, (data) => {
+ context.result = data;
+ resolve();
+ }, reject);
+ xhr.send();
+ });
+};
+function runMiddlewares(middleware, context) {
+ let index = -1;
+ return dispatch(0);
+ function dispatch(i, err) {
+ if (err)
+ return Promise.reject(err);
+ if (i <= index)
+ return Promise.reject(new Error("next() called multiple times"));
+ index = i;
+ const fn = middleware[i];
+ if (!fn)
+ return Promise.resolve();
+ try {
+ return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
+ } catch (err2) {
+ return Promise.reject(err2);
+ }
+ }
+}
+class Live2DLoader {
+ static load(context) {
+ return runMiddlewares(this.middlewares, context).then(() => context.result);
+ }
+}
+Live2DLoader.middlewares = [XHRLoader.loader];
+function createTexture(url2, options = {}) {
+ var _a;
+ const textureOptions = { resourceOptions: { crossorigin: options.crossOrigin } };
+ if (Texture.fromURL) {
+ return Texture.fromURL(url2, textureOptions).catch((e) => {
+ if (e instanceof Error) {
+ throw e;
+ }
+ const err = new Error("Texture loading error");
+ err.event = e;
+ throw err;
+ });
+ }
+ textureOptions.resourceOptions.autoLoad = false;
+ const texture = Texture.from(url2, textureOptions);
+ if (texture.baseTexture.valid) {
+ return Promise.resolve(texture);
+ }
+ const resource = texture.baseTexture.resource;
+ (_a = resource._live2d_load) != null ? _a : resource._live2d_load = new Promise((resolve, reject) => {
+ const errorHandler = (event) => {
+ resource.source.removeEventListener("error", errorHandler);
+ const err = new Error("Texture loading error");
+ err.event = event;
+ reject(err);
+ };
+ resource.source.addEventListener("error", errorHandler);
+ resource.load().then(() => resolve(texture)).catch(errorHandler);
+ });
+ return resource._live2d_load;
+}
+const TAG = "Live2DFactory";
+const urlToJSON = (context, next) => __async(void 0, null, function* () {
+ if (typeof context.source === "string") {
+ const data = yield Live2DLoader.load({
+ url: context.source,
+ type: "json",
+ target: context.live2dModel
+ });
+ data.url = context.source;
+ context.source = data;
+ context.live2dModel.emit("settingsJSONLoaded", data);
+ }
+ return next();
+});
+const jsonToSettings = (context, next) => __async(void 0, null, function* () {
+ if (context.source instanceof ModelSettings) {
+ context.settings = context.source;
+ return next();
+ } else if (typeof context.source === "object") {
+ const runtime = Live2DFactory.findRuntime(context.source);
+ if (runtime) {
+ const settings = runtime.createModelSettings(context.source);
+ context.settings = settings;
+ context.live2dModel.emit("settingsLoaded", settings);
+ return next();
+ }
+ }
+ throw new TypeError("Unknown settings format.");
+});
+const waitUntilReady = (context, next) => {
+ if (context.settings) {
+ const runtime = Live2DFactory.findRuntime(context.settings);
+ if (runtime) {
+ return runtime.ready().then(next);
+ }
+ }
+ return next();
+};
+const setupOptionals = (context, next) => __async(void 0, null, function* () {
+ yield next();
+ const internalModel = context.internalModel;
+ if (internalModel) {
+ const settings = context.settings;
+ const runtime = Live2DFactory.findRuntime(settings);
+ if (runtime) {
+ const tasks = [];
+ if (settings.pose) {
+ tasks.push(Live2DLoader.load({
+ settings,
+ url: settings.pose,
+ type: "json",
+ target: internalModel
+ }).then((data) => {
+ internalModel.pose = runtime.createPose(internalModel.coreModel, data);
+ context.live2dModel.emit("poseLoaded", internalModel.pose);
+ }).catch((e) => {
+ context.live2dModel.emit("poseLoadError", e);
+ logger.warn(TAG, "Failed to load pose.", e);
+ }));
+ }
+ if (settings.physics) {
+ tasks.push(Live2DLoader.load({
+ settings,
+ url: settings.physics,
+ type: "json",
+ target: internalModel
+ }).then((data) => {
+ internalModel.physics = runtime.createPhysics(internalModel.coreModel, data);
+ context.live2dModel.emit("physicsLoaded", internalModel.physics);
+ }).catch((e) => {
+ context.live2dModel.emit("physicsLoadError", e);
+ logger.warn(TAG, "Failed to load physics.", e);
+ }));
+ }
+ if (tasks.length) {
+ yield Promise.all(tasks);
+ }
+ }
+ }
+});
+const setupEssentials = (context, next) => __async(void 0, null, function* () {
+ if (context.settings) {
+ const live2DModel = context.live2dModel;
+ const textureLoadings = context.settings.textures.map((tex) => {
+ const url2 = context.settings.resolveURL(tex);
+ return createTexture(url2, { crossOrigin: context.options.crossOrigin });
+ });
+ yield next();
+ if (context.internalModel) {
+ live2DModel.internalModel = context.internalModel;
+ live2DModel.emit("modelLoaded", context.internalModel);
+ } else {
+ throw new TypeError("Missing internal model.");
+ }
+ live2DModel.textures = yield Promise.all(textureLoadings);
+ live2DModel.emit("textureLoaded", live2DModel.textures);
+ } else {
+ throw new TypeError("Missing settings.");
+ }
+});
+const createInternalModel = (context, next) => __async(void 0, null, function* () {
+ const settings = context.settings;
+ if (settings instanceof ModelSettings) {
+ const runtime = Live2DFactory.findRuntime(settings);
+ if (!runtime) {
+ throw new TypeError("Unknown model settings.");
+ }
+ const modelData = yield Live2DLoader.load({
+ settings,
+ url: settings.moc,
+ type: "arraybuffer",
+ target: context.live2dModel
+ });
+ if (!runtime.isValidMoc(modelData)) {
+ throw new Error("Invalid moc data");
+ }
+ const coreModel = runtime.createCoreModel(modelData);
+ context.internalModel = runtime.createInternalModel(coreModel, settings, context.options);
+ return next();
+ }
+ throw new TypeError("Missing settings.");
+});
+const _Live2DFactory = class {
+ static registerRuntime(runtime) {
+ _Live2DFactory.runtimes.push(runtime);
+ _Live2DFactory.runtimes.sort((a, b) => b.version - a.version);
+ }
+ static findRuntime(source) {
+ for (const runtime of _Live2DFactory.runtimes) {
+ if (runtime.test(source)) {
+ return runtime;
+ }
+ }
+ }
+ static setupLive2DModel(live2dModel, source, options) {
+ return __async(this, null, function* () {
+ const textureLoaded = new Promise((resolve) => live2dModel.once("textureLoaded", resolve));
+ const modelLoaded = new Promise((resolve) => live2dModel.once("modelLoaded", resolve));
+ const readyEventEmitted = Promise.all([textureLoaded, modelLoaded]).then(() => live2dModel.emit("ready"));
+ yield runMiddlewares(_Live2DFactory.live2DModelMiddlewares, {
+ live2dModel,
+ source,
+ options: options || {}
+ });
+ yield readyEventEmitted;
+ live2dModel.emit("load");
+ });
+ }
+ static loadMotion(motionManager, group, index) {
+ var _a, _b;
+ const handleError = (e) => motionManager.emit("motionLoadError", group, index, e);
+ try {
+ const definition = (_a = motionManager.definitions[group]) == null ? void 0 : _a[index];
+ if (!definition) {
+ return Promise.resolve(void 0);
+ }
+ if (!motionManager.listeners("destroy").includes(_Live2DFactory.releaseTasks)) {
+ motionManager.once("destroy", _Live2DFactory.releaseTasks);
+ }
+ let tasks = _Live2DFactory.motionTasksMap.get(motionManager);
+ if (!tasks) {
+ tasks = {};
+ _Live2DFactory.motionTasksMap.set(motionManager, tasks);
+ }
+ let taskGroup = tasks[group];
+ if (!taskGroup) {
+ taskGroup = [];
+ tasks[group] = taskGroup;
+ }
+ const path = motionManager.getMotionFile(definition);
+ (_b = taskGroup[index]) != null ? _b : taskGroup[index] = Live2DLoader.load({
+ url: path,
+ settings: motionManager.settings,
+ type: motionManager.motionDataType,
+ target: motionManager
+ }).then((data) => {
+ var _a2;
+ const taskGroup2 = (_a2 = _Live2DFactory.motionTasksMap.get(motionManager)) == null ? void 0 : _a2[group];
+ if (taskGroup2) {
+ delete taskGroup2[index];
+ }
+ const motion = motionManager.createMotion(data, group, definition);
+ motionManager.emit("motionLoaded", group, index, motion);
+ return motion;
+ }).catch((e) => {
+ logger.warn(motionManager.tag, `Failed to load motion: ${path}
+`, e);
+ handleError(e);
+ });
+ return taskGroup[index];
+ } catch (e) {
+ logger.warn(motionManager.tag, `Failed to load motion at "${group}"[${index}]
+`, e);
+ handleError(e);
+ }
+ return Promise.resolve(void 0);
+ }
+ static loadExpression(expressionManager, index) {
+ var _a;
+ const handleError = (e) => expressionManager.emit("expressionLoadError", index, e);
+ try {
+ const definition = expressionManager.definitions[index];
+ if (!definition) {
+ return Promise.resolve(void 0);
+ }
+ if (!expressionManager.listeners("destroy").includes(_Live2DFactory.releaseTasks)) {
+ expressionManager.once("destroy", _Live2DFactory.releaseTasks);
+ }
+ let tasks = _Live2DFactory.expressionTasksMap.get(expressionManager);
+ if (!tasks) {
+ tasks = [];
+ _Live2DFactory.expressionTasksMap.set(expressionManager, tasks);
+ }
+ const path = expressionManager.getExpressionFile(definition);
+ (_a = tasks[index]) != null ? _a : tasks[index] = Live2DLoader.load({
+ url: path,
+ settings: expressionManager.settings,
+ type: "json",
+ target: expressionManager
+ }).then((data) => {
+ const tasks2 = _Live2DFactory.expressionTasksMap.get(expressionManager);
+ if (tasks2) {
+ delete tasks2[index];
+ }
+ const expression = expressionManager.createExpression(data, definition);
+ expressionManager.emit("expressionLoaded", index, expression);
+ return expression;
+ }).catch((e) => {
+ logger.warn(expressionManager.tag, `Failed to load expression: ${path}
+`, e);
+ handleError(e);
+ });
+ return tasks[index];
+ } catch (e) {
+ logger.warn(expressionManager.tag, `Failed to load expression at [${index}]
+`, e);
+ handleError(e);
+ }
+ return Promise.resolve(void 0);
+ }
+ static releaseTasks() {
+ if (this instanceof MotionManager) {
+ _Live2DFactory.motionTasksMap.delete(this);
+ } else {
+ _Live2DFactory.expressionTasksMap.delete(this);
+ }
+ }
+};
+let Live2DFactory = _Live2DFactory;
+Live2DFactory.runtimes = [];
+Live2DFactory.urlToJSON = urlToJSON;
+Live2DFactory.jsonToSettings = jsonToSettings;
+Live2DFactory.waitUntilReady = waitUntilReady;
+Live2DFactory.setupOptionals = setupOptionals;
+Live2DFactory.setupEssentials = setupEssentials;
+Live2DFactory.createInternalModel = createInternalModel;
+Live2DFactory.live2DModelMiddlewares = [
+ urlToJSON,
+ jsonToSettings,
+ waitUntilReady,
+ setupOptionals,
+ setupEssentials,
+ createInternalModel
+];
+Live2DFactory.motionTasksMap = /* @__PURE__ */ new WeakMap();
+Live2DFactory.expressionTasksMap = /* @__PURE__ */ new WeakMap();
+MotionManager.prototype["_loadMotion"] = function(group, index) {
+ return Live2DFactory.loadMotion(this, group, index);
+};
+ExpressionManager.prototype["_loadExpression"] = function(index) {
+ return Live2DFactory.loadExpression(this, index);
+};
+class InteractionMixin {
+ constructor() {
+ this._autoInteract = false;
+ }
+ get autoInteract() {
+ return this._autoInteract;
+ }
+ set autoInteract(autoInteract) {
+ if (autoInteract !== this._autoInteract) {
+ if (autoInteract) {
+ this.on("pointertap", onTap, this);
+ } else {
+ this.off("pointertap", onTap, this);
+ }
+ this._autoInteract = autoInteract;
+ }
+ }
+ registerInteraction(manager) {
+ if (manager !== this.interactionManager) {
+ this.unregisterInteraction();
+ if (this._autoInteract && manager) {
+ this.interactionManager = manager;
+ manager.on("pointermove", onPointerMove, this);
+ }
+ }
+ }
+ unregisterInteraction() {
+ var _a;
+ if (this.interactionManager) {
+ (_a = this.interactionManager) == null ? void 0 : _a.off("pointermove", onPointerMove, this);
+ this.interactionManager = void 0;
+ }
+ }
+}
+function onTap(event) {
+ this.tap(event.data.global.x, event.data.global.y);
+}
+function onPointerMove(event) {
+ this.focus(event.data.global.x, event.data.global.y);
+}
+class Live2DTransform extends Transform {
+}
+const tempPoint = new Point();
+const tempMatrix$1 = new Matrix();
+let tickerRef;
+class Live2DModel extends Container {
+ constructor(options) {
+ super();
+ this.tag = "Live2DModel(uninitialized)";
+ this.textures = [];
+ this.transform = new Live2DTransform();
+ this.anchor = new ObservablePoint(this.onAnchorChange, this, 0, 0);
+ this.glContextID = -1;
+ this.elapsedTime = performance.now();
+ this.deltaTime = 0;
+ this._autoUpdate = false;
+ this.once("modelLoaded", () => this.init(options));
+ }
+ static from(source, options) {
+ const model = new this(options);
+ return Live2DFactory.setupLive2DModel(model, source, options).then(() => model);
+ }
+ static fromSync(source, options) {
+ const model = new this(options);
+ Live2DFactory.setupLive2DModel(model, source, options).then(options == null ? void 0 : options.onLoad).catch(options == null ? void 0 : options.onError);
+ return model;
+ }
+ static registerTicker(tickerClass) {
+ tickerRef = tickerClass;
+ }
+ get autoUpdate() {
+ return this._autoUpdate;
+ }
+ set autoUpdate(autoUpdate) {
+ var _a;
+ tickerRef || (tickerRef = (_a = window.PIXI) == null ? void 0 : _a.Ticker);
+ if (autoUpdate) {
+ if (!this._destroyed) {
+ if (tickerRef) {
+ tickerRef.shared.add(this.onTickerUpdate, this);
+ this._autoUpdate = true;
+ } else {
+ logger.warn(this.tag, "No Ticker registered, please call Live2DModel.registerTicker(Ticker).");
+ }
+ }
+ } else {
+ tickerRef == null ? void 0 : tickerRef.shared.remove(this.onTickerUpdate, this);
+ this._autoUpdate = false;
+ }
+ }
+ init(options) {
+ this.tag = `Live2DModel(${this.internalModel.settings.name})`;
+ const _options = Object.assign({
+ autoUpdate: true,
+ autoInteract: true
+ }, options);
+ if (_options.autoInteract) {
+ this.interactive = true;
+ }
+ this.autoInteract = _options.autoInteract;
+ this.autoUpdate = _options.autoUpdate;
+ }
+ onAnchorChange() {
+ this.pivot.set(this.anchor.x * this.internalModel.width, this.anchor.y * this.internalModel.height);
+ }
+ motion(group, index, priority, sound, volume, expression) {
+ return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority) : this.internalModel.motionManager.startMotion(group, index, priority, sound, volume, expression);
+ }
+ resetMotions() {
+ return this.internalModel.motionManager.stopAllMotions();
+ }
+ speak(sound, volume, expression) {
+ return this.internalModel.motionManager.speakUp(sound, volume, expression);
+ }
+ stopSpeaking() {
+ return this.internalModel.motionManager.stopSpeaking();
+ }
+ expression(id) {
+ if (this.internalModel.motionManager.expressionManager) {
+ return id === void 0 ? this.internalModel.motionManager.expressionManager.setRandomExpression() : this.internalModel.motionManager.expressionManager.setExpression(id);
+ }
+ return Promise.resolve(false);
+ }
+ focus(x, y, instant = false) {
+ tempPoint.x = x;
+ tempPoint.y = y;
+ this.toModelPosition(tempPoint, tempPoint, true);
+ let tx = tempPoint.x / this.internalModel.originalWidth * 2 - 1;
+ let ty = tempPoint.y / this.internalModel.originalHeight * 2 - 1;
+ let radian = Math.atan2(ty, tx);
+ this.internalModel.focusController.focus(Math.cos(radian), -Math.sin(radian), instant);
+ }
+ tap(x, y) {
+ const hitAreaNames = this.hitTest(x, y);
+ if (hitAreaNames.length) {
+ logger.log(this.tag, `Hit`, hitAreaNames);
+ this.emit("hit", hitAreaNames);
+ }
+ }
+ hitTest(x, y) {
+ tempPoint.x = x;
+ tempPoint.y = y;
+ this.toModelPosition(tempPoint, tempPoint);
+ return this.internalModel.hitTest(tempPoint.x, tempPoint.y);
+ }
+ toModelPosition(position, result = position.clone(), skipUpdate) {
+ if (!skipUpdate) {
+ this._recursivePostUpdateTransform();
+ if (!this.parent) {
+ this.parent = this._tempDisplayObjectParent;
+ this.displayObjectUpdateTransform();
+ this.parent = null;
+ } else {
+ this.displayObjectUpdateTransform();
+ }
+ }
+ this.transform.worldTransform.applyInverse(position, result);
+ this.internalModel.localTransform.applyInverse(result, result);
+ return result;
+ }
+ containsPoint(point) {
+ return this.getBounds(true).contains(point.x, point.y);
+ }
+ _calculateBounds() {
+ this._bounds.addFrame(this.transform, 0, 0, this.internalModel.width, this.internalModel.height);
+ }
+ onTickerUpdate() {
+ this.update(tickerRef.shared.deltaMS);
+ }
+ update(dt) {
+ this.deltaTime += dt;
+ this.elapsedTime += dt;
+ }
+ _render(renderer) {
+ this.registerInteraction(renderer.plugins.interaction);
+ renderer.batch.reset();
+ renderer.geometry.reset();
+ renderer.shader.reset();
+ renderer.state.reset();
+ let shouldUpdateTexture = false;
+ if (this.glContextID !== renderer.CONTEXT_UID) {
+ this.glContextID = renderer.CONTEXT_UID;
+ this.internalModel.updateWebGLContext(renderer.gl, this.glContextID);
+ shouldUpdateTexture = true;
+ }
+ for (let i = 0; i < this.textures.length; i++) {
+ const texture = this.textures[i];
+ if (!texture.valid) {
+ continue;
+ }
+ if (shouldUpdateTexture || !texture.baseTexture._glTextures[this.glContextID]) {
+ renderer.gl.pixelStorei(WebGLRenderingContext.UNPACK_FLIP_Y_WEBGL, this.internalModel.textureFlipY);
+ renderer.texture.bind(texture.baseTexture, 0);
+ }
+ this.internalModel.bindTexture(i, texture.baseTexture._glTextures[this.glContextID].texture);
+ texture.baseTexture.touched = renderer.textureGC.count;
+ }
+ const viewport = renderer.framebuffer.viewport;
+ this.internalModel.viewport = [viewport.x, viewport.y, viewport.width, viewport.height];
+ if (this.deltaTime) {
+ this.internalModel.update(this.deltaTime, this.elapsedTime);
+ this.deltaTime = 0;
+ }
+ const internalTransform = tempMatrix$1.copyFrom(renderer.globalUniforms.uniforms.projectionMatrix).append(this.worldTransform);
+ this.internalModel.updateTransform(internalTransform);
+ this.internalModel.draw(renderer.gl);
+ renderer.state.reset();
+ renderer.texture.reset();
+ }
+ destroy(options) {
+ this.emit("destroy");
+ this.autoUpdate = false;
+ this.unregisterInteraction();
+ if (options == null ? void 0 : options.texture) {
+ this.textures.forEach((texture) => texture.destroy(options.baseTexture));
+ }
+ this.internalModel.destroy();
+ super.destroy(options);
+ }
+}
+applyMixins(Live2DModel, [InteractionMixin]);
+const _FileLoader = class {
+ static resolveURL(settingsURL, filePath) {
+ var _a;
+ const resolved = (_a = _FileLoader.filesMap[settingsURL]) == null ? void 0 : _a[filePath];
+ if (resolved === void 0) {
+ throw new Error("Cannot find this file from uploaded files: " + filePath);
+ }
+ return resolved;
+ }
+ static upload(files, settings) {
+ return __async(this, null, function* () {
+ const fileMap = {};
+ for (const definedFile of settings.getDefinedFiles()) {
+ const actualPath = decodeURI(url.resolve(settings.url, definedFile));
+ const actualFile = files.find((file) => file.webkitRelativePath === actualPath);
+ if (actualFile) {
+ fileMap[definedFile] = URL.createObjectURL(actualFile);
+ }
+ }
+ _FileLoader.filesMap[settings._objectURL] = fileMap;
+ });
+ }
+ static createSettings(files) {
+ return __async(this, null, function* () {
+ const settingsFile = files.find((file) => file.name.endsWith("model.json") || file.name.endsWith("model3.json"));
+ if (!settingsFile) {
+ throw new TypeError("Settings file not found");
+ }
+ const settingsText = yield _FileLoader.readText(settingsFile);
+ const settingsJSON = JSON.parse(settingsText);
+ settingsJSON.url = settingsFile.webkitRelativePath;
+ const runtime = Live2DFactory.findRuntime(settingsJSON);
+ if (!runtime) {
+ throw new Error("Unknown settings JSON");
+ }
+ const settings = runtime.createModelSettings(settingsJSON);
+ settings._objectURL = URL.createObjectURL(settingsFile);
+ return settings;
+ });
+ }
+ static readText(file) {
+ return __async(this, null, function* () {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = () => resolve(reader.result);
+ reader.onerror = reject;
+ reader.readAsText(file, "utf8");
+ });
+ });
+ }
+};
+let FileLoader = _FileLoader;
+FileLoader.filesMap = {};
+FileLoader.factory = (context, next) => __async(void 0, null, function* () {
+ if (Array.isArray(context.source) && context.source[0] instanceof File) {
+ const files = context.source;
+ let settings = files.settings;
+ if (!settings) {
+ settings = yield _FileLoader.createSettings(files);
+ } else if (!settings._objectURL) {
+ throw new Error('"_objectURL" must be specified in ModelSettings');
+ }
+ settings.validateFiles(files.map((file) => encodeURI(file.webkitRelativePath)));
+ yield _FileLoader.upload(files, settings);
+ settings.resolveURL = function(url2) {
+ return _FileLoader.resolveURL(this._objectURL, url2);
+ };
+ context.source = settings;
+ context.live2dModel.once("modelLoaded", (internalModel) => {
+ internalModel.once("destroy", function() {
+ const objectURL = this.settings._objectURL;
+ URL.revokeObjectURL(objectURL);
+ if (_FileLoader.filesMap[objectURL]) {
+ for (const resourceObjectURL of Object.values(_FileLoader.filesMap[objectURL])) {
+ URL.revokeObjectURL(resourceObjectURL);
+ }
+ }
+ delete _FileLoader.filesMap[objectURL];
+ });
+ });
+ }
+ return next();
+});
+Live2DFactory.live2DModelMiddlewares.unshift(FileLoader.factory);
+const _ZipLoader = class {
+ static unzip(reader, settings) {
+ return __async(this, null, function* () {
+ const filePaths = yield _ZipLoader.getFilePaths(reader);
+ const requiredFilePaths = [];
+ for (const definedFile of settings.getDefinedFiles()) {
+ const actualPath = decodeURI(url.resolve(settings.url, definedFile));
+ if (filePaths.includes(actualPath)) {
+ requiredFilePaths.push(actualPath);
+ }
+ }
+ const files = yield _ZipLoader.getFiles(reader, requiredFilePaths);
+ for (let i = 0; i < files.length; i++) {
+ const path = requiredFilePaths[i];
+ const file = files[i];
+ Object.defineProperty(file, "webkitRelativePath", {
+ value: path
+ });
+ }
+ return files;
+ });
+ }
+ static createSettings(reader) {
+ return __async(this, null, function* () {
+ const filePaths = yield _ZipLoader.getFilePaths(reader);
+ const settingsFilePath = filePaths.find((path) => path.endsWith("model.json") || path.endsWith("model3.json"));
+ if (!settingsFilePath) {
+ throw new Error("Settings file not found");
+ }
+ const settingsText = yield _ZipLoader.readText(reader, settingsFilePath);
+ if (!settingsText) {
+ throw new Error("Empty settings file: " + settingsFilePath);
+ }
+ const settingsJSON = JSON.parse(settingsText);
+ settingsJSON.url = settingsFilePath;
+ const runtime = Live2DFactory.findRuntime(settingsJSON);
+ if (!runtime) {
+ throw new Error("Unknown settings JSON");
+ }
+ return runtime.createModelSettings(settingsJSON);
+ });
+ }
+ static zipReader(data, url2) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static getFilePaths(reader) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static getFiles(reader, paths) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static readText(reader, path) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static releaseReader(reader) {
+ }
+};
+let ZipLoader = _ZipLoader;
+ZipLoader.ZIP_PROTOCOL = "zip://";
+ZipLoader.uid = 0;
+ZipLoader.factory = (context, next) => __async(void 0, null, function* () {
+ const source = context.source;
+ let sourceURL;
+ let zipBlob;
+ let settings;
+ if (typeof source === "string" && (source.endsWith(".zip") || source.startsWith(_ZipLoader.ZIP_PROTOCOL))) {
+ if (source.startsWith(_ZipLoader.ZIP_PROTOCOL)) {
+ sourceURL = source.slice(_ZipLoader.ZIP_PROTOCOL.length);
+ } else {
+ sourceURL = source;
+ }
+ zipBlob = yield Live2DLoader.load({
+ url: sourceURL,
+ type: "blob",
+ target: context.live2dModel
+ });
+ } else if (Array.isArray(source) && source.length === 1 && source[0] instanceof File && source[0].name.endsWith(".zip")) {
+ zipBlob = source[0];
+ sourceURL = URL.createObjectURL(zipBlob);
+ settings = source.settings;
+ }
+ if (zipBlob) {
+ if (!zipBlob.size) {
+ throw new Error("Empty zip file");
+ }
+ const reader = yield _ZipLoader.zipReader(zipBlob, sourceURL);
+ if (!settings) {
+ settings = yield _ZipLoader.createSettings(reader);
+ }
+ settings._objectURL = _ZipLoader.ZIP_PROTOCOL + _ZipLoader.uid + "/" + settings.url;
+ const files = yield _ZipLoader.unzip(reader, settings);
+ files.settings = settings;
+ context.source = files;
+ if (sourceURL.startsWith("blob:")) {
+ context.live2dModel.once("modelLoaded", (internalModel) => {
+ internalModel.once("destroy", function() {
+ URL.revokeObjectURL(sourceURL);
+ });
+ });
+ }
+ _ZipLoader.releaseReader(reader);
+ }
+ return next();
+});
+Live2DFactory.live2DModelMiddlewares.unshift(ZipLoader.factory);
+if (!window.Live2D) {
+ throw new Error("Could not find Cubism 2 runtime. This plugin requires live2d.min.js to be loaded.");
+}
+const originalUpdateParam = Live2DMotion.prototype.updateParam;
+Live2DMotion.prototype.updateParam = function(model, entry) {
+ originalUpdateParam.call(this, model, entry);
+ if (entry.isFinished() && this.onFinishHandler) {
+ this.onFinishHandler(this);
+ delete this.onFinishHandler;
+ }
+};
+class Live2DExpression extends AMotion {
+ constructor(json) {
+ super();
+ this.params = [];
+ this.setFadeIn(json.fade_in > 0 ? json.fade_in : config.expressionFadingDuration);
+ this.setFadeOut(json.fade_out > 0 ? json.fade_out : config.expressionFadingDuration);
+ if (Array.isArray(json.params)) {
+ json.params.forEach((param) => {
+ const calc = param.calc || "add";
+ if (calc === "add") {
+ const defaultValue = param.def || 0;
+ param.val -= defaultValue;
+ } else if (calc === "mult") {
+ const defaultValue = param.def || 1;
+ param.val /= defaultValue;
+ }
+ this.params.push({
+ calc,
+ val: param.val,
+ id: param.id
+ });
+ });
+ }
+ }
+ updateParamExe(model, time, weight, motionQueueEnt) {
+ this.params.forEach((param) => {
+ model.setParamFloat(param.id, param.val * weight);
+ });
+ }
+}
+class Cubism2ExpressionManager extends ExpressionManager {
+ constructor(settings, options) {
+ var _a;
+ super(settings, options);
+ this.queueManager = new MotionQueueManager();
+ this.definitions = (_a = this.settings.expressions) != null ? _a : [];
+ this.init();
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ getExpressionIndex(name) {
+ return this.definitions.findIndex((def) => def.name === name);
+ }
+ getExpressionFile(definition) {
+ return definition.file;
+ }
+ createExpression(data, definition) {
+ return new Live2DExpression(data);
+ }
+ _setExpression(motion) {
+ return this.queueManager.startMotion(motion);
+ }
+ stopAllExpressions() {
+ this.queueManager.stopAllMotions();
+ }
+ updateParameters(model, dt) {
+ return this.queueManager.updateParam(model);
+ }
+}
+class Cubism2MotionManager extends MotionManager {
+ constructor(settings, options) {
+ super(settings, options);
+ this.groups = { idle: "idle" };
+ this.motionDataType = "arraybuffer";
+ this.queueManager = new MotionQueueManager();
+ this.definitions = this.settings.motions;
+ this.init(options);
+ }
+ init(options) {
+ super.init(options);
+ if (this.settings.expressions) {
+ this.expressionManager = new Cubism2ExpressionManager(this.settings, options);
+ }
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ createMotion(data, group, definition) {
+ const motion = Live2DMotion.loadMotion(data);
+ const defaultFadingDuration = group === this.groups.idle ? config.idleMotionFadingDuration : config.motionFadingDuration;
+ motion.setFadeIn(definition.fade_in > 0 ? definition.fade_in : defaultFadingDuration);
+ motion.setFadeOut(definition.fade_out > 0 ? definition.fade_out : defaultFadingDuration);
+ return motion;
+ }
+ getMotionFile(definition) {
+ return definition.file;
+ }
+ getMotionName(definition) {
+ return definition.file;
+ }
+ getSoundFile(definition) {
+ return definition.sound;
+ }
+ _startMotion(motion, onFinish) {
+ motion.onFinishHandler = onFinish;
+ this.queueManager.stopAllMotions();
+ return this.queueManager.startMotion(motion);
+ }
+ _stopAllMotions() {
+ this.queueManager.stopAllMotions();
+ }
+ updateParameters(model, now) {
+ return this.queueManager.updateParam(model);
+ }
+ destroy() {
+ super.destroy();
+ this.queueManager = void 0;
+ }
+}
+class Live2DEyeBlink {
+ constructor(coreModel) {
+ this.coreModel = coreModel;
+ this.blinkInterval = 4e3;
+ this.closingDuration = 100;
+ this.closedDuration = 50;
+ this.openingDuration = 150;
+ this.eyeState = 0;
+ this.eyeParamValue = 1;
+ this.closedTimer = 0;
+ this.nextBlinkTimeLeft = this.blinkInterval;
+ this.leftParam = coreModel.getParamIndex("PARAM_EYE_L_OPEN");
+ this.rightParam = coreModel.getParamIndex("PARAM_EYE_R_OPEN");
+ }
+ setEyeParams(value) {
+ this.eyeParamValue = clamp(value, 0, 1);
+ this.coreModel.setParamFloat(this.leftParam, this.eyeParamValue);
+ this.coreModel.setParamFloat(this.rightParam, this.eyeParamValue);
+ }
+ update(dt) {
+ switch (this.eyeState) {
+ case 0:
+ this.nextBlinkTimeLeft -= dt;
+ if (this.nextBlinkTimeLeft < 0) {
+ this.eyeState = 1;
+ this.nextBlinkTimeLeft = this.blinkInterval + this.closingDuration + this.closedDuration + this.openingDuration + rand(0, 2e3);
+ }
+ break;
+ case 1:
+ this.setEyeParams(this.eyeParamValue + dt / this.closingDuration);
+ if (this.eyeParamValue <= 0) {
+ this.eyeState = 2;
+ this.closedTimer = 0;
+ }
+ break;
+ case 2:
+ this.closedTimer += dt;
+ if (this.closedTimer >= this.closedDuration) {
+ this.eyeState = 3;
+ }
+ break;
+ case 3:
+ this.setEyeParams(this.eyeParamValue + dt / this.openingDuration);
+ if (this.eyeParamValue >= 1) {
+ this.eyeState = 0;
+ }
+ }
+ }
+}
+const tempMatrixArray = new Float32Array([
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+]);
+class Cubism2InternalModel extends InternalModel {
+ constructor(coreModel, settings, options) {
+ super();
+ this.textureFlipY = true;
+ this.drawDataCount = 0;
+ this.disableCulling = false;
+ this.coreModel = coreModel;
+ this.settings = settings;
+ this.motionManager = new Cubism2MotionManager(settings, options);
+ this.eyeBlink = new Live2DEyeBlink(coreModel);
+ this.eyeballXParamIndex = coreModel.getParamIndex("PARAM_EYE_BALL_X");
+ this.eyeballYParamIndex = coreModel.getParamIndex("PARAM_EYE_BALL_Y");
+ this.angleXParamIndex = coreModel.getParamIndex("PARAM_ANGLE_X");
+ this.angleYParamIndex = coreModel.getParamIndex("PARAM_ANGLE_Y");
+ this.angleZParamIndex = coreModel.getParamIndex("PARAM_ANGLE_Z");
+ this.bodyAngleXParamIndex = coreModel.getParamIndex("PARAM_BODY_ANGLE_X");
+ this.breathParamIndex = coreModel.getParamIndex("PARAM_BREATH");
+ this.init();
+ }
+ init() {
+ super.init();
+ if (this.settings.initParams) {
+ this.settings.initParams.forEach(({ id, value }) => this.coreModel.setParamFloat(id, value));
+ }
+ if (this.settings.initOpacities) {
+ this.settings.initOpacities.forEach(({ id, value }) => this.coreModel.setPartsOpacity(id, value));
+ }
+ this.coreModel.saveParam();
+ const arr = this.coreModel.getModelContext()._$aS;
+ if (arr == null ? void 0 : arr.length) {
+ this.drawDataCount = arr.length;
+ }
+ let culling = this.coreModel.drawParamWebGL.culling;
+ Object.defineProperty(this.coreModel.drawParamWebGL, "culling", {
+ set: (v) => culling = v,
+ get: () => this.disableCulling ? false : culling
+ });
+ const clipManager = this.coreModel.getModelContext().clipManager;
+ const originalSetupClip = clipManager.setupClip;
+ clipManager.setupClip = (modelContext, drawParam) => {
+ originalSetupClip.call(clipManager, modelContext, drawParam);
+ drawParam.gl.viewport(...this.viewport);
+ };
+ }
+ getSize() {
+ return [this.coreModel.getCanvasWidth(), this.coreModel.getCanvasHeight()];
+ }
+ getLayout() {
+ const layout = {};
+ if (this.settings.layout) {
+ for (const key of Object.keys(this.settings.layout)) {
+ let commonKey = key;
+ if (key === "center_x") {
+ commonKey = "centerX";
+ } else if (key === "center_y") {
+ commonKey = "centerY";
+ }
+ layout[commonKey] = this.settings.layout[key];
+ }
+ }
+ return layout;
+ }
+ updateWebGLContext(gl, glContextID) {
+ const drawParamWebGL = this.coreModel.drawParamWebGL;
+ drawParamWebGL.firstDraw = true;
+ drawParamWebGL.setGL(gl);
+ drawParamWebGL.glno = glContextID;
+ for (const prop in drawParamWebGL) {
+ if (drawParamWebGL.hasOwnProperty(prop) && drawParamWebGL[prop] instanceof WebGLBuffer) {
+ drawParamWebGL[prop] = null;
+ }
+ }
+ const clipManager = this.coreModel.getModelContext().clipManager;
+ clipManager.curFrameNo = glContextID;
+ const framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
+ clipManager.getMaskRenderTexture();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+ }
+ bindTexture(index, texture) {
+ this.coreModel.setTexture(index, texture);
+ }
+ getHitAreaDefs() {
+ var _a;
+ return ((_a = this.settings.hitAreas) == null ? void 0 : _a.map((hitArea) => ({
+ id: hitArea.id,
+ name: hitArea.name,
+ index: this.coreModel.getDrawDataIndex(hitArea.id)
+ }))) || [];
+ }
+ getDrawableIDs() {
+ const modelContext = this.coreModel.getModelContext();
+ const ids = [];
+ for (let i = 0; i < this.drawDataCount; i++) {
+ const drawData = modelContext.getDrawData(i);
+ if (drawData) {
+ ids.push(drawData.getDrawDataID().id);
+ }
+ }
+ return ids;
+ }
+ getDrawableIndex(id) {
+ return this.coreModel.getDrawDataIndex(id);
+ }
+ getDrawableVertices(drawIndex) {
+ if (typeof drawIndex === "string") {
+ drawIndex = this.coreModel.getDrawDataIndex(drawIndex);
+ if (drawIndex === -1)
+ throw new TypeError("Unable to find drawable ID: " + drawIndex);
+ }
+ return this.coreModel.getTransformedPoints(drawIndex).slice();
+ }
+ update(dt, now) {
+ var _a, _b, _c, _d;
+ super.update(dt, now);
+ const model = this.coreModel;
+ this.emit("beforeMotionUpdate");
+ const motionUpdated = this.motionManager.update(this.coreModel, now);
+ this.emit("afterMotionUpdate");
+ model.saveParam();
+ (_a = this.motionManager.expressionManager) == null ? void 0 : _a.update(model, now);
+ if (!motionUpdated) {
+ (_b = this.eyeBlink) == null ? void 0 : _b.update(dt);
+ }
+ this.updateFocus();
+ this.updateNaturalMovements(dt, now);
+ (_c = this.physics) == null ? void 0 : _c.update(now);
+ (_d = this.pose) == null ? void 0 : _d.update(dt);
+ this.emit("beforeModelUpdate");
+ model.update();
+ model.loadParam();
+ }
+ updateFocus() {
+ this.coreModel.addToParamFloat(this.eyeballXParamIndex, this.focusController.x);
+ this.coreModel.addToParamFloat(this.eyeballYParamIndex, this.focusController.y);
+ this.coreModel.addToParamFloat(this.angleXParamIndex, this.focusController.x * 30);
+ this.coreModel.addToParamFloat(this.angleYParamIndex, this.focusController.y * 30);
+ this.coreModel.addToParamFloat(this.angleZParamIndex, this.focusController.x * this.focusController.y * -30);
+ this.coreModel.addToParamFloat(this.bodyAngleXParamIndex, this.focusController.x * 10);
+ }
+ updateNaturalMovements(dt, now) {
+ const t = now / 1e3 * 2 * Math.PI;
+ this.coreModel.addToParamFloat(this.angleXParamIndex, 15 * Math.sin(t / 6.5345) * 0.5);
+ this.coreModel.addToParamFloat(this.angleYParamIndex, 8 * Math.sin(t / 3.5345) * 0.5);
+ this.coreModel.addToParamFloat(this.angleZParamIndex, 10 * Math.sin(t / 5.5345) * 0.5);
+ this.coreModel.addToParamFloat(this.bodyAngleXParamIndex, 4 * Math.sin(t / 15.5345) * 0.5);
+ this.coreModel.setParamFloat(this.breathParamIndex, 0.5 + 0.5 * Math.sin(t / 3.2345));
+ }
+ draw(gl) {
+ const disableCulling = this.disableCulling;
+ if (gl.getParameter(gl.FRAMEBUFFER_BINDING)) {
+ this.disableCulling = true;
+ }
+ const matrix = this.drawingMatrix;
+ tempMatrixArray[0] = matrix.a;
+ tempMatrixArray[1] = matrix.b;
+ tempMatrixArray[4] = matrix.c;
+ tempMatrixArray[5] = matrix.d;
+ tempMatrixArray[12] = matrix.tx;
+ tempMatrixArray[13] = matrix.ty;
+ this.coreModel.setMatrix(tempMatrixArray);
+ this.coreModel.draw();
+ this.disableCulling = disableCulling;
+ }
+ destroy() {
+ super.destroy();
+ this.coreModel = void 0;
+ }
+}
+class Cubism2ModelSettings extends ModelSettings {
+ constructor(json) {
+ super(json);
+ this.motions = {};
+ if (!Cubism2ModelSettings.isValidJSON(json)) {
+ throw new TypeError("Invalid JSON.");
+ }
+ this.moc = json.model;
+ copyArray("string", json, this, "textures", "textures");
+ this.copy(json);
+ }
+ static isValidJSON(json) {
+ var _a;
+ return !!json && typeof json.model === "string" && ((_a = json.textures) == null ? void 0 : _a.length) > 0 && json.textures.every((item) => typeof item === "string");
+ }
+ copy(json) {
+ copyProperty("string", json, this, "name", "name");
+ copyProperty("string", json, this, "pose", "pose");
+ copyProperty("string", json, this, "physics", "physics");
+ copyProperty("object", json, this, "layout", "layout");
+ copyProperty("object", json, this, "motions", "motions");
+ copyArray("object", json, this, "hit_areas", "hitAreas");
+ copyArray("object", json, this, "expressions", "expressions");
+ copyArray("object", json, this, "init_params", "initParams");
+ copyArray("object", json, this, "init_opacities", "initOpacities");
+ }
+ replaceFiles(replace) {
+ super.replaceFiles(replace);
+ for (const [group, motions] of Object.entries(this.motions)) {
+ for (let i = 0; i < motions.length; i++) {
+ motions[i].file = replace(motions[i].file, `motions.${group}[${i}].file`);
+ if (motions[i].sound !== void 0) {
+ motions[i].sound = replace(motions[i].sound, `motions.${group}[${i}].sound`);
+ }
+ }
+ }
+ if (this.expressions) {
+ for (let i = 0; i < this.expressions.length; i++) {
+ this.expressions[i].file = replace(this.expressions[i].file, `expressions[${i}].file`);
+ }
+ }
+ }
+}
+const SRC_TYPE_MAP = {
+ x: PhysicsHair.Src.SRC_TO_X,
+ y: PhysicsHair.Src.SRC_TO_Y,
+ angle: PhysicsHair.Src.SRC_TO_G_ANGLE
+};
+const TARGET_TYPE_MAP = {
+ x: PhysicsHair.Src.SRC_TO_X,
+ y: PhysicsHair.Src.SRC_TO_Y,
+ angle: PhysicsHair.Src.SRC_TO_G_ANGLE
+};
+class Live2DPhysics {
+ constructor(coreModel, json) {
+ this.coreModel = coreModel;
+ this.physicsHairs = [];
+ if (json.physics_hair) {
+ this.physicsHairs = json.physics_hair.map((definition) => {
+ const physicsHair = new PhysicsHair();
+ physicsHair.setup(definition.setup.length, definition.setup.regist, definition.setup.mass);
+ definition.src.forEach(({ id, ptype, scale, weight }) => {
+ const type = SRC_TYPE_MAP[ptype];
+ if (type) {
+ physicsHair.addSrcParam(type, id, scale, weight);
+ }
+ });
+ definition.targets.forEach(({ id, ptype, scale, weight }) => {
+ const type = TARGET_TYPE_MAP[ptype];
+ if (type) {
+ physicsHair.addTargetParam(type, id, scale, weight);
+ }
+ });
+ return physicsHair;
+ });
+ }
+ }
+ update(elapsed) {
+ this.physicsHairs.forEach((physicsHair) => physicsHair.update(this.coreModel, elapsed));
+ }
+}
+class Live2DPartsParam {
+ constructor(id) {
+ this.id = id;
+ this.paramIndex = -1;
+ this.partsIndex = -1;
+ this.link = [];
+ }
+ initIndex(model) {
+ this.paramIndex = model.getParamIndex("VISIBLE:" + this.id);
+ this.partsIndex = model.getPartsDataIndex(PartsDataID.getID(this.id));
+ model.setParamFloat(this.paramIndex, 1);
+ }
+}
+class Live2DPose {
+ constructor(coreModel, json) {
+ this.coreModel = coreModel;
+ this.opacityAnimDuration = 500;
+ this.partsGroups = [];
+ if (json.parts_visible) {
+ this.partsGroups = json.parts_visible.map(({ group }) => group.map(({ id, link }) => {
+ const parts = new Live2DPartsParam(id);
+ if (link) {
+ parts.link = link.map((l) => new Live2DPartsParam(l));
+ }
+ return parts;
+ }));
+ this.init();
+ }
+ }
+ init() {
+ this.partsGroups.forEach((group) => {
+ group.forEach((parts) => {
+ parts.initIndex(this.coreModel);
+ if (parts.paramIndex >= 0) {
+ const visible = this.coreModel.getParamFloat(parts.paramIndex) !== 0;
+ this.coreModel.setPartsOpacity(parts.partsIndex, visible ? 1 : 0);
+ this.coreModel.setParamFloat(parts.paramIndex, visible ? 1 : 0);
+ if (parts.link.length > 0) {
+ parts.link.forEach((p) => p.initIndex(this.coreModel));
+ }
+ }
+ });
+ });
+ }
+ normalizePartsOpacityGroup(partsGroup, dt) {
+ const model = this.coreModel;
+ const phi = 0.5;
+ const maxBackOpacity = 0.15;
+ let visibleOpacity = 1;
+ let visibleIndex = partsGroup.findIndex(({ paramIndex, partsIndex }) => partsIndex >= 0 && model.getParamFloat(paramIndex) !== 0);
+ if (visibleIndex >= 0) {
+ const originalOpacity = model.getPartsOpacity(partsGroup[visibleIndex].partsIndex);
+ visibleOpacity = clamp(originalOpacity + dt / this.opacityAnimDuration, 0, 1);
+ } else {
+ visibleIndex = 0;
+ visibleOpacity = 1;
+ }
+ partsGroup.forEach(({ partsIndex }, index) => {
+ if (partsIndex >= 0) {
+ if (visibleIndex == index) {
+ model.setPartsOpacity(partsIndex, visibleOpacity);
+ } else {
+ let opacity = model.getPartsOpacity(partsIndex);
+ let a1;
+ if (visibleOpacity < phi) {
+ a1 = visibleOpacity * (phi - 1) / phi + 1;
+ } else {
+ a1 = (1 - visibleOpacity) * phi / (1 - phi);
+ }
+ let backOp = (1 - a1) * (1 - visibleOpacity);
+ if (backOp > maxBackOpacity) {
+ a1 = 1 - maxBackOpacity / (1 - visibleOpacity);
+ }
+ if (opacity > a1) {
+ opacity = a1;
+ }
+ model.setPartsOpacity(partsIndex, opacity);
+ }
+ }
+ });
+ }
+ copyOpacity(partsGroup) {
+ const model = this.coreModel;
+ partsGroup.forEach(({ partsIndex, link }) => {
+ if (partsIndex >= 0 && link) {
+ const opacity = model.getPartsOpacity(partsIndex);
+ link.forEach(({ partsIndex: partsIndex2 }) => {
+ if (partsIndex2 >= 0) {
+ model.setPartsOpacity(partsIndex2, opacity);
+ }
+ });
+ }
+ });
+ }
+ update(dt) {
+ this.partsGroups.forEach((partGroup) => {
+ this.normalizePartsOpacityGroup(partGroup, dt);
+ this.copyOpacity(partGroup);
+ });
+ }
+}
+Live2DFactory.registerRuntime({
+ version: 2,
+ test(source) {
+ return source instanceof Cubism2ModelSettings || Cubism2ModelSettings.isValidJSON(source);
+ },
+ ready() {
+ return Promise.resolve();
+ },
+ isValidMoc(modelData) {
+ if (modelData.byteLength < 3) {
+ return false;
+ }
+ const view = new Int8Array(modelData, 0, 3);
+ return String.fromCharCode(...view) === "moc";
+ },
+ createModelSettings(json) {
+ return new Cubism2ModelSettings(json);
+ },
+ createCoreModel(data) {
+ const model = Live2DModelWebGL.loadModel(data);
+ const error = Live2D.getError();
+ if (error)
+ throw error;
+ return model;
+ },
+ createInternalModel(coreModel, settings, options) {
+ return new Cubism2InternalModel(coreModel, settings, options);
+ },
+ createPose(coreModel, data) {
+ return new Live2DPose(coreModel, data);
+ },
+ createPhysics(coreModel, data) {
+ return new Live2DPhysics(coreModel, data);
+ }
+});
+if (!window.Live2DCubismCore) {
+ throw new Error("Could not find Cubism 4 runtime. This plugin requires live2dcubismcore.js to be loaded.");
+}
+class CubismVector2 {
+ constructor(x, y) {
+ this.x = x || 0;
+ this.y = y || 0;
+ }
+ add(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x + vector2.x;
+ ret.y = this.y + vector2.y;
+ return ret;
+ }
+ substract(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x - vector2.x;
+ ret.y = this.y - vector2.y;
+ return ret;
+ }
+ multiply(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x * vector2.x;
+ ret.y = this.y * vector2.y;
+ return ret;
+ }
+ multiplyByScaler(scalar) {
+ return this.multiply(new CubismVector2(scalar, scalar));
+ }
+ division(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x / vector2.x;
+ ret.y = this.y / vector2.y;
+ return ret;
+ }
+ divisionByScalar(scalar) {
+ return this.division(new CubismVector2(scalar, scalar));
+ }
+ getLength() {
+ return Math.sqrt(this.x * this.x + this.y * this.y);
+ }
+ getDistanceWith(a) {
+ return Math.sqrt((this.x - a.x) * (this.x - a.x) + (this.y - a.y) * (this.y - a.y));
+ }
+ dot(a) {
+ return this.x * a.x + this.y * a.y;
+ }
+ normalize() {
+ const length = Math.pow(this.x * this.x + this.y * this.y, 0.5);
+ this.x = this.x / length;
+ this.y = this.y / length;
+ }
+ isEqual(rhs) {
+ return this.x == rhs.x && this.y == rhs.y;
+ }
+ isNotEqual(rhs) {
+ return !this.isEqual(rhs);
+ }
+}
+const _CubismMath = class {
+ static range(value, min, max) {
+ if (value < min) {
+ value = min;
+ } else if (value > max) {
+ value = max;
+ }
+ return value;
+ }
+ static sin(x) {
+ return Math.sin(x);
+ }
+ static cos(x) {
+ return Math.cos(x);
+ }
+ static abs(x) {
+ return Math.abs(x);
+ }
+ static sqrt(x) {
+ return Math.sqrt(x);
+ }
+ static cbrt(x) {
+ if (x === 0) {
+ return x;
+ }
+ let cx = x;
+ const isNegativeNumber = cx < 0;
+ if (isNegativeNumber) {
+ cx = -cx;
+ }
+ let ret;
+ if (cx === Infinity) {
+ ret = Infinity;
+ } else {
+ ret = Math.exp(Math.log(cx) / 3);
+ ret = (cx / (ret * ret) + 2 * ret) / 3;
+ }
+ return isNegativeNumber ? -ret : ret;
+ }
+ static getEasingSine(value) {
+ if (value < 0) {
+ return 0;
+ } else if (value > 1) {
+ return 1;
+ }
+ return 0.5 - 0.5 * this.cos(value * Math.PI);
+ }
+ static max(left, right) {
+ return left > right ? left : right;
+ }
+ static min(left, right) {
+ return left > right ? right : left;
+ }
+ static degreesToRadian(degrees) {
+ return degrees / 180 * Math.PI;
+ }
+ static radianToDegrees(radian) {
+ return radian * 180 / Math.PI;
+ }
+ static directionToRadian(from, to) {
+ const q1 = Math.atan2(to.y, to.x);
+ const q2 = Math.atan2(from.y, from.x);
+ let ret = q1 - q2;
+ while (ret < -Math.PI) {
+ ret += Math.PI * 2;
+ }
+ while (ret > Math.PI) {
+ ret -= Math.PI * 2;
+ }
+ return ret;
+ }
+ static directionToDegrees(from, to) {
+ const radian = this.directionToRadian(from, to);
+ let degree = this.radianToDegrees(radian);
+ if (to.x - from.x > 0) {
+ degree = -degree;
+ }
+ return degree;
+ }
+ static radianToDirection(totalAngle) {
+ const ret = new CubismVector2();
+ ret.x = this.sin(totalAngle);
+ ret.y = this.cos(totalAngle);
+ return ret;
+ }
+ static quadraticEquation(a, b, c) {
+ if (this.abs(a) < _CubismMath.Epsilon) {
+ if (this.abs(b) < _CubismMath.Epsilon) {
+ return -c;
+ }
+ return -c / b;
+ }
+ return -(b + this.sqrt(b * b - 4 * a * c)) / (2 * a);
+ }
+ static cardanoAlgorithmForBezier(a, b, c, d) {
+ if (this.sqrt(a) < _CubismMath.Epsilon) {
+ return this.range(this.quadraticEquation(b, c, d), 0, 1);
+ }
+ const ba = b / a;
+ const ca = c / a;
+ const da = d / a;
+ const p = (3 * ca - ba * ba) / 3;
+ const p3 = p / 3;
+ const q = (2 * ba * ba * ba - 9 * ba * ca + 27 * da) / 27;
+ const q2 = q / 2;
+ const discriminant = q2 * q2 + p3 * p3 * p3;
+ const center = 0.5;
+ const threshold = center + 0.01;
+ if (discriminant < 0) {
+ const mp3 = -p / 3;
+ const mp33 = mp3 * mp3 * mp3;
+ const r = this.sqrt(mp33);
+ const t = -q / (2 * r);
+ const cosphi = this.range(t, -1, 1);
+ const phi = Math.acos(cosphi);
+ const crtr = this.cbrt(r);
+ const t1 = 2 * crtr;
+ const root12 = t1 * this.cos(phi / 3) - ba / 3;
+ if (this.abs(root12 - center) < threshold) {
+ return this.range(root12, 0, 1);
+ }
+ const root2 = t1 * this.cos((phi + 2 * Math.PI) / 3) - ba / 3;
+ if (this.abs(root2 - center) < threshold) {
+ return this.range(root2, 0, 1);
+ }
+ const root3 = t1 * this.cos((phi + 4 * Math.PI) / 3) - ba / 3;
+ return this.range(root3, 0, 1);
+ }
+ if (discriminant == 0) {
+ let u12;
+ if (q2 < 0) {
+ u12 = this.cbrt(-q2);
+ } else {
+ u12 = -this.cbrt(q2);
+ }
+ const root12 = 2 * u12 - ba / 3;
+ if (this.abs(root12 - center) < threshold) {
+ return this.range(root12, 0, 1);
+ }
+ const root2 = -u12 - ba / 3;
+ return this.range(root2, 0, 1);
+ }
+ const sd = this.sqrt(discriminant);
+ const u1 = this.cbrt(sd - q2);
+ const v1 = this.cbrt(sd + q2);
+ const root1 = u1 - v1 - ba / 3;
+ return this.range(root1, 0, 1);
+ }
+ constructor() {
+ }
+};
+let CubismMath = _CubismMath;
+CubismMath.Epsilon = 1e-5;
+class CubismMatrix44 {
+ constructor() {
+ this._tr = new Float32Array(16);
+ this.loadIdentity();
+ }
+ static multiply(a, b, dst) {
+ const c = new Float32Array([
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]);
+ const n = 4;
+ for (let i = 0; i < n; ++i) {
+ for (let j = 0; j < n; ++j) {
+ for (let k = 0; k < n; ++k) {
+ c[j + i * 4] += a[k + i * 4] * b[j + k * 4];
+ }
+ }
+ }
+ for (let i = 0; i < 16; ++i) {
+ dst[i] = c[i];
+ }
+ }
+ loadIdentity() {
+ const c = new Float32Array([
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ]);
+ this.setMatrix(c);
+ }
+ setMatrix(tr) {
+ for (let i = 0; i < 16; ++i) {
+ this._tr[i] = tr[i];
+ }
+ }
+ getArray() {
+ return this._tr;
+ }
+ getScaleX() {
+ return this._tr[0];
+ }
+ getScaleY() {
+ return this._tr[5];
+ }
+ getTranslateX() {
+ return this._tr[12];
+ }
+ getTranslateY() {
+ return this._tr[13];
+ }
+ transformX(src) {
+ return this._tr[0] * src + this._tr[12];
+ }
+ transformY(src) {
+ return this._tr[5] * src + this._tr[13];
+ }
+ invertTransformX(src) {
+ return (src - this._tr[12]) / this._tr[0];
+ }
+ invertTransformY(src) {
+ return (src - this._tr[13]) / this._tr[5];
+ }
+ translateRelative(x, y) {
+ const tr1 = new Float32Array([
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ x,
+ y,
+ 0,
+ 1
+ ]);
+ CubismMatrix44.multiply(tr1, this._tr, this._tr);
+ }
+ translate(x, y) {
+ this._tr[12] = x;
+ this._tr[13] = y;
+ }
+ translateX(x) {
+ this._tr[12] = x;
+ }
+ translateY(y) {
+ this._tr[13] = y;
+ }
+ scaleRelative(x, y) {
+ const tr1 = new Float32Array([
+ x,
+ 0,
+ 0,
+ 0,
+ 0,
+ y,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ]);
+ CubismMatrix44.multiply(tr1, this._tr, this._tr);
+ }
+ scale(x, y) {
+ this._tr[0] = x;
+ this._tr[5] = y;
+ }
+ multiplyByMatrix(m) {
+ CubismMatrix44.multiply(m.getArray(), this._tr, this._tr);
+ }
+ clone() {
+ const cloneMatrix = new CubismMatrix44();
+ for (let i = 0; i < this._tr.length; i++) {
+ cloneMatrix._tr[i] = this._tr[i];
+ }
+ return cloneMatrix;
+ }
+}
+class CubismRenderer {
+ initialize(model) {
+ this._model = model;
+ }
+ drawModel() {
+ if (this.getModel() == null)
+ return;
+ this.saveProfile();
+ this.doDrawModel();
+ this.restoreProfile();
+ }
+ setMvpMatrix(matrix44) {
+ this._mvpMatrix4x4.setMatrix(matrix44.getArray());
+ }
+ getMvpMatrix() {
+ return this._mvpMatrix4x4;
+ }
+ setModelColor(red, green, blue, alpha) {
+ if (red < 0) {
+ red = 0;
+ } else if (red > 1) {
+ red = 1;
+ }
+ if (green < 0) {
+ green = 0;
+ } else if (green > 1) {
+ green = 1;
+ }
+ if (blue < 0) {
+ blue = 0;
+ } else if (blue > 1) {
+ blue = 1;
+ }
+ if (alpha < 0) {
+ alpha = 0;
+ } else if (alpha > 1) {
+ alpha = 1;
+ }
+ this._modelColor.R = red;
+ this._modelColor.G = green;
+ this._modelColor.B = blue;
+ this._modelColor.A = alpha;
+ }
+ getModelColor() {
+ return Object.assign({}, this._modelColor);
+ }
+ setIsPremultipliedAlpha(enable) {
+ this._isPremultipliedAlpha = enable;
+ }
+ isPremultipliedAlpha() {
+ return this._isPremultipliedAlpha;
+ }
+ setIsCulling(culling) {
+ this._isCulling = culling;
+ }
+ isCulling() {
+ return this._isCulling;
+ }
+ setAnisotropy(n) {
+ this._anisotropy = n;
+ }
+ getAnisotropy() {
+ return this._anisotropy;
+ }
+ getModel() {
+ return this._model;
+ }
+ useHighPrecisionMask(high) {
+ this._useHighPrecisionMask = high;
+ }
+ isUsingHighPrecisionMask() {
+ return this._useHighPrecisionMask;
+ }
+ constructor() {
+ this._isCulling = false;
+ this._isPremultipliedAlpha = false;
+ this._anisotropy = 0;
+ this._modelColor = new CubismTextureColor();
+ this._useHighPrecisionMask = false;
+ this._mvpMatrix4x4 = new CubismMatrix44();
+ this._mvpMatrix4x4.loadIdentity();
+ }
+}
+var CubismBlendMode = /* @__PURE__ */ ((CubismBlendMode2) => {
+ CubismBlendMode2[CubismBlendMode2["CubismBlendMode_Normal"] = 0] = "CubismBlendMode_Normal";
+ CubismBlendMode2[CubismBlendMode2["CubismBlendMode_Additive"] = 1] = "CubismBlendMode_Additive";
+ CubismBlendMode2[CubismBlendMode2["CubismBlendMode_Multiplicative"] = 2] = "CubismBlendMode_Multiplicative";
+ return CubismBlendMode2;
+})(CubismBlendMode || {});
+class CubismTextureColor {
+ constructor(r = 1, g = 1, b = 1, a = 1) {
+ this.R = r;
+ this.G = g;
+ this.B = b;
+ this.A = a;
+ }
+}
+let s_isStarted = false;
+let s_isInitialized = false;
+let s_option = void 0;
+const Constant = {
+ vertexOffset: 0,
+ vertexStep: 2
+};
+class CubismFramework {
+ static startUp(option) {
+ if (s_isStarted) {
+ CubismLogInfo("CubismFramework.startUp() is already done.");
+ return s_isStarted;
+ }
+ if (Live2DCubismCore._isStarted) {
+ s_isStarted = true;
+ return true;
+ }
+ Live2DCubismCore._isStarted = true;
+ s_option = option;
+ if (s_option) {
+ Live2DCubismCore.Logging.csmSetLogFunction(s_option.logFunction);
+ }
+ s_isStarted = true;
+ if (s_isStarted) {
+ const version = Live2DCubismCore.Version.csmGetVersion();
+ const major = (version & 4278190080) >> 24;
+ const minor = (version & 16711680) >> 16;
+ const patch = version & 65535;
+ const versionNumber = version;
+ CubismLogInfo(`Live2D Cubism Core version: {0}.{1}.{2} ({3})`, ("00" + major).slice(-2), ("00" + minor).slice(-2), ("0000" + patch).slice(-4), versionNumber);
+ }
+ CubismLogInfo("CubismFramework.startUp() is complete.");
+ return s_isStarted;
+ }
+ static cleanUp() {
+ s_isStarted = false;
+ s_isInitialized = false;
+ s_option = void 0;
+ }
+ static initialize(memorySize = 0) {
+ if (!s_isStarted) {
+ CubismLogWarning("CubismFramework is not started.");
+ return;
+ }
+ if (s_isInitialized) {
+ CubismLogWarning("CubismFramework.initialize() skipped, already initialized.");
+ return;
+ }
+ Live2DCubismCore.Memory.initializeAmountOfMemory(memorySize);
+ s_isInitialized = true;
+ CubismLogInfo("CubismFramework.initialize() is complete.");
+ }
+ static dispose() {
+ if (!s_isStarted) {
+ CubismLogWarning("CubismFramework is not started.");
+ return;
+ }
+ if (!s_isInitialized) {
+ CubismLogWarning("CubismFramework.dispose() skipped, not initialized.");
+ return;
+ }
+ CubismRenderer.staticRelease();
+ s_isInitialized = false;
+ CubismLogInfo("CubismFramework.dispose() is complete.");
+ }
+ static isStarted() {
+ return s_isStarted;
+ }
+ static isInitialized() {
+ return s_isInitialized;
+ }
+ static coreLogFunction(message) {
+ if (!Live2DCubismCore.Logging.csmGetLogFunction()) {
+ return;
+ }
+ Live2DCubismCore.Logging.csmGetLogFunction()(message);
+ }
+ static getLoggingLevel() {
+ if (s_option != null) {
+ return s_option.loggingLevel;
+ }
+ return LogLevel.LogLevel_Off;
+ }
+ constructor() {
+ }
+}
+var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
+ LogLevel2[LogLevel2["LogLevel_Verbose"] = 0] = "LogLevel_Verbose";
+ LogLevel2[LogLevel2["LogLevel_Debug"] = 1] = "LogLevel_Debug";
+ LogLevel2[LogLevel2["LogLevel_Info"] = 2] = "LogLevel_Info";
+ LogLevel2[LogLevel2["LogLevel_Warning"] = 3] = "LogLevel_Warning";
+ LogLevel2[LogLevel2["LogLevel_Error"] = 4] = "LogLevel_Error";
+ LogLevel2[LogLevel2["LogLevel_Off"] = 5] = "LogLevel_Off";
+ return LogLevel2;
+})(LogLevel || {});
+const CSM_ASSERT = () => {
+};
+function CubismLogDebug(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Debug, "[CSM][D]" + fmt + "\n", args);
+}
+function CubismLogInfo(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Info, "[CSM][I]" + fmt + "\n", args);
+}
+function CubismLogWarning(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Warning, "[CSM][W]" + fmt + "\n", args);
+}
+function CubismLogError(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Error, "[CSM][E]" + fmt + "\n", args);
+}
+class CubismDebug {
+ static print(logLevel, format, args) {
+ if (logLevel < CubismFramework.getLoggingLevel()) {
+ return;
+ }
+ const logPrint = CubismFramework.coreLogFunction;
+ if (!logPrint)
+ return;
+ const buffer = format.replace(/{(\d+)}/g, (m, k) => {
+ return args[k];
+ });
+ logPrint(buffer);
+ }
+ static dumpBytes(logLevel, data, length) {
+ for (let i = 0; i < length; i++) {
+ if (i % 16 == 0 && i > 0)
+ this.print(logLevel, "\n");
+ else if (i % 8 == 0 && i > 0)
+ this.print(logLevel, " ");
+ this.print(logLevel, "{0} ", [data[i] & 255]);
+ }
+ this.print(logLevel, "\n");
+ }
+ constructor() {
+ }
+}
+class ACubismMotion {
+ constructor() {
+ this._fadeInSeconds = -1;
+ this._fadeOutSeconds = -1;
+ this._weight = 1;
+ this._offsetSeconds = 0;
+ this._firedEventValues = [];
+ }
+ release() {
+ this._weight = 0;
+ }
+ updateParameters(model, motionQueueEntry, userTimeSeconds) {
+ if (!motionQueueEntry.isAvailable() || motionQueueEntry.isFinished()) {
+ return;
+ }
+ if (!motionQueueEntry.isStarted()) {
+ motionQueueEntry.setIsStarted(true);
+ motionQueueEntry.setStartTime(userTimeSeconds - this._offsetSeconds);
+ motionQueueEntry.setFadeInStartTime(userTimeSeconds);
+ const duration = this.getDuration();
+ if (motionQueueEntry.getEndTime() < 0) {
+ motionQueueEntry.setEndTime(duration <= 0 ? -1 : motionQueueEntry.getStartTime() + duration);
+ }
+ }
+ let fadeWeight = this._weight;
+ const fadeIn = this._fadeInSeconds == 0 ? 1 : CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / this._fadeInSeconds);
+ const fadeOut = this._fadeOutSeconds == 0 || motionQueueEntry.getEndTime() < 0 ? 1 : CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / this._fadeOutSeconds);
+ fadeWeight = fadeWeight * fadeIn * fadeOut;
+ motionQueueEntry.setState(userTimeSeconds, fadeWeight);
+ this.doUpdateParameters(model, userTimeSeconds, fadeWeight, motionQueueEntry);
+ if (motionQueueEntry.getEndTime() > 0 && motionQueueEntry.getEndTime() < userTimeSeconds) {
+ motionQueueEntry.setIsFinished(true);
+ }
+ }
+ setFadeInTime(fadeInSeconds) {
+ this._fadeInSeconds = fadeInSeconds;
+ }
+ setFadeOutTime(fadeOutSeconds) {
+ this._fadeOutSeconds = fadeOutSeconds;
+ }
+ getFadeOutTime() {
+ return this._fadeOutSeconds;
+ }
+ getFadeInTime() {
+ return this._fadeInSeconds;
+ }
+ setWeight(weight) {
+ this._weight = weight;
+ }
+ getWeight() {
+ return this._weight;
+ }
+ getDuration() {
+ return -1;
+ }
+ getLoopDuration() {
+ return -1;
+ }
+ setOffsetTime(offsetSeconds) {
+ this._offsetSeconds = offsetSeconds;
+ }
+ getFiredEvent(beforeCheckTimeSeconds, motionTimeSeconds) {
+ return this._firedEventValues;
+ }
+ setFinishedMotionHandler(onFinishedMotionHandler) {
+ this._onFinishedMotion = onFinishedMotionHandler;
+ }
+ getFinishedMotionHandler() {
+ return this._onFinishedMotion;
+ }
+ isExistModelOpacity() {
+ return false;
+ }
+ getModelOpacityIndex() {
+ return -1;
+ }
+ getModelOpacityId(index) {
+ return void 0;
+ }
+ getModelOpacityValue() {
+ return 1;
+ }
+}
+const DefaultFadeTime = 1;
+class CubismExpressionMotion extends ACubismMotion {
+ constructor() {
+ super();
+ this._parameters = [];
+ }
+ static create(json) {
+ const expression = new CubismExpressionMotion();
+ expression.parse(json);
+ return expression;
+ }
+ doUpdateParameters(model, userTimeSeconds, weight, motionQueueEntry) {
+ for (let i = 0; i < this._parameters.length; ++i) {
+ const parameter = this._parameters[i];
+ switch (parameter.blendType) {
+ case ExpressionBlendType.ExpressionBlendType_Add: {
+ model.addParameterValueById(parameter.parameterId, parameter.value, weight);
+ break;
+ }
+ case ExpressionBlendType.ExpressionBlendType_Multiply: {
+ model.multiplyParameterValueById(parameter.parameterId, parameter.value, weight);
+ break;
+ }
+ case ExpressionBlendType.ExpressionBlendType_Overwrite: {
+ model.setParameterValueById(parameter.parameterId, parameter.value, weight);
+ break;
+ }
+ }
+ }
+ }
+ parse(json) {
+ this.setFadeInTime(json.FadeInTime != void 0 ? json.FadeInTime : DefaultFadeTime);
+ this.setFadeOutTime(json.FadeOutTime != void 0 ? json.FadeOutTime : DefaultFadeTime);
+ const parameterCount = (json.Parameters || []).length;
+ for (let i = 0; i < parameterCount; ++i) {
+ const param = json.Parameters[i];
+ const parameterId = param.Id;
+ const value = param.Value;
+ let blendType;
+ if (!param.Blend || param.Blend === "Add") {
+ blendType = ExpressionBlendType.ExpressionBlendType_Add;
+ } else if (param.Blend === "Multiply") {
+ blendType = ExpressionBlendType.ExpressionBlendType_Multiply;
+ } else if (param.Blend === "Overwrite") {
+ blendType = ExpressionBlendType.ExpressionBlendType_Overwrite;
+ } else {
+ blendType = ExpressionBlendType.ExpressionBlendType_Add;
+ }
+ const item = {
+ parameterId,
+ blendType,
+ value
+ };
+ this._parameters.push(item);
+ }
+ }
+}
+var ExpressionBlendType = /* @__PURE__ */ ((ExpressionBlendType2) => {
+ ExpressionBlendType2[ExpressionBlendType2["ExpressionBlendType_Add"] = 0] = "ExpressionBlendType_Add";
+ ExpressionBlendType2[ExpressionBlendType2["ExpressionBlendType_Multiply"] = 1] = "ExpressionBlendType_Multiply";
+ ExpressionBlendType2[ExpressionBlendType2["ExpressionBlendType_Overwrite"] = 2] = "ExpressionBlendType_Overwrite";
+ return ExpressionBlendType2;
+})(ExpressionBlendType || {});
+class CubismMotionQueueEntry {
+ constructor() {
+ this._autoDelete = false;
+ this._available = true;
+ this._finished = false;
+ this._started = false;
+ this._startTimeSeconds = -1;
+ this._fadeInStartTimeSeconds = 0;
+ this._endTimeSeconds = -1;
+ this._stateTimeSeconds = 0;
+ this._stateWeight = 0;
+ this._lastEventCheckSeconds = 0;
+ this._motionQueueEntryHandle = this;
+ this._fadeOutSeconds = 0;
+ this._isTriggeredFadeOut = false;
+ }
+ release() {
+ if (this._autoDelete && this._motion) {
+ this._motion.release();
+ }
+ }
+ setFadeOut(fadeOutSeconds) {
+ this._fadeOutSeconds = fadeOutSeconds;
+ this._isTriggeredFadeOut = true;
+ }
+ startFadeOut(fadeOutSeconds, userTimeSeconds) {
+ const newEndTimeSeconds = userTimeSeconds + fadeOutSeconds;
+ this._isTriggeredFadeOut = true;
+ if (this._endTimeSeconds < 0 || newEndTimeSeconds < this._endTimeSeconds) {
+ this._endTimeSeconds = newEndTimeSeconds;
+ }
+ }
+ isFinished() {
+ return this._finished;
+ }
+ isStarted() {
+ return this._started;
+ }
+ getStartTime() {
+ return this._startTimeSeconds;
+ }
+ getFadeInStartTime() {
+ return this._fadeInStartTimeSeconds;
+ }
+ getEndTime() {
+ return this._endTimeSeconds;
+ }
+ setStartTime(startTime) {
+ this._startTimeSeconds = startTime;
+ }
+ setFadeInStartTime(startTime) {
+ this._fadeInStartTimeSeconds = startTime;
+ }
+ setEndTime(endTime) {
+ this._endTimeSeconds = endTime;
+ }
+ setIsFinished(f) {
+ this._finished = f;
+ }
+ setIsStarted(f) {
+ this._started = f;
+ }
+ isAvailable() {
+ return this._available;
+ }
+ setIsAvailable(v) {
+ this._available = v;
+ }
+ setState(timeSeconds, weight) {
+ this._stateTimeSeconds = timeSeconds;
+ this._stateWeight = weight;
+ }
+ getStateTime() {
+ return this._stateTimeSeconds;
+ }
+ getStateWeight() {
+ return this._stateWeight;
+ }
+ getLastCheckEventSeconds() {
+ return this._lastEventCheckSeconds;
+ }
+ setLastCheckEventSeconds(checkSeconds) {
+ this._lastEventCheckSeconds = checkSeconds;
+ }
+ isTriggeredFadeOut() {
+ return this._isTriggeredFadeOut;
+ }
+ getFadeOutSeconds() {
+ return this._fadeOutSeconds;
+ }
+}
+class CubismMotionQueueManager {
+ constructor() {
+ this._userTimeSeconds = 0;
+ this._eventCustomData = null;
+ this._motions = [];
+ }
+ release() {
+ for (let i = 0; i < this._motions.length; ++i) {
+ if (this._motions[i]) {
+ this._motions[i].release();
+ }
+ }
+ this._motions = void 0;
+ }
+ startMotion(motion, autoDelete, userTimeSeconds) {
+ if (motion == null) {
+ return InvalidMotionQueueEntryHandleValue;
+ }
+ let motionQueueEntry;
+ for (let i = 0; i < this._motions.length; ++i) {
+ motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ continue;
+ }
+ motionQueueEntry.setFadeOut(motionQueueEntry._motion.getFadeOutTime());
+ }
+ motionQueueEntry = new CubismMotionQueueEntry();
+ motionQueueEntry._autoDelete = autoDelete;
+ motionQueueEntry._motion = motion;
+ this._motions.push(motionQueueEntry);
+ return motionQueueEntry._motionQueueEntryHandle;
+ }
+ isFinished() {
+ let i = 0;
+ while (i < this._motions.length) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ this._motions.splice(i, 1);
+ continue;
+ }
+ const motion = motionQueueEntry._motion;
+ if (motion == null) {
+ motionQueueEntry.release();
+ this._motions.splice(i, 1);
+ continue;
+ }
+ if (!motionQueueEntry.isFinished()) {
+ return false;
+ }
+ i++;
+ }
+ return true;
+ }
+ isFinishedByHandle(motionQueueEntryNumber) {
+ for (let i = 0; i < this._motions.length; i++) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ continue;
+ }
+ if (motionQueueEntry._motionQueueEntryHandle == motionQueueEntryNumber && !motionQueueEntry.isFinished()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ stopAllMotions() {
+ for (let i = 0; i < this._motions.length; i++) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry != null) {
+ motionQueueEntry.release();
+ }
+ }
+ this._motions = [];
+ }
+ getCubismMotionQueueEntry(motionQueueEntryNumber) {
+ return this._motions.find((entry) => entry != null && entry._motionQueueEntryHandle == motionQueueEntryNumber);
+ }
+ setEventCallback(callback, customData = null) {
+ this._eventCallBack = callback;
+ this._eventCustomData = customData;
+ }
+ doUpdateMotion(model, userTimeSeconds) {
+ let updated = false;
+ let i = 0;
+ while (i < this._motions.length) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ this._motions.splice(i, 1);
+ continue;
+ }
+ const motion = motionQueueEntry._motion;
+ if (motion == null) {
+ motionQueueEntry.release();
+ this._motions.splice(i, 1);
+ continue;
+ }
+ motion.updateParameters(model, motionQueueEntry, userTimeSeconds);
+ updated = true;
+ const firedList = motion.getFiredEvent(motionQueueEntry.getLastCheckEventSeconds() - motionQueueEntry.getStartTime(), userTimeSeconds - motionQueueEntry.getStartTime());
+ for (let i2 = 0; i2 < firedList.length; ++i2) {
+ this._eventCallBack(this, firedList[i2], this._eventCustomData);
+ }
+ motionQueueEntry.setLastCheckEventSeconds(userTimeSeconds);
+ if (motionQueueEntry.isFinished()) {
+ motionQueueEntry.release();
+ this._motions.splice(i, 1);
+ } else {
+ if (motionQueueEntry.isTriggeredFadeOut()) {
+ motionQueueEntry.startFadeOut(motionQueueEntry.getFadeOutSeconds(), userTimeSeconds);
+ }
+ i++;
+ }
+ }
+ return updated;
+ }
+}
+const InvalidMotionQueueEntryHandleValue = -1;
+class Cubism4ExpressionManager extends ExpressionManager {
+ constructor(settings, options) {
+ var _a;
+ super(settings, options);
+ this.queueManager = new CubismMotionQueueManager();
+ this.definitions = (_a = settings.expressions) != null ? _a : [];
+ this.init();
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ getExpressionIndex(name) {
+ return this.definitions.findIndex((def) => def.Name === name);
+ }
+ getExpressionFile(definition) {
+ return definition.File;
+ }
+ createExpression(data, definition) {
+ return CubismExpressionMotion.create(data);
+ }
+ _setExpression(motion) {
+ return this.queueManager.startMotion(motion, false, performance.now());
+ }
+ stopAllExpressions() {
+ this.queueManager.stopAllMotions();
+ }
+ updateParameters(model, now) {
+ return this.queueManager.doUpdateMotion(model, now);
+ }
+}
+class CubismModelSettingsJson {
+ constructor(json) {
+ this.groups = json.Groups;
+ this.hitAreas = json.HitAreas;
+ this.layout = json.Layout;
+ this.moc = json.FileReferences.Moc;
+ this.expressions = json.FileReferences.Expressions;
+ this.motions = json.FileReferences.Motions;
+ this.textures = json.FileReferences.Textures;
+ this.physics = json.FileReferences.Physics;
+ this.pose = json.FileReferences.Pose;
+ }
+ getEyeBlinkParameters() {
+ var _a, _b;
+ return (_b = (_a = this.groups) == null ? void 0 : _a.find((group) => group.Name === "EyeBlink")) == null ? void 0 : _b.Ids;
+ }
+ getLipSyncParameters() {
+ var _a, _b;
+ return (_b = (_a = this.groups) == null ? void 0 : _a.find((group) => group.Name === "LipSync")) == null ? void 0 : _b.Ids;
+ }
+}
+class Cubism4ModelSettings extends ModelSettings {
+ constructor(json) {
+ super(json);
+ if (!Cubism4ModelSettings.isValidJSON(json)) {
+ throw new TypeError("Invalid JSON.");
+ }
+ Object.assign(this, new CubismModelSettingsJson(json));
+ }
+ static isValidJSON(json) {
+ var _a;
+ return !!(json == null ? void 0 : json.FileReferences) && typeof json.FileReferences.Moc === "string" && ((_a = json.FileReferences.Textures) == null ? void 0 : _a.length) > 0 && json.FileReferences.Textures.every((item) => typeof item === "string");
+ }
+ replaceFiles(replace) {
+ super.replaceFiles(replace);
+ if (this.motions) {
+ for (const [group, motions] of Object.entries(this.motions)) {
+ for (let i = 0; i < motions.length; i++) {
+ motions[i].File = replace(motions[i].File, `motions.${group}[${i}].File`);
+ if (motions[i].Sound !== void 0) {
+ motions[i].Sound = replace(motions[i].Sound, `motions.${group}[${i}].Sound`);
+ }
+ }
+ }
+ }
+ if (this.expressions) {
+ for (let i = 0; i < this.expressions.length; i++) {
+ this.expressions[i].File = replace(this.expressions[i].File, `expressions[${i}].File`);
+ }
+ }
+ }
+}
+applyMixins(Cubism4ModelSettings, [CubismModelSettingsJson]);
+var CubismMotionCurveTarget = /* @__PURE__ */ ((CubismMotionCurveTarget2) => {
+ CubismMotionCurveTarget2[CubismMotionCurveTarget2["CubismMotionCurveTarget_Model"] = 0] = "CubismMotionCurveTarget_Model";
+ CubismMotionCurveTarget2[CubismMotionCurveTarget2["CubismMotionCurveTarget_Parameter"] = 1] = "CubismMotionCurveTarget_Parameter";
+ CubismMotionCurveTarget2[CubismMotionCurveTarget2["CubismMotionCurveTarget_PartOpacity"] = 2] = "CubismMotionCurveTarget_PartOpacity";
+ return CubismMotionCurveTarget2;
+})(CubismMotionCurveTarget || {});
+var CubismMotionSegmentType = /* @__PURE__ */ ((CubismMotionSegmentType2) => {
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_Linear"] = 0] = "CubismMotionSegmentType_Linear";
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_Bezier"] = 1] = "CubismMotionSegmentType_Bezier";
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_Stepped"] = 2] = "CubismMotionSegmentType_Stepped";
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_InverseStepped"] = 3] = "CubismMotionSegmentType_InverseStepped";
+ return CubismMotionSegmentType2;
+})(CubismMotionSegmentType || {});
+class CubismMotionPoint {
+ constructor(time = 0, value = 0) {
+ this.time = time;
+ this.value = value;
+ }
+}
+class CubismMotionSegment {
+ constructor() {
+ this.basePointIndex = 0;
+ this.segmentType = 0;
+ }
+}
+class CubismMotionCurve {
+ constructor() {
+ this.id = "";
+ this.type = 0;
+ this.segmentCount = 0;
+ this.baseSegmentIndex = 0;
+ this.fadeInTime = 0;
+ this.fadeOutTime = 0;
+ }
+}
+class CubismMotionEvent {
+ constructor() {
+ this.fireTime = 0;
+ this.value = "";
+ }
+}
+class CubismMotionData {
+ constructor() {
+ this.duration = 0;
+ this.loop = false;
+ this.curveCount = 0;
+ this.eventCount = 0;
+ this.fps = 0;
+ this.curves = [];
+ this.segments = [];
+ this.points = [];
+ this.events = [];
+ }
+}
+class CubismMotionJson {
+ constructor(json) {
+ this._json = json;
+ }
+ release() {
+ this._json = void 0;
+ }
+ getMotionDuration() {
+ return this._json.Meta.Duration;
+ }
+ isMotionLoop() {
+ return this._json.Meta.Loop || false;
+ }
+ getEvaluationOptionFlag(flagType) {
+ if (EvaluationOptionFlag.EvaluationOptionFlag_AreBeziersRistricted == flagType) {
+ return !!this._json.Meta.AreBeziersRestricted;
+ }
+ return false;
+ }
+ getMotionCurveCount() {
+ return this._json.Meta.CurveCount;
+ }
+ getMotionFps() {
+ return this._json.Meta.Fps;
+ }
+ getMotionTotalSegmentCount() {
+ return this._json.Meta.TotalSegmentCount;
+ }
+ getMotionTotalPointCount() {
+ return this._json.Meta.TotalPointCount;
+ }
+ getMotionFadeInTime() {
+ return this._json.Meta.FadeInTime;
+ }
+ getMotionFadeOutTime() {
+ return this._json.Meta.FadeOutTime;
+ }
+ getMotionCurveTarget(curveIndex) {
+ return this._json.Curves[curveIndex].Target;
+ }
+ getMotionCurveId(curveIndex) {
+ return this._json.Curves[curveIndex].Id;
+ }
+ getMotionCurveFadeInTime(curveIndex) {
+ return this._json.Curves[curveIndex].FadeInTime;
+ }
+ getMotionCurveFadeOutTime(curveIndex) {
+ return this._json.Curves[curveIndex].FadeOutTime;
+ }
+ getMotionCurveSegmentCount(curveIndex) {
+ return this._json.Curves[curveIndex].Segments.length;
+ }
+ getMotionCurveSegment(curveIndex, segmentIndex) {
+ return this._json.Curves[curveIndex].Segments[segmentIndex];
+ }
+ getEventCount() {
+ return this._json.Meta.UserDataCount || 0;
+ }
+ getTotalEventValueSize() {
+ return this._json.Meta.TotalUserDataSize;
+ }
+ getEventTime(userDataIndex) {
+ return this._json.UserData[userDataIndex].Time;
+ }
+ getEventValue(userDataIndex) {
+ return this._json.UserData[userDataIndex].Value;
+ }
+}
+var EvaluationOptionFlag = /* @__PURE__ */ ((EvaluationOptionFlag2) => {
+ EvaluationOptionFlag2[EvaluationOptionFlag2["EvaluationOptionFlag_AreBeziersRistricted"] = 0] = "EvaluationOptionFlag_AreBeziersRistricted";
+ return EvaluationOptionFlag2;
+})(EvaluationOptionFlag || {});
+const EffectNameEyeBlink = "EyeBlink";
+const EffectNameLipSync = "LipSync";
+const TargetNameModel = "Model";
+const TargetNameParameter = "Parameter";
+const TargetNamePartOpacity = "PartOpacity";
+const IdNameOpacity = "Opacity";
+const UseOldBeziersCurveMotion = false;
+function lerpPoints(a, b, t) {
+ const result = new CubismMotionPoint();
+ result.time = a.time + (b.time - a.time) * t;
+ result.value = a.value + (b.value - a.value) * t;
+ return result;
+}
+function linearEvaluate(points, time) {
+ let t = (time - points[0].time) / (points[1].time - points[0].time);
+ if (t < 0) {
+ t = 0;
+ }
+ return points[0].value + (points[1].value - points[0].value) * t;
+}
+function bezierEvaluate(points, time) {
+ let t = (time - points[0].time) / (points[3].time - points[0].time);
+ if (t < 0) {
+ t = 0;
+ }
+ const p01 = lerpPoints(points[0], points[1], t);
+ const p12 = lerpPoints(points[1], points[2], t);
+ const p23 = lerpPoints(points[2], points[3], t);
+ const p012 = lerpPoints(p01, p12, t);
+ const p123 = lerpPoints(p12, p23, t);
+ return lerpPoints(p012, p123, t).value;
+}
+function bezierEvaluateCardanoInterpretation(points, time) {
+ const x = time;
+ const x1 = points[0].time;
+ const x2 = points[3].time;
+ const cx1 = points[1].time;
+ const cx2 = points[2].time;
+ const a = x2 - 3 * cx2 + 3 * cx1 - x1;
+ const b = 3 * cx2 - 6 * cx1 + 3 * x1;
+ const c = 3 * cx1 - 3 * x1;
+ const d = x1 - x;
+ const t = CubismMath.cardanoAlgorithmForBezier(a, b, c, d);
+ const p01 = lerpPoints(points[0], points[1], t);
+ const p12 = lerpPoints(points[1], points[2], t);
+ const p23 = lerpPoints(points[2], points[3], t);
+ const p012 = lerpPoints(p01, p12, t);
+ const p123 = lerpPoints(p12, p23, t);
+ return lerpPoints(p012, p123, t).value;
+}
+function steppedEvaluate(points, time) {
+ return points[0].value;
+}
+function inverseSteppedEvaluate(points, time) {
+ return points[1].value;
+}
+function evaluateCurve(motionData, index, time) {
+ const curve = motionData.curves[index];
+ let target = -1;
+ const totalSegmentCount = curve.baseSegmentIndex + curve.segmentCount;
+ let pointPosition = 0;
+ for (let i = curve.baseSegmentIndex; i < totalSegmentCount; ++i) {
+ pointPosition = motionData.segments[i].basePointIndex + (motionData.segments[i].segmentType == CubismMotionSegmentType.CubismMotionSegmentType_Bezier ? 3 : 1);
+ if (motionData.points[pointPosition].time > time) {
+ target = i;
+ break;
+ }
+ }
+ if (target == -1) {
+ return motionData.points[pointPosition].value;
+ }
+ const segment = motionData.segments[target];
+ return segment.evaluate(motionData.points.slice(segment.basePointIndex), time);
+}
+class CubismMotion extends ACubismMotion {
+ constructor() {
+ super();
+ this._eyeBlinkParameterIds = [];
+ this._lipSyncParameterIds = [];
+ this._sourceFrameRate = 30;
+ this._loopDurationSeconds = -1;
+ this._isLoop = false;
+ this._isLoopFadeIn = true;
+ this._lastWeight = 0;
+ this._modelOpacity = 1;
+ }
+ static create(json, onFinishedMotionHandler) {
+ const ret = new CubismMotion();
+ ret.parse(json);
+ ret._sourceFrameRate = ret._motionData.fps;
+ ret._loopDurationSeconds = ret._motionData.duration;
+ ret._onFinishedMotion = onFinishedMotionHandler;
+ return ret;
+ }
+ doUpdateParameters(model, userTimeSeconds, fadeWeight, motionQueueEntry) {
+ if (this._modelCurveIdEyeBlink == null) {
+ this._modelCurveIdEyeBlink = EffectNameEyeBlink;
+ }
+ if (this._modelCurveIdLipSync == null) {
+ this._modelCurveIdLipSync = EffectNameLipSync;
+ }
+ if (this._modelCurveIdOpacity == null) {
+ this._modelCurveIdOpacity = IdNameOpacity;
+ }
+ let timeOffsetSeconds = userTimeSeconds - motionQueueEntry.getStartTime();
+ if (timeOffsetSeconds < 0) {
+ timeOffsetSeconds = 0;
+ }
+ let lipSyncValue = Number.MAX_VALUE;
+ let eyeBlinkValue = Number.MAX_VALUE;
+ const MaxTargetSize = 64;
+ let lipSyncFlags = 0;
+ let eyeBlinkFlags = 0;
+ if (this._eyeBlinkParameterIds.length > MaxTargetSize) {
+ CubismLogDebug("too many eye blink targets : {0}", this._eyeBlinkParameterIds.length);
+ }
+ if (this._lipSyncParameterIds.length > MaxTargetSize) {
+ CubismLogDebug("too many lip sync targets : {0}", this._lipSyncParameterIds.length);
+ }
+ const tmpFadeIn = this._fadeInSeconds <= 0 ? 1 : CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / this._fadeInSeconds);
+ const tmpFadeOut = this._fadeOutSeconds <= 0 || motionQueueEntry.getEndTime() < 0 ? 1 : CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / this._fadeOutSeconds);
+ let value;
+ let c, parameterIndex;
+ let time = timeOffsetSeconds;
+ if (this._isLoop) {
+ while (time > this._motionData.duration) {
+ time -= this._motionData.duration;
+ }
+ }
+ const curves = this._motionData.curves;
+ for (c = 0; c < this._motionData.curveCount && curves[c].type == CubismMotionCurveTarget.CubismMotionCurveTarget_Model; ++c) {
+ value = evaluateCurve(this._motionData, c, time);
+ if (curves[c].id == this._modelCurveIdEyeBlink) {
+ eyeBlinkValue = value;
+ } else if (curves[c].id == this._modelCurveIdLipSync) {
+ lipSyncValue = value;
+ } else if (curves[c].id == this._modelCurveIdOpacity) {
+ this._modelOpacity = value;
+ model.setModelOapcity(this.getModelOpacityValue());
+ }
+ }
+ for (; c < this._motionData.curveCount && curves[c].type == CubismMotionCurveTarget.CubismMotionCurveTarget_Parameter; ++c) {
+ parameterIndex = model.getParameterIndex(curves[c].id);
+ if (parameterIndex == -1) {
+ continue;
+ }
+ const sourceValue = model.getParameterValueByIndex(parameterIndex);
+ value = evaluateCurve(this._motionData, c, time);
+ if (eyeBlinkValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._eyeBlinkParameterIds.length && i < MaxTargetSize; ++i) {
+ if (this._eyeBlinkParameterIds[i] == curves[c].id) {
+ value *= eyeBlinkValue;
+ eyeBlinkFlags |= 1 << i;
+ break;
+ }
+ }
+ }
+ if (lipSyncValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._lipSyncParameterIds.length && i < MaxTargetSize; ++i) {
+ if (this._lipSyncParameterIds[i] == curves[c].id) {
+ value += lipSyncValue;
+ lipSyncFlags |= 1 << i;
+ break;
+ }
+ }
+ }
+ let v;
+ if (curves[c].fadeInTime < 0 && curves[c].fadeOutTime < 0) {
+ v = sourceValue + (value - sourceValue) * fadeWeight;
+ } else {
+ let fin;
+ let fout;
+ if (curves[c].fadeInTime < 0) {
+ fin = tmpFadeIn;
+ } else {
+ fin = curves[c].fadeInTime == 0 ? 1 : CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / curves[c].fadeInTime);
+ }
+ if (curves[c].fadeOutTime < 0) {
+ fout = tmpFadeOut;
+ } else {
+ fout = curves[c].fadeOutTime == 0 || motionQueueEntry.getEndTime() < 0 ? 1 : CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / curves[c].fadeOutTime);
+ }
+ const paramWeight = this._weight * fin * fout;
+ v = sourceValue + (value - sourceValue) * paramWeight;
+ }
+ model.setParameterValueByIndex(parameterIndex, v, 1);
+ }
+ {
+ if (eyeBlinkValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._eyeBlinkParameterIds.length && i < MaxTargetSize; ++i) {
+ const sourceValue = model.getParameterValueById(this._eyeBlinkParameterIds[i]);
+ if (eyeBlinkFlags >> i & 1) {
+ continue;
+ }
+ const v = sourceValue + (eyeBlinkValue - sourceValue) * fadeWeight;
+ model.setParameterValueById(this._eyeBlinkParameterIds[i], v);
+ }
+ }
+ if (lipSyncValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._lipSyncParameterIds.length && i < MaxTargetSize; ++i) {
+ const sourceValue = model.getParameterValueById(this._lipSyncParameterIds[i]);
+ if (lipSyncFlags >> i & 1) {
+ continue;
+ }
+ const v = sourceValue + (lipSyncValue - sourceValue) * fadeWeight;
+ model.setParameterValueById(this._lipSyncParameterIds[i], v);
+ }
+ }
+ }
+ for (; c < this._motionData.curveCount && curves[c].type == CubismMotionCurveTarget.CubismMotionCurveTarget_PartOpacity; ++c) {
+ value = evaluateCurve(this._motionData, c, time);
+ if (CubismConfig.setOpacityFromMotion) {
+ model.setPartOpacityById(curves[c].id, value);
+ } else {
+ parameterIndex = model.getParameterIndex(curves[c].id);
+ if (parameterIndex == -1) {
+ continue;
+ }
+ model.setParameterValueByIndex(parameterIndex, value);
+ }
+ }
+ if (timeOffsetSeconds >= this._motionData.duration) {
+ if (this._isLoop) {
+ motionQueueEntry.setStartTime(userTimeSeconds);
+ if (this._isLoopFadeIn) {
+ motionQueueEntry.setFadeInStartTime(userTimeSeconds);
+ }
+ } else {
+ if (this._onFinishedMotion) {
+ this._onFinishedMotion(this);
+ }
+ motionQueueEntry.setIsFinished(true);
+ }
+ }
+ this._lastWeight = fadeWeight;
+ }
+ setIsLoop(loop) {
+ this._isLoop = loop;
+ }
+ isLoop() {
+ return this._isLoop;
+ }
+ setIsLoopFadeIn(loopFadeIn) {
+ this._isLoopFadeIn = loopFadeIn;
+ }
+ isLoopFadeIn() {
+ return this._isLoopFadeIn;
+ }
+ getDuration() {
+ return this._isLoop ? -1 : this._loopDurationSeconds;
+ }
+ getLoopDuration() {
+ return this._loopDurationSeconds;
+ }
+ setParameterFadeInTime(parameterId, value) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ curves[i].fadeInTime = value;
+ return;
+ }
+ }
+ }
+ setParameterFadeOutTime(parameterId, value) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ curves[i].fadeOutTime = value;
+ return;
+ }
+ }
+ }
+ getParameterFadeInTime(parameterId) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ return curves[i].fadeInTime;
+ }
+ }
+ return -1;
+ }
+ getParameterFadeOutTime(parameterId) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ return curves[i].fadeOutTime;
+ }
+ }
+ return -1;
+ }
+ setEffectIds(eyeBlinkParameterIds, lipSyncParameterIds) {
+ this._eyeBlinkParameterIds = eyeBlinkParameterIds;
+ this._lipSyncParameterIds = lipSyncParameterIds;
+ }
+ release() {
+ this._motionData = void 0;
+ }
+ parse(motionJson) {
+ this._motionData = new CubismMotionData();
+ const json = new CubismMotionJson(motionJson);
+ this._motionData.duration = json.getMotionDuration();
+ this._motionData.loop = json.isMotionLoop();
+ this._motionData.curveCount = json.getMotionCurveCount();
+ this._motionData.fps = json.getMotionFps();
+ this._motionData.eventCount = json.getEventCount();
+ const areBeziersRestructed = json.getEvaluationOptionFlag(EvaluationOptionFlag.EvaluationOptionFlag_AreBeziersRistricted);
+ const fadeInSeconds = json.getMotionFadeInTime();
+ const fadeOutSeconds = json.getMotionFadeOutTime();
+ if (fadeInSeconds !== void 0) {
+ this._fadeInSeconds = fadeInSeconds < 0 ? 1 : fadeInSeconds;
+ } else {
+ this._fadeInSeconds = 1;
+ }
+ if (fadeOutSeconds !== void 0) {
+ this._fadeOutSeconds = fadeOutSeconds < 0 ? 1 : fadeOutSeconds;
+ } else {
+ this._fadeOutSeconds = 1;
+ }
+ this._motionData.curves = Array.from({
+ length: this._motionData.curveCount
+ }).map(() => new CubismMotionCurve());
+ this._motionData.segments = Array.from({
+ length: json.getMotionTotalSegmentCount()
+ }).map(() => new CubismMotionSegment());
+ this._motionData.events = Array.from({
+ length: this._motionData.eventCount
+ }).map(() => new CubismMotionEvent());
+ this._motionData.points = [];
+ let totalPointCount = 0;
+ let totalSegmentCount = 0;
+ for (let curveCount = 0; curveCount < this._motionData.curveCount; ++curveCount) {
+ const curve = this._motionData.curves[curveCount];
+ switch (json.getMotionCurveTarget(curveCount)) {
+ case TargetNameModel:
+ curve.type = CubismMotionCurveTarget.CubismMotionCurveTarget_Model;
+ break;
+ case TargetNameParameter:
+ curve.type = CubismMotionCurveTarget.CubismMotionCurveTarget_Parameter;
+ break;
+ case TargetNamePartOpacity:
+ curve.type = CubismMotionCurveTarget.CubismMotionCurveTarget_PartOpacity;
+ break;
+ default:
+ CubismLogWarning('Warning : Unable to get segment type from Curve! The number of "CurveCount" may be incorrect!');
+ }
+ curve.id = json.getMotionCurveId(curveCount);
+ curve.baseSegmentIndex = totalSegmentCount;
+ const fadeInTime = json.getMotionCurveFadeInTime(curveCount);
+ const fadeOutTime = json.getMotionCurveFadeOutTime(curveCount);
+ curve.fadeInTime = fadeInTime !== void 0 ? fadeInTime : -1;
+ curve.fadeOutTime = fadeOutTime !== void 0 ? fadeOutTime : -1;
+ for (let segmentPosition = 0; segmentPosition < json.getMotionCurveSegmentCount(curveCount); ) {
+ if (segmentPosition == 0) {
+ this._motionData.segments[totalSegmentCount].basePointIndex = totalPointCount;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition), json.getMotionCurveSegment(curveCount, segmentPosition + 1));
+ totalPointCount += 1;
+ segmentPosition += 2;
+ } else {
+ this._motionData.segments[totalSegmentCount].basePointIndex = totalPointCount - 1;
+ }
+ const segment = json.getMotionCurveSegment(curveCount, segmentPosition);
+ switch (segment) {
+ case CubismMotionSegmentType.CubismMotionSegmentType_Linear: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Linear;
+ this._motionData.segments[totalSegmentCount].evaluate = linearEvaluate;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ totalPointCount += 1;
+ segmentPosition += 3;
+ break;
+ }
+ case CubismMotionSegmentType.CubismMotionSegmentType_Bezier: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Bezier;
+ if (areBeziersRestructed || UseOldBeziersCurveMotion) {
+ this._motionData.segments[totalSegmentCount].evaluate = bezierEvaluate;
+ } else {
+ this._motionData.segments[totalSegmentCount].evaluate = bezierEvaluateCardanoInterpretation;
+ }
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ this._motionData.points[totalPointCount + 1] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 3), json.getMotionCurveSegment(curveCount, segmentPosition + 4));
+ this._motionData.points[totalPointCount + 2] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 5), json.getMotionCurveSegment(curveCount, segmentPosition + 6));
+ totalPointCount += 3;
+ segmentPosition += 7;
+ break;
+ }
+ case CubismMotionSegmentType.CubismMotionSegmentType_Stepped: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Stepped;
+ this._motionData.segments[totalSegmentCount].evaluate = steppedEvaluate;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ totalPointCount += 1;
+ segmentPosition += 3;
+ break;
+ }
+ case CubismMotionSegmentType.CubismMotionSegmentType_InverseStepped: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_InverseStepped;
+ this._motionData.segments[totalSegmentCount].evaluate = inverseSteppedEvaluate;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ totalPointCount += 1;
+ segmentPosition += 3;
+ break;
+ }
+ }
+ ++curve.segmentCount;
+ ++totalSegmentCount;
+ }
+ this._motionData.curves.push(curve);
+ }
+ for (let userdatacount = 0; userdatacount < json.getEventCount(); ++userdatacount) {
+ this._motionData.events[userdatacount].fireTime = json.getEventTime(userdatacount);
+ this._motionData.events[userdatacount].value = json.getEventValue(userdatacount);
+ }
+ json.release();
+ }
+ getFiredEvent(beforeCheckTimeSeconds, motionTimeSeconds) {
+ this._firedEventValues.length = 0;
+ for (let u = 0; u < this._motionData.eventCount; ++u) {
+ if (this._motionData.events[u].fireTime > beforeCheckTimeSeconds && this._motionData.events[u].fireTime <= motionTimeSeconds) {
+ this._firedEventValues.push(this._motionData.events[u].value);
+ }
+ }
+ return this._firedEventValues;
+ }
+ isExistModelOpacity() {
+ for (let i = 0; i < this._motionData.curveCount; i++) {
+ const curve = this._motionData.curves[i];
+ if (curve.type != CubismMotionCurveTarget.CubismMotionCurveTarget_Model) {
+ continue;
+ }
+ if (curve.id === IdNameOpacity) {
+ return true;
+ }
+ }
+ return false;
+ }
+ getModelOpacityIndex() {
+ if (this.isExistModelOpacity()) {
+ for (let i = 0; i < this._motionData.curveCount; i++) {
+ const curve = this._motionData.curves[i];
+ if (curve.type != CubismMotionCurveTarget.CubismMotionCurveTarget_Model) {
+ continue;
+ }
+ if (curve.id === IdNameOpacity) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+ getModelOpacityId(index) {
+ if (index != -1) {
+ const curve = this._motionData.curves[index];
+ if (curve.type == CubismMotionCurveTarget.CubismMotionCurveTarget_Model) {
+ if (curve.id === IdNameOpacity) {
+ return curve.id;
+ }
+ }
+ }
+ return void 0;
+ }
+ getModelOpacityValue() {
+ return this._modelOpacity;
+ }
+}
+class Cubism4MotionManager extends MotionManager {
+ constructor(settings, options) {
+ var _a;
+ super(settings, options);
+ this.groups = { idle: "Idle" };
+ this.motionDataType = "json";
+ this.queueManager = new CubismMotionQueueManager();
+ this.definitions = (_a = settings.motions) != null ? _a : {};
+ this.eyeBlinkIds = settings.getEyeBlinkParameters() || [];
+ this.lipSyncIds = settings.getLipSyncParameters() || [];
+ this.init(options);
+ }
+ init(options) {
+ super.init(options);
+ if (this.settings.expressions) {
+ this.expressionManager = new Cubism4ExpressionManager(this.settings, options);
+ }
+ this.queueManager.setEventCallback((caller, eventValue, customData) => {
+ this.emit("motion:" + eventValue);
+ });
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ _startMotion(motion, onFinish) {
+ motion.setFinishedMotionHandler(onFinish);
+ this.queueManager.stopAllMotions();
+ return this.queueManager.startMotion(motion, false, performance.now());
+ }
+ _stopAllMotions() {
+ this.queueManager.stopAllMotions();
+ }
+ createMotion(data, group, definition) {
+ const motion = CubismMotion.create(data);
+ const json = new CubismMotionJson(data);
+ const defaultFadingDuration = (group === this.groups.idle ? config.idleMotionFadingDuration : config.motionFadingDuration) / 1e3;
+ if (json.getMotionFadeInTime() === void 0) {
+ motion.setFadeInTime(definition.FadeInTime > 0 ? definition.FadeInTime : defaultFadingDuration);
+ }
+ if (json.getMotionFadeOutTime() === void 0) {
+ motion.setFadeOutTime(definition.FadeOutTime > 0 ? definition.FadeOutTime : defaultFadingDuration);
+ }
+ motion.setEffectIds(this.eyeBlinkIds, this.lipSyncIds);
+ return motion;
+ }
+ getMotionFile(definition) {
+ return definition.File;
+ }
+ getMotionName(definition) {
+ return definition.File;
+ }
+ getSoundFile(definition) {
+ return definition.Sound;
+ }
+ updateParameters(model, now) {
+ return this.queueManager.doUpdateMotion(model, now);
+ }
+ destroy() {
+ super.destroy();
+ this.queueManager.release();
+ this.queueManager = void 0;
+ }
+}
+const ParamAngleX = "ParamAngleX";
+const ParamAngleY = "ParamAngleY";
+const ParamAngleZ = "ParamAngleZ";
+const ParamEyeBallX = "ParamEyeBallX";
+const ParamEyeBallY = "ParamEyeBallY";
+const ParamBodyAngleX = "ParamBodyAngleX";
+const ParamBreath = "ParamBreath";
+class CubismBreath {
+ constructor() {
+ this._breathParameters = [];
+ this._currentTime = 0;
+ }
+ static create() {
+ return new CubismBreath();
+ }
+ setParameters(breathParameters) {
+ this._breathParameters = breathParameters;
+ }
+ getParameters() {
+ return this._breathParameters;
+ }
+ updateParameters(model, deltaTimeSeconds) {
+ this._currentTime += deltaTimeSeconds;
+ const t = this._currentTime * 2 * 3.14159;
+ for (let i = 0; i < this._breathParameters.length; ++i) {
+ const data = this._breathParameters[i];
+ model.addParameterValueById(data.parameterId, data.offset + data.peak * Math.sin(t / data.cycle), data.weight);
+ }
+ }
+}
+class BreathParameterData {
+ constructor(parameterId, offset, peak, cycle, weight) {
+ this.parameterId = parameterId == void 0 ? void 0 : parameterId;
+ this.offset = offset == void 0 ? 0 : offset;
+ this.peak = peak == void 0 ? 0 : peak;
+ this.cycle = cycle == void 0 ? 0 : cycle;
+ this.weight = weight == void 0 ? 0 : weight;
+ }
+}
+const _CubismEyeBlink = class {
+ static create(modelSetting) {
+ return new _CubismEyeBlink(modelSetting);
+ }
+ setBlinkingInterval(blinkingInterval) {
+ this._blinkingIntervalSeconds = blinkingInterval;
+ }
+ setBlinkingSetting(closing, closed, opening) {
+ this._closingSeconds = closing;
+ this._closedSeconds = closed;
+ this._openingSeconds = opening;
+ }
+ setParameterIds(parameterIds) {
+ this._parameterIds = parameterIds;
+ }
+ getParameterIds() {
+ return this._parameterIds;
+ }
+ updateParameters(model, deltaTimeSeconds) {
+ this._userTimeSeconds += deltaTimeSeconds;
+ let parameterValue;
+ let t = 0;
+ switch (this._blinkingState) {
+ case EyeState.EyeState_Closing:
+ t = (this._userTimeSeconds - this._stateStartTimeSeconds) / this._closingSeconds;
+ if (t >= 1) {
+ t = 1;
+ this._blinkingState = EyeState.EyeState_Closed;
+ this._stateStartTimeSeconds = this._userTimeSeconds;
+ }
+ parameterValue = 1 - t;
+ break;
+ case EyeState.EyeState_Closed:
+ t = (this._userTimeSeconds - this._stateStartTimeSeconds) / this._closedSeconds;
+ if (t >= 1) {
+ this._blinkingState = EyeState.EyeState_Opening;
+ this._stateStartTimeSeconds = this._userTimeSeconds;
+ }
+ parameterValue = 0;
+ break;
+ case EyeState.EyeState_Opening:
+ t = (this._userTimeSeconds - this._stateStartTimeSeconds) / this._openingSeconds;
+ if (t >= 1) {
+ t = 1;
+ this._blinkingState = EyeState.EyeState_Interval;
+ this._nextBlinkingTime = this.determinNextBlinkingTiming();
+ }
+ parameterValue = t;
+ break;
+ case EyeState.EyeState_Interval:
+ if (this._nextBlinkingTime < this._userTimeSeconds) {
+ this._blinkingState = EyeState.EyeState_Closing;
+ this._stateStartTimeSeconds = this._userTimeSeconds;
+ }
+ parameterValue = 1;
+ break;
+ case EyeState.EyeState_First:
+ default:
+ this._blinkingState = EyeState.EyeState_Interval;
+ this._nextBlinkingTime = this.determinNextBlinkingTiming();
+ parameterValue = 1;
+ break;
+ }
+ if (!_CubismEyeBlink.CloseIfZero) {
+ parameterValue = -parameterValue;
+ }
+ for (let i = 0; i < this._parameterIds.length; ++i) {
+ model.setParameterValueById(this._parameterIds[i], parameterValue);
+ }
+ }
+ constructor(modelSetting) {
+ var _a, _b;
+ this._blinkingState = EyeState.EyeState_First;
+ this._nextBlinkingTime = 0;
+ this._stateStartTimeSeconds = 0;
+ this._blinkingIntervalSeconds = 4;
+ this._closingSeconds = 0.1;
+ this._closedSeconds = 0.05;
+ this._openingSeconds = 0.15;
+ this._userTimeSeconds = 0;
+ this._parameterIds = [];
+ if (modelSetting == null) {
+ return;
+ }
+ this._parameterIds = (_b = (_a = modelSetting.getEyeBlinkParameters()) == null ? void 0 : _a.slice()) != null ? _b : this._parameterIds;
+ }
+ determinNextBlinkingTiming() {
+ const r = Math.random();
+ return this._userTimeSeconds + r * (2 * this._blinkingIntervalSeconds - 1);
+ }
+};
+let CubismEyeBlink = _CubismEyeBlink;
+CubismEyeBlink.CloseIfZero = true;
+var EyeState = /* @__PURE__ */ ((EyeState2) => {
+ EyeState2[EyeState2["EyeState_First"] = 0] = "EyeState_First";
+ EyeState2[EyeState2["EyeState_Interval"] = 1] = "EyeState_Interval";
+ EyeState2[EyeState2["EyeState_Closing"] = 2] = "EyeState_Closing";
+ EyeState2[EyeState2["EyeState_Closed"] = 3] = "EyeState_Closed";
+ EyeState2[EyeState2["EyeState_Opening"] = 4] = "EyeState_Opening";
+ return EyeState2;
+})(EyeState || {});
+class csmRect {
+ constructor(x = 0, y = 0, w = 0, h = 0) {
+ this.x = x;
+ this.y = y;
+ this.width = w;
+ this.height = h;
+ }
+ getCenterX() {
+ return this.x + 0.5 * this.width;
+ }
+ getCenterY() {
+ return this.y + 0.5 * this.height;
+ }
+ getRight() {
+ return this.x + this.width;
+ }
+ getBottom() {
+ return this.y + this.height;
+ }
+ setRect(r) {
+ this.x = r.x;
+ this.y = r.y;
+ this.width = r.width;
+ this.height = r.height;
+ }
+ expand(w, h) {
+ this.x -= w;
+ this.y -= h;
+ this.width += w * 2;
+ this.height += h * 2;
+ }
+}
+const ColorChannelCount = 4;
+const ClippingMaskMaxCountOnDefault = 36;
+const ClippingMaskMaxCountOnMultiRenderTexture = 32;
+const ShaderCount = 10;
+let s_instance;
+let s_viewport;
+let s_fbo;
+class CubismClippingManager_WebGL {
+ getChannelFlagAsColor(channelNo) {
+ return this._channelColors[channelNo];
+ }
+ getMaskRenderTexture() {
+ if (this._maskTexture && this._maskTexture.textures != null) {
+ this._maskTexture.frameNo = this._currentFrameNo;
+ } else {
+ this._maskRenderTextures = [];
+ this._maskColorBuffers = [];
+ const size = this._clippingMaskBufferSize;
+ for (let index = 0; index < this._renderTextureCount; index++) {
+ this._maskColorBuffers.push(this.gl.createTexture());
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this._maskColorBuffers[index]);
+ this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, size, size, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, null);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, null);
+ this._maskRenderTextures.push(this.gl.createFramebuffer());
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this._maskRenderTextures[index]);
+ this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, this._maskColorBuffers[index], 0);
+ }
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, s_fbo);
+ this._maskTexture = new CubismRenderTextureResource(this._currentFrameNo, this._maskRenderTextures);
+ }
+ return this._maskTexture.textures;
+ }
+ setGL(gl) {
+ this.gl = gl;
+ }
+ calcClippedDrawTotalBounds(model, clippingContext) {
+ let clippedDrawTotalMinX = Number.MAX_VALUE;
+ let clippedDrawTotalMinY = Number.MAX_VALUE;
+ let clippedDrawTotalMaxX = Number.MIN_VALUE;
+ let clippedDrawTotalMaxY = Number.MIN_VALUE;
+ const clippedDrawCount = clippingContext._clippedDrawableIndexList.length;
+ for (let clippedDrawableIndex = 0; clippedDrawableIndex < clippedDrawCount; clippedDrawableIndex++) {
+ const drawableIndex = clippingContext._clippedDrawableIndexList[clippedDrawableIndex];
+ const drawableVertexCount = model.getDrawableVertexCount(drawableIndex);
+ const drawableVertexes = model.getDrawableVertices(drawableIndex);
+ let minX = Number.MAX_VALUE;
+ let minY = Number.MAX_VALUE;
+ let maxX = -Number.MAX_VALUE;
+ let maxY = -Number.MAX_VALUE;
+ const loop = drawableVertexCount * Constant.vertexStep;
+ for (let pi = Constant.vertexOffset; pi < loop; pi += Constant.vertexStep) {
+ const x = drawableVertexes[pi];
+ const y = drawableVertexes[pi + 1];
+ if (x < minX) {
+ minX = x;
+ }
+ if (x > maxX) {
+ maxX = x;
+ }
+ if (y < minY) {
+ minY = y;
+ }
+ if (y > maxY) {
+ maxY = y;
+ }
+ }
+ if (minX == Number.MAX_VALUE) {
+ continue;
+ }
+ if (minX < clippedDrawTotalMinX) {
+ clippedDrawTotalMinX = minX;
+ }
+ if (minY < clippedDrawTotalMinY) {
+ clippedDrawTotalMinY = minY;
+ }
+ if (maxX > clippedDrawTotalMaxX) {
+ clippedDrawTotalMaxX = maxX;
+ }
+ if (maxY > clippedDrawTotalMaxY) {
+ clippedDrawTotalMaxY = maxY;
+ }
+ if (clippedDrawTotalMinX == Number.MAX_VALUE) {
+ clippingContext._allClippedDrawRect.x = 0;
+ clippingContext._allClippedDrawRect.y = 0;
+ clippingContext._allClippedDrawRect.width = 0;
+ clippingContext._allClippedDrawRect.height = 0;
+ clippingContext._isUsing = false;
+ } else {
+ clippingContext._isUsing = true;
+ const w = clippedDrawTotalMaxX - clippedDrawTotalMinX;
+ const h = clippedDrawTotalMaxY - clippedDrawTotalMinY;
+ clippingContext._allClippedDrawRect.x = clippedDrawTotalMinX;
+ clippingContext._allClippedDrawRect.y = clippedDrawTotalMinY;
+ clippingContext._allClippedDrawRect.width = w;
+ clippingContext._allClippedDrawRect.height = h;
+ }
+ }
+ }
+ constructor() {
+ this._currentMaskRenderTexture = null;
+ this._currentFrameNo = 0;
+ this._renderTextureCount = 0;
+ this._clippingMaskBufferSize = 256;
+ this._clippingContextListForMask = [];
+ this._clippingContextListForDraw = [];
+ this._channelColors = [];
+ this._tmpBoundsOnModel = new csmRect();
+ this._tmpMatrix = new CubismMatrix44();
+ this._tmpMatrixForMask = new CubismMatrix44();
+ this._tmpMatrixForDraw = new CubismMatrix44();
+ let tmp = new CubismTextureColor();
+ tmp.R = 1;
+ tmp.G = 0;
+ tmp.B = 0;
+ tmp.A = 0;
+ this._channelColors.push(tmp);
+ tmp = new CubismTextureColor();
+ tmp.R = 0;
+ tmp.G = 1;
+ tmp.B = 0;
+ tmp.A = 0;
+ this._channelColors.push(tmp);
+ tmp = new CubismTextureColor();
+ tmp.R = 0;
+ tmp.G = 0;
+ tmp.B = 1;
+ tmp.A = 0;
+ this._channelColors.push(tmp);
+ tmp = new CubismTextureColor();
+ tmp.R = 0;
+ tmp.G = 0;
+ tmp.B = 0;
+ tmp.A = 1;
+ this._channelColors.push(tmp);
+ }
+ release() {
+ var _a;
+ const self = this;
+ for (let i = 0; i < this._clippingContextListForMask.length; i++) {
+ if (this._clippingContextListForMask[i]) {
+ (_a = this._clippingContextListForMask[i]) == null ? void 0 : _a.release();
+ }
+ }
+ self._clippingContextListForMask = void 0;
+ self._clippingContextListForDraw = void 0;
+ if (this._maskTexture) {
+ for (let i = 0; i < this._maskTexture.textures.length; i++) {
+ this.gl.deleteFramebuffer(this._maskTexture.textures[i]);
+ }
+ this._maskTexture = void 0;
+ }
+ self._channelColors = void 0;
+ if (this._maskColorBuffers) {
+ for (let index = 0; index < this._maskColorBuffers.length; index++) {
+ this.gl.deleteTexture(this._maskColorBuffers[index]);
+ }
+ }
+ this._maskColorBuffers = void 0;
+ this._maskRenderTextures = void 0;
+ this._clearedFrameBufferflags = void 0;
+ }
+ initialize(model, drawableCount, drawableMasks, drawableMaskCounts, renderTextureCount) {
+ if (renderTextureCount % 1 != 0) {
+ CubismLogWarning("The number of render textures must be specified as an integer. The decimal point is rounded down and corrected to an integer.");
+ renderTextureCount = ~~renderTextureCount;
+ }
+ if (renderTextureCount < 1) {
+ CubismLogWarning("The number of render textures must be an integer greater than or equal to 1. Set the number of render textures to 1.");
+ }
+ this._renderTextureCount = renderTextureCount < 1 ? 1 : renderTextureCount;
+ this._clearedFrameBufferflags = [];
+ for (let i = 0; i < drawableCount; i++) {
+ if (drawableMaskCounts[i] <= 0) {
+ this._clippingContextListForDraw.push(null);
+ continue;
+ }
+ let clippingContext = this.findSameClip(drawableMasks[i], drawableMaskCounts[i]);
+ if (clippingContext == null) {
+ clippingContext = new CubismClippingContext(this, drawableMasks[i], drawableMaskCounts[i]);
+ this._clippingContextListForMask.push(clippingContext);
+ }
+ clippingContext.addClippedDrawable(i);
+ this._clippingContextListForDraw.push(clippingContext);
+ }
+ }
+ setupClippingContext(model, renderer) {
+ this._currentFrameNo++;
+ let usingClipCount = 0;
+ for (let clipIndex = 0; clipIndex < this._clippingContextListForMask.length; clipIndex++) {
+ const cc = this._clippingContextListForMask[clipIndex];
+ this.calcClippedDrawTotalBounds(model, cc);
+ if (cc._isUsing) {
+ usingClipCount++;
+ }
+ }
+ if (usingClipCount > 0) {
+ this.setupLayoutBounds(renderer.isUsingHighPrecisionMask() ? 0 : usingClipCount);
+ if (!renderer.isUsingHighPrecisionMask()) {
+ this.gl.viewport(0, 0, this._clippingMaskBufferSize, this._clippingMaskBufferSize);
+ this._currentMaskRenderTexture = this.getMaskRenderTexture()[0];
+ renderer.preDraw();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this._currentMaskRenderTexture);
+ }
+ if (!this._clearedFrameBufferflags) {
+ this._clearedFrameBufferflags = [];
+ }
+ for (let index = 0; index < this._renderTextureCount; index++) {
+ this._clearedFrameBufferflags[index] = false;
+ }
+ for (let clipIndex = 0; clipIndex < this._clippingContextListForMask.length; clipIndex++) {
+ const clipContext = this._clippingContextListForMask[clipIndex];
+ const allClipedDrawRect = clipContext._allClippedDrawRect;
+ const layoutBoundsOnTex01 = clipContext._layoutBounds;
+ const MARGIN = 0.05;
+ let scaleX = 0;
+ let scaleY = 0;
+ const clipContextRenderTexture = this.getMaskRenderTexture()[clipContext._bufferIndex];
+ if (this._currentMaskRenderTexture != clipContextRenderTexture && !renderer.isUsingHighPrecisionMask()) {
+ this._currentMaskRenderTexture = clipContextRenderTexture;
+ renderer.preDraw();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this._currentMaskRenderTexture);
+ }
+ if (renderer.isUsingHighPrecisionMask()) {
+ const ppu = model.getPixelsPerUnit();
+ const maskPixelSize = clipContext.getClippingManager()._clippingMaskBufferSize;
+ const physicalMaskWidth = layoutBoundsOnTex01.width * maskPixelSize;
+ const physicalMaskHeight = layoutBoundsOnTex01.height * maskPixelSize;
+ this._tmpBoundsOnModel.setRect(allClipedDrawRect);
+ if (this._tmpBoundsOnModel.width * ppu > physicalMaskWidth) {
+ this._tmpBoundsOnModel.expand(allClipedDrawRect.width * MARGIN, 0);
+ scaleX = layoutBoundsOnTex01.width / this._tmpBoundsOnModel.width;
+ } else {
+ scaleX = ppu / physicalMaskWidth;
+ }
+ if (this._tmpBoundsOnModel.height * ppu > physicalMaskHeight) {
+ this._tmpBoundsOnModel.expand(0, allClipedDrawRect.height * MARGIN);
+ scaleY = layoutBoundsOnTex01.height / this._tmpBoundsOnModel.height;
+ } else {
+ scaleY = ppu / physicalMaskHeight;
+ }
+ } else {
+ this._tmpBoundsOnModel.setRect(allClipedDrawRect);
+ this._tmpBoundsOnModel.expand(allClipedDrawRect.width * MARGIN, allClipedDrawRect.height * MARGIN);
+ scaleX = layoutBoundsOnTex01.width / this._tmpBoundsOnModel.width;
+ scaleY = layoutBoundsOnTex01.height / this._tmpBoundsOnModel.height;
+ }
+ {
+ this._tmpMatrix.loadIdentity();
+ {
+ this._tmpMatrix.translateRelative(-1, -1);
+ this._tmpMatrix.scaleRelative(2, 2);
+ }
+ {
+ this._tmpMatrix.translateRelative(layoutBoundsOnTex01.x, layoutBoundsOnTex01.y);
+ this._tmpMatrix.scaleRelative(scaleX, scaleY);
+ this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x, -this._tmpBoundsOnModel.y);
+ }
+ this._tmpMatrixForMask.setMatrix(this._tmpMatrix.getArray());
+ }
+ {
+ this._tmpMatrix.loadIdentity();
+ {
+ this._tmpMatrix.translateRelative(layoutBoundsOnTex01.x, layoutBoundsOnTex01.y);
+ this._tmpMatrix.scaleRelative(scaleX, scaleY);
+ this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x, -this._tmpBoundsOnModel.y);
+ }
+ this._tmpMatrixForDraw.setMatrix(this._tmpMatrix.getArray());
+ }
+ clipContext._matrixForMask.setMatrix(this._tmpMatrixForMask.getArray());
+ clipContext._matrixForDraw.setMatrix(this._tmpMatrixForDraw.getArray());
+ if (!renderer.isUsingHighPrecisionMask()) {
+ const clipDrawCount = clipContext._clippingIdCount;
+ for (let i = 0; i < clipDrawCount; i++) {
+ const clipDrawIndex = clipContext._clippingIdList[i];
+ if (!model.getDrawableDynamicFlagVertexPositionsDidChange(clipDrawIndex)) {
+ continue;
+ }
+ renderer.setIsCulling(model.getDrawableCulling(clipDrawIndex) != false);
+ if (!this._clearedFrameBufferflags[clipContext._bufferIndex]) {
+ this.gl.clearColor(1, 1, 1, 1);
+ this.gl.clear(this.gl.COLOR_BUFFER_BIT);
+ this._clearedFrameBufferflags[clipContext._bufferIndex] = true;
+ }
+ renderer.setClippingContextBufferForMask(clipContext);
+ renderer.drawMesh(model.getDrawableTextureIndex(clipDrawIndex), model.getDrawableVertexIndexCount(clipDrawIndex), model.getDrawableVertexCount(clipDrawIndex), model.getDrawableVertexIndices(clipDrawIndex), model.getDrawableVertices(clipDrawIndex), model.getDrawableVertexUvs(clipDrawIndex), model.getMultiplyColor(clipDrawIndex), model.getScreenColor(clipDrawIndex), model.getDrawableOpacity(clipDrawIndex), CubismBlendMode.CubismBlendMode_Normal, false);
+ }
+ }
+ }
+ if (!renderer.isUsingHighPrecisionMask()) {
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, s_fbo);
+ renderer.setClippingContextBufferForMask(null);
+ this.gl.viewport(s_viewport[0], s_viewport[1], s_viewport[2], s_viewport[3]);
+ }
+ }
+ }
+ findSameClip(drawableMasks, drawableMaskCounts) {
+ for (let i = 0; i < this._clippingContextListForMask.length; i++) {
+ const clippingContext = this._clippingContextListForMask[i];
+ const count = clippingContext._clippingIdCount;
+ if (count != drawableMaskCounts) {
+ continue;
+ }
+ let sameCount = 0;
+ for (let j = 0; j < count; j++) {
+ const clipId = clippingContext._clippingIdList[j];
+ for (let k = 0; k < count; k++) {
+ if (drawableMasks[k] == clipId) {
+ sameCount++;
+ break;
+ }
+ }
+ }
+ if (sameCount == count) {
+ return clippingContext;
+ }
+ }
+ return null;
+ }
+ setupLayoutBounds(usingClipCount) {
+ const useClippingMaskMaxCount = this._renderTextureCount <= 1 ? ClippingMaskMaxCountOnDefault : ClippingMaskMaxCountOnMultiRenderTexture * this._renderTextureCount;
+ if (usingClipCount <= 0 || usingClipCount > useClippingMaskMaxCount) {
+ if (usingClipCount > useClippingMaskMaxCount) {
+ CubismLogError("not supported mask count : {0}\n[Details] render texture count : {1}, mask count : {2}", usingClipCount - useClippingMaskMaxCount, this._renderTextureCount, usingClipCount);
+ }
+ for (let index = 0; index < this._clippingContextListForMask.length; index++) {
+ const clipContext = this._clippingContextListForMask[index];
+ clipContext._layoutChannelNo = 0;
+ clipContext._layoutBounds.x = 0;
+ clipContext._layoutBounds.y = 0;
+ clipContext._layoutBounds.width = 1;
+ clipContext._layoutBounds.height = 1;
+ clipContext._bufferIndex = 0;
+ }
+ return;
+ }
+ const layoutCountMaxValue = this._renderTextureCount <= 1 ? 9 : 8;
+ let countPerSheetDiv = usingClipCount / this._renderTextureCount;
+ let countPerSheetMod = usingClipCount % this._renderTextureCount;
+ countPerSheetDiv = ~~countPerSheetDiv;
+ countPerSheetMod = ~~countPerSheetMod;
+ let div = countPerSheetDiv / ColorChannelCount;
+ let mod = countPerSheetDiv % ColorChannelCount;
+ div = ~~div;
+ mod = ~~mod;
+ let curClipIndex = 0;
+ for (let renderTextureNo = 0; renderTextureNo < this._renderTextureCount; renderTextureNo++) {
+ for (let channelNo = 0; channelNo < ColorChannelCount; channelNo++) {
+ let layoutCount = div + (channelNo < mod ? 1 : 0);
+ const checkChannelNo = mod + 1 >= ColorChannelCount ? 0 : mod + 1;
+ if (layoutCount < layoutCountMaxValue && channelNo == checkChannelNo) {
+ layoutCount += renderTextureNo < countPerSheetMod ? 1 : 0;
+ }
+ if (layoutCount == 0)
+ ;
+ else if (layoutCount == 1) {
+ const clipContext = this._clippingContextListForMask[curClipIndex++];
+ clipContext._layoutChannelNo = channelNo;
+ clipContext._layoutBounds.x = 0;
+ clipContext._layoutBounds.y = 0;
+ clipContext._layoutBounds.width = 1;
+ clipContext._layoutBounds.height = 1;
+ clipContext._bufferIndex = renderTextureNo;
+ } else if (layoutCount == 2) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 2;
+ xpos = ~~xpos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos * 0.5;
+ cc._layoutBounds.y = 0;
+ cc._layoutBounds.width = 0.5;
+ cc._layoutBounds.height = 1;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else if (layoutCount <= 4) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 2;
+ let ypos = i / 2;
+ xpos = ~~xpos;
+ ypos = ~~ypos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos * 0.5;
+ cc._layoutBounds.y = ypos * 0.5;
+ cc._layoutBounds.width = 0.5;
+ cc._layoutBounds.height = 0.5;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else if (layoutCount <= layoutCountMaxValue) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 3;
+ let ypos = i / 3;
+ xpos = ~~xpos;
+ ypos = ~~ypos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos / 3;
+ cc._layoutBounds.y = ypos / 3;
+ cc._layoutBounds.width = 1 / 3;
+ cc._layoutBounds.height = 1 / 3;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else if (CubismConfig.supportMoreMaskDivisions && layoutCount <= 16) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 4;
+ let ypos = i / 4;
+ xpos = ~~xpos;
+ ypos = ~~ypos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos / 4;
+ cc._layoutBounds.y = ypos / 4;
+ cc._layoutBounds.width = 1 / 4;
+ cc._layoutBounds.height = 1 / 4;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else {
+ CubismLogError("not supported mask count : {0}\n[Details] render texture count : {1}, mask count : {2}", usingClipCount - useClippingMaskMaxCount, this._renderTextureCount, usingClipCount);
+ for (let index = 0; index < layoutCount; index++) {
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = 0;
+ cc._layoutBounds.x = 0;
+ cc._layoutBounds.y = 0;
+ cc._layoutBounds.width = 1;
+ cc._layoutBounds.height = 1;
+ cc._bufferIndex = 0;
+ }
+ }
+ }
+ }
+ }
+ getColorBuffer() {
+ return this._maskColorBuffers;
+ }
+ getClippingContextListForDraw() {
+ return this._clippingContextListForDraw;
+ }
+ getClippingMaskCount() {
+ return this._clippingContextListForMask.length;
+ }
+ setClippingMaskBufferSize(size) {
+ this._clippingMaskBufferSize = size;
+ }
+ getClippingMaskBufferSize() {
+ return this._clippingMaskBufferSize;
+ }
+ getRenderTextureCount() {
+ return this._renderTextureCount;
+ }
+}
+class CubismRenderTextureResource {
+ constructor(frameNo, texture) {
+ this.frameNo = frameNo;
+ this.textures = texture;
+ }
+}
+class CubismClippingContext {
+ constructor(manager, clippingDrawableIndices, clipCount) {
+ this._isUsing = false;
+ this._owner = manager;
+ this._clippingIdList = clippingDrawableIndices;
+ this._clippingIdCount = clipCount;
+ this._allClippedDrawRect = new csmRect();
+ this._layoutBounds = new csmRect();
+ this._clippedDrawableIndexList = [];
+ this._matrixForMask = new CubismMatrix44();
+ this._matrixForDraw = new CubismMatrix44();
+ this._bufferIndex = 0;
+ }
+ release() {
+ const self = this;
+ self._layoutBounds = void 0;
+ self._allClippedDrawRect = void 0;
+ self._clippedDrawableIndexList = void 0;
+ }
+ addClippedDrawable(drawableIndex) {
+ this._clippedDrawableIndexList.push(drawableIndex);
+ }
+ getClippingManager() {
+ return this._owner;
+ }
+ setGl(gl) {
+ this._owner.setGL(gl);
+ }
+}
+class CubismRendererProfile_WebGL {
+ setGlEnable(index, enabled) {
+ if (enabled)
+ this.gl.enable(index);
+ else
+ this.gl.disable(index);
+ }
+ setGlEnableVertexAttribArray(index, enabled) {
+ if (enabled)
+ this.gl.enableVertexAttribArray(index);
+ else
+ this.gl.disableVertexAttribArray(index);
+ }
+ save() {
+ if (this.gl == null) {
+ CubismLogError("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");
+ return;
+ }
+ this._lastArrayBufferBinding = this.gl.getParameter(this.gl.ARRAY_BUFFER_BINDING);
+ this._lastArrayBufferBinding = this.gl.getParameter(this.gl.ELEMENT_ARRAY_BUFFER_BINDING);
+ this._lastProgram = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
+ this._lastActiveTexture = this.gl.getParameter(this.gl.ACTIVE_TEXTURE);
+ this.gl.activeTexture(this.gl.TEXTURE1);
+ this._lastTexture1Binding2D = this.gl.getParameter(this.gl.TEXTURE_BINDING_2D);
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this._lastTexture0Binding2D = this.gl.getParameter(this.gl.TEXTURE_BINDING_2D);
+ this._lastVertexAttribArrayEnabled[0] = this.gl.getVertexAttrib(0, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastVertexAttribArrayEnabled[1] = this.gl.getVertexAttrib(1, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastVertexAttribArrayEnabled[2] = this.gl.getVertexAttrib(2, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastVertexAttribArrayEnabled[3] = this.gl.getVertexAttrib(3, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastScissorTest = this.gl.isEnabled(this.gl.SCISSOR_TEST);
+ this._lastStencilTest = this.gl.isEnabled(this.gl.STENCIL_TEST);
+ this._lastDepthTest = this.gl.isEnabled(this.gl.DEPTH_TEST);
+ this._lastCullFace = this.gl.isEnabled(this.gl.CULL_FACE);
+ this._lastBlend = this.gl.isEnabled(this.gl.BLEND);
+ this._lastFrontFace = this.gl.getParameter(this.gl.FRONT_FACE);
+ this._lastColorMask = this.gl.getParameter(this.gl.COLOR_WRITEMASK);
+ this._lastBlending[0] = this.gl.getParameter(this.gl.BLEND_SRC_RGB);
+ this._lastBlending[1] = this.gl.getParameter(this.gl.BLEND_DST_RGB);
+ this._lastBlending[2] = this.gl.getParameter(this.gl.BLEND_SRC_ALPHA);
+ this._lastBlending[3] = this.gl.getParameter(this.gl.BLEND_DST_ALPHA);
+ this._lastFBO = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING);
+ this._lastViewport = this.gl.getParameter(this.gl.VIEWPORT);
+ }
+ restore() {
+ if (this.gl == null) {
+ CubismLogError("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");
+ return;
+ }
+ this.gl.useProgram(this._lastProgram);
+ this.setGlEnableVertexAttribArray(0, this._lastVertexAttribArrayEnabled[0]);
+ this.setGlEnableVertexAttribArray(1, this._lastVertexAttribArrayEnabled[1]);
+ this.setGlEnableVertexAttribArray(2, this._lastVertexAttribArrayEnabled[2]);
+ this.setGlEnableVertexAttribArray(3, this._lastVertexAttribArrayEnabled[3]);
+ this.setGlEnable(this.gl.SCISSOR_TEST, this._lastScissorTest);
+ this.setGlEnable(this.gl.STENCIL_TEST, this._lastStencilTest);
+ this.setGlEnable(this.gl.DEPTH_TEST, this._lastDepthTest);
+ this.setGlEnable(this.gl.CULL_FACE, this._lastCullFace);
+ this.setGlEnable(this.gl.BLEND, this._lastBlend);
+ this.gl.frontFace(this._lastFrontFace);
+ this.gl.colorMask(this._lastColorMask[0], this._lastColorMask[1], this._lastColorMask[2], this._lastColorMask[3]);
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this._lastArrayBufferBinding);
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this._lastElementArrayBufferBinding);
+ this.gl.activeTexture(this.gl.TEXTURE1);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this._lastTexture1Binding2D);
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this._lastTexture0Binding2D);
+ this.gl.activeTexture(this._lastActiveTexture);
+ this.gl.blendFuncSeparate(this._lastBlending[0], this._lastBlending[1], this._lastBlending[2], this._lastBlending[3]);
+ }
+ setGl(gl) {
+ this.gl = gl;
+ }
+ constructor() {
+ this._lastVertexAttribArrayEnabled = new Array(4);
+ this._lastColorMask = new Array(4);
+ this._lastBlending = new Array(4);
+ this._lastViewport = new Array(4);
+ }
+}
+class CubismShader_WebGL {
+ static getInstance() {
+ if (s_instance == null) {
+ s_instance = new CubismShader_WebGL();
+ return s_instance;
+ }
+ return s_instance;
+ }
+ static deleteInstance() {
+ if (s_instance) {
+ s_instance.release();
+ s_instance = void 0;
+ }
+ }
+ constructor() {
+ this._shaderSets = [];
+ }
+ release() {
+ this.releaseShaderProgram();
+ }
+ setupShaderProgram(renderer, textureId, vertexCount, vertexArray, indexArray, uvArray, bufferData, opacity, colorBlendMode, baseColor, multiplyColor, screenColor, isPremultipliedAlpha, matrix4x4, invertedMask) {
+ if (!isPremultipliedAlpha) {
+ CubismLogError("NoPremultipliedAlpha is not allowed");
+ }
+ if (this._shaderSets.length == 0) {
+ this.generateShaders();
+ }
+ let SRC_COLOR;
+ let DST_COLOR;
+ let SRC_ALPHA;
+ let DST_ALPHA;
+ const clippingContextBufferForMask = renderer.getClippingContextBufferForMask();
+ if (clippingContextBufferForMask != null) {
+ const shaderSet = this._shaderSets[ShaderNames.ShaderNames_SetupMask];
+ this.gl.useProgram(shaderSet.shaderProgram);
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, textureId);
+ this.gl.uniform1i(shaderSet.samplerTexture0Location, 0);
+ if (bufferData.vertex == null) {
+ bufferData.vertex = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.vertex);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, vertexArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributePositionLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributePositionLocation, 2, this.gl.FLOAT, false, 0, 0);
+ if (bufferData.uv == null) {
+ bufferData.uv = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.uv);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, uvArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributeTexCoordLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributeTexCoordLocation, 2, this.gl.FLOAT, false, 0, 0);
+ const channelNo = clippingContextBufferForMask._layoutChannelNo;
+ const colorChannel = clippingContextBufferForMask.getClippingManager().getChannelFlagAsColor(channelNo);
+ this.gl.uniform4f(shaderSet.uniformChannelFlagLocation, colorChannel.R, colorChannel.G, colorChannel.B, colorChannel.A);
+ this.gl.uniformMatrix4fv(shaderSet.uniformClipMatrixLocation, false, clippingContextBufferForMask._matrixForMask.getArray());
+ const rect = clippingContextBufferForMask._layoutBounds;
+ this.gl.uniform4f(shaderSet.uniformBaseColorLocation, rect.x * 2 - 1, rect.y * 2 - 1, rect.getRight() * 2 - 1, rect.getBottom() * 2 - 1);
+ this.gl.uniform4f(shaderSet.uniformMultiplyColorLocation, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A);
+ this.gl.uniform4f(shaderSet.uniformScreenColorLocation, screenColor.R, screenColor.G, screenColor.B, screenColor.A);
+ SRC_COLOR = this.gl.ZERO;
+ DST_COLOR = this.gl.ONE_MINUS_SRC_COLOR;
+ SRC_ALPHA = this.gl.ZERO;
+ DST_ALPHA = this.gl.ONE_MINUS_SRC_ALPHA;
+ } else {
+ const clippingContextBufferForDraw = renderer.getClippingContextBufferForDraw();
+ const masked = clippingContextBufferForDraw != null;
+ const offset = masked ? invertedMask ? 2 : 1 : 0;
+ let shaderSet;
+ switch (colorBlendMode) {
+ case CubismBlendMode.CubismBlendMode_Normal:
+ default:
+ shaderSet = this._shaderSets[ShaderNames.ShaderNames_NormalPremultipliedAlpha + offset];
+ SRC_COLOR = this.gl.ONE;
+ DST_COLOR = this.gl.ONE_MINUS_SRC_ALPHA;
+ SRC_ALPHA = this.gl.ONE;
+ DST_ALPHA = this.gl.ONE_MINUS_SRC_ALPHA;
+ break;
+ case CubismBlendMode.CubismBlendMode_Additive:
+ shaderSet = this._shaderSets[ShaderNames.ShaderNames_AddPremultipliedAlpha + offset];
+ SRC_COLOR = this.gl.ONE;
+ DST_COLOR = this.gl.ONE;
+ SRC_ALPHA = this.gl.ZERO;
+ DST_ALPHA = this.gl.ONE;
+ break;
+ case CubismBlendMode.CubismBlendMode_Multiplicative:
+ shaderSet = this._shaderSets[ShaderNames.ShaderNames_MultPremultipliedAlpha + offset];
+ SRC_COLOR = this.gl.DST_COLOR;
+ DST_COLOR = this.gl.ONE_MINUS_SRC_ALPHA;
+ SRC_ALPHA = this.gl.ZERO;
+ DST_ALPHA = this.gl.ONE;
+ break;
+ }
+ this.gl.useProgram(shaderSet.shaderProgram);
+ if (bufferData.vertex == null) {
+ bufferData.vertex = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.vertex);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, vertexArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributePositionLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributePositionLocation, 2, this.gl.FLOAT, false, 0, 0);
+ if (bufferData.uv == null) {
+ bufferData.uv = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.uv);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, uvArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributeTexCoordLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributeTexCoordLocation, 2, this.gl.FLOAT, false, 0, 0);
+ if (clippingContextBufferForDraw != null) {
+ this.gl.activeTexture(this.gl.TEXTURE1);
+ const tex = clippingContextBufferForDraw.getClippingManager().getColorBuffer()[renderer.getClippingContextBufferForDraw()._bufferIndex];
+ this.gl.bindTexture(this.gl.TEXTURE_2D, tex);
+ this.gl.uniform1i(shaderSet.samplerTexture1Location, 1);
+ this.gl.uniformMatrix4fv(shaderSet.uniformClipMatrixLocation, false, clippingContextBufferForDraw._matrixForDraw.getArray());
+ const channelNo = clippingContextBufferForDraw._layoutChannelNo;
+ const colorChannel = clippingContextBufferForDraw.getClippingManager().getChannelFlagAsColor(channelNo);
+ this.gl.uniform4f(shaderSet.uniformChannelFlagLocation, colorChannel.R, colorChannel.G, colorChannel.B, colorChannel.A);
+ }
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, textureId);
+ this.gl.uniform1i(shaderSet.samplerTexture0Location, 0);
+ this.gl.uniformMatrix4fv(shaderSet.uniformMatrixLocation, false, matrix4x4.getArray());
+ this.gl.uniform4f(shaderSet.uniformBaseColorLocation, baseColor.R, baseColor.G, baseColor.B, baseColor.A);
+ this.gl.uniform4f(shaderSet.uniformMultiplyColorLocation, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A);
+ this.gl.uniform4f(shaderSet.uniformScreenColorLocation, screenColor.R, screenColor.G, screenColor.B, screenColor.A);
+ }
+ if (bufferData.index == null) {
+ bufferData.index = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, bufferData.index);
+ this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, indexArray, this.gl.DYNAMIC_DRAW);
+ this.gl.blendFuncSeparate(SRC_COLOR, DST_COLOR, SRC_ALPHA, DST_ALPHA);
+ }
+ releaseShaderProgram() {
+ for (let i = 0; i < this._shaderSets.length; i++) {
+ this.gl.deleteProgram(this._shaderSets[i].shaderProgram);
+ this._shaderSets[i].shaderProgram = 0;
+ }
+ this._shaderSets = [];
+ }
+ generateShaders() {
+ for (let i = 0; i < ShaderCount; i++) {
+ this._shaderSets.push({});
+ }
+ this._shaderSets[0].shaderProgram = this.loadShaderProgram(vertexShaderSrcSetupMask, fragmentShaderSrcsetupMask);
+ this._shaderSets[1].shaderProgram = this.loadShaderProgram(vertexShaderSrc, fragmentShaderSrcPremultipliedAlpha);
+ this._shaderSets[2].shaderProgram = this.loadShaderProgram(vertexShaderSrcMasked, fragmentShaderSrcMaskPremultipliedAlpha);
+ this._shaderSets[3].shaderProgram = this.loadShaderProgram(vertexShaderSrcMasked, fragmentShaderSrcMaskInvertedPremultipliedAlpha);
+ this._shaderSets[4].shaderProgram = this._shaderSets[1].shaderProgram;
+ this._shaderSets[5].shaderProgram = this._shaderSets[2].shaderProgram;
+ this._shaderSets[6].shaderProgram = this._shaderSets[3].shaderProgram;
+ this._shaderSets[7].shaderProgram = this._shaderSets[1].shaderProgram;
+ this._shaderSets[8].shaderProgram = this._shaderSets[2].shaderProgram;
+ this._shaderSets[9].shaderProgram = this._shaderSets[3].shaderProgram;
+ this._shaderSets[0].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[0].shaderProgram, "a_position");
+ this._shaderSets[0].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[0].shaderProgram, "a_texCoord");
+ this._shaderSets[0].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "s_texture0");
+ this._shaderSets[0].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_clipMatrix");
+ this._shaderSets[0].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_channelFlag");
+ this._shaderSets[0].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_baseColor");
+ this._shaderSets[0].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_multiplyColor");
+ this._shaderSets[0].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_screenColor");
+ this._shaderSets[1].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[1].shaderProgram, "a_position");
+ this._shaderSets[1].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[1].shaderProgram, "a_texCoord");
+ this._shaderSets[1].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "s_texture0");
+ this._shaderSets[1].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_matrix");
+ this._shaderSets[1].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_baseColor");
+ this._shaderSets[1].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_multiplyColor");
+ this._shaderSets[1].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_screenColor");
+ this._shaderSets[2].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[2].shaderProgram, "a_position");
+ this._shaderSets[2].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[2].shaderProgram, "a_texCoord");
+ this._shaderSets[2].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "s_texture0");
+ this._shaderSets[2].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "s_texture1");
+ this._shaderSets[2].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_matrix");
+ this._shaderSets[2].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_clipMatrix");
+ this._shaderSets[2].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_channelFlag");
+ this._shaderSets[2].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_baseColor");
+ this._shaderSets[2].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_multiplyColor");
+ this._shaderSets[2].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_screenColor");
+ this._shaderSets[3].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[3].shaderProgram, "a_position");
+ this._shaderSets[3].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[3].shaderProgram, "a_texCoord");
+ this._shaderSets[3].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "s_texture0");
+ this._shaderSets[3].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "s_texture1");
+ this._shaderSets[3].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_matrix");
+ this._shaderSets[3].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_clipMatrix");
+ this._shaderSets[3].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_channelFlag");
+ this._shaderSets[3].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_baseColor");
+ this._shaderSets[3].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_multiplyColor");
+ this._shaderSets[3].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_screenColor");
+ this._shaderSets[4].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[4].shaderProgram, "a_position");
+ this._shaderSets[4].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[4].shaderProgram, "a_texCoord");
+ this._shaderSets[4].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "s_texture0");
+ this._shaderSets[4].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_matrix");
+ this._shaderSets[4].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_baseColor");
+ this._shaderSets[4].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_multiplyColor");
+ this._shaderSets[4].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_screenColor");
+ this._shaderSets[5].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[5].shaderProgram, "a_position");
+ this._shaderSets[5].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[5].shaderProgram, "a_texCoord");
+ this._shaderSets[5].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "s_texture0");
+ this._shaderSets[5].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "s_texture1");
+ this._shaderSets[5].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_matrix");
+ this._shaderSets[5].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_clipMatrix");
+ this._shaderSets[5].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_channelFlag");
+ this._shaderSets[5].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_baseColor");
+ this._shaderSets[5].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_multiplyColor");
+ this._shaderSets[5].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_screenColor");
+ this._shaderSets[6].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[6].shaderProgram, "a_position");
+ this._shaderSets[6].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[6].shaderProgram, "a_texCoord");
+ this._shaderSets[6].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "s_texture0");
+ this._shaderSets[6].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "s_texture1");
+ this._shaderSets[6].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_matrix");
+ this._shaderSets[6].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_clipMatrix");
+ this._shaderSets[6].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_channelFlag");
+ this._shaderSets[6].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_baseColor");
+ this._shaderSets[6].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_multiplyColor");
+ this._shaderSets[6].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_screenColor");
+ this._shaderSets[7].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[7].shaderProgram, "a_position");
+ this._shaderSets[7].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[7].shaderProgram, "a_texCoord");
+ this._shaderSets[7].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "s_texture0");
+ this._shaderSets[7].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_matrix");
+ this._shaderSets[7].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_baseColor");
+ this._shaderSets[7].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_multiplyColor");
+ this._shaderSets[7].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_screenColor");
+ this._shaderSets[8].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[8].shaderProgram, "a_position");
+ this._shaderSets[8].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[8].shaderProgram, "a_texCoord");
+ this._shaderSets[8].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "s_texture0");
+ this._shaderSets[8].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "s_texture1");
+ this._shaderSets[8].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_matrix");
+ this._shaderSets[8].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_clipMatrix");
+ this._shaderSets[8].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_channelFlag");
+ this._shaderSets[8].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_baseColor");
+ this._shaderSets[8].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_multiplyColor");
+ this._shaderSets[8].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_screenColor");
+ this._shaderSets[9].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[9].shaderProgram, "a_position");
+ this._shaderSets[9].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[9].shaderProgram, "a_texCoord");
+ this._shaderSets[9].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "s_texture0");
+ this._shaderSets[9].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "s_texture1");
+ this._shaderSets[9].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_matrix");
+ this._shaderSets[9].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_clipMatrix");
+ this._shaderSets[9].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_channelFlag");
+ this._shaderSets[9].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_baseColor");
+ this._shaderSets[9].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_multiplyColor");
+ this._shaderSets[9].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_screenColor");
+ }
+ loadShaderProgram(vertexShaderSource, fragmentShaderSource) {
+ const shaderProgram = this.gl.createProgram();
+ const vertShader = this.compileShaderSource(this.gl.VERTEX_SHADER, vertexShaderSource);
+ if (!vertShader) {
+ CubismLogError("Vertex shader compile error!");
+ return 0;
+ }
+ const fragShader = this.compileShaderSource(this.gl.FRAGMENT_SHADER, fragmentShaderSource);
+ if (!fragShader) {
+ CubismLogError("Vertex shader compile error!");
+ return 0;
+ }
+ this.gl.attachShader(shaderProgram, vertShader);
+ this.gl.attachShader(shaderProgram, fragShader);
+ this.gl.linkProgram(shaderProgram);
+ const linkStatus = this.gl.getProgramParameter(shaderProgram, this.gl.LINK_STATUS);
+ if (!linkStatus) {
+ CubismLogError("Failed to link program: {0}", shaderProgram);
+ this.gl.deleteShader(vertShader);
+ this.gl.deleteShader(fragShader);
+ if (shaderProgram) {
+ this.gl.deleteProgram(shaderProgram);
+ }
+ return 0;
+ }
+ this.gl.deleteShader(vertShader);
+ this.gl.deleteShader(fragShader);
+ return shaderProgram;
+ }
+ compileShaderSource(shaderType, shaderSource) {
+ const source = shaderSource;
+ const shader = this.gl.createShader(shaderType);
+ this.gl.shaderSource(shader, source);
+ this.gl.compileShader(shader);
+ if (!shader) {
+ const log = this.gl.getShaderInfoLog(shader);
+ CubismLogError("Shader compile log: {0} ", log);
+ }
+ const status = this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS);
+ if (!status) {
+ this.gl.deleteShader(shader);
+ return null;
+ }
+ return shader;
+ }
+ setGl(gl) {
+ this.gl = gl;
+ }
+}
+var ShaderNames = /* @__PURE__ */ ((ShaderNames2) => {
+ ShaderNames2[ShaderNames2["ShaderNames_SetupMask"] = 0] = "ShaderNames_SetupMask";
+ ShaderNames2[ShaderNames2["ShaderNames_NormalPremultipliedAlpha"] = 1] = "ShaderNames_NormalPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_NormalMaskedPremultipliedAlpha"] = 2] = "ShaderNames_NormalMaskedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_NomralMaskedInvertedPremultipliedAlpha"] = 3] = "ShaderNames_NomralMaskedInvertedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_AddPremultipliedAlpha"] = 4] = "ShaderNames_AddPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_AddMaskedPremultipliedAlpha"] = 5] = "ShaderNames_AddMaskedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_AddMaskedPremultipliedAlphaInverted"] = 6] = "ShaderNames_AddMaskedPremultipliedAlphaInverted";
+ ShaderNames2[ShaderNames2["ShaderNames_MultPremultipliedAlpha"] = 7] = "ShaderNames_MultPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_MultMaskedPremultipliedAlpha"] = 8] = "ShaderNames_MultMaskedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_MultMaskedPremultipliedAlphaInverted"] = 9] = "ShaderNames_MultMaskedPremultipliedAlphaInverted";
+ return ShaderNames2;
+})(ShaderNames || {});
+const vertexShaderSrcSetupMask = "attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_myPos;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_clipMatrix * a_position; v_myPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}";
+const fragmentShaderSrcsetupMask = "precision mediump float;varying vec2 v_texCoord;varying vec4 v_myPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;void main(){ float isInside = step(u_baseColor.x, v_myPos.x/v_myPos.w) * step(u_baseColor.y, v_myPos.y/v_myPos.w) * step(v_myPos.x/v_myPos.w, u_baseColor.z) * step(v_myPos.y/v_myPos.w, u_baseColor.w); gl_FragColor = u_channelFlag * texture2D(s_texture0, v_texCoord).a * isInside;}";
+const vertexShaderSrc = "attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;uniform mat4 u_matrix;void main(){ gl_Position = u_matrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}";
+const vertexShaderSrcMasked = "attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform mat4 u_matrix;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_matrix * a_position; v_clipPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}";
+const fragmentShaderSrcPremultipliedAlpha = "precision mediump float;varying vec2 v_texCoord;uniform vec4 u_baseColor;uniform sampler2D s_texture0;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 color = texColor * u_baseColor; gl_FragColor = vec4(color.rgb, color.a);}";
+const fragmentShaderSrcMaskPremultipliedAlpha = "precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * maskVal; gl_FragColor = col_formask;}";
+const fragmentShaderSrcMaskInvertedPremultipliedAlpha = "precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_channelFlag;uniform vec4 u_baseColor;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * (1.0 - maskVal); gl_FragColor = col_formask;}";
+class CubismRenderer_WebGL extends CubismRenderer {
+ constructor() {
+ super();
+ this._clippingContextBufferForMask = null;
+ this._clippingContextBufferForDraw = null;
+ this._rendererProfile = new CubismRendererProfile_WebGL();
+ this.firstDraw = true;
+ this._textures = {};
+ this._sortedDrawableIndexList = [];
+ this._bufferData = {
+ vertex: null,
+ uv: null,
+ index: null
+ };
+ }
+ initialize(model, maskBufferCount = 1) {
+ if (model.isUsingMasking()) {
+ this._clippingManager = new CubismClippingManager_WebGL();
+ this._clippingManager.initialize(model, model.getDrawableCount(), model.getDrawableMasks(), model.getDrawableMaskCounts(), maskBufferCount);
+ }
+ for (let i = model.getDrawableCount() - 1; i >= 0; i--) {
+ this._sortedDrawableIndexList[i] = 0;
+ }
+ super.initialize(model);
+ }
+ bindTexture(modelTextureNo, glTexture) {
+ this._textures[modelTextureNo] = glTexture;
+ }
+ getBindedTextures() {
+ return this._textures;
+ }
+ setClippingMaskBufferSize(size) {
+ if (!this._model.isUsingMasking()) {
+ return;
+ }
+ const renderTextureCount = this._clippingManager.getRenderTextureCount();
+ this._clippingManager.release();
+ this._clippingManager = new CubismClippingManager_WebGL();
+ this._clippingManager.setClippingMaskBufferSize(size);
+ this._clippingManager.initialize(this.getModel(), this.getModel().getDrawableCount(), this.getModel().getDrawableMasks(), this.getModel().getDrawableMaskCounts(), renderTextureCount);
+ }
+ getClippingMaskBufferSize() {
+ return this._model.isUsingMasking() ? this._clippingManager.getClippingMaskBufferSize() : -1;
+ }
+ getRenderTextureCount() {
+ return this._model.isUsingMasking() ? this._clippingManager.getRenderTextureCount() : -1;
+ }
+ release() {
+ var _a, _b, _c;
+ const self = this;
+ this._clippingManager.release();
+ self._clippingManager = void 0;
+ (_a = this.gl) == null ? void 0 : _a.deleteBuffer(this._bufferData.vertex);
+ this._bufferData.vertex = null;
+ (_b = this.gl) == null ? void 0 : _b.deleteBuffer(this._bufferData.uv);
+ this._bufferData.uv = null;
+ (_c = this.gl) == null ? void 0 : _c.deleteBuffer(this._bufferData.index);
+ this._bufferData.index = null;
+ self._bufferData = void 0;
+ self._textures = void 0;
+ }
+ doDrawModel() {
+ if (this.gl == null) {
+ CubismLogError("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");
+ return;
+ }
+ if (this._clippingManager != null) {
+ this.preDraw();
+ this._clippingManager.setupClippingContext(this.getModel(), this);
+ }
+ this.preDraw();
+ const drawableCount = this.getModel().getDrawableCount();
+ const renderOrder = this.getModel().getDrawableRenderOrders();
+ for (let i = 0; i < drawableCount; ++i) {
+ const order = renderOrder[i];
+ this._sortedDrawableIndexList[order] = i;
+ }
+ for (let i = 0; i < drawableCount; ++i) {
+ const drawableIndex = this._sortedDrawableIndexList[i];
+ if (!this.getModel().getDrawableDynamicFlagIsVisible(drawableIndex)) {
+ continue;
+ }
+ const clipContext = this._clippingManager != null ? this._clippingManager.getClippingContextListForDraw()[drawableIndex] : null;
+ if (clipContext != null && this.isUsingHighPrecisionMask()) {
+ if (clipContext._isUsing) {
+ this.gl.viewport(0, 0, this._clippingManager.getClippingMaskBufferSize(), this._clippingManager.getClippingMaskBufferSize());
+ this.preDraw();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, clipContext.getClippingManager().getMaskRenderTexture()[clipContext._bufferIndex]);
+ this.gl.clearColor(1, 1, 1, 1);
+ this.gl.clear(this.gl.COLOR_BUFFER_BIT);
+ }
+ {
+ const clipDrawCount = clipContext._clippingIdCount;
+ for (let index = 0; index < clipDrawCount; index++) {
+ const clipDrawIndex = clipContext._clippingIdList[index];
+ if (!this._model.getDrawableDynamicFlagVertexPositionsDidChange(clipDrawIndex)) {
+ continue;
+ }
+ this.setIsCulling(this._model.getDrawableCulling(clipDrawIndex) != false);
+ this.setClippingContextBufferForMask(clipContext);
+ this.drawMesh(this.getModel().getDrawableTextureIndex(clipDrawIndex), this.getModel().getDrawableVertexIndexCount(clipDrawIndex), this.getModel().getDrawableVertexCount(clipDrawIndex), this.getModel().getDrawableVertexIndices(clipDrawIndex), this.getModel().getDrawableVertices(clipDrawIndex), this.getModel().getDrawableVertexUvs(clipDrawIndex), this.getModel().getMultiplyColor(clipDrawIndex), this.getModel().getScreenColor(clipDrawIndex), this.getModel().getDrawableOpacity(clipDrawIndex), CubismBlendMode.CubismBlendMode_Normal, false);
+ }
+ }
+ {
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, s_fbo);
+ this.setClippingContextBufferForMask(null);
+ this.gl.viewport(s_viewport[0], s_viewport[1], s_viewport[2], s_viewport[3]);
+ this.preDraw();
+ }
+ }
+ this.setClippingContextBufferForDraw(clipContext);
+ this.setIsCulling(this.getModel().getDrawableCulling(drawableIndex));
+ this.drawMesh(this.getModel().getDrawableTextureIndex(drawableIndex), this.getModel().getDrawableVertexIndexCount(drawableIndex), this.getModel().getDrawableVertexCount(drawableIndex), this.getModel().getDrawableVertexIndices(drawableIndex), this.getModel().getDrawableVertices(drawableIndex), this.getModel().getDrawableVertexUvs(drawableIndex), this.getModel().getMultiplyColor(drawableIndex), this.getModel().getScreenColor(drawableIndex), this.getModel().getDrawableOpacity(drawableIndex), this.getModel().getDrawableBlendMode(drawableIndex), this.getModel().getDrawableInvertedMaskBit(drawableIndex));
+ }
+ }
+ drawMesh(textureNo, indexCount, vertexCount, indexArray, vertexArray, uvArray, multiplyColor, screenColor, opacity, colorBlendMode, invertedMask) {
+ if (this.isCulling()) {
+ this.gl.enable(this.gl.CULL_FACE);
+ } else {
+ this.gl.disable(this.gl.CULL_FACE);
+ }
+ this.gl.frontFace(this.gl.CCW);
+ const modelColorRGBA = this.getModelColor();
+ if (this.getClippingContextBufferForMask() == null) {
+ modelColorRGBA.A *= opacity;
+ if (this.isPremultipliedAlpha()) {
+ modelColorRGBA.R *= modelColorRGBA.A;
+ modelColorRGBA.G *= modelColorRGBA.A;
+ modelColorRGBA.B *= modelColorRGBA.A;
+ }
+ }
+ let drawtexture = null;
+ if (this._textures[textureNo] != null) {
+ drawtexture = this._textures[textureNo];
+ }
+ CubismShader_WebGL.getInstance().setupShaderProgram(this, drawtexture, vertexCount, vertexArray, indexArray, uvArray, this._bufferData, opacity, colorBlendMode, modelColorRGBA, multiplyColor, screenColor, this.isPremultipliedAlpha(), this.getMvpMatrix(), invertedMask);
+ this.gl.drawElements(this.gl.TRIANGLES, indexCount, this.gl.UNSIGNED_SHORT, 0);
+ this.gl.useProgram(null);
+ this.setClippingContextBufferForDraw(null);
+ this.setClippingContextBufferForMask(null);
+ }
+ saveProfile() {
+ this._rendererProfile.save();
+ }
+ restoreProfile() {
+ this._rendererProfile.restore();
+ }
+ static doStaticRelease() {
+ CubismShader_WebGL.deleteInstance();
+ }
+ setRenderState(fbo, viewport) {
+ s_fbo = fbo;
+ s_viewport = viewport;
+ }
+ preDraw() {
+ if (this.firstDraw) {
+ this.firstDraw = false;
+ }
+ this.gl.disable(this.gl.SCISSOR_TEST);
+ this.gl.disable(this.gl.STENCIL_TEST);
+ this.gl.disable(this.gl.DEPTH_TEST);
+ this.gl.frontFace(this.gl.CW);
+ this.gl.enable(this.gl.BLEND);
+ this.gl.colorMask(true, true, true, true);
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);
+ if (this.getAnisotropy() > 0 && this._extension) {
+ for (const tex of Object.entries(this._textures)) {
+ this.gl.bindTexture(this.gl.TEXTURE_2D, tex);
+ this.gl.texParameterf(this.gl.TEXTURE_2D, this._extension.TEXTURE_MAX_ANISOTROPY_EXT, this.getAnisotropy());
+ }
+ }
+ }
+ setClippingContextBufferForMask(clip) {
+ this._clippingContextBufferForMask = clip;
+ }
+ getClippingContextBufferForMask() {
+ return this._clippingContextBufferForMask;
+ }
+ setClippingContextBufferForDraw(clip) {
+ this._clippingContextBufferForDraw = clip;
+ }
+ getClippingContextBufferForDraw() {
+ return this._clippingContextBufferForDraw;
+ }
+ startUp(gl) {
+ this.gl = gl;
+ if (this._clippingManager) {
+ this._clippingManager.setGL(gl);
+ }
+ CubismShader_WebGL.getInstance().setGl(gl);
+ this._rendererProfile.setGl(gl);
+ this._extension = this.gl.getExtension("EXT_texture_filter_anisotropic") || this.gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic") || this.gl.getExtension("MOZ_EXT_texture_filter_anisotropic");
+ }
+}
+CubismRenderer.staticRelease = () => {
+ CubismRenderer_WebGL.doStaticRelease();
+};
+const tempMatrix = new CubismMatrix44();
+class Cubism4InternalModel extends InternalModel {
+ constructor(coreModel, settings, options) {
+ super();
+ this.lipSync = true;
+ this.breath = CubismBreath.create();
+ this.renderer = new CubismRenderer_WebGL();
+ this.idParamAngleX = ParamAngleX;
+ this.idParamAngleY = ParamAngleY;
+ this.idParamAngleZ = ParamAngleZ;
+ this.idParamEyeBallX = ParamEyeBallX;
+ this.idParamEyeBallY = ParamEyeBallY;
+ this.idParamBodyAngleX = ParamBodyAngleX;
+ this.idParamBreath = ParamBreath;
+ this.pixelsPerUnit = 1;
+ this.centeringTransform = new Matrix();
+ this.coreModel = coreModel;
+ this.settings = settings;
+ this.motionManager = new Cubism4MotionManager(settings, options);
+ this.init();
+ }
+ init() {
+ var _a;
+ super.init();
+ if (((_a = this.settings.getEyeBlinkParameters()) == null ? void 0 : _a.length) > 0) {
+ this.eyeBlink = CubismEyeBlink.create(this.settings);
+ }
+ this.breath.setParameters([
+ new BreathParameterData(this.idParamAngleX, 0, 15, 6.5345, 0.5),
+ new BreathParameterData(this.idParamAngleY, 0, 8, 3.5345, 0.5),
+ new BreathParameterData(this.idParamAngleZ, 0, 10, 5.5345, 0.5),
+ new BreathParameterData(this.idParamBodyAngleX, 0, 4, 15.5345, 0.5),
+ new BreathParameterData(this.idParamBreath, 0, 0.5, 3.2345, 0.5)
+ ]);
+ this.renderer.initialize(this.coreModel);
+ this.renderer.setIsPremultipliedAlpha(true);
+ }
+ getSize() {
+ return [this.coreModel.getModel().canvasinfo.CanvasWidth, this.coreModel.getModel().canvasinfo.CanvasHeight];
+ }
+ getLayout() {
+ const layout = {};
+ if (this.settings.layout) {
+ for (const key of Object.keys(this.settings.layout)) {
+ const commonKey = key.charAt(0).toLowerCase() + key.slice(1);
+ layout[commonKey] = this.settings.layout[key];
+ }
+ }
+ return layout;
+ }
+ setupLayout() {
+ super.setupLayout();
+ this.pixelsPerUnit = this.coreModel.getModel().canvasinfo.PixelsPerUnit;
+ this.centeringTransform.scale(this.pixelsPerUnit, this.pixelsPerUnit).translate(this.originalWidth / 2, this.originalHeight / 2);
+ }
+ updateWebGLContext(gl, glContextID) {
+ this.renderer.firstDraw = true;
+ this.renderer._bufferData = {
+ vertex: null,
+ uv: null,
+ index: null
+ };
+ this.renderer.startUp(gl);
+ this.renderer._clippingManager._currentFrameNo = glContextID;
+ this.renderer._clippingManager._maskTexture = void 0;
+ CubismShader_WebGL.getInstance()._shaderSets = [];
+ }
+ bindTexture(index, texture) {
+ this.renderer.bindTexture(index, texture);
+ }
+ getHitAreaDefs() {
+ var _a, _b;
+ return (_b = (_a = this.settings.hitAreas) == null ? void 0 : _a.map((hitArea) => ({
+ id: hitArea.Id,
+ name: hitArea.Name,
+ index: this.coreModel.getDrawableIndex(hitArea.Id)
+ }))) != null ? _b : [];
+ }
+ getDrawableIDs() {
+ return this.coreModel.getDrawableIds();
+ }
+ getDrawableIndex(id) {
+ return this.coreModel.getDrawableIndex(id);
+ }
+ getDrawableVertices(drawIndex) {
+ if (typeof drawIndex === "string") {
+ drawIndex = this.coreModel.getDrawableIndex(drawIndex);
+ if (drawIndex === -1)
+ throw new TypeError("Unable to find drawable ID: " + drawIndex);
+ }
+ const arr = this.coreModel.getDrawableVertices(drawIndex).slice();
+ for (let i = 0; i < arr.length; i += 2) {
+ arr[i] = arr[i] * this.pixelsPerUnit + this.originalWidth / 2;
+ arr[i + 1] = -arr[i + 1] * this.pixelsPerUnit + this.originalHeight / 2;
+ }
+ return arr;
+ }
+ updateTransform(transform) {
+ this.drawingMatrix.copyFrom(this.centeringTransform).prepend(this.localTransform).prepend(transform);
+ }
+ update(dt, now) {
+ var _a, _b, _c, _d;
+ super.update(dt, now);
+ dt /= 1e3;
+ now /= 1e3;
+ const model = this.coreModel;
+ this.emit("beforeMotionUpdate");
+ const motionUpdated = this.motionManager.update(this.coreModel, now);
+ this.emit("afterMotionUpdate");
+ model.saveParameters();
+ (_a = this.motionManager.expressionManager) == null ? void 0 : _a.update(model, now);
+ if (!motionUpdated) {
+ (_b = this.eyeBlink) == null ? void 0 : _b.updateParameters(model, dt);
+ }
+ this.updateFocus();
+ this.updateNaturalMovements(dt * 1e3, now * 1e3);
+ (_c = this.physics) == null ? void 0 : _c.evaluate(model, dt);
+ (_d = this.pose) == null ? void 0 : _d.updateParameters(model, dt);
+ this.emit("beforeModelUpdate");
+ model.update();
+ model.loadParameters();
+ }
+ updateFocus() {
+ this.coreModel.addParameterValueById(this.idParamEyeBallX, this.focusController.x);
+ this.coreModel.addParameterValueById(this.idParamEyeBallY, this.focusController.y);
+ this.coreModel.addParameterValueById(this.idParamAngleX, this.focusController.x * 30);
+ this.coreModel.addParameterValueById(this.idParamAngleY, this.focusController.y * 30);
+ this.coreModel.addParameterValueById(this.idParamAngleZ, this.focusController.x * this.focusController.y * -30);
+ this.coreModel.addParameterValueById(this.idParamBodyAngleX, this.focusController.x * 10);
+ }
+ updateNaturalMovements(dt, now) {
+ var _a;
+ (_a = this.breath) == null ? void 0 : _a.updateParameters(this.coreModel, dt / 1e3);
+ }
+ draw(gl) {
+ const matrix = this.drawingMatrix;
+ const array = tempMatrix.getArray();
+ array[0] = matrix.a;
+ array[1] = matrix.b;
+ array[4] = -matrix.c;
+ array[5] = -matrix.d;
+ array[12] = matrix.tx;
+ array[13] = matrix.ty;
+ this.renderer.setMvpMatrix(tempMatrix);
+ this.renderer.setRenderState(gl.getParameter(gl.FRAMEBUFFER_BINDING), this.viewport);
+ this.renderer.drawModel();
+ }
+ destroy() {
+ super.destroy();
+ this.renderer.release();
+ this.coreModel.release();
+ this.renderer = void 0;
+ this.coreModel = void 0;
+ }
+}
+let startupPromise;
+let startupRetries = 20;
+function cubism4Ready() {
+ if (CubismFramework.isStarted()) {
+ return Promise.resolve();
+ }
+ startupPromise != null ? startupPromise : startupPromise = new Promise((resolve, reject) => {
+ function startUpWithRetry() {
+ try {
+ startUpCubism4();
+ resolve();
+ } catch (e) {
+ startupRetries--;
+ if (startupRetries < 0) {
+ const err = new Error("Failed to start up Cubism 4 framework.");
+ err.cause = e;
+ reject(err);
+ return;
+ }
+ logger.log("Cubism4", "Startup failed, retrying 10ms later...");
+ setTimeout(startUpWithRetry, 10);
+ }
+ }
+ startUpWithRetry();
+ });
+ return startupPromise;
+}
+function startUpCubism4(options) {
+ options = Object.assign({
+ logFunction: console.log,
+ loggingLevel: LogLevel.LogLevel_Verbose
+ }, options);
+ CubismFramework.startUp(options);
+ CubismFramework.initialize();
+}
+const Epsilon = 1e-3;
+const DefaultFadeInSeconds = 0.5;
+class CubismPose {
+ static create(pose3json) {
+ const ret = new CubismPose();
+ if (typeof pose3json.FadeInTime === "number") {
+ ret._fadeTimeSeconds = pose3json.FadeInTime;
+ if (ret._fadeTimeSeconds <= 0) {
+ ret._fadeTimeSeconds = DefaultFadeInSeconds;
+ }
+ }
+ const poseListInfo = pose3json.Groups;
+ const poseCount = poseListInfo.length;
+ for (let poseIndex = 0; poseIndex < poseCount; ++poseIndex) {
+ const idListInfo = poseListInfo[poseIndex];
+ const idCount = idListInfo.length;
+ let groupCount = 0;
+ for (let groupIndex = 0; groupIndex < idCount; ++groupIndex) {
+ const partInfo = idListInfo[groupIndex];
+ const partData = new PartData();
+ partData.partId = partInfo.Id;
+ const linkListInfo = partInfo.Link;
+ if (linkListInfo) {
+ const linkCount = linkListInfo.length;
+ for (let linkIndex = 0; linkIndex < linkCount; ++linkIndex) {
+ const linkPart = new PartData();
+ linkPart.partId = linkListInfo[linkIndex];
+ partData.link.push(linkPart);
+ }
+ }
+ ret._partGroups.push(partData);
+ ++groupCount;
+ }
+ ret._partGroupCounts.push(groupCount);
+ }
+ return ret;
+ }
+ updateParameters(model, deltaTimeSeconds) {
+ if (model != this._lastModel) {
+ this.reset(model);
+ }
+ this._lastModel = model;
+ if (deltaTimeSeconds < 0) {
+ deltaTimeSeconds = 0;
+ }
+ let beginIndex = 0;
+ for (let i = 0; i < this._partGroupCounts.length; i++) {
+ const partGroupCount = this._partGroupCounts[i];
+ this.doFade(model, deltaTimeSeconds, beginIndex, partGroupCount);
+ beginIndex += partGroupCount;
+ }
+ this.copyPartOpacities(model);
+ }
+ reset(model) {
+ let beginIndex = 0;
+ for (let i = 0; i < this._partGroupCounts.length; ++i) {
+ const groupCount = this._partGroupCounts[i];
+ for (let j = beginIndex; j < beginIndex + groupCount; ++j) {
+ this._partGroups[j].initialize(model);
+ const partsIndex = this._partGroups[j].partIndex;
+ const paramIndex = this._partGroups[j].parameterIndex;
+ if (partsIndex < 0) {
+ continue;
+ }
+ model.setPartOpacityByIndex(partsIndex, j == beginIndex ? 1 : 0);
+ model.setParameterValueByIndex(paramIndex, j == beginIndex ? 1 : 0);
+ for (let k = 0; k < this._partGroups[j].link.length; ++k) {
+ this._partGroups[j].link[k].initialize(model);
+ }
+ }
+ beginIndex += groupCount;
+ }
+ }
+ copyPartOpacities(model) {
+ for (let groupIndex = 0; groupIndex < this._partGroups.length; ++groupIndex) {
+ const partData = this._partGroups[groupIndex];
+ if (partData.link.length == 0) {
+ continue;
+ }
+ const partIndex = this._partGroups[groupIndex].partIndex;
+ const opacity = model.getPartOpacityByIndex(partIndex);
+ for (let linkIndex = 0; linkIndex < partData.link.length; ++linkIndex) {
+ const linkPart = partData.link[linkIndex];
+ const linkPartIndex = linkPart.partIndex;
+ if (linkPartIndex < 0) {
+ continue;
+ }
+ model.setPartOpacityByIndex(linkPartIndex, opacity);
+ }
+ }
+ }
+ doFade(model, deltaTimeSeconds, beginIndex, partGroupCount) {
+ let visiblePartIndex = -1;
+ let newOpacity = 1;
+ const phi = 0.5;
+ const backOpacityThreshold = 0.15;
+ for (let i = beginIndex; i < beginIndex + partGroupCount; ++i) {
+ const partIndex = this._partGroups[i].partIndex;
+ const paramIndex = this._partGroups[i].parameterIndex;
+ if (model.getParameterValueByIndex(paramIndex) > Epsilon) {
+ if (visiblePartIndex >= 0) {
+ break;
+ }
+ visiblePartIndex = i;
+ newOpacity = model.getPartOpacityByIndex(partIndex);
+ newOpacity += deltaTimeSeconds / this._fadeTimeSeconds;
+ if (newOpacity > 1) {
+ newOpacity = 1;
+ }
+ }
+ }
+ if (visiblePartIndex < 0) {
+ visiblePartIndex = 0;
+ newOpacity = 1;
+ }
+ for (let i = beginIndex; i < beginIndex + partGroupCount; ++i) {
+ const partsIndex = this._partGroups[i].partIndex;
+ if (visiblePartIndex == i) {
+ model.setPartOpacityByIndex(partsIndex, newOpacity);
+ } else {
+ let opacity = model.getPartOpacityByIndex(partsIndex);
+ let a1;
+ if (newOpacity < phi) {
+ a1 = newOpacity * (phi - 1) / phi + 1;
+ } else {
+ a1 = (1 - newOpacity) * phi / (1 - phi);
+ }
+ const backOpacity = (1 - a1) * (1 - newOpacity);
+ if (backOpacity > backOpacityThreshold) {
+ a1 = 1 - backOpacityThreshold / (1 - newOpacity);
+ }
+ if (opacity > a1) {
+ opacity = a1;
+ }
+ model.setPartOpacityByIndex(partsIndex, opacity);
+ }
+ }
+ }
+ constructor() {
+ this._fadeTimeSeconds = DefaultFadeInSeconds;
+ this._lastModel = void 0;
+ this._partGroups = [];
+ this._partGroupCounts = [];
+ }
+}
+class PartData {
+ constructor(v) {
+ this.parameterIndex = 0;
+ this.partIndex = 0;
+ this.partId = "";
+ this.link = [];
+ if (v != void 0) {
+ this.assignment(v);
+ }
+ }
+ assignment(v) {
+ this.partId = v.partId;
+ this.link = v.link.map((link) => link.clone());
+ return this;
+ }
+ initialize(model) {
+ this.parameterIndex = model.getParameterIndex(this.partId);
+ this.partIndex = model.getPartIndex(this.partId);
+ model.setParameterValueByIndex(this.parameterIndex, 1);
+ }
+ clone() {
+ const clonePartData = new PartData();
+ clonePartData.partId = this.partId;
+ clonePartData.parameterIndex = this.parameterIndex;
+ clonePartData.partIndex = this.partIndex;
+ clonePartData.link = this.link.map((link) => link.clone());
+ return clonePartData;
+ }
+}
+class DrawableColorData {
+ constructor(isOverwritten = false, color = new CubismTextureColor()) {
+ this.isOverwritten = isOverwritten;
+ this.Color = color;
+ }
+}
+class PartColorData {
+ constructor(isOverwritten = false, color = new CubismTextureColor()) {
+ this.isOverwritten = isOverwritten;
+ this.Color = color;
+ }
+}
+class DrawableCullingData {
+ constructor(isOverwritten = false, isCulling = false) {
+ this.isOverwritten = isOverwritten;
+ this.isCulling = isCulling;
+ }
+}
+class CubismModel {
+ update() {
+ this._model.update();
+ this._model.drawables.resetDynamicFlags();
+ }
+ getPixelsPerUnit() {
+ if (this._model == null) {
+ return 0;
+ }
+ return this._model.canvasinfo.PixelsPerUnit;
+ }
+ getCanvasWidth() {
+ if (this._model == null) {
+ return 0;
+ }
+ return this._model.canvasinfo.CanvasWidth / this._model.canvasinfo.PixelsPerUnit;
+ }
+ getCanvasHeight() {
+ if (this._model == null) {
+ return 0;
+ }
+ return this._model.canvasinfo.CanvasHeight / this._model.canvasinfo.PixelsPerUnit;
+ }
+ saveParameters() {
+ const parameterCount = this._model.parameters.count;
+ const savedParameterCount = this._savedParameters.length;
+ for (let i = 0; i < parameterCount; ++i) {
+ if (i < savedParameterCount) {
+ this._savedParameters[i] = this._parameterValues[i];
+ } else {
+ this._savedParameters.push(this._parameterValues[i]);
+ }
+ }
+ }
+ getMultiplyColor(index) {
+ if (this.getOverwriteFlagForModelMultiplyColors() || this.getOverwriteFlagForDrawableMultiplyColors(index)) {
+ return this._userMultiplyColors[index].Color;
+ }
+ const color = this.getDrawableMultiplyColor(index);
+ return color;
+ }
+ getScreenColor(index) {
+ if (this.getOverwriteFlagForModelScreenColors() || this.getOverwriteFlagForDrawableScreenColors(index)) {
+ return this._userScreenColors[index].Color;
+ }
+ const color = this.getDrawableScreenColor(index);
+ return color;
+ }
+ setMultiplyColorByTextureColor(index, color) {
+ this.setMultiplyColorByRGBA(index, color.R, color.G, color.B, color.A);
+ }
+ setMultiplyColorByRGBA(index, r, g, b, a = 1) {
+ this._userMultiplyColors[index].Color.R = r;
+ this._userMultiplyColors[index].Color.G = g;
+ this._userMultiplyColors[index].Color.B = b;
+ this._userMultiplyColors[index].Color.A = a;
+ }
+ setScreenColorByTextureColor(index, color) {
+ this.setScreenColorByRGBA(index, color.R, color.G, color.B, color.A);
+ }
+ setScreenColorByRGBA(index, r, g, b, a = 1) {
+ this._userScreenColors[index].Color.R = r;
+ this._userScreenColors[index].Color.G = g;
+ this._userScreenColors[index].Color.B = b;
+ this._userScreenColors[index].Color.A = a;
+ }
+ getPartMultiplyColor(partIndex) {
+ return this._userPartMultiplyColors[partIndex].Color;
+ }
+ getPartScreenColor(partIndex) {
+ return this._userPartScreenColors[partIndex].Color;
+ }
+ setPartColor(partIndex, r, g, b, a, partColors, drawableColors) {
+ partColors[partIndex].Color.R = r;
+ partColors[partIndex].Color.G = g;
+ partColors[partIndex].Color.B = b;
+ partColors[partIndex].Color.A = a;
+ if (partColors[partIndex].isOverwritten) {
+ for (let i = 0; i < this._partChildDrawables[partIndex].length; ++i) {
+ const drawableIndex = this._partChildDrawables[partIndex][i];
+ drawableColors[drawableIndex].Color.R = r;
+ drawableColors[drawableIndex].Color.G = g;
+ drawableColors[drawableIndex].Color.B = b;
+ drawableColors[drawableIndex].Color.A = a;
+ }
+ }
+ }
+ setPartMultiplyColorByTextureColor(partIndex, color) {
+ this.setPartMultiplyColorByRGBA(partIndex, color.R, color.G, color.B, color.A);
+ }
+ setPartMultiplyColorByRGBA(partIndex, r, g, b, a) {
+ this.setPartColor(partIndex, r, g, b, a, this._userPartMultiplyColors, this._userMultiplyColors);
+ }
+ setPartScreenColorByTextureColor(partIndex, color) {
+ this.setPartScreenColorByRGBA(partIndex, color.R, color.G, color.B, color.A);
+ }
+ setPartScreenColorByRGBA(partIndex, r, g, b, a) {
+ this.setPartColor(partIndex, r, g, b, a, this._userPartScreenColors, this._userScreenColors);
+ }
+ getOverwriteFlagForModelMultiplyColors() {
+ return this._isOverwrittenModelMultiplyColors;
+ }
+ getOverwriteFlagForModelScreenColors() {
+ return this._isOverwrittenModelScreenColors;
+ }
+ setOverwriteFlagForModelMultiplyColors(value) {
+ this._isOverwrittenModelMultiplyColors = value;
+ }
+ setOverwriteFlagForModelScreenColors(value) {
+ this._isOverwrittenModelScreenColors = value;
+ }
+ getOverwriteFlagForDrawableMultiplyColors(drawableindex) {
+ return this._userMultiplyColors[drawableindex].isOverwritten;
+ }
+ getOverwriteFlagForDrawableScreenColors(drawableindex) {
+ return this._userScreenColors[drawableindex].isOverwritten;
+ }
+ setOverwriteFlagForDrawableMultiplyColors(drawableindex, value) {
+ this._userMultiplyColors[drawableindex].isOverwritten = value;
+ }
+ setOverwriteFlagForDrawableScreenColors(drawableindex, value) {
+ this._userScreenColors[drawableindex].isOverwritten = value;
+ }
+ getOverwriteColorForPartMultiplyColors(partIndex) {
+ return this._userPartMultiplyColors[partIndex].isOverwritten;
+ }
+ getOverwriteColorForPartScreenColors(partIndex) {
+ return this._userPartScreenColors[partIndex].isOverwritten;
+ }
+ setOverwriteColorForPartColors(partIndex, value, partColors, drawableColors) {
+ partColors[partIndex].isOverwritten = value;
+ for (let i = 0; i < this._partChildDrawables[partIndex].length; ++i) {
+ const drawableIndex = this._partChildDrawables[partIndex][i];
+ drawableColors[drawableIndex].isOverwritten = value;
+ if (value) {
+ drawableColors[drawableIndex].Color.R = partColors[partIndex].Color.R;
+ drawableColors[drawableIndex].Color.G = partColors[partIndex].Color.G;
+ drawableColors[drawableIndex].Color.B = partColors[partIndex].Color.B;
+ drawableColors[drawableIndex].Color.A = partColors[partIndex].Color.A;
+ }
+ }
+ }
+ setOverwriteColorForPartMultiplyColors(partIndex, value) {
+ this._userPartMultiplyColors[partIndex].isOverwritten = value;
+ this.setOverwriteColorForPartColors(partIndex, value, this._userPartMultiplyColors, this._userMultiplyColors);
+ }
+ setOverwriteColorForPartScreenColors(partIndex, value) {
+ this._userPartScreenColors[partIndex].isOverwritten = value;
+ this.setOverwriteColorForPartColors(partIndex, value, this._userPartScreenColors, this._userScreenColors);
+ }
+ getDrawableCulling(drawableIndex) {
+ if (this.getOverwriteFlagForModelCullings() || this.getOverwriteFlagForDrawableCullings(drawableIndex)) {
+ return this._userCullings[drawableIndex].isCulling;
+ }
+ const constantFlags = this._model.drawables.constantFlags;
+ return !Live2DCubismCore.Utils.hasIsDoubleSidedBit(constantFlags[drawableIndex]);
+ }
+ setDrawableCulling(drawableIndex, isCulling) {
+ this._userCullings[drawableIndex].isCulling = isCulling;
+ }
+ getOverwriteFlagForModelCullings() {
+ return this._isOverwrittenCullings;
+ }
+ setOverwriteFlagForModelCullings(isOverwrittenCullings) {
+ this._isOverwrittenCullings = isOverwrittenCullings;
+ }
+ getOverwriteFlagForDrawableCullings(drawableIndex) {
+ return this._userCullings[drawableIndex].isOverwritten;
+ }
+ setOverwriteFlagForDrawableCullings(drawableIndex, isOverwrittenCullings) {
+ this._userCullings[drawableIndex].isOverwritten = isOverwrittenCullings;
+ }
+ getModelOapcity() {
+ return this._modelOpacity;
+ }
+ setModelOapcity(value) {
+ this._modelOpacity = value;
+ }
+ getModel() {
+ return this._model;
+ }
+ getPartIndex(partId) {
+ let partIndex;
+ const partCount = this._model.parts.count;
+ for (partIndex = 0; partIndex < partCount; ++partIndex) {
+ if (partId == this._partIds[partIndex]) {
+ return partIndex;
+ }
+ }
+ if (partId in this._notExistPartId) {
+ return this._notExistPartId[partId];
+ }
+ partIndex = partCount + this._notExistPartId.length;
+ this._notExistPartId[partId] = partIndex;
+ this._notExistPartOpacities[partIndex] = 0;
+ return partIndex;
+ }
+ getPartId(partIndex) {
+ return this._model.parts.ids[partIndex];
+ }
+ getPartCount() {
+ return this._model.parts.count;
+ }
+ setPartOpacityByIndex(partIndex, opacity) {
+ if (partIndex in this._notExistPartOpacities) {
+ this._notExistPartOpacities[partIndex] = opacity;
+ return;
+ }
+ CSM_ASSERT(0 <= partIndex && partIndex < this.getPartCount());
+ this._partOpacities[partIndex] = opacity;
+ }
+ setPartOpacityById(partId, opacity) {
+ const index = this.getPartIndex(partId);
+ if (index < 0) {
+ return;
+ }
+ this.setPartOpacityByIndex(index, opacity);
+ }
+ getPartOpacityByIndex(partIndex) {
+ if (partIndex in this._notExistPartOpacities) {
+ return this._notExistPartOpacities[partIndex];
+ }
+ CSM_ASSERT(0 <= partIndex && partIndex < this.getPartCount());
+ return this._partOpacities[partIndex];
+ }
+ getPartOpacityById(partId) {
+ const index = this.getPartIndex(partId);
+ if (index < 0) {
+ return 0;
+ }
+ return this.getPartOpacityByIndex(index);
+ }
+ getParameterIndex(parameterId) {
+ let parameterIndex;
+ const idCount = this._model.parameters.count;
+ for (parameterIndex = 0; parameterIndex < idCount; ++parameterIndex) {
+ if (parameterId != this._parameterIds[parameterIndex]) {
+ continue;
+ }
+ return parameterIndex;
+ }
+ if (parameterId in this._notExistParameterId) {
+ return this._notExistParameterId[parameterId];
+ }
+ parameterIndex = this._model.parameters.count + Object.keys(this._notExistParameterId).length;
+ this._notExistParameterId[parameterId] = parameterIndex;
+ this._notExistParameterValues[parameterIndex] = 0;
+ return parameterIndex;
+ }
+ getParameterCount() {
+ return this._model.parameters.count;
+ }
+ getParameterType(parameterIndex) {
+ return this._model.parameters.types[parameterIndex];
+ }
+ getParameterMaximumValue(parameterIndex) {
+ return this._model.parameters.maximumValues[parameterIndex];
+ }
+ getParameterMinimumValue(parameterIndex) {
+ return this._model.parameters.minimumValues[parameterIndex];
+ }
+ getParameterDefaultValue(parameterIndex) {
+ return this._model.parameters.defaultValues[parameterIndex];
+ }
+ getParameterValueByIndex(parameterIndex) {
+ if (parameterIndex in this._notExistParameterValues) {
+ return this._notExistParameterValues[parameterIndex];
+ }
+ CSM_ASSERT(0 <= parameterIndex && parameterIndex < this.getParameterCount());
+ return this._parameterValues[parameterIndex];
+ }
+ getParameterValueById(parameterId) {
+ const parameterIndex = this.getParameterIndex(parameterId);
+ return this.getParameterValueByIndex(parameterIndex);
+ }
+ setParameterValueByIndex(parameterIndex, value, weight = 1) {
+ if (parameterIndex in this._notExistParameterValues) {
+ this._notExistParameterValues[parameterIndex] = weight == 1 ? value : this._notExistParameterValues[parameterIndex] * (1 - weight) + value * weight;
+ return;
+ }
+ CSM_ASSERT(0 <= parameterIndex && parameterIndex < this.getParameterCount());
+ if (this._model.parameters.maximumValues[parameterIndex] < value) {
+ value = this._model.parameters.maximumValues[parameterIndex];
+ }
+ if (this._model.parameters.minimumValues[parameterIndex] > value) {
+ value = this._model.parameters.minimumValues[parameterIndex];
+ }
+ this._parameterValues[parameterIndex] = weight == 1 ? value : this._parameterValues[parameterIndex] = this._parameterValues[parameterIndex] * (1 - weight) + value * weight;
+ }
+ setParameterValueById(parameterId, value, weight = 1) {
+ const index = this.getParameterIndex(parameterId);
+ this.setParameterValueByIndex(index, value, weight);
+ }
+ addParameterValueByIndex(parameterIndex, value, weight = 1) {
+ this.setParameterValueByIndex(parameterIndex, this.getParameterValueByIndex(parameterIndex) + value * weight);
+ }
+ addParameterValueById(parameterId, value, weight = 1) {
+ const index = this.getParameterIndex(parameterId);
+ this.addParameterValueByIndex(index, value, weight);
+ }
+ multiplyParameterValueById(parameterId, value, weight = 1) {
+ const index = this.getParameterIndex(parameterId);
+ this.multiplyParameterValueByIndex(index, value, weight);
+ }
+ multiplyParameterValueByIndex(parameterIndex, value, weight = 1) {
+ this.setParameterValueByIndex(parameterIndex, this.getParameterValueByIndex(parameterIndex) * (1 + (value - 1) * weight));
+ }
+ getDrawableIds() {
+ return this._drawableIds.slice();
+ }
+ getDrawableIndex(drawableId) {
+ const drawableCount = this._model.drawables.count;
+ for (let drawableIndex = 0; drawableIndex < drawableCount; ++drawableIndex) {
+ if (this._drawableIds[drawableIndex] == drawableId) {
+ return drawableIndex;
+ }
+ }
+ return -1;
+ }
+ getDrawableCount() {
+ return this._model.drawables.count;
+ }
+ getDrawableId(drawableIndex) {
+ return this._model.drawables.ids[drawableIndex];
+ }
+ getDrawableRenderOrders() {
+ return this._model.drawables.renderOrders;
+ }
+ getDrawableTextureIndices(drawableIndex) {
+ return this.getDrawableTextureIndex(drawableIndex);
+ }
+ getDrawableTextureIndex(drawableIndex) {
+ const textureIndices = this._model.drawables.textureIndices;
+ return textureIndices[drawableIndex];
+ }
+ getDrawableDynamicFlagVertexPositionsDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasVertexPositionsDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableVertexIndexCount(drawableIndex) {
+ return this._model.drawables.indexCounts[drawableIndex];
+ }
+ getDrawableVertexCount(drawableIndex) {
+ return this._model.drawables.vertexCounts[drawableIndex];
+ }
+ getDrawableVertices(drawableIndex) {
+ return this.getDrawableVertexPositions(drawableIndex);
+ }
+ getDrawableVertexIndices(drawableIndex) {
+ return this._model.drawables.indices[drawableIndex];
+ }
+ getDrawableVertexPositions(drawableIndex) {
+ return this._model.drawables.vertexPositions[drawableIndex];
+ }
+ getDrawableVertexUvs(drawableIndex) {
+ return this._model.drawables.vertexUvs[drawableIndex];
+ }
+ getDrawableOpacity(drawableIndex) {
+ return this._model.drawables.opacities[drawableIndex];
+ }
+ getDrawableMultiplyColor(drawableIndex) {
+ const multiplyColors = this._model.drawables.multiplyColors;
+ const index = drawableIndex * 4;
+ const multiplyColor = new CubismTextureColor();
+ multiplyColor.R = multiplyColors[index];
+ multiplyColor.G = multiplyColors[index + 1];
+ multiplyColor.B = multiplyColors[index + 2];
+ multiplyColor.A = multiplyColors[index + 3];
+ return multiplyColor;
+ }
+ getDrawableScreenColor(drawableIndex) {
+ const screenColors = this._model.drawables.screenColors;
+ const index = drawableIndex * 4;
+ const screenColor = new CubismTextureColor();
+ screenColor.R = screenColors[index];
+ screenColor.G = screenColors[index + 1];
+ screenColor.B = screenColors[index + 2];
+ screenColor.A = screenColors[index + 3];
+ return screenColor;
+ }
+ getDrawableParentPartIndex(drawableIndex) {
+ return this._model.drawables.parentPartIndices[drawableIndex];
+ }
+ getDrawableBlendMode(drawableIndex) {
+ const constantFlags = this._model.drawables.constantFlags;
+ return Live2DCubismCore.Utils.hasBlendAdditiveBit(constantFlags[drawableIndex]) ? CubismBlendMode.CubismBlendMode_Additive : Live2DCubismCore.Utils.hasBlendMultiplicativeBit(constantFlags[drawableIndex]) ? CubismBlendMode.CubismBlendMode_Multiplicative : CubismBlendMode.CubismBlendMode_Normal;
+ }
+ getDrawableInvertedMaskBit(drawableIndex) {
+ const constantFlags = this._model.drawables.constantFlags;
+ return Live2DCubismCore.Utils.hasIsInvertedMaskBit(constantFlags[drawableIndex]);
+ }
+ getDrawableMasks() {
+ return this._model.drawables.masks;
+ }
+ getDrawableMaskCounts() {
+ return this._model.drawables.maskCounts;
+ }
+ isUsingMasking() {
+ for (let d = 0; d < this._model.drawables.count; ++d) {
+ if (this._model.drawables.maskCounts[d] <= 0) {
+ continue;
+ }
+ return true;
+ }
+ return false;
+ }
+ getDrawableDynamicFlagIsVisible(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasIsVisibleBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagVisibilityDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasVisibilityDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagOpacityDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasOpacityDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagRenderOrderDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasRenderOrderDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagBlendColorDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasBlendColorDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ loadParameters() {
+ let parameterCount = this._model.parameters.count;
+ const savedParameterCount = this._savedParameters.length;
+ if (parameterCount > savedParameterCount) {
+ parameterCount = savedParameterCount;
+ }
+ for (let i = 0; i < parameterCount; ++i) {
+ this._parameterValues[i] = this._savedParameters[i];
+ }
+ }
+ initialize() {
+ this._parameterValues = this._model.parameters.values;
+ this._partOpacities = this._model.parts.opacities;
+ this._parameterMaximumValues = this._model.parameters.maximumValues;
+ this._parameterMinimumValues = this._model.parameters.minimumValues;
+ {
+ const parameterIds = this._model.parameters.ids;
+ const parameterCount = this._model.parameters.count;
+ for (let i = 0; i < parameterCount; ++i) {
+ this._parameterIds.push(parameterIds[i]);
+ }
+ }
+ const partCount = this._model.parts.count;
+ {
+ const partIds = this._model.parts.ids;
+ for (let i = 0; i < partCount; ++i) {
+ this._partIds.push(partIds[i]);
+ }
+ }
+ {
+ const drawableIds = this._model.drawables.ids;
+ const drawableCount = this._model.drawables.count;
+ const userCulling = new DrawableCullingData(false, false);
+ {
+ for (let i = 0; i < partCount; ++i) {
+ const multiplyColor = new CubismTextureColor(1, 1, 1, 1);
+ const screenColor = new CubismTextureColor(0, 0, 0, 1);
+ const userMultiplyColor = new PartColorData(false, multiplyColor);
+ const userScreenColor = new PartColorData(false, screenColor);
+ this._userPartMultiplyColors.push(userMultiplyColor);
+ this._userPartScreenColors.push(userScreenColor);
+ this._partChildDrawables.push([]);
+ }
+ }
+ {
+ for (let i = 0; i < drawableCount; ++i) {
+ const multiplyColor = new CubismTextureColor(1, 1, 1, 1);
+ const screenColor = new CubismTextureColor(0, 0, 0, 1);
+ const userMultiplyColor = new DrawableColorData(false, multiplyColor);
+ const userScreenColor = new DrawableColorData(false, screenColor);
+ this._drawableIds.push(drawableIds[i]);
+ this._userMultiplyColors.push(userMultiplyColor);
+ this._userScreenColors.push(userScreenColor);
+ this._userCullings.push(userCulling);
+ const parentIndex = this.getDrawableParentPartIndex(i);
+ if (parentIndex >= 0) {
+ this._partChildDrawables[parentIndex].push(i);
+ }
+ }
+ }
+ }
+ }
+ constructor(model) {
+ this._model = model;
+ this._savedParameters = [];
+ this._parameterIds = [];
+ this._drawableIds = [];
+ this._partIds = [];
+ this._isOverwrittenModelMultiplyColors = false;
+ this._isOverwrittenModelScreenColors = false;
+ this._isOverwrittenCullings = false;
+ this._modelOpacity = 1;
+ this._userMultiplyColors = [];
+ this._userScreenColors = [];
+ this._userCullings = [];
+ this._userPartMultiplyColors = [];
+ this._userPartScreenColors = [];
+ this._partChildDrawables = [];
+ this._notExistPartId = {};
+ this._notExistParameterId = {};
+ this._notExistParameterValues = {};
+ this._notExistPartOpacities = {};
+ this.initialize();
+ }
+ release() {
+ this._model.release();
+ this._model = void 0;
+ }
+}
+class CubismMoc {
+ static create(mocBytes, shouldCheckMocConsistency) {
+ if (shouldCheckMocConsistency) {
+ const consistency = this.hasMocConsistency(mocBytes);
+ if (!consistency) {
+ throw new Error(`Inconsistent MOC3.`);
+ }
+ }
+ const moc = Live2DCubismCore.Moc.fromArrayBuffer(mocBytes);
+ if (moc) {
+ const cubismMoc = new CubismMoc(moc);
+ cubismMoc._mocVersion = Live2DCubismCore.Version.csmGetMocVersion(moc, mocBytes);
+ return cubismMoc;
+ }
+ throw new Error("Failed to CubismMoc.create().");
+ }
+ createModel() {
+ let cubismModel;
+ const model = Live2DCubismCore.Model.fromMoc(this._moc);
+ if (model) {
+ cubismModel = new CubismModel(model);
+ ++this._modelCount;
+ return cubismModel;
+ }
+ throw new Error("Unknown error");
+ }
+ deleteModel(model) {
+ if (model != null) {
+ --this._modelCount;
+ }
+ }
+ constructor(moc) {
+ this._moc = moc;
+ this._modelCount = 0;
+ this._mocVersion = 0;
+ }
+ release() {
+ this._moc._release();
+ this._moc = void 0;
+ }
+ getLatestMocVersion() {
+ return Live2DCubismCore.Version.csmGetLatestMocVersion();
+ }
+ getMocVersion() {
+ return this._mocVersion;
+ }
+ static hasMocConsistency(mocBytes) {
+ const isConsistent = Live2DCubismCore.Moc.prototype.hasMocConsistency(mocBytes);
+ return isConsistent === 1 ? true : false;
+ }
+}
+var CubismPhysicsTargetType = /* @__PURE__ */ ((CubismPhysicsTargetType2) => {
+ CubismPhysicsTargetType2[CubismPhysicsTargetType2["CubismPhysicsTargetType_Parameter"] = 0] = "CubismPhysicsTargetType_Parameter";
+ return CubismPhysicsTargetType2;
+})(CubismPhysicsTargetType || {});
+var CubismPhysicsSource = /* @__PURE__ */ ((CubismPhysicsSource2) => {
+ CubismPhysicsSource2[CubismPhysicsSource2["CubismPhysicsSource_X"] = 0] = "CubismPhysicsSource_X";
+ CubismPhysicsSource2[CubismPhysicsSource2["CubismPhysicsSource_Y"] = 1] = "CubismPhysicsSource_Y";
+ CubismPhysicsSource2[CubismPhysicsSource2["CubismPhysicsSource_Angle"] = 2] = "CubismPhysicsSource_Angle";
+ return CubismPhysicsSource2;
+})(CubismPhysicsSource || {});
+class CubismPhysicsParticle {
+ constructor() {
+ this.initialPosition = new CubismVector2(0, 0);
+ this.position = new CubismVector2(0, 0);
+ this.lastPosition = new CubismVector2(0, 0);
+ this.lastGravity = new CubismVector2(0, 0);
+ this.force = new CubismVector2(0, 0);
+ this.velocity = new CubismVector2(0, 0);
+ }
+}
+class CubismPhysicsSubRig {
+ constructor() {
+ this.normalizationPosition = {};
+ this.normalizationAngle = {};
+ }
+}
+class CubismPhysicsInput {
+ constructor() {
+ this.source = {};
+ }
+}
+class CubismPhysicsOutput {
+ constructor() {
+ this.destination = {};
+ this.translationScale = new CubismVector2(0, 0);
+ }
+}
+class CubismPhysicsRig {
+ constructor() {
+ this.settings = [];
+ this.inputs = [];
+ this.outputs = [];
+ this.particles = [];
+ this.gravity = new CubismVector2(0, 0);
+ this.wind = new CubismVector2(0, 0);
+ this.fps = 0;
+ }
+}
+class CubismPhysicsJson {
+ constructor(json) {
+ this._json = json;
+ }
+ release() {
+ this._json = void 0;
+ }
+ getGravity() {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this._json.Meta.EffectiveForces.Gravity.X;
+ ret.y = this._json.Meta.EffectiveForces.Gravity.Y;
+ return ret;
+ }
+ getWind() {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this._json.Meta.EffectiveForces.Wind.X;
+ ret.y = this._json.Meta.EffectiveForces.Wind.Y;
+ return ret;
+ }
+ getFps() {
+ return this._json.Meta.Fps || 0;
+ }
+ getSubRigCount() {
+ return this._json.Meta.PhysicsSettingCount;
+ }
+ getTotalInputCount() {
+ return this._json.Meta.TotalInputCount;
+ }
+ getTotalOutputCount() {
+ return this._json.Meta.TotalOutputCount;
+ }
+ getVertexCount() {
+ return this._json.Meta.VertexCount;
+ }
+ getNormalizationPositionMinimumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Position.Minimum;
+ }
+ getNormalizationPositionMaximumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Position.Maximum;
+ }
+ getNormalizationPositionDefaultValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Position.Default;
+ }
+ getNormalizationAngleMinimumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Angle.Minimum;
+ }
+ getNormalizationAngleMaximumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Angle.Maximum;
+ }
+ getNormalizationAngleDefaultValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Angle.Default;
+ }
+ getInputCount(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input.length;
+ }
+ getInputWeight(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Weight;
+ }
+ getInputReflect(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Reflect;
+ }
+ getInputType(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Type;
+ }
+ getInputSourceId(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Source.Id;
+ }
+ getOutputCount(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output.length;
+ }
+ getOutputVertexIndex(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].VertexIndex;
+ }
+ getOutputAngleScale(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Scale;
+ }
+ getOutputWeight(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Weight;
+ }
+ getOutputDestinationId(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Destination.Id;
+ }
+ getOutputType(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Type;
+ }
+ getOutputReflect(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Reflect;
+ }
+ getParticleCount(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices.length;
+ }
+ getParticleMobility(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Mobility;
+ }
+ getParticleDelay(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Delay;
+ }
+ getParticleAcceleration(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Acceleration;
+ }
+ getParticleRadius(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Radius;
+ }
+ getParticlePosition(physicsSettingIndex, vertexIndex) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Position.X;
+ ret.y = this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Position.Y;
+ return ret;
+ }
+}
+const PhysicsTypeTagX = "X";
+const PhysicsTypeTagY = "Y";
+const PhysicsTypeTagAngle = "Angle";
+const AirResistance = 5;
+const MaximumWeight = 100;
+const MovementThreshold = 1e-3;
+const MaxDeltaTime = 5;
+class CubismPhysics {
+ static create(json) {
+ const ret = new CubismPhysics();
+ ret.parse(json);
+ ret._physicsRig.gravity.y = 0;
+ return ret;
+ }
+ static delete(physics) {
+ if (physics != null) {
+ physics.release();
+ }
+ }
+ parse(physicsJson) {
+ this._physicsRig = new CubismPhysicsRig();
+ const json = new CubismPhysicsJson(physicsJson);
+ this._physicsRig.gravity = json.getGravity();
+ this._physicsRig.wind = json.getWind();
+ this._physicsRig.subRigCount = json.getSubRigCount();
+ this._physicsRig.fps = json.getFps();
+ this._currentRigOutputs = [];
+ this._previousRigOutputs = [];
+ let inputIndex = 0, outputIndex = 0, particleIndex = 0;
+ for (let i = 0; i < this._physicsRig.subRigCount; ++i) {
+ const setting = new CubismPhysicsSubRig();
+ setting.normalizationPosition.minimum = json.getNormalizationPositionMinimumValue(i);
+ setting.normalizationPosition.maximum = json.getNormalizationPositionMaximumValue(i);
+ setting.normalizationPosition.defalut = json.getNormalizationPositionDefaultValue(i);
+ setting.normalizationAngle.minimum = json.getNormalizationAngleMinimumValue(i);
+ setting.normalizationAngle.maximum = json.getNormalizationAngleMaximumValue(i);
+ setting.normalizationAngle.defalut = json.getNormalizationAngleDefaultValue(i);
+ setting.inputCount = json.getInputCount(i);
+ setting.baseInputIndex = inputIndex;
+ inputIndex += setting.inputCount;
+ for (let j = 0; j < setting.inputCount; ++j) {
+ const input = new CubismPhysicsInput();
+ input.sourceParameterIndex = -1;
+ input.weight = json.getInputWeight(i, j);
+ input.reflect = json.getInputReflect(i, j);
+ switch (json.getInputType(i, j)) {
+ case PhysicsTypeTagX:
+ input.type = CubismPhysicsSource.CubismPhysicsSource_X;
+ input.getNormalizedParameterValue = getInputTranslationXFromNormalizedParameterValue;
+ break;
+ case PhysicsTypeTagY:
+ input.type = CubismPhysicsSource.CubismPhysicsSource_Y;
+ input.getNormalizedParameterValue = getInputTranslationYFromNormalizedParamterValue;
+ break;
+ case PhysicsTypeTagAngle:
+ input.type = CubismPhysicsSource.CubismPhysicsSource_Angle;
+ input.getNormalizedParameterValue = getInputAngleFromNormalizedParameterValue;
+ break;
+ }
+ input.source.targetType = CubismPhysicsTargetType.CubismPhysicsTargetType_Parameter;
+ input.source.id = json.getInputSourceId(i, j);
+ this._physicsRig.inputs.push(input);
+ }
+ setting.outputCount = json.getOutputCount(i);
+ setting.baseOutputIndex = outputIndex;
+ const currentRigOutput = new PhysicsOutput();
+ const previousRigOutput = new PhysicsOutput();
+ for (let j = 0; j < setting.outputCount; ++j) {
+ currentRigOutput.outputs[j] = 0;
+ previousRigOutput.outputs[j] = 0;
+ let output = this._physicsRig.outputs[outputIndex + j];
+ if (!output) {
+ output = new CubismPhysicsOutput();
+ this._physicsRig.outputs[outputIndex + j] = output;
+ }
+ output.destinationParameterIndex = -1;
+ output.vertexIndex = json.getOutputVertexIndex(i, j);
+ output.angleScale = json.getOutputAngleScale(i, j);
+ output.weight = json.getOutputWeight(i, j);
+ output.destination.targetType = CubismPhysicsTargetType.CubismPhysicsTargetType_Parameter;
+ output.destination.id = json.getOutputDestinationId(i, j);
+ switch (json.getOutputType(i, j)) {
+ case PhysicsTypeTagX:
+ output.type = CubismPhysicsSource.CubismPhysicsSource_X;
+ output.getValue = getOutputTranslationX;
+ output.getScale = getOutputScaleTranslationX;
+ break;
+ case PhysicsTypeTagY:
+ output.type = CubismPhysicsSource.CubismPhysicsSource_Y;
+ output.getValue = getOutputTranslationY;
+ output.getScale = getOutputScaleTranslationY;
+ break;
+ case PhysicsTypeTagAngle:
+ output.type = CubismPhysicsSource.CubismPhysicsSource_Angle;
+ output.getValue = getOutputAngle;
+ output.getScale = getOutputScaleAngle;
+ break;
+ }
+ output.reflect = json.getOutputReflect(i, j);
+ }
+ this._currentRigOutputs.push(currentRigOutput);
+ this._previousRigOutputs.push(previousRigOutput);
+ outputIndex += setting.outputCount;
+ setting.particleCount = json.getParticleCount(i);
+ setting.baseParticleIndex = particleIndex;
+ particleIndex += setting.particleCount;
+ for (let j = 0; j < setting.particleCount; ++j) {
+ const particle = new CubismPhysicsParticle();
+ particle.mobility = json.getParticleMobility(i, j);
+ particle.delay = json.getParticleDelay(i, j);
+ particle.acceleration = json.getParticleAcceleration(i, j);
+ particle.radius = json.getParticleRadius(i, j);
+ particle.position = json.getParticlePosition(i, j);
+ this._physicsRig.particles.push(particle);
+ }
+ this._physicsRig.settings.push(setting);
+ }
+ this.initialize();
+ json.release();
+ }
+ stabilization(model) {
+ var _a, _b, _c, _d;
+ let totalAngle;
+ let weight;
+ let radAngle;
+ let outputValue;
+ const totalTranslation = new CubismVector2();
+ let currentSetting;
+ let currentInputs;
+ let currentOutputs;
+ let currentParticles;
+ let parameterValues;
+ let parameterMaximumValues;
+ let parameterMinimumValues;
+ let parameterDefaultValues;
+ parameterValues = model.getModel().parameters.values;
+ parameterMaximumValues = model.getModel().parameters.maximumValues;
+ parameterMinimumValues = model.getModel().parameters.minimumValues;
+ parameterDefaultValues = model.getModel().parameters.defaultValues;
+ if (((_b = (_a = this._parameterCaches) == null ? void 0 : _a.length) != null ? _b : 0) < model.getParameterCount()) {
+ this._parameterCaches = new Float32Array(model.getParameterCount());
+ }
+ if (((_d = (_c = this._parameterInputCaches) == null ? void 0 : _c.length) != null ? _d : 0) < model.getParameterCount()) {
+ this._parameterInputCaches = new Float32Array(model.getParameterCount());
+ }
+ for (let j = 0; j < model.getParameterCount(); ++j) {
+ this._parameterCaches[j] = parameterValues[j];
+ this._parameterInputCaches[j] = parameterValues[j];
+ }
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ totalAngle = { angle: 0 };
+ totalTranslation.x = 0;
+ totalTranslation.y = 0;
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentInputs = this._physicsRig.inputs.slice(currentSetting.baseInputIndex);
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ currentParticles = this._physicsRig.particles.slice(currentSetting.baseParticleIndex);
+ for (let i = 0; i < currentSetting.inputCount; ++i) {
+ weight = currentInputs[i].weight / MaximumWeight;
+ if (currentInputs[i].sourceParameterIndex == -1) {
+ currentInputs[i].sourceParameterIndex = model.getParameterIndex(currentInputs[i].source.id);
+ }
+ currentInputs[i].getNormalizedParameterValue(totalTranslation, totalAngle, parameterValues[currentInputs[i].sourceParameterIndex], parameterMinimumValues[currentInputs[i].sourceParameterIndex], parameterMaximumValues[currentInputs[i].sourceParameterIndex], parameterDefaultValues[currentInputs[i].sourceParameterIndex], currentSetting.normalizationPosition, currentSetting.normalizationAngle, currentInputs[i].reflect, weight);
+ this._parameterCaches[currentInputs[i].sourceParameterIndex] = parameterValues[currentInputs[i].sourceParameterIndex];
+ }
+ radAngle = CubismMath.degreesToRadian(-totalAngle.angle);
+ totalTranslation.x = totalTranslation.x * CubismMath.cos(radAngle) - totalTranslation.y * CubismMath.sin(radAngle);
+ totalTranslation.y = totalTranslation.x * CubismMath.sin(radAngle) + totalTranslation.y * CubismMath.cos(radAngle);
+ updateParticlesForStabilization(currentParticles, currentSetting.particleCount, totalTranslation, totalAngle.angle, this._options.wind, MovementThreshold * currentSetting.normalizationPosition.maximum);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ const particleIndex = currentOutputs[i].vertexIndex;
+ if (currentOutputs[i].destinationParameterIndex == -1) {
+ currentOutputs[i].destinationParameterIndex = model.getParameterIndex(currentOutputs[i].destination.id);
+ }
+ if (particleIndex < 1 || particleIndex >= currentSetting.particleCount) {
+ continue;
+ }
+ let translation = new CubismVector2();
+ translation = currentParticles[particleIndex].position.substract(currentParticles[particleIndex - 1].position);
+ outputValue = currentOutputs[i].getValue(translation, currentParticles, particleIndex, currentOutputs[i].reflect, this._options.gravity);
+ this._currentRigOutputs[settingIndex].outputs[i] = outputValue;
+ this._previousRigOutputs[settingIndex].outputs[i] = outputValue;
+ const destinationParameterIndex = currentOutputs[i].destinationParameterIndex;
+ const outParameterCaches = !Float32Array.prototype.slice && "subarray" in Float32Array.prototype ? JSON.parse(JSON.stringify(parameterValues.subarray(destinationParameterIndex))) : parameterValues.slice(destinationParameterIndex);
+ updateOutputParameterValue(outParameterCaches, parameterMinimumValues[destinationParameterIndex], parameterMaximumValues[destinationParameterIndex], outputValue, currentOutputs[i]);
+ for (let offset = destinationParameterIndex, outParamIndex = 0; offset < this._parameterCaches.length; offset++, outParamIndex++) {
+ parameterValues[offset] = this._parameterCaches[offset] = outParameterCaches[outParamIndex];
+ }
+ }
+ }
+ }
+ evaluate(model, deltaTimeSeconds) {
+ var _a, _b, _c, _d;
+ let totalAngle;
+ let weight;
+ let radAngle;
+ let outputValue;
+ const totalTranslation = new CubismVector2();
+ let currentSetting;
+ let currentInputs;
+ let currentOutputs;
+ let currentParticles;
+ if (0 >= deltaTimeSeconds) {
+ return;
+ }
+ let parameterValues;
+ let parameterMaximumValues;
+ let parameterMinimumValues;
+ let parameterDefaultValues;
+ let physicsDeltaTime;
+ this._currentRemainTime += deltaTimeSeconds;
+ if (this._currentRemainTime > MaxDeltaTime) {
+ this._currentRemainTime = 0;
+ }
+ parameterValues = model.getModel().parameters.values;
+ parameterMaximumValues = model.getModel().parameters.maximumValues;
+ parameterMinimumValues = model.getModel().parameters.minimumValues;
+ parameterDefaultValues = model.getModel().parameters.defaultValues;
+ if (((_b = (_a = this._parameterCaches) == null ? void 0 : _a.length) != null ? _b : 0) < model.getParameterCount()) {
+ this._parameterCaches = new Float32Array(model.getParameterCount());
+ }
+ if (((_d = (_c = this._parameterInputCaches) == null ? void 0 : _c.length) != null ? _d : 0) < model.getParameterCount()) {
+ this._parameterInputCaches = new Float32Array(model.getParameterCount());
+ for (let j = 0; j < model.getParameterCount(); ++j) {
+ this._parameterInputCaches[j] = parameterValues[j];
+ }
+ }
+ if (this._physicsRig.fps > 0) {
+ physicsDeltaTime = 1 / this._physicsRig.fps;
+ } else {
+ physicsDeltaTime = deltaTimeSeconds;
+ }
+ while (this._currentRemainTime >= physicsDeltaTime) {
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ this._previousRigOutputs[settingIndex].outputs[i] = this._currentRigOutputs[settingIndex].outputs[i];
+ }
+ }
+ const inputWeight = physicsDeltaTime / this._currentRemainTime;
+ for (let j = 0; j < model.getParameterCount(); ++j) {
+ this._parameterCaches[j] = this._parameterInputCaches[j] * (1 - inputWeight) + parameterValues[j] * inputWeight;
+ this._parameterInputCaches[j] = this._parameterCaches[j];
+ }
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ totalAngle = { angle: 0 };
+ totalTranslation.x = 0;
+ totalTranslation.y = 0;
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentInputs = this._physicsRig.inputs.slice(currentSetting.baseInputIndex);
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ currentParticles = this._physicsRig.particles.slice(currentSetting.baseParticleIndex);
+ for (let i = 0; i < currentSetting.inputCount; ++i) {
+ weight = currentInputs[i].weight / MaximumWeight;
+ if (currentInputs[i].sourceParameterIndex == -1) {
+ currentInputs[i].sourceParameterIndex = model.getParameterIndex(currentInputs[i].source.id);
+ }
+ currentInputs[i].getNormalizedParameterValue(totalTranslation, totalAngle, this._parameterCaches[currentInputs[i].sourceParameterIndex], parameterMinimumValues[currentInputs[i].sourceParameterIndex], parameterMaximumValues[currentInputs[i].sourceParameterIndex], parameterDefaultValues[currentInputs[i].sourceParameterIndex], currentSetting.normalizationPosition, currentSetting.normalizationAngle, currentInputs[i].reflect, weight);
+ }
+ radAngle = CubismMath.degreesToRadian(-totalAngle.angle);
+ totalTranslation.x = totalTranslation.x * CubismMath.cos(radAngle) - totalTranslation.y * CubismMath.sin(radAngle);
+ totalTranslation.y = totalTranslation.x * CubismMath.sin(radAngle) + totalTranslation.y * CubismMath.cos(radAngle);
+ updateParticles(currentParticles, currentSetting.particleCount, totalTranslation, totalAngle.angle, this._options.wind, MovementThreshold * currentSetting.normalizationPosition.maximum, physicsDeltaTime, AirResistance);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ const particleIndex = currentOutputs[i].vertexIndex;
+ if (currentOutputs[i].destinationParameterIndex == -1) {
+ currentOutputs[i].destinationParameterIndex = model.getParameterIndex(currentOutputs[i].destination.id);
+ }
+ if (particleIndex < 1 || particleIndex >= currentSetting.particleCount) {
+ continue;
+ }
+ const translation = new CubismVector2();
+ translation.x = currentParticles[particleIndex].position.x - currentParticles[particleIndex - 1].position.x;
+ translation.y = currentParticles[particleIndex].position.y - currentParticles[particleIndex - 1].position.y;
+ outputValue = currentOutputs[i].getValue(translation, currentParticles, particleIndex, currentOutputs[i].reflect, this._options.gravity);
+ this._currentRigOutputs[settingIndex].outputs[i] = outputValue;
+ const destinationParameterIndex = currentOutputs[i].destinationParameterIndex;
+ const outParameterCaches = !Float32Array.prototype.slice && "subarray" in Float32Array.prototype ? JSON.parse(JSON.stringify(this._parameterCaches.subarray(destinationParameterIndex))) : this._parameterCaches.slice(destinationParameterIndex);
+ updateOutputParameterValue(outParameterCaches, parameterMinimumValues[destinationParameterIndex], parameterMaximumValues[destinationParameterIndex], outputValue, currentOutputs[i]);
+ for (let offset = destinationParameterIndex, outParamIndex = 0; offset < this._parameterCaches.length; offset++, outParamIndex++) {
+ this._parameterCaches[offset] = outParameterCaches[outParamIndex];
+ }
+ }
+ }
+ this._currentRemainTime -= physicsDeltaTime;
+ }
+ const alpha = this._currentRemainTime / physicsDeltaTime;
+ this.interpolate(model, alpha);
+ }
+ interpolate(model, weight) {
+ let currentOutputs;
+ let currentSetting;
+ let parameterValues;
+ let parameterMaximumValues;
+ let parameterMinimumValues;
+ parameterValues = model.getModel().parameters.values;
+ parameterMaximumValues = model.getModel().parameters.maximumValues;
+ parameterMinimumValues = model.getModel().parameters.minimumValues;
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ if (currentOutputs[i].destinationParameterIndex == -1) {
+ continue;
+ }
+ const destinationParameterIndex = currentOutputs[i].destinationParameterIndex;
+ const outParameterValues = !Float32Array.prototype.slice && "subarray" in Float32Array.prototype ? JSON.parse(JSON.stringify(parameterValues.subarray(destinationParameterIndex))) : parameterValues.slice(destinationParameterIndex);
+ updateOutputParameterValue(outParameterValues, parameterMinimumValues[destinationParameterIndex], parameterMaximumValues[destinationParameterIndex], this._previousRigOutputs[settingIndex].outputs[i] * (1 - weight) + this._currentRigOutputs[settingIndex].outputs[i] * weight, currentOutputs[i]);
+ for (let offset = destinationParameterIndex, outParamIndex = 0; offset < parameterValues.length; offset++, outParamIndex++) {
+ parameterValues[offset] = outParameterValues[outParamIndex];
+ }
+ }
+ }
+ }
+ setOptions(options) {
+ this._options = options;
+ }
+ getOption() {
+ return this._options;
+ }
+ constructor() {
+ this._options = new Options();
+ this._options.gravity.y = -1;
+ this._options.gravity.x = 0;
+ this._options.wind.x = 0;
+ this._options.wind.y = 0;
+ this._currentRigOutputs = [];
+ this._previousRigOutputs = [];
+ this._currentRemainTime = 0;
+ }
+ release() {
+ this._physicsRig = void 0;
+ }
+ initialize() {
+ let strand;
+ let currentSetting;
+ let radius;
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ currentSetting = this._physicsRig.settings[settingIndex];
+ strand = this._physicsRig.particles.slice(currentSetting.baseParticleIndex);
+ strand[0].initialPosition = new CubismVector2(0, 0);
+ strand[0].lastPosition = new CubismVector2(strand[0].initialPosition.x, strand[0].initialPosition.y);
+ strand[0].lastGravity = new CubismVector2(0, -1);
+ strand[0].lastGravity.y *= -1;
+ strand[0].velocity = new CubismVector2(0, 0);
+ strand[0].force = new CubismVector2(0, 0);
+ for (let i = 1; i < currentSetting.particleCount; ++i) {
+ radius = new CubismVector2(0, 0);
+ radius.y = strand[i].radius;
+ strand[i].initialPosition = new CubismVector2(strand[i - 1].initialPosition.x + radius.x, strand[i - 1].initialPosition.y + radius.y);
+ strand[i].position = new CubismVector2(strand[i].initialPosition.x, strand[i].initialPosition.y);
+ strand[i].lastPosition = new CubismVector2(strand[i].initialPosition.x, strand[i].initialPosition.y);
+ strand[i].lastGravity = new CubismVector2(0, -1);
+ strand[i].lastGravity.y *= -1;
+ strand[i].velocity = new CubismVector2(0, 0);
+ strand[i].force = new CubismVector2(0, 0);
+ }
+ }
+ }
+}
+class Options {
+ constructor() {
+ this.gravity = new CubismVector2(0, 0);
+ this.wind = new CubismVector2(0, 0);
+ }
+}
+class PhysicsOutput {
+ constructor() {
+ this.outputs = [];
+ }
+}
+function getInputTranslationXFromNormalizedParameterValue(targetTranslation, targetAngle, value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition, normalizationAngle, isInverted, weight) {
+ targetTranslation.x += normalizeParameterValue(value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition.minimum, normalizationPosition.maximum, normalizationPosition.defalut, isInverted) * weight;
+}
+function getInputTranslationYFromNormalizedParamterValue(targetTranslation, targetAngle, value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition, normalizationAngle, isInverted, weight) {
+ targetTranslation.y += normalizeParameterValue(value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition.minimum, normalizationPosition.maximum, normalizationPosition.defalut, isInverted) * weight;
+}
+function getInputAngleFromNormalizedParameterValue(targetTranslation, targetAngle, value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizaitionPosition, normalizationAngle, isInverted, weight) {
+ targetAngle.angle += normalizeParameterValue(value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationAngle.minimum, normalizationAngle.maximum, normalizationAngle.defalut, isInverted) * weight;
+}
+function getOutputTranslationX(translation, particles, particleIndex, isInverted, parentGravity) {
+ let outputValue = translation.x;
+ if (isInverted) {
+ outputValue *= -1;
+ }
+ return outputValue;
+}
+function getOutputTranslationY(translation, particles, particleIndex, isInverted, parentGravity) {
+ let outputValue = translation.y;
+ if (isInverted) {
+ outputValue *= -1;
+ }
+ return outputValue;
+}
+function getOutputAngle(translation, particles, particleIndex, isInverted, parentGravity) {
+ let outputValue;
+ if (particleIndex >= 2) {
+ parentGravity = particles[particleIndex - 1].position.substract(particles[particleIndex - 2].position);
+ } else {
+ parentGravity = parentGravity.multiplyByScaler(-1);
+ }
+ outputValue = CubismMath.directionToRadian(parentGravity, translation);
+ if (isInverted) {
+ outputValue *= -1;
+ }
+ return outputValue;
+}
+function getRangeValue(min, max) {
+ return Math.abs(Math.max(min, max) - Math.min(min, max));
+}
+function getDefaultValue(min, max) {
+ const minValue = Math.min(min, max);
+ return minValue + getRangeValue(min, max) / 2;
+}
+function getOutputScaleTranslationX(translationScale, angleScale) {
+ return translationScale.x;
+}
+function getOutputScaleTranslationY(translationScale, angleScale) {
+ return translationScale.y;
+}
+function getOutputScaleAngle(translationScale, angleScale) {
+ return angleScale;
+}
+function updateParticles(strand, strandCount, totalTranslation, totalAngle, windDirection, thresholdValue, deltaTimeSeconds, airResistance) {
+ let totalRadian;
+ let delay;
+ let radian;
+ let currentGravity;
+ let direction = new CubismVector2(0, 0);
+ let velocity = new CubismVector2(0, 0);
+ let force = new CubismVector2(0, 0);
+ let newDirection = new CubismVector2(0, 0);
+ strand[0].position = new CubismVector2(totalTranslation.x, totalTranslation.y);
+ totalRadian = CubismMath.degreesToRadian(totalAngle);
+ currentGravity = CubismMath.radianToDirection(totalRadian);
+ currentGravity.normalize();
+ for (let i = 1; i < strandCount; ++i) {
+ strand[i].force = currentGravity.multiplyByScaler(strand[i].acceleration).add(windDirection);
+ strand[i].lastPosition = new CubismVector2(strand[i].position.x, strand[i].position.y);
+ delay = strand[i].delay * deltaTimeSeconds * 30;
+ direction = strand[i].position.substract(strand[i - 1].position);
+ radian = CubismMath.directionToRadian(strand[i].lastGravity, currentGravity) / airResistance;
+ direction.x = CubismMath.cos(radian) * direction.x - direction.y * CubismMath.sin(radian);
+ direction.y = CubismMath.sin(radian) * direction.x + direction.y * CubismMath.cos(radian);
+ strand[i].position = strand[i - 1].position.add(direction);
+ velocity = strand[i].velocity.multiplyByScaler(delay);
+ force = strand[i].force.multiplyByScaler(delay).multiplyByScaler(delay);
+ strand[i].position = strand[i].position.add(velocity).add(force);
+ newDirection = strand[i].position.substract(strand[i - 1].position);
+ newDirection.normalize();
+ strand[i].position = strand[i - 1].position.add(newDirection.multiplyByScaler(strand[i].radius));
+ if (CubismMath.abs(strand[i].position.x) < thresholdValue) {
+ strand[i].position.x = 0;
+ }
+ if (delay != 0) {
+ strand[i].velocity = strand[i].position.substract(strand[i].lastPosition);
+ strand[i].velocity = strand[i].velocity.divisionByScalar(delay);
+ strand[i].velocity = strand[i].velocity.multiplyByScaler(strand[i].mobility);
+ }
+ strand[i].force = new CubismVector2(0, 0);
+ strand[i].lastGravity = new CubismVector2(currentGravity.x, currentGravity.y);
+ }
+}
+function updateParticlesForStabilization(strand, strandCount, totalTranslation, totalAngle, windDirection, thresholdValue) {
+ let totalRadian;
+ let currentGravity;
+ let force = new CubismVector2(0, 0);
+ strand[0].position = new CubismVector2(totalTranslation.x, totalTranslation.y);
+ totalRadian = CubismMath.degreesToRadian(totalAngle);
+ currentGravity = CubismMath.radianToDirection(totalRadian);
+ currentGravity.normalize();
+ for (let i = 1; i < strandCount; ++i) {
+ strand[i].force = currentGravity.multiplyByScaler(strand[i].acceleration).add(windDirection);
+ strand[i].lastPosition = new CubismVector2(strand[i].position.x, strand[i].position.y);
+ strand[i].velocity = new CubismVector2(0, 0);
+ force = strand[i].force;
+ force.normalize();
+ force = force.multiplyByScaler(strand[i].radius);
+ strand[i].position = strand[i - 1].position.add(force);
+ if (CubismMath.abs(strand[i].position.x) < thresholdValue) {
+ strand[i].position.x = 0;
+ }
+ strand[i].force = new CubismVector2(0, 0);
+ strand[i].lastGravity = new CubismVector2(currentGravity.x, currentGravity.y);
+ }
+}
+function updateOutputParameterValue(parameterValue, parameterValueMinimum, parameterValueMaximum, translation, output) {
+ let outputScale;
+ let value;
+ let weight;
+ outputScale = output.getScale(output.translationScale, output.angleScale);
+ value = translation * outputScale;
+ if (value < parameterValueMinimum) {
+ if (value < output.valueBelowMinimum) {
+ output.valueBelowMinimum = value;
+ }
+ value = parameterValueMinimum;
+ } else if (value > parameterValueMaximum) {
+ if (value > output.valueExceededMaximum) {
+ output.valueExceededMaximum = value;
+ }
+ value = parameterValueMaximum;
+ }
+ weight = output.weight / MaximumWeight;
+ if (weight >= 1) {
+ parameterValue[0] = value;
+ } else {
+ value = parameterValue[0] * (1 - weight) + value * weight;
+ parameterValue[0] = value;
+ }
+}
+function normalizeParameterValue(value, parameterMinimum, parameterMaximum, parameterDefault, normalizedMinimum, normalizedMaximum, normalizedDefault, isInverted) {
+ let result = 0;
+ const maxValue = CubismMath.max(parameterMaximum, parameterMinimum);
+ if (maxValue < value) {
+ value = maxValue;
+ }
+ const minValue = CubismMath.min(parameterMaximum, parameterMinimum);
+ if (minValue > value) {
+ value = minValue;
+ }
+ const minNormValue = CubismMath.min(normalizedMinimum, normalizedMaximum);
+ const maxNormValue = CubismMath.max(normalizedMinimum, normalizedMaximum);
+ const middleNormValue = normalizedDefault;
+ const middleValue = getDefaultValue(minValue, maxValue);
+ const paramValue = value - middleValue;
+ switch (Math.sign(paramValue)) {
+ case 1: {
+ const nLength = maxNormValue - middleNormValue;
+ const pLength = maxValue - middleValue;
+ if (pLength != 0) {
+ result = paramValue * (nLength / pLength);
+ result += middleNormValue;
+ }
+ break;
+ }
+ case -1: {
+ const nLength = minNormValue - middleNormValue;
+ const pLength = minValue - middleValue;
+ if (pLength != 0) {
+ result = paramValue * (nLength / pLength);
+ result += middleNormValue;
+ }
+ break;
+ }
+ case 0: {
+ result = middleNormValue;
+ break;
+ }
+ }
+ return isInverted ? result : result * -1;
+}
+Live2DFactory.registerRuntime({
+ version: 4,
+ ready: cubism4Ready,
+ test(source) {
+ return source instanceof Cubism4ModelSettings || Cubism4ModelSettings.isValidJSON(source);
+ },
+ isValidMoc(modelData) {
+ if (modelData.byteLength < 4) {
+ return false;
+ }
+ const view = new Int8Array(modelData, 0, 4);
+ return String.fromCharCode(...view) === "MOC3";
+ },
+ createModelSettings(json) {
+ return new Cubism4ModelSettings(json);
+ },
+ createCoreModel(data, options) {
+ const moc = CubismMoc.create(data, !!(options == null ? void 0 : options.checkMocConsistency));
+ try {
+ const model = moc.createModel();
+ model.__moc = moc;
+ return model;
+ } catch (e) {
+ try {
+ moc.release();
+ } catch (ignored) {
+ }
+ throw e;
+ }
+ },
+ createInternalModel(coreModel, settings, options) {
+ const model = new Cubism4InternalModel(coreModel, settings, options);
+ const coreModelWithMoc = coreModel;
+ if (coreModelWithMoc.__moc) {
+ model.__moc = coreModelWithMoc.__moc;
+ delete coreModelWithMoc.__moc;
+ model.once("destroy", releaseMoc);
+ }
+ return model;
+ },
+ createPhysics(coreModel, data) {
+ return CubismPhysics.create(data);
+ },
+ createPose(coreModel, data) {
+ return CubismPose.create(data);
+ }
+});
+function releaseMoc() {
+ var _a;
+ (_a = this.__moc) == null ? void 0 : _a.release();
+}
+export { Cubism2ExpressionManager, Cubism2InternalModel, Cubism2ModelSettings, Cubism2MotionManager, Cubism4ExpressionManager, Cubism4InternalModel, Cubism4ModelSettings, Cubism4MotionManager, ExpressionManager, FileLoader, FocusController, InteractionMixin, InternalModel, LOGICAL_HEIGHT, LOGICAL_WIDTH, Live2DExpression, Live2DEyeBlink, Live2DFactory, Live2DLoader, Live2DModel, Live2DPhysics, Live2DPose, Live2DTransform, ModelSettings, MotionManager, MotionPreloadStrategy, MotionPriority, MotionState, SoundManager, VERSION, XHRLoader, ZipLoader, applyMixins, clamp, config, copyArray, copyProperty, cubism4Ready, folderName, logger, rand, remove, startUpCubism4 };
diff --git a/dist/index.js b/dist/index.js
new file mode 100644
index 00000000..94507684
--- /dev/null
+++ b/dist/index.js
@@ -0,0 +1,7010 @@
+var __pow = Math.pow;
+var __async = (__this, __arguments, generator) => {
+ return new Promise((resolve, reject) => {
+ var fulfilled = (value) => {
+ try {
+ step(generator.next(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var rejected = (value) => {
+ try {
+ step(generator.throw(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
+ step((generator = generator.apply(__this, __arguments)).next());
+ });
+};
+(function(global, factory) {
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@pixi/utils"), require("@pixi/math"), require("@pixi/core"), require("@pixi/display")) : typeof define === "function" && define.amd ? define(["exports", "@pixi/utils", "@pixi/math", "@pixi/core", "@pixi/display"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory((global.PIXI = global.PIXI || {}, global.PIXI.live2d = global.PIXI.live2d || {}), global.PIXI.utils, global.PIXI, global.PIXI, global.PIXI));
+})(this, function(exports2, utils, math, core, display) {
+ "use strict";
+ const LOGICAL_WIDTH = 2;
+ const LOGICAL_HEIGHT = 2;
+ var CubismConfig;
+ ((CubismConfig2) => {
+ CubismConfig2.supportMoreMaskDivisions = true;
+ CubismConfig2.setOpacityFromMotion = false;
+ })(CubismConfig || (CubismConfig = {}));
+ exports2.config = void 0;
+ ((config2) => {
+ config2.LOG_LEVEL_VERBOSE = 0;
+ config2.LOG_LEVEL_WARNING = 1;
+ config2.LOG_LEVEL_ERROR = 2;
+ config2.LOG_LEVEL_NONE = 999;
+ config2.logLevel = config2.LOG_LEVEL_WARNING;
+ config2.sound = true;
+ config2.motionSync = true;
+ config2.motionFadingDuration = 500;
+ config2.idleMotionFadingDuration = 2e3;
+ config2.expressionFadingDuration = 500;
+ config2.preserveExpressionOnMotion = true;
+ config2.cubism4 = CubismConfig;
+ })(exports2.config || (exports2.config = {}));
+ const VERSION = "0.4.0";
+ const logger = {
+ log(tag, ...messages) {
+ if (exports2.config.logLevel <= exports2.config.LOG_LEVEL_VERBOSE) {
+ console.log(`[${tag}]`, ...messages);
+ }
+ },
+ warn(tag, ...messages) {
+ if (exports2.config.logLevel <= exports2.config.LOG_LEVEL_WARNING) {
+ console.warn(`[${tag}]`, ...messages);
+ }
+ },
+ error(tag, ...messages) {
+ if (exports2.config.logLevel <= exports2.config.LOG_LEVEL_ERROR) {
+ console.error(`[${tag}]`, ...messages);
+ }
+ }
+ };
+ function clamp(num, lower, upper) {
+ return num < lower ? lower : num > upper ? upper : num;
+ }
+ function rand(min, max) {
+ return Math.random() * (max - min) + min;
+ }
+ function copyProperty(type, from, to, fromKey, toKey) {
+ const value = from[fromKey];
+ if (value !== null && typeof value === type) {
+ to[toKey] = value;
+ }
+ }
+ function copyArray(type, from, to, fromKey, toKey) {
+ const array = from[fromKey];
+ if (Array.isArray(array)) {
+ to[toKey] = array.filter((item) => item !== null && typeof item === type);
+ }
+ }
+ function applyMixins(derivedCtor, baseCtors) {
+ baseCtors.forEach((baseCtor) => {
+ Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
+ if (name !== "constructor") {
+ Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
+ }
+ });
+ });
+ }
+ function folderName(url) {
+ let lastSlashIndex = url.lastIndexOf("/");
+ if (lastSlashIndex != -1) {
+ url = url.slice(0, lastSlashIndex);
+ }
+ lastSlashIndex = url.lastIndexOf("/");
+ if (lastSlashIndex !== -1) {
+ url = url.slice(lastSlashIndex + 1);
+ }
+ return url;
+ }
+ function remove(array, item) {
+ const index = array.indexOf(item);
+ if (index !== -1) {
+ array.splice(index, 1);
+ }
+ }
+ class ExpressionManager extends utils.EventEmitter {
+ constructor(settings, options) {
+ super();
+ this.expressions = [];
+ this.reserveExpressionIndex = -1;
+ this.destroyed = false;
+ this.settings = settings;
+ this.tag = `ExpressionManager(${settings.name})`;
+ }
+ init() {
+ this.defaultExpression = this.createExpression({}, void 0);
+ this.currentExpression = this.defaultExpression;
+ this.stopAllExpressions();
+ }
+ loadExpression(index) {
+ return __async(this, null, function* () {
+ if (!this.definitions[index]) {
+ logger.warn(this.tag, `Undefined expression at [${index}]`);
+ return void 0;
+ }
+ if (this.expressions[index] === null) {
+ logger.warn(this.tag, `Cannot set expression at [${index}] because it's already failed in loading.`);
+ return void 0;
+ }
+ if (this.expressions[index]) {
+ return this.expressions[index];
+ }
+ const expression = yield this._loadExpression(index);
+ this.expressions[index] = expression;
+ return expression;
+ });
+ }
+ _loadExpression(index) {
+ throw new Error("Not implemented.");
+ }
+ setRandomExpression() {
+ return __async(this, null, function* () {
+ if (this.definitions.length) {
+ const availableIndices = [];
+ for (let i = 0; i < this.definitions.length; i++) {
+ if (this.expressions[i] !== null && this.expressions[i] !== this.currentExpression && i !== this.reserveExpressionIndex) {
+ availableIndices.push(i);
+ }
+ }
+ if (availableIndices.length) {
+ const index = Math.floor(Math.random() * availableIndices.length);
+ return this.setExpression(index);
+ }
+ }
+ return false;
+ });
+ }
+ resetExpression() {
+ this._setExpression(this.defaultExpression);
+ }
+ restoreExpression() {
+ this._setExpression(this.currentExpression);
+ }
+ setExpression(index) {
+ return __async(this, null, function* () {
+ if (typeof index !== "number") {
+ index = this.getExpressionIndex(index);
+ }
+ if (!(index > -1 && index < this.definitions.length)) {
+ return false;
+ }
+ if (index === this.expressions.indexOf(this.currentExpression)) {
+ return false;
+ }
+ this.reserveExpressionIndex = index;
+ const expression = yield this.loadExpression(index);
+ if (!expression || this.reserveExpressionIndex !== index) {
+ return false;
+ }
+ this.reserveExpressionIndex = -1;
+ this.currentExpression = expression;
+ this._setExpression(expression);
+ return true;
+ });
+ }
+ update(model, now) {
+ if (!this.isFinished()) {
+ return this.updateParameters(model, now);
+ }
+ return false;
+ }
+ destroy() {
+ this.destroyed = true;
+ this.emit("destroy");
+ const self2 = this;
+ self2.definitions = void 0;
+ self2.expressions = void 0;
+ }
+ }
+ const EPSILON = 0.01;
+ const MAX_SPEED = 40 / 7.5;
+ const ACCELERATION_TIME = 1 / (0.15 * 1e3);
+ class FocusController {
+ constructor() {
+ this.targetX = 0;
+ this.targetY = 0;
+ this.x = 0;
+ this.y = 0;
+ this.vx = 0;
+ this.vy = 0;
+ }
+ focus(x, y, instant = false) {
+ this.targetX = clamp(x, -1, 1);
+ this.targetY = clamp(y, -1, 1);
+ if (instant) {
+ this.x = this.targetX;
+ this.y = this.targetY;
+ }
+ }
+ update(dt) {
+ const dx = this.targetX - this.x;
+ const dy = this.targetY - this.y;
+ if (Math.abs(dx) < EPSILON && Math.abs(dy) < EPSILON)
+ return;
+ const d = Math.sqrt(__pow(dx, 2) + __pow(dy, 2));
+ const maxSpeed = MAX_SPEED / (1e3 / dt);
+ let ax = maxSpeed * (dx / d) - this.vx;
+ let ay = maxSpeed * (dy / d) - this.vy;
+ const a = Math.sqrt(__pow(ax, 2) + __pow(ay, 2));
+ const maxA = maxSpeed * ACCELERATION_TIME * dt;
+ if (a > maxA) {
+ ax *= maxA / a;
+ ay *= maxA / a;
+ }
+ this.vx += ax;
+ this.vy += ay;
+ const v = Math.sqrt(__pow(this.vx, 2) + __pow(this.vy, 2));
+ const maxV = 0.5 * (Math.sqrt(__pow(maxA, 2) + 8 * maxA * d) - maxA);
+ if (v > maxV) {
+ this.vx *= maxV / v;
+ this.vy *= maxV / v;
+ }
+ this.x += this.vx;
+ this.y += this.vy;
+ }
+ }
+ class ModelSettings {
+ constructor(json) {
+ this.json = json;
+ let url2 = json.url;
+ if (typeof url2 !== "string") {
+ throw new TypeError("The `url` field in settings JSON must be defined as a string.");
+ }
+ this.url = url2;
+ this.name = folderName(this.url);
+ }
+ resolveURL(path) {
+ return utils.url.resolve(this.url, path);
+ }
+ replaceFiles(replacer) {
+ this.moc = replacer(this.moc, "moc");
+ if (this.pose !== void 0) {
+ this.pose = replacer(this.pose, "pose");
+ }
+ if (this.physics !== void 0) {
+ this.physics = replacer(this.physics, "physics");
+ }
+ for (let i = 0; i < this.textures.length; i++) {
+ this.textures[i] = replacer(this.textures[i], `textures[${i}]`);
+ }
+ }
+ getDefinedFiles() {
+ const files = [];
+ this.replaceFiles((file) => {
+ files.push(file);
+ return file;
+ });
+ return files;
+ }
+ validateFiles(files) {
+ const assertFileExists = (expectedFile, shouldThrow) => {
+ const actualPath = this.resolveURL(expectedFile);
+ if (!files.includes(actualPath)) {
+ if (shouldThrow) {
+ throw new Error(`File "${expectedFile}" is defined in settings, but doesn't exist in given files`);
+ }
+ return false;
+ }
+ return true;
+ };
+ const essentialFiles = [this.moc, ...this.textures];
+ essentialFiles.forEach((texture) => assertFileExists(texture, true));
+ const definedFiles = this.getDefinedFiles();
+ return definedFiles.filter((file) => assertFileExists(file, false));
+ }
+ }
+ var MotionPriority = /* @__PURE__ */ ((MotionPriority2) => {
+ MotionPriority2[MotionPriority2["NONE"] = 0] = "NONE";
+ MotionPriority2[MotionPriority2["IDLE"] = 1] = "IDLE";
+ MotionPriority2[MotionPriority2["NORMAL"] = 2] = "NORMAL";
+ MotionPriority2[MotionPriority2["FORCE"] = 3] = "FORCE";
+ return MotionPriority2;
+ })(MotionPriority || {});
+ class MotionState {
+ constructor() {
+ this.debug = false;
+ this.currentPriority = 0;
+ this.reservePriority = 0;
+ }
+ reserve(group, index, priority) {
+ if (priority <= 0) {
+ logger.log(this.tag, `Cannot start a motion with MotionPriority.NONE.`);
+ return false;
+ }
+ if (group === this.currentGroup && index === this.currentIndex) {
+ logger.log(this.tag, `Motion is already playing.`, this.dump(group, index));
+ return false;
+ }
+ if (group === this.reservedGroup && index === this.reservedIndex || group === this.reservedIdleGroup && index === this.reservedIdleIndex) {
+ logger.log(this.tag, `Motion is already reserved.`, this.dump(group, index));
+ return false;
+ }
+ if (priority === 1) {
+ if (this.currentPriority !== 0) {
+ logger.log(this.tag, `Cannot start idle motion because another motion is playing.`, this.dump(group, index));
+ return false;
+ }
+ if (this.reservedIdleGroup !== void 0) {
+ logger.log(this.tag, `Cannot start idle motion because another idle motion has reserved.`, this.dump(group, index));
+ return false;
+ }
+ this.setReservedIdle(group, index);
+ } else {
+ if (priority < 3) {
+ if (priority <= this.currentPriority) {
+ logger.log(this.tag, "Cannot start motion because another motion is playing as an equivalent or higher priority.", this.dump(group, index));
+ return false;
+ }
+ if (priority <= this.reservePriority) {
+ logger.log(this.tag, "Cannot start motion because another motion has reserved as an equivalent or higher priority.", this.dump(group, index));
+ return false;
+ }
+ }
+ this.setReserved(group, index, priority);
+ }
+ return true;
+ }
+ start(motion, group, index, priority) {
+ if (priority === 1) {
+ this.setReservedIdle(void 0, void 0);
+ if (this.currentPriority !== 0) {
+ logger.log(this.tag, "Cannot start idle motion because another motion is playing.", this.dump(group, index));
+ return false;
+ }
+ } else {
+ if (group !== this.reservedGroup || index !== this.reservedIndex) {
+ logger.log(this.tag, "Cannot start motion because another motion has taken the place.", this.dump(group, index));
+ return false;
+ }
+ this.setReserved(void 0, void 0, 0);
+ }
+ if (!motion) {
+ return false;
+ }
+ this.setCurrent(group, index, priority);
+ return true;
+ }
+ complete() {
+ this.setCurrent(void 0, void 0, 0);
+ }
+ setCurrent(group, index, priority) {
+ this.currentPriority = priority;
+ this.currentGroup = group;
+ this.currentIndex = index;
+ }
+ setReserved(group, index, priority) {
+ this.reservePriority = priority;
+ this.reservedGroup = group;
+ this.reservedIndex = index;
+ }
+ setReservedIdle(group, index) {
+ this.reservedIdleGroup = group;
+ this.reservedIdleIndex = index;
+ }
+ isActive(group, index) {
+ return group === this.currentGroup && index === this.currentIndex || group === this.reservedGroup && index === this.reservedIndex || group === this.reservedIdleGroup && index === this.reservedIdleIndex;
+ }
+ reset() {
+ this.setCurrent(void 0, void 0, 0);
+ this.setReserved(void 0, void 0, 0);
+ this.setReservedIdle(void 0, void 0);
+ }
+ shouldRequestIdleMotion() {
+ return this.currentGroup === void 0 && this.reservedIdleGroup === void 0;
+ }
+ shouldOverrideExpression() {
+ return !exports2.config.preserveExpressionOnMotion && this.currentPriority > 1;
+ }
+ dump(requestedGroup, requestedIndex) {
+ if (this.debug) {
+ const keys = [
+ "currentPriority",
+ "reservePriority",
+ "currentGroup",
+ "currentIndex",
+ "reservedGroup",
+ "reservedIndex",
+ "reservedIdleGroup",
+ "reservedIdleIndex"
+ ];
+ return `
+ group = "${requestedGroup}", index = ${requestedIndex}
+` + keys.map((key) => "[" + key + "] " + this[key]).join("\n");
+ }
+ return "";
+ }
+ }
+ const TAG$2 = "SoundManager";
+ const VOLUME = 0.9;
+ class SoundManager {
+ static get volume() {
+ return this._volume;
+ }
+ static set volume(value) {
+ this._volume = (value > 1 ? 1 : value < 0 ? 0 : value) || 0;
+ this.audios.forEach((audio) => audio.volume = this._volume);
+ }
+ static add(file, onFinish, onError) {
+ const audio = new Audio(file);
+ audio.volume = this._volume;
+ audio.preload = "auto";
+ audio.autoplay = true;
+ audio.crossOrigin = "anonymous";
+ audio.addEventListener("ended", () => {
+ this.dispose(audio);
+ onFinish == null ? void 0 : onFinish();
+ });
+ audio.addEventListener("error", (e) => {
+ this.dispose(audio);
+ logger.warn(TAG$2, `Error occurred on "${file}"`, e.error);
+ onError == null ? void 0 : onError(e.error);
+ });
+ this.audios.push(audio);
+ return audio;
+ }
+ static play(audio) {
+ return new Promise((resolve, reject) => {
+ var _a;
+ (_a = audio.play()) == null ? void 0 : _a.catch((e) => {
+ audio.dispatchEvent(new ErrorEvent("error", { error: e }));
+ reject(e);
+ });
+ if (audio.readyState === audio.HAVE_ENOUGH_DATA) {
+ resolve();
+ } else {
+ audio.addEventListener("canplaythrough", resolve);
+ }
+ });
+ }
+ static addContext(audio) {
+ const context = new AudioContext();
+ this.contexts.push(context);
+ return context;
+ }
+ static addAnalyzer(audio, context) {
+ const source = context.createMediaElementSource(audio);
+ const analyser = context.createAnalyser();
+ analyser.fftSize = 256;
+ analyser.minDecibels = -90;
+ analyser.maxDecibels = -10;
+ analyser.smoothingTimeConstant = 0.85;
+ source.connect(analyser);
+ analyser.connect(context.destination);
+ this.analysers.push(analyser);
+ return analyser;
+ }
+ static analyze(analyser) {
+ if (analyser != void 0) {
+ let pcmData = new Float32Array(analyser.fftSize);
+ let sumSquares = 0;
+ analyser.getFloatTimeDomainData(pcmData);
+ for (const amplitude of pcmData) {
+ sumSquares += amplitude * amplitude;
+ }
+ return parseFloat(Math.sqrt(sumSquares / pcmData.length * 20).toFixed(1));
+ } else {
+ return parseFloat(Math.random().toFixed(1));
+ }
+ }
+ static dispose(audio) {
+ audio.pause();
+ audio.removeAttribute("src");
+ remove(this.audios, audio);
+ }
+ static destroy() {
+ for (let i = this.contexts.length - 1; i >= 0; i--) {
+ this.contexts[i].close();
+ }
+ for (let i = this.audios.length - 1; i >= 0; i--) {
+ this.dispose(this.audios[i]);
+ }
+ }
+ }
+ SoundManager.audios = [];
+ SoundManager.analysers = [];
+ SoundManager.contexts = [];
+ SoundManager._volume = VOLUME;
+ var MotionPreloadStrategy = /* @__PURE__ */ ((MotionPreloadStrategy2) => {
+ MotionPreloadStrategy2["ALL"] = "ALL";
+ MotionPreloadStrategy2["IDLE"] = "IDLE";
+ MotionPreloadStrategy2["NONE"] = "NONE";
+ return MotionPreloadStrategy2;
+ })(MotionPreloadStrategy || {});
+ class MotionManager extends utils.EventEmitter {
+ constructor(settings, options) {
+ super();
+ this.motionGroups = {};
+ this.state = new MotionState();
+ this.playing = false;
+ this.destroyed = false;
+ this.settings = settings;
+ this.tag = `MotionManager(${settings.name})`;
+ this.state.tag = this.tag;
+ }
+ init(options) {
+ if (options == null ? void 0 : options.idleMotionGroup) {
+ this.groups.idle = options.idleMotionGroup;
+ }
+ this.setupMotions(options);
+ this.stopAllMotions();
+ }
+ setupMotions(options) {
+ for (const group of Object.keys(this.definitions)) {
+ this.motionGroups[group] = [];
+ }
+ let groups;
+ switch (options == null ? void 0 : options.motionPreload) {
+ case "NONE":
+ return;
+ case "ALL":
+ groups = Object.keys(this.definitions);
+ break;
+ case "IDLE":
+ default:
+ groups = [this.groups.idle];
+ break;
+ }
+ for (const group of groups) {
+ if (this.definitions[group]) {
+ for (let i = 0; i < this.definitions[group].length; i++) {
+ this.loadMotion(group, i).then();
+ }
+ }
+ }
+ }
+ loadMotion(group, index) {
+ return __async(this, null, function* () {
+ var _a;
+ if (!((_a = this.definitions[group]) == null ? void 0 : _a[index])) {
+ logger.warn(this.tag, `Undefined motion at "${group}"[${index}]`);
+ return void 0;
+ }
+ if (this.motionGroups[group][index] === null) {
+ logger.warn(this.tag, `Cannot start motion at "${group}"[${index}] because it's already failed in loading.`);
+ return void 0;
+ }
+ if (this.motionGroups[group][index]) {
+ return this.motionGroups[group][index];
+ }
+ const motion = yield this._loadMotion(group, index);
+ if (this.destroyed) {
+ return;
+ }
+ this.motionGroups[group][index] = motion != null ? motion : null;
+ return motion;
+ });
+ }
+ _loadMotion(group, index) {
+ throw new Error("Not implemented.");
+ }
+ speakUp(sound, volume, expression) {
+ return __async(this, null, function* () {
+ if (!exports2.config.sound) {
+ return false;
+ }
+ let audio;
+ let analyzer;
+ let context;
+ if (this.currentAudio) {
+ if (!this.currentAudio.ended) {
+ return false;
+ }
+ }
+ let soundURL;
+ const isBase64Content = sound && sound.startsWith("data:audio/wav;base64");
+ if (sound && !isBase64Content) {
+ var A = document.createElement("a");
+ A.href = sound;
+ sound = A.href;
+ soundURL = sound;
+ } else {
+ soundURL = "data:audio/wav;base64";
+ }
+ const isUrlPath = sound && (sound.startsWith("http") || sound.startsWith("blob"));
+ let file;
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ audio = SoundManager.add(file, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ }, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ });
+ this.currentAudio = audio;
+ let _volume = 1;
+ if (volume !== void 0) {
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+ } catch (e) {
+ logger.warn(this.tag, "Failed to create audio", soundURL, e);
+ }
+ }
+ if (audio) {
+ const readyToPlay = SoundManager.play(audio).catch((e) => logger.warn(this.tag, "Failed to play audio", audio.src, e));
+ if (exports2.config.motionSync) {
+ yield readyToPlay;
+ }
+ }
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ if (expression && this.expressionManager) {
+ this.expressionManager.setExpression(expression);
+ }
+ this.playing = true;
+ return true;
+ });
+ }
+ startMotion(_0, _1) {
+ return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, sound, volume, expression) {
+ var _a;
+ if (this.currentAudio) {
+ if (!this.currentAudio.ended) {
+ return false;
+ }
+ }
+ if (!this.state.reserve(group, index, priority)) {
+ return false;
+ }
+ const definition = (_a = this.definitions[group]) == null ? void 0 : _a[index];
+ if (!definition) {
+ return false;
+ }
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ }
+ let audio;
+ let analyzer;
+ let context;
+ if (exports2.config.sound) {
+ const isBase64Content = sound && sound.startsWith("data:audio/wav;base64");
+ if (sound && !isBase64Content) {
+ var A = document.createElement("a");
+ A.href = sound;
+ sound = A.href;
+ }
+ const isUrlPath = sound && (sound.startsWith("http") || sound.startsWith("blob"));
+ const soundURL = this.getSoundFile(definition);
+ let file = soundURL;
+ if (soundURL) {
+ file = this.settings.resolveURL(soundURL) + "?cache-buster=" + new Date().getTime();
+ }
+ if (isUrlPath || isBase64Content) {
+ file = sound;
+ }
+ const that = this;
+ if (file) {
+ try {
+ audio = SoundManager.add(file, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ }, () => {
+ expression && that.expressionManager && that.expressionManager.resetExpression();
+ that.currentAudio = void 0;
+ });
+ this.currentAudio = audio;
+ let _volume = 1;
+ if (volume !== void 0) {
+ _volume = volume;
+ }
+ SoundManager.volume = _volume;
+ context = SoundManager.addContext(this.currentAudio);
+ this.currentContext = context;
+ analyzer = SoundManager.addAnalyzer(this.currentAudio, this.currentContext);
+ this.currentAnalyzer = analyzer;
+ } catch (e) {
+ logger.warn(this.tag, "Failed to create audio", soundURL, e);
+ }
+ }
+ }
+ const motion = yield this.loadMotion(group, index);
+ if (audio) {
+ priority = 3;
+ const readyToPlay = SoundManager.play(audio).catch((e) => logger.warn(this.tag, "Failed to play audio", audio.src, e));
+ if (exports2.config.motionSync) {
+ yield readyToPlay;
+ }
+ }
+ if (!this.state.start(motion, group, index, priority)) {
+ if (audio) {
+ SoundManager.dispose(audio);
+ this.currentAudio = void 0;
+ }
+ return false;
+ }
+ if (this.state.shouldOverrideExpression()) {
+ this.expressionManager && this.expressionManager.resetExpression();
+ }
+ logger.log(this.tag, "Start motion:", this.getMotionName(definition));
+ this.emit("motionStart", group, index, audio);
+ if (expression && this.expressionManager) {
+ this.expressionManager.setExpression(expression);
+ }
+ this.playing = true;
+ this._startMotion(motion);
+ return true;
+ });
+ }
+ startRandomMotion(group, priority, sound, volume) {
+ return __async(this, null, function* () {
+ const groupDefs = this.definitions[group];
+ if (groupDefs == null ? void 0 : groupDefs.length) {
+ const availableIndices = [];
+ for (let i = 0; i < groupDefs.length; i++) {
+ if (this.motionGroups[group][i] !== null && !this.state.isActive(group, i)) {
+ availableIndices.push(i);
+ }
+ }
+ if (availableIndices.length) {
+ const index = availableIndices[Math.floor(Math.random() * availableIndices.length)];
+ return this.startMotion(group, index, priority, sound, volume);
+ }
+ }
+ return false;
+ });
+ }
+ stopSpeaking() {
+ if (this.currentAudio) {
+ SoundManager.dispose(this.currentAudio);
+ this.currentAudio = void 0;
+ }
+ }
+ stopAllMotions() {
+ this._stopAllMotions();
+ this.state.reset();
+ this.stopSpeaking();
+ }
+ update(model, now) {
+ var _a;
+ if (this.isFinished()) {
+ if (this.playing) {
+ this.playing = false;
+ this.emit("motionFinish");
+ }
+ if (this.state.shouldOverrideExpression()) {
+ (_a = this.expressionManager) == null ? void 0 : _a.restoreExpression();
+ }
+ this.state.complete();
+ if (this.state.shouldRequestIdleMotion()) {
+ this.startRandomMotion(this.groups.idle, MotionPriority.IDLE);
+ }
+ }
+ return this.updateParameters(model, now);
+ }
+ mouthSync() {
+ if (this.currentAnalyzer) {
+ return SoundManager.analyze(this.currentAnalyzer);
+ } else {
+ return 0;
+ }
+ }
+ destroy() {
+ var _a;
+ this.destroyed = true;
+ this.emit("destroy");
+ this.stopAllMotions();
+ (_a = this.expressionManager) == null ? void 0 : _a.destroy();
+ const self2 = this;
+ self2.definitions = void 0;
+ self2.motionGroups = void 0;
+ }
+ }
+ const tempBounds = { x: 0, y: 0, width: 0, height: 0 };
+ class InternalModel extends utils.EventEmitter {
+ constructor() {
+ super(...arguments);
+ this.focusController = new FocusController();
+ this.originalWidth = 0;
+ this.originalHeight = 0;
+ this.width = 0;
+ this.height = 0;
+ this.localTransform = new math.Matrix();
+ this.drawingMatrix = new math.Matrix();
+ this.hitAreas = {};
+ this.textureFlipY = false;
+ this.viewport = [0, 0, 0, 0];
+ this.destroyed = false;
+ }
+ init() {
+ this.setupLayout();
+ this.setupHitAreas();
+ }
+ setupLayout() {
+ const self2 = this;
+ const size = this.getSize();
+ self2.originalWidth = size[0];
+ self2.originalHeight = size[1];
+ const layout = Object.assign({
+ width: LOGICAL_WIDTH,
+ height: LOGICAL_HEIGHT
+ }, this.getLayout());
+ this.localTransform.scale(layout.width / LOGICAL_WIDTH, layout.height / LOGICAL_HEIGHT);
+ self2.width = this.originalWidth * this.localTransform.a;
+ self2.height = this.originalHeight * this.localTransform.d;
+ const offsetX = layout.x !== void 0 && layout.x - layout.width / 2 || layout.centerX !== void 0 && layout.centerX || layout.left !== void 0 && layout.left - layout.width / 2 || layout.right !== void 0 && layout.right + layout.width / 2 || 0;
+ const offsetY = layout.y !== void 0 && layout.y - layout.height / 2 || layout.centerY !== void 0 && layout.centerY || layout.top !== void 0 && layout.top - layout.height / 2 || layout.bottom !== void 0 && layout.bottom + layout.height / 2 || 0;
+ this.localTransform.translate(this.width * offsetX, -this.height * offsetY);
+ }
+ setupHitAreas() {
+ const definitions = this.getHitAreaDefs().filter((hitArea) => hitArea.index >= 0);
+ for (const def of definitions) {
+ this.hitAreas[def.name] = def;
+ }
+ }
+ hitTest(x, y) {
+ return Object.keys(this.hitAreas).filter((hitAreaName) => this.isHit(hitAreaName, x, y));
+ }
+ isHit(hitAreaName, x, y) {
+ if (!this.hitAreas[hitAreaName]) {
+ return false;
+ }
+ const drawIndex = this.hitAreas[hitAreaName].index;
+ const bounds = this.getDrawableBounds(drawIndex, tempBounds);
+ return bounds.x <= x && x <= bounds.x + bounds.width && bounds.y <= y && y <= bounds.y + bounds.height;
+ }
+ getDrawableBounds(index, bounds) {
+ const vertices = this.getDrawableVertices(index);
+ let left = vertices[0];
+ let right = vertices[0];
+ let top = vertices[1];
+ let bottom = vertices[1];
+ for (let i = 0; i < vertices.length; i += 2) {
+ const vx = vertices[i];
+ const vy = vertices[i + 1];
+ left = Math.min(vx, left);
+ right = Math.max(vx, right);
+ top = Math.min(vy, top);
+ bottom = Math.max(vy, bottom);
+ }
+ bounds != null ? bounds : bounds = {};
+ bounds.x = left;
+ bounds.y = top;
+ bounds.width = right - left;
+ bounds.height = bottom - top;
+ return bounds;
+ }
+ updateTransform(transform) {
+ this.drawingMatrix.copyFrom(transform).append(this.localTransform);
+ }
+ update(dt, now) {
+ this.focusController.update(dt);
+ }
+ destroy() {
+ this.destroyed = true;
+ this.emit("destroy");
+ this.motionManager.destroy();
+ this.motionManager = void 0;
+ }
+ }
+ const TAG$1 = "XHRLoader";
+ class NetworkError extends Error {
+ constructor(message, url, status, aborted = false) {
+ super(message);
+ this.url = url;
+ this.status = status;
+ this.aborted = aborted;
+ }
+ }
+ const _XHRLoader = class {
+ static createXHR(target, url, type, onload, onerror) {
+ const xhr = new XMLHttpRequest();
+ _XHRLoader.allXhrSet.add(xhr);
+ if (target) {
+ let xhrSet = _XHRLoader.xhrMap.get(target);
+ if (!xhrSet) {
+ xhrSet = /* @__PURE__ */ new Set([xhr]);
+ _XHRLoader.xhrMap.set(target, xhrSet);
+ } else {
+ xhrSet.add(xhr);
+ }
+ if (!target.listeners("destroy").includes(_XHRLoader.cancelXHRs)) {
+ target.once("destroy", _XHRLoader.cancelXHRs);
+ }
+ }
+ xhr.open("GET", url);
+ xhr.responseType = type;
+ xhr.onload = () => {
+ if ((xhr.status === 200 || xhr.status === 0) && xhr.response) {
+ onload(xhr.response);
+ } else {
+ xhr.onerror();
+ }
+ };
+ xhr.onerror = () => {
+ logger.warn(TAG$1, `Failed to load resource as ${xhr.responseType} (Status ${xhr.status}): ${url}`);
+ onerror(new NetworkError("Network error.", url, xhr.status));
+ };
+ xhr.onabort = () => onerror(new NetworkError("Aborted.", url, xhr.status, true));
+ xhr.onloadend = () => {
+ var _a;
+ _XHRLoader.allXhrSet.delete(xhr);
+ if (target) {
+ (_a = _XHRLoader.xhrMap.get(target)) == null ? void 0 : _a.delete(xhr);
+ }
+ };
+ return xhr;
+ }
+ static cancelXHRs() {
+ var _a;
+ (_a = _XHRLoader.xhrMap.get(this)) == null ? void 0 : _a.forEach((xhr) => {
+ xhr.abort();
+ _XHRLoader.allXhrSet.delete(xhr);
+ });
+ _XHRLoader.xhrMap.delete(this);
+ }
+ static release() {
+ _XHRLoader.allXhrSet.forEach((xhr) => xhr.abort());
+ _XHRLoader.allXhrSet.clear();
+ _XHRLoader.xhrMap = /* @__PURE__ */ new WeakMap();
+ }
+ };
+ let XHRLoader = _XHRLoader;
+ XHRLoader.xhrMap = /* @__PURE__ */ new WeakMap();
+ XHRLoader.allXhrSet = /* @__PURE__ */ new Set();
+ XHRLoader.loader = (context, next) => {
+ return new Promise((resolve, reject) => {
+ const xhr = _XHRLoader.createXHR(context.target, context.settings ? context.settings.resolveURL(context.url) : context.url, context.type, (data) => {
+ context.result = data;
+ resolve();
+ }, reject);
+ xhr.send();
+ });
+ };
+ function runMiddlewares(middleware, context) {
+ let index = -1;
+ return dispatch(0);
+ function dispatch(i, err) {
+ if (err)
+ return Promise.reject(err);
+ if (i <= index)
+ return Promise.reject(new Error("next() called multiple times"));
+ index = i;
+ const fn = middleware[i];
+ if (!fn)
+ return Promise.resolve();
+ try {
+ return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
+ } catch (err2) {
+ return Promise.reject(err2);
+ }
+ }
+ }
+ class Live2DLoader {
+ static load(context) {
+ return runMiddlewares(this.middlewares, context).then(() => context.result);
+ }
+ }
+ Live2DLoader.middlewares = [XHRLoader.loader];
+ function createTexture(url, options = {}) {
+ var _a;
+ const textureOptions = { resourceOptions: { crossorigin: options.crossOrigin } };
+ if (core.Texture.fromURL) {
+ return core.Texture.fromURL(url, textureOptions).catch((e) => {
+ if (e instanceof Error) {
+ throw e;
+ }
+ const err = new Error("Texture loading error");
+ err.event = e;
+ throw err;
+ });
+ }
+ textureOptions.resourceOptions.autoLoad = false;
+ const texture = core.Texture.from(url, textureOptions);
+ if (texture.baseTexture.valid) {
+ return Promise.resolve(texture);
+ }
+ const resource = texture.baseTexture.resource;
+ (_a = resource._live2d_load) != null ? _a : resource._live2d_load = new Promise((resolve, reject) => {
+ const errorHandler = (event) => {
+ resource.source.removeEventListener("error", errorHandler);
+ const err = new Error("Texture loading error");
+ err.event = event;
+ reject(err);
+ };
+ resource.source.addEventListener("error", errorHandler);
+ resource.load().then(() => resolve(texture)).catch(errorHandler);
+ });
+ return resource._live2d_load;
+ }
+ const TAG = "Live2DFactory";
+ const urlToJSON = (context, next) => __async(this, null, function* () {
+ if (typeof context.source === "string") {
+ const data = yield Live2DLoader.load({
+ url: context.source,
+ type: "json",
+ target: context.live2dModel
+ });
+ data.url = context.source;
+ context.source = data;
+ context.live2dModel.emit("settingsJSONLoaded", data);
+ }
+ return next();
+ });
+ const jsonToSettings = (context, next) => __async(this, null, function* () {
+ if (context.source instanceof ModelSettings) {
+ context.settings = context.source;
+ return next();
+ } else if (typeof context.source === "object") {
+ const runtime = Live2DFactory.findRuntime(context.source);
+ if (runtime) {
+ const settings = runtime.createModelSettings(context.source);
+ context.settings = settings;
+ context.live2dModel.emit("settingsLoaded", settings);
+ return next();
+ }
+ }
+ throw new TypeError("Unknown settings format.");
+ });
+ const waitUntilReady = (context, next) => {
+ if (context.settings) {
+ const runtime = Live2DFactory.findRuntime(context.settings);
+ if (runtime) {
+ return runtime.ready().then(next);
+ }
+ }
+ return next();
+ };
+ const setupOptionals = (context, next) => __async(this, null, function* () {
+ yield next();
+ const internalModel = context.internalModel;
+ if (internalModel) {
+ const settings = context.settings;
+ const runtime = Live2DFactory.findRuntime(settings);
+ if (runtime) {
+ const tasks = [];
+ if (settings.pose) {
+ tasks.push(Live2DLoader.load({
+ settings,
+ url: settings.pose,
+ type: "json",
+ target: internalModel
+ }).then((data) => {
+ internalModel.pose = runtime.createPose(internalModel.coreModel, data);
+ context.live2dModel.emit("poseLoaded", internalModel.pose);
+ }).catch((e) => {
+ context.live2dModel.emit("poseLoadError", e);
+ logger.warn(TAG, "Failed to load pose.", e);
+ }));
+ }
+ if (settings.physics) {
+ tasks.push(Live2DLoader.load({
+ settings,
+ url: settings.physics,
+ type: "json",
+ target: internalModel
+ }).then((data) => {
+ internalModel.physics = runtime.createPhysics(internalModel.coreModel, data);
+ context.live2dModel.emit("physicsLoaded", internalModel.physics);
+ }).catch((e) => {
+ context.live2dModel.emit("physicsLoadError", e);
+ logger.warn(TAG, "Failed to load physics.", e);
+ }));
+ }
+ if (tasks.length) {
+ yield Promise.all(tasks);
+ }
+ }
+ }
+ });
+ const setupEssentials = (context, next) => __async(this, null, function* () {
+ if (context.settings) {
+ const live2DModel = context.live2dModel;
+ const textureLoadings = context.settings.textures.map((tex) => {
+ const url = context.settings.resolveURL(tex);
+ return createTexture(url, { crossOrigin: context.options.crossOrigin });
+ });
+ yield next();
+ if (context.internalModel) {
+ live2DModel.internalModel = context.internalModel;
+ live2DModel.emit("modelLoaded", context.internalModel);
+ } else {
+ throw new TypeError("Missing internal model.");
+ }
+ live2DModel.textures = yield Promise.all(textureLoadings);
+ live2DModel.emit("textureLoaded", live2DModel.textures);
+ } else {
+ throw new TypeError("Missing settings.");
+ }
+ });
+ const createInternalModel = (context, next) => __async(this, null, function* () {
+ const settings = context.settings;
+ if (settings instanceof ModelSettings) {
+ const runtime = Live2DFactory.findRuntime(settings);
+ if (!runtime) {
+ throw new TypeError("Unknown model settings.");
+ }
+ const modelData = yield Live2DLoader.load({
+ settings,
+ url: settings.moc,
+ type: "arraybuffer",
+ target: context.live2dModel
+ });
+ if (!runtime.isValidMoc(modelData)) {
+ throw new Error("Invalid moc data");
+ }
+ const coreModel = runtime.createCoreModel(modelData);
+ context.internalModel = runtime.createInternalModel(coreModel, settings, context.options);
+ return next();
+ }
+ throw new TypeError("Missing settings.");
+ });
+ const _Live2DFactory = class {
+ static registerRuntime(runtime) {
+ _Live2DFactory.runtimes.push(runtime);
+ _Live2DFactory.runtimes.sort((a, b) => b.version - a.version);
+ }
+ static findRuntime(source) {
+ for (const runtime of _Live2DFactory.runtimes) {
+ if (runtime.test(source)) {
+ return runtime;
+ }
+ }
+ }
+ static setupLive2DModel(live2dModel, source, options) {
+ return __async(this, null, function* () {
+ const textureLoaded = new Promise((resolve) => live2dModel.once("textureLoaded", resolve));
+ const modelLoaded = new Promise((resolve) => live2dModel.once("modelLoaded", resolve));
+ const readyEventEmitted = Promise.all([textureLoaded, modelLoaded]).then(() => live2dModel.emit("ready"));
+ yield runMiddlewares(_Live2DFactory.live2DModelMiddlewares, {
+ live2dModel,
+ source,
+ options: options || {}
+ });
+ yield readyEventEmitted;
+ live2dModel.emit("load");
+ });
+ }
+ static loadMotion(motionManager, group, index) {
+ var _a, _b;
+ const handleError = (e) => motionManager.emit("motionLoadError", group, index, e);
+ try {
+ const definition = (_a = motionManager.definitions[group]) == null ? void 0 : _a[index];
+ if (!definition) {
+ return Promise.resolve(void 0);
+ }
+ if (!motionManager.listeners("destroy").includes(_Live2DFactory.releaseTasks)) {
+ motionManager.once("destroy", _Live2DFactory.releaseTasks);
+ }
+ let tasks = _Live2DFactory.motionTasksMap.get(motionManager);
+ if (!tasks) {
+ tasks = {};
+ _Live2DFactory.motionTasksMap.set(motionManager, tasks);
+ }
+ let taskGroup = tasks[group];
+ if (!taskGroup) {
+ taskGroup = [];
+ tasks[group] = taskGroup;
+ }
+ const path = motionManager.getMotionFile(definition);
+ (_b = taskGroup[index]) != null ? _b : taskGroup[index] = Live2DLoader.load({
+ url: path,
+ settings: motionManager.settings,
+ type: motionManager.motionDataType,
+ target: motionManager
+ }).then((data) => {
+ var _a2;
+ const taskGroup2 = (_a2 = _Live2DFactory.motionTasksMap.get(motionManager)) == null ? void 0 : _a2[group];
+ if (taskGroup2) {
+ delete taskGroup2[index];
+ }
+ const motion = motionManager.createMotion(data, group, definition);
+ motionManager.emit("motionLoaded", group, index, motion);
+ return motion;
+ }).catch((e) => {
+ logger.warn(motionManager.tag, `Failed to load motion: ${path}
+`, e);
+ handleError(e);
+ });
+ return taskGroup[index];
+ } catch (e) {
+ logger.warn(motionManager.tag, `Failed to load motion at "${group}"[${index}]
+`, e);
+ handleError(e);
+ }
+ return Promise.resolve(void 0);
+ }
+ static loadExpression(expressionManager, index) {
+ var _a;
+ const handleError = (e) => expressionManager.emit("expressionLoadError", index, e);
+ try {
+ const definition = expressionManager.definitions[index];
+ if (!definition) {
+ return Promise.resolve(void 0);
+ }
+ if (!expressionManager.listeners("destroy").includes(_Live2DFactory.releaseTasks)) {
+ expressionManager.once("destroy", _Live2DFactory.releaseTasks);
+ }
+ let tasks = _Live2DFactory.expressionTasksMap.get(expressionManager);
+ if (!tasks) {
+ tasks = [];
+ _Live2DFactory.expressionTasksMap.set(expressionManager, tasks);
+ }
+ const path = expressionManager.getExpressionFile(definition);
+ (_a = tasks[index]) != null ? _a : tasks[index] = Live2DLoader.load({
+ url: path,
+ settings: expressionManager.settings,
+ type: "json",
+ target: expressionManager
+ }).then((data) => {
+ const tasks2 = _Live2DFactory.expressionTasksMap.get(expressionManager);
+ if (tasks2) {
+ delete tasks2[index];
+ }
+ const expression = expressionManager.createExpression(data, definition);
+ expressionManager.emit("expressionLoaded", index, expression);
+ return expression;
+ }).catch((e) => {
+ logger.warn(expressionManager.tag, `Failed to load expression: ${path}
+`, e);
+ handleError(e);
+ });
+ return tasks[index];
+ } catch (e) {
+ logger.warn(expressionManager.tag, `Failed to load expression at [${index}]
+`, e);
+ handleError(e);
+ }
+ return Promise.resolve(void 0);
+ }
+ static releaseTasks() {
+ if (this instanceof MotionManager) {
+ _Live2DFactory.motionTasksMap.delete(this);
+ } else {
+ _Live2DFactory.expressionTasksMap.delete(this);
+ }
+ }
+ };
+ let Live2DFactory = _Live2DFactory;
+ Live2DFactory.runtimes = [];
+ Live2DFactory.urlToJSON = urlToJSON;
+ Live2DFactory.jsonToSettings = jsonToSettings;
+ Live2DFactory.waitUntilReady = waitUntilReady;
+ Live2DFactory.setupOptionals = setupOptionals;
+ Live2DFactory.setupEssentials = setupEssentials;
+ Live2DFactory.createInternalModel = createInternalModel;
+ Live2DFactory.live2DModelMiddlewares = [
+ urlToJSON,
+ jsonToSettings,
+ waitUntilReady,
+ setupOptionals,
+ setupEssentials,
+ createInternalModel
+ ];
+ Live2DFactory.motionTasksMap = /* @__PURE__ */ new WeakMap();
+ Live2DFactory.expressionTasksMap = /* @__PURE__ */ new WeakMap();
+ MotionManager.prototype["_loadMotion"] = function(group, index) {
+ return Live2DFactory.loadMotion(this, group, index);
+ };
+ ExpressionManager.prototype["_loadExpression"] = function(index) {
+ return Live2DFactory.loadExpression(this, index);
+ };
+ class InteractionMixin {
+ constructor() {
+ this._autoInteract = false;
+ }
+ get autoInteract() {
+ return this._autoInteract;
+ }
+ set autoInteract(autoInteract) {
+ if (autoInteract !== this._autoInteract) {
+ if (autoInteract) {
+ this.on("pointertap", onTap, this);
+ } else {
+ this.off("pointertap", onTap, this);
+ }
+ this._autoInteract = autoInteract;
+ }
+ }
+ registerInteraction(manager) {
+ if (manager !== this.interactionManager) {
+ this.unregisterInteraction();
+ if (this._autoInteract && manager) {
+ this.interactionManager = manager;
+ manager.on("pointermove", onPointerMove, this);
+ }
+ }
+ }
+ unregisterInteraction() {
+ var _a;
+ if (this.interactionManager) {
+ (_a = this.interactionManager) == null ? void 0 : _a.off("pointermove", onPointerMove, this);
+ this.interactionManager = void 0;
+ }
+ }
+ }
+ function onTap(event) {
+ this.tap(event.data.global.x, event.data.global.y);
+ }
+ function onPointerMove(event) {
+ this.focus(event.data.global.x, event.data.global.y);
+ }
+ class Live2DTransform extends math.Transform {
+ }
+ const tempPoint = new math.Point();
+ const tempMatrix$1 = new math.Matrix();
+ let tickerRef;
+ class Live2DModel extends display.Container {
+ constructor(options) {
+ super();
+ this.tag = "Live2DModel(uninitialized)";
+ this.textures = [];
+ this.transform = new Live2DTransform();
+ this.anchor = new math.ObservablePoint(this.onAnchorChange, this, 0, 0);
+ this.glContextID = -1;
+ this.elapsedTime = performance.now();
+ this.deltaTime = 0;
+ this._autoUpdate = false;
+ this.once("modelLoaded", () => this.init(options));
+ }
+ static from(source, options) {
+ const model = new this(options);
+ return Live2DFactory.setupLive2DModel(model, source, options).then(() => model);
+ }
+ static fromSync(source, options) {
+ const model = new this(options);
+ Live2DFactory.setupLive2DModel(model, source, options).then(options == null ? void 0 : options.onLoad).catch(options == null ? void 0 : options.onError);
+ return model;
+ }
+ static registerTicker(tickerClass) {
+ tickerRef = tickerClass;
+ }
+ get autoUpdate() {
+ return this._autoUpdate;
+ }
+ set autoUpdate(autoUpdate) {
+ var _a;
+ tickerRef || (tickerRef = (_a = window.PIXI) == null ? void 0 : _a.Ticker);
+ if (autoUpdate) {
+ if (!this._destroyed) {
+ if (tickerRef) {
+ tickerRef.shared.add(this.onTickerUpdate, this);
+ this._autoUpdate = true;
+ } else {
+ logger.warn(this.tag, "No Ticker registered, please call Live2DModel.registerTicker(Ticker).");
+ }
+ }
+ } else {
+ tickerRef == null ? void 0 : tickerRef.shared.remove(this.onTickerUpdate, this);
+ this._autoUpdate = false;
+ }
+ }
+ init(options) {
+ this.tag = `Live2DModel(${this.internalModel.settings.name})`;
+ const _options = Object.assign({
+ autoUpdate: true,
+ autoInteract: true
+ }, options);
+ if (_options.autoInteract) {
+ this.interactive = true;
+ }
+ this.autoInteract = _options.autoInteract;
+ this.autoUpdate = _options.autoUpdate;
+ }
+ onAnchorChange() {
+ this.pivot.set(this.anchor.x * this.internalModel.width, this.anchor.y * this.internalModel.height);
+ }
+ motion(group, index, priority, sound, volume, expression) {
+ return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority) : this.internalModel.motionManager.startMotion(group, index, priority, sound, volume, expression);
+ }
+ resetMotions() {
+ return this.internalModel.motionManager.stopAllMotions();
+ }
+ speak(sound, volume, expression) {
+ return this.internalModel.motionManager.speakUp(sound, volume, expression);
+ }
+ stopSpeaking() {
+ return this.internalModel.motionManager.stopSpeaking();
+ }
+ expression(id) {
+ if (this.internalModel.motionManager.expressionManager) {
+ return id === void 0 ? this.internalModel.motionManager.expressionManager.setRandomExpression() : this.internalModel.motionManager.expressionManager.setExpression(id);
+ }
+ return Promise.resolve(false);
+ }
+ focus(x, y, instant = false) {
+ tempPoint.x = x;
+ tempPoint.y = y;
+ this.toModelPosition(tempPoint, tempPoint, true);
+ let tx = tempPoint.x / this.internalModel.originalWidth * 2 - 1;
+ let ty = tempPoint.y / this.internalModel.originalHeight * 2 - 1;
+ let radian = Math.atan2(ty, tx);
+ this.internalModel.focusController.focus(Math.cos(radian), -Math.sin(radian), instant);
+ }
+ tap(x, y) {
+ const hitAreaNames = this.hitTest(x, y);
+ if (hitAreaNames.length) {
+ logger.log(this.tag, `Hit`, hitAreaNames);
+ this.emit("hit", hitAreaNames);
+ }
+ }
+ hitTest(x, y) {
+ tempPoint.x = x;
+ tempPoint.y = y;
+ this.toModelPosition(tempPoint, tempPoint);
+ return this.internalModel.hitTest(tempPoint.x, tempPoint.y);
+ }
+ toModelPosition(position, result = position.clone(), skipUpdate) {
+ if (!skipUpdate) {
+ this._recursivePostUpdateTransform();
+ if (!this.parent) {
+ this.parent = this._tempDisplayObjectParent;
+ this.displayObjectUpdateTransform();
+ this.parent = null;
+ } else {
+ this.displayObjectUpdateTransform();
+ }
+ }
+ this.transform.worldTransform.applyInverse(position, result);
+ this.internalModel.localTransform.applyInverse(result, result);
+ return result;
+ }
+ containsPoint(point) {
+ return this.getBounds(true).contains(point.x, point.y);
+ }
+ _calculateBounds() {
+ this._bounds.addFrame(this.transform, 0, 0, this.internalModel.width, this.internalModel.height);
+ }
+ onTickerUpdate() {
+ this.update(tickerRef.shared.deltaMS);
+ }
+ update(dt) {
+ this.deltaTime += dt;
+ this.elapsedTime += dt;
+ }
+ _render(renderer) {
+ this.registerInteraction(renderer.plugins.interaction);
+ renderer.batch.reset();
+ renderer.geometry.reset();
+ renderer.shader.reset();
+ renderer.state.reset();
+ let shouldUpdateTexture = false;
+ if (this.glContextID !== renderer.CONTEXT_UID) {
+ this.glContextID = renderer.CONTEXT_UID;
+ this.internalModel.updateWebGLContext(renderer.gl, this.glContextID);
+ shouldUpdateTexture = true;
+ }
+ for (let i = 0; i < this.textures.length; i++) {
+ const texture = this.textures[i];
+ if (!texture.valid) {
+ continue;
+ }
+ if (shouldUpdateTexture || !texture.baseTexture._glTextures[this.glContextID]) {
+ renderer.gl.pixelStorei(WebGLRenderingContext.UNPACK_FLIP_Y_WEBGL, this.internalModel.textureFlipY);
+ renderer.texture.bind(texture.baseTexture, 0);
+ }
+ this.internalModel.bindTexture(i, texture.baseTexture._glTextures[this.glContextID].texture);
+ texture.baseTexture.touched = renderer.textureGC.count;
+ }
+ const viewport = renderer.framebuffer.viewport;
+ this.internalModel.viewport = [viewport.x, viewport.y, viewport.width, viewport.height];
+ if (this.deltaTime) {
+ this.internalModel.update(this.deltaTime, this.elapsedTime);
+ this.deltaTime = 0;
+ }
+ const internalTransform = tempMatrix$1.copyFrom(renderer.globalUniforms.uniforms.projectionMatrix).append(this.worldTransform);
+ this.internalModel.updateTransform(internalTransform);
+ this.internalModel.draw(renderer.gl);
+ renderer.state.reset();
+ renderer.texture.reset();
+ }
+ destroy(options) {
+ this.emit("destroy");
+ this.autoUpdate = false;
+ this.unregisterInteraction();
+ if (options == null ? void 0 : options.texture) {
+ this.textures.forEach((texture) => texture.destroy(options.baseTexture));
+ }
+ this.internalModel.destroy();
+ super.destroy(options);
+ }
+ }
+ applyMixins(Live2DModel, [InteractionMixin]);
+ const _FileLoader = class {
+ static resolveURL(settingsURL, filePath) {
+ var _a;
+ const resolved = (_a = _FileLoader.filesMap[settingsURL]) == null ? void 0 : _a[filePath];
+ if (resolved === void 0) {
+ throw new Error("Cannot find this file from uploaded files: " + filePath);
+ }
+ return resolved;
+ }
+ static upload(files, settings) {
+ return __async(this, null, function* () {
+ const fileMap = {};
+ for (const definedFile of settings.getDefinedFiles()) {
+ const actualPath = decodeURI(utils.url.resolve(settings.url, definedFile));
+ const actualFile = files.find((file) => file.webkitRelativePath === actualPath);
+ if (actualFile) {
+ fileMap[definedFile] = URL.createObjectURL(actualFile);
+ }
+ }
+ _FileLoader.filesMap[settings._objectURL] = fileMap;
+ });
+ }
+ static createSettings(files) {
+ return __async(this, null, function* () {
+ const settingsFile = files.find((file) => file.name.endsWith("model.json") || file.name.endsWith("model3.json"));
+ if (!settingsFile) {
+ throw new TypeError("Settings file not found");
+ }
+ const settingsText = yield _FileLoader.readText(settingsFile);
+ const settingsJSON = JSON.parse(settingsText);
+ settingsJSON.url = settingsFile.webkitRelativePath;
+ const runtime = Live2DFactory.findRuntime(settingsJSON);
+ if (!runtime) {
+ throw new Error("Unknown settings JSON");
+ }
+ const settings = runtime.createModelSettings(settingsJSON);
+ settings._objectURL = URL.createObjectURL(settingsFile);
+ return settings;
+ });
+ }
+ static readText(file) {
+ return __async(this, null, function* () {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = () => resolve(reader.result);
+ reader.onerror = reject;
+ reader.readAsText(file, "utf8");
+ });
+ });
+ }
+ };
+ let FileLoader = _FileLoader;
+ FileLoader.filesMap = {};
+ FileLoader.factory = (context, next) => __async(this, null, function* () {
+ if (Array.isArray(context.source) && context.source[0] instanceof File) {
+ const files = context.source;
+ let settings = files.settings;
+ if (!settings) {
+ settings = yield _FileLoader.createSettings(files);
+ } else if (!settings._objectURL) {
+ throw new Error('"_objectURL" must be specified in ModelSettings');
+ }
+ settings.validateFiles(files.map((file) => encodeURI(file.webkitRelativePath)));
+ yield _FileLoader.upload(files, settings);
+ settings.resolveURL = function(url) {
+ return _FileLoader.resolveURL(this._objectURL, url);
+ };
+ context.source = settings;
+ context.live2dModel.once("modelLoaded", (internalModel) => {
+ internalModel.once("destroy", function() {
+ const objectURL = this.settings._objectURL;
+ URL.revokeObjectURL(objectURL);
+ if (_FileLoader.filesMap[objectURL]) {
+ for (const resourceObjectURL of Object.values(_FileLoader.filesMap[objectURL])) {
+ URL.revokeObjectURL(resourceObjectURL);
+ }
+ }
+ delete _FileLoader.filesMap[objectURL];
+ });
+ });
+ }
+ return next();
+ });
+ Live2DFactory.live2DModelMiddlewares.unshift(FileLoader.factory);
+ const _ZipLoader = class {
+ static unzip(reader, settings) {
+ return __async(this, null, function* () {
+ const filePaths = yield _ZipLoader.getFilePaths(reader);
+ const requiredFilePaths = [];
+ for (const definedFile of settings.getDefinedFiles()) {
+ const actualPath = decodeURI(utils.url.resolve(settings.url, definedFile));
+ if (filePaths.includes(actualPath)) {
+ requiredFilePaths.push(actualPath);
+ }
+ }
+ const files = yield _ZipLoader.getFiles(reader, requiredFilePaths);
+ for (let i = 0; i < files.length; i++) {
+ const path = requiredFilePaths[i];
+ const file = files[i];
+ Object.defineProperty(file, "webkitRelativePath", {
+ value: path
+ });
+ }
+ return files;
+ });
+ }
+ static createSettings(reader) {
+ return __async(this, null, function* () {
+ const filePaths = yield _ZipLoader.getFilePaths(reader);
+ const settingsFilePath = filePaths.find((path) => path.endsWith("model.json") || path.endsWith("model3.json"));
+ if (!settingsFilePath) {
+ throw new Error("Settings file not found");
+ }
+ const settingsText = yield _ZipLoader.readText(reader, settingsFilePath);
+ if (!settingsText) {
+ throw new Error("Empty settings file: " + settingsFilePath);
+ }
+ const settingsJSON = JSON.parse(settingsText);
+ settingsJSON.url = settingsFilePath;
+ const runtime = Live2DFactory.findRuntime(settingsJSON);
+ if (!runtime) {
+ throw new Error("Unknown settings JSON");
+ }
+ return runtime.createModelSettings(settingsJSON);
+ });
+ }
+ static zipReader(data, url) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static getFilePaths(reader) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static getFiles(reader, paths) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static readText(reader, path) {
+ return __async(this, null, function* () {
+ throw new Error("Not implemented");
+ });
+ }
+ static releaseReader(reader) {
+ }
+ };
+ let ZipLoader = _ZipLoader;
+ ZipLoader.ZIP_PROTOCOL = "zip://";
+ ZipLoader.uid = 0;
+ ZipLoader.factory = (context, next) => __async(this, null, function* () {
+ const source = context.source;
+ let sourceURL;
+ let zipBlob;
+ let settings;
+ if (typeof source === "string" && (source.endsWith(".zip") || source.startsWith(_ZipLoader.ZIP_PROTOCOL))) {
+ if (source.startsWith(_ZipLoader.ZIP_PROTOCOL)) {
+ sourceURL = source.slice(_ZipLoader.ZIP_PROTOCOL.length);
+ } else {
+ sourceURL = source;
+ }
+ zipBlob = yield Live2DLoader.load({
+ url: sourceURL,
+ type: "blob",
+ target: context.live2dModel
+ });
+ } else if (Array.isArray(source) && source.length === 1 && source[0] instanceof File && source[0].name.endsWith(".zip")) {
+ zipBlob = source[0];
+ sourceURL = URL.createObjectURL(zipBlob);
+ settings = source.settings;
+ }
+ if (zipBlob) {
+ if (!zipBlob.size) {
+ throw new Error("Empty zip file");
+ }
+ const reader = yield _ZipLoader.zipReader(zipBlob, sourceURL);
+ if (!settings) {
+ settings = yield _ZipLoader.createSettings(reader);
+ }
+ settings._objectURL = _ZipLoader.ZIP_PROTOCOL + _ZipLoader.uid + "/" + settings.url;
+ const files = yield _ZipLoader.unzip(reader, settings);
+ files.settings = settings;
+ context.source = files;
+ if (sourceURL.startsWith("blob:")) {
+ context.live2dModel.once("modelLoaded", (internalModel) => {
+ internalModel.once("destroy", function() {
+ URL.revokeObjectURL(sourceURL);
+ });
+ });
+ }
+ _ZipLoader.releaseReader(reader);
+ }
+ return next();
+ });
+ Live2DFactory.live2DModelMiddlewares.unshift(ZipLoader.factory);
+ if (!window.Live2D) {
+ throw new Error("Could not find Cubism 2 runtime. This plugin requires live2d.min.js to be loaded.");
+ }
+ const originalUpdateParam = Live2DMotion.prototype.updateParam;
+ Live2DMotion.prototype.updateParam = function(model, entry) {
+ originalUpdateParam.call(this, model, entry);
+ if (entry.isFinished() && this.onFinishHandler) {
+ this.onFinishHandler(this);
+ delete this.onFinishHandler;
+ }
+ };
+ class Live2DExpression extends AMotion {
+ constructor(json) {
+ super();
+ this.params = [];
+ this.setFadeIn(json.fade_in > 0 ? json.fade_in : exports2.config.expressionFadingDuration);
+ this.setFadeOut(json.fade_out > 0 ? json.fade_out : exports2.config.expressionFadingDuration);
+ if (Array.isArray(json.params)) {
+ json.params.forEach((param) => {
+ const calc = param.calc || "add";
+ if (calc === "add") {
+ const defaultValue = param.def || 0;
+ param.val -= defaultValue;
+ } else if (calc === "mult") {
+ const defaultValue = param.def || 1;
+ param.val /= defaultValue;
+ }
+ this.params.push({
+ calc,
+ val: param.val,
+ id: param.id
+ });
+ });
+ }
+ }
+ updateParamExe(model, time, weight, motionQueueEnt) {
+ this.params.forEach((param) => {
+ model.setParamFloat(param.id, param.val * weight);
+ });
+ }
+ }
+ class Cubism2ExpressionManager extends ExpressionManager {
+ constructor(settings, options) {
+ var _a;
+ super(settings, options);
+ this.queueManager = new MotionQueueManager();
+ this.definitions = (_a = this.settings.expressions) != null ? _a : [];
+ this.init();
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ getExpressionIndex(name) {
+ return this.definitions.findIndex((def) => def.name === name);
+ }
+ getExpressionFile(definition) {
+ return definition.file;
+ }
+ createExpression(data, definition) {
+ return new Live2DExpression(data);
+ }
+ _setExpression(motion) {
+ return this.queueManager.startMotion(motion);
+ }
+ stopAllExpressions() {
+ this.queueManager.stopAllMotions();
+ }
+ updateParameters(model, dt) {
+ return this.queueManager.updateParam(model);
+ }
+ }
+ class Cubism2MotionManager extends MotionManager {
+ constructor(settings, options) {
+ super(settings, options);
+ this.groups = { idle: "idle" };
+ this.motionDataType = "arraybuffer";
+ this.queueManager = new MotionQueueManager();
+ this.definitions = this.settings.motions;
+ this.init(options);
+ }
+ init(options) {
+ super.init(options);
+ if (this.settings.expressions) {
+ this.expressionManager = new Cubism2ExpressionManager(this.settings, options);
+ }
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ createMotion(data, group, definition) {
+ const motion = Live2DMotion.loadMotion(data);
+ const defaultFadingDuration = group === this.groups.idle ? exports2.config.idleMotionFadingDuration : exports2.config.motionFadingDuration;
+ motion.setFadeIn(definition.fade_in > 0 ? definition.fade_in : defaultFadingDuration);
+ motion.setFadeOut(definition.fade_out > 0 ? definition.fade_out : defaultFadingDuration);
+ return motion;
+ }
+ getMotionFile(definition) {
+ return definition.file;
+ }
+ getMotionName(definition) {
+ return definition.file;
+ }
+ getSoundFile(definition) {
+ return definition.sound;
+ }
+ _startMotion(motion, onFinish) {
+ motion.onFinishHandler = onFinish;
+ this.queueManager.stopAllMotions();
+ return this.queueManager.startMotion(motion);
+ }
+ _stopAllMotions() {
+ this.queueManager.stopAllMotions();
+ }
+ updateParameters(model, now) {
+ return this.queueManager.updateParam(model);
+ }
+ destroy() {
+ super.destroy();
+ this.queueManager = void 0;
+ }
+ }
+ class Live2DEyeBlink {
+ constructor(coreModel) {
+ this.coreModel = coreModel;
+ this.blinkInterval = 4e3;
+ this.closingDuration = 100;
+ this.closedDuration = 50;
+ this.openingDuration = 150;
+ this.eyeState = 0;
+ this.eyeParamValue = 1;
+ this.closedTimer = 0;
+ this.nextBlinkTimeLeft = this.blinkInterval;
+ this.leftParam = coreModel.getParamIndex("PARAM_EYE_L_OPEN");
+ this.rightParam = coreModel.getParamIndex("PARAM_EYE_R_OPEN");
+ }
+ setEyeParams(value) {
+ this.eyeParamValue = clamp(value, 0, 1);
+ this.coreModel.setParamFloat(this.leftParam, this.eyeParamValue);
+ this.coreModel.setParamFloat(this.rightParam, this.eyeParamValue);
+ }
+ update(dt) {
+ switch (this.eyeState) {
+ case 0:
+ this.nextBlinkTimeLeft -= dt;
+ if (this.nextBlinkTimeLeft < 0) {
+ this.eyeState = 1;
+ this.nextBlinkTimeLeft = this.blinkInterval + this.closingDuration + this.closedDuration + this.openingDuration + rand(0, 2e3);
+ }
+ break;
+ case 1:
+ this.setEyeParams(this.eyeParamValue + dt / this.closingDuration);
+ if (this.eyeParamValue <= 0) {
+ this.eyeState = 2;
+ this.closedTimer = 0;
+ }
+ break;
+ case 2:
+ this.closedTimer += dt;
+ if (this.closedTimer >= this.closedDuration) {
+ this.eyeState = 3;
+ }
+ break;
+ case 3:
+ this.setEyeParams(this.eyeParamValue + dt / this.openingDuration);
+ if (this.eyeParamValue >= 1) {
+ this.eyeState = 0;
+ }
+ }
+ }
+ }
+ const tempMatrixArray = new Float32Array([
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ]);
+ class Cubism2InternalModel extends InternalModel {
+ constructor(coreModel, settings, options) {
+ super();
+ this.textureFlipY = true;
+ this.drawDataCount = 0;
+ this.disableCulling = false;
+ this.coreModel = coreModel;
+ this.settings = settings;
+ this.motionManager = new Cubism2MotionManager(settings, options);
+ this.eyeBlink = new Live2DEyeBlink(coreModel);
+ this.eyeballXParamIndex = coreModel.getParamIndex("PARAM_EYE_BALL_X");
+ this.eyeballYParamIndex = coreModel.getParamIndex("PARAM_EYE_BALL_Y");
+ this.angleXParamIndex = coreModel.getParamIndex("PARAM_ANGLE_X");
+ this.angleYParamIndex = coreModel.getParamIndex("PARAM_ANGLE_Y");
+ this.angleZParamIndex = coreModel.getParamIndex("PARAM_ANGLE_Z");
+ this.bodyAngleXParamIndex = coreModel.getParamIndex("PARAM_BODY_ANGLE_X");
+ this.breathParamIndex = coreModel.getParamIndex("PARAM_BREATH");
+ this.init();
+ }
+ init() {
+ super.init();
+ if (this.settings.initParams) {
+ this.settings.initParams.forEach(({ id, value }) => this.coreModel.setParamFloat(id, value));
+ }
+ if (this.settings.initOpacities) {
+ this.settings.initOpacities.forEach(({ id, value }) => this.coreModel.setPartsOpacity(id, value));
+ }
+ this.coreModel.saveParam();
+ const arr = this.coreModel.getModelContext()._$aS;
+ if (arr == null ? void 0 : arr.length) {
+ this.drawDataCount = arr.length;
+ }
+ let culling = this.coreModel.drawParamWebGL.culling;
+ Object.defineProperty(this.coreModel.drawParamWebGL, "culling", {
+ set: (v) => culling = v,
+ get: () => this.disableCulling ? false : culling
+ });
+ const clipManager = this.coreModel.getModelContext().clipManager;
+ const originalSetupClip = clipManager.setupClip;
+ clipManager.setupClip = (modelContext, drawParam) => {
+ originalSetupClip.call(clipManager, modelContext, drawParam);
+ drawParam.gl.viewport(...this.viewport);
+ };
+ }
+ getSize() {
+ return [this.coreModel.getCanvasWidth(), this.coreModel.getCanvasHeight()];
+ }
+ getLayout() {
+ const layout = {};
+ if (this.settings.layout) {
+ for (const key of Object.keys(this.settings.layout)) {
+ let commonKey = key;
+ if (key === "center_x") {
+ commonKey = "centerX";
+ } else if (key === "center_y") {
+ commonKey = "centerY";
+ }
+ layout[commonKey] = this.settings.layout[key];
+ }
+ }
+ return layout;
+ }
+ updateWebGLContext(gl, glContextID) {
+ const drawParamWebGL = this.coreModel.drawParamWebGL;
+ drawParamWebGL.firstDraw = true;
+ drawParamWebGL.setGL(gl);
+ drawParamWebGL.glno = glContextID;
+ for (const prop in drawParamWebGL) {
+ if (drawParamWebGL.hasOwnProperty(prop) && drawParamWebGL[prop] instanceof WebGLBuffer) {
+ drawParamWebGL[prop] = null;
+ }
+ }
+ const clipManager = this.coreModel.getModelContext().clipManager;
+ clipManager.curFrameNo = glContextID;
+ const framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
+ clipManager.getMaskRenderTexture();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+ }
+ bindTexture(index, texture) {
+ this.coreModel.setTexture(index, texture);
+ }
+ getHitAreaDefs() {
+ var _a;
+ return ((_a = this.settings.hitAreas) == null ? void 0 : _a.map((hitArea) => ({
+ id: hitArea.id,
+ name: hitArea.name,
+ index: this.coreModel.getDrawDataIndex(hitArea.id)
+ }))) || [];
+ }
+ getDrawableIDs() {
+ const modelContext = this.coreModel.getModelContext();
+ const ids = [];
+ for (let i = 0; i < this.drawDataCount; i++) {
+ const drawData = modelContext.getDrawData(i);
+ if (drawData) {
+ ids.push(drawData.getDrawDataID().id);
+ }
+ }
+ return ids;
+ }
+ getDrawableIndex(id) {
+ return this.coreModel.getDrawDataIndex(id);
+ }
+ getDrawableVertices(drawIndex) {
+ if (typeof drawIndex === "string") {
+ drawIndex = this.coreModel.getDrawDataIndex(drawIndex);
+ if (drawIndex === -1)
+ throw new TypeError("Unable to find drawable ID: " + drawIndex);
+ }
+ return this.coreModel.getTransformedPoints(drawIndex).slice();
+ }
+ update(dt, now) {
+ var _a, _b, _c, _d;
+ super.update(dt, now);
+ const model = this.coreModel;
+ this.emit("beforeMotionUpdate");
+ const motionUpdated = this.motionManager.update(this.coreModel, now);
+ this.emit("afterMotionUpdate");
+ model.saveParam();
+ (_a = this.motionManager.expressionManager) == null ? void 0 : _a.update(model, now);
+ if (!motionUpdated) {
+ (_b = this.eyeBlink) == null ? void 0 : _b.update(dt);
+ }
+ this.updateFocus();
+ this.updateNaturalMovements(dt, now);
+ (_c = this.physics) == null ? void 0 : _c.update(now);
+ (_d = this.pose) == null ? void 0 : _d.update(dt);
+ this.emit("beforeModelUpdate");
+ model.update();
+ model.loadParam();
+ }
+ updateFocus() {
+ this.coreModel.addToParamFloat(this.eyeballXParamIndex, this.focusController.x);
+ this.coreModel.addToParamFloat(this.eyeballYParamIndex, this.focusController.y);
+ this.coreModel.addToParamFloat(this.angleXParamIndex, this.focusController.x * 30);
+ this.coreModel.addToParamFloat(this.angleYParamIndex, this.focusController.y * 30);
+ this.coreModel.addToParamFloat(this.angleZParamIndex, this.focusController.x * this.focusController.y * -30);
+ this.coreModel.addToParamFloat(this.bodyAngleXParamIndex, this.focusController.x * 10);
+ }
+ updateNaturalMovements(dt, now) {
+ const t = now / 1e3 * 2 * Math.PI;
+ this.coreModel.addToParamFloat(this.angleXParamIndex, 15 * Math.sin(t / 6.5345) * 0.5);
+ this.coreModel.addToParamFloat(this.angleYParamIndex, 8 * Math.sin(t / 3.5345) * 0.5);
+ this.coreModel.addToParamFloat(this.angleZParamIndex, 10 * Math.sin(t / 5.5345) * 0.5);
+ this.coreModel.addToParamFloat(this.bodyAngleXParamIndex, 4 * Math.sin(t / 15.5345) * 0.5);
+ this.coreModel.setParamFloat(this.breathParamIndex, 0.5 + 0.5 * Math.sin(t / 3.2345));
+ }
+ draw(gl) {
+ const disableCulling = this.disableCulling;
+ if (gl.getParameter(gl.FRAMEBUFFER_BINDING)) {
+ this.disableCulling = true;
+ }
+ const matrix = this.drawingMatrix;
+ tempMatrixArray[0] = matrix.a;
+ tempMatrixArray[1] = matrix.b;
+ tempMatrixArray[4] = matrix.c;
+ tempMatrixArray[5] = matrix.d;
+ tempMatrixArray[12] = matrix.tx;
+ tempMatrixArray[13] = matrix.ty;
+ this.coreModel.setMatrix(tempMatrixArray);
+ this.coreModel.draw();
+ this.disableCulling = disableCulling;
+ }
+ destroy() {
+ super.destroy();
+ this.coreModel = void 0;
+ }
+ }
+ class Cubism2ModelSettings extends ModelSettings {
+ constructor(json) {
+ super(json);
+ this.motions = {};
+ if (!Cubism2ModelSettings.isValidJSON(json)) {
+ throw new TypeError("Invalid JSON.");
+ }
+ this.moc = json.model;
+ copyArray("string", json, this, "textures", "textures");
+ this.copy(json);
+ }
+ static isValidJSON(json) {
+ var _a;
+ return !!json && typeof json.model === "string" && ((_a = json.textures) == null ? void 0 : _a.length) > 0 && json.textures.every((item) => typeof item === "string");
+ }
+ copy(json) {
+ copyProperty("string", json, this, "name", "name");
+ copyProperty("string", json, this, "pose", "pose");
+ copyProperty("string", json, this, "physics", "physics");
+ copyProperty("object", json, this, "layout", "layout");
+ copyProperty("object", json, this, "motions", "motions");
+ copyArray("object", json, this, "hit_areas", "hitAreas");
+ copyArray("object", json, this, "expressions", "expressions");
+ copyArray("object", json, this, "init_params", "initParams");
+ copyArray("object", json, this, "init_opacities", "initOpacities");
+ }
+ replaceFiles(replace) {
+ super.replaceFiles(replace);
+ for (const [group, motions] of Object.entries(this.motions)) {
+ for (let i = 0; i < motions.length; i++) {
+ motions[i].file = replace(motions[i].file, `motions.${group}[${i}].file`);
+ if (motions[i].sound !== void 0) {
+ motions[i].sound = replace(motions[i].sound, `motions.${group}[${i}].sound`);
+ }
+ }
+ }
+ if (this.expressions) {
+ for (let i = 0; i < this.expressions.length; i++) {
+ this.expressions[i].file = replace(this.expressions[i].file, `expressions[${i}].file`);
+ }
+ }
+ }
+ }
+ const SRC_TYPE_MAP = {
+ x: PhysicsHair.Src.SRC_TO_X,
+ y: PhysicsHair.Src.SRC_TO_Y,
+ angle: PhysicsHair.Src.SRC_TO_G_ANGLE
+ };
+ const TARGET_TYPE_MAP = {
+ x: PhysicsHair.Src.SRC_TO_X,
+ y: PhysicsHair.Src.SRC_TO_Y,
+ angle: PhysicsHair.Src.SRC_TO_G_ANGLE
+ };
+ class Live2DPhysics {
+ constructor(coreModel, json) {
+ this.coreModel = coreModel;
+ this.physicsHairs = [];
+ if (json.physics_hair) {
+ this.physicsHairs = json.physics_hair.map((definition) => {
+ const physicsHair = new PhysicsHair();
+ physicsHair.setup(definition.setup.length, definition.setup.regist, definition.setup.mass);
+ definition.src.forEach(({ id, ptype, scale, weight }) => {
+ const type = SRC_TYPE_MAP[ptype];
+ if (type) {
+ physicsHair.addSrcParam(type, id, scale, weight);
+ }
+ });
+ definition.targets.forEach(({ id, ptype, scale, weight }) => {
+ const type = TARGET_TYPE_MAP[ptype];
+ if (type) {
+ physicsHair.addTargetParam(type, id, scale, weight);
+ }
+ });
+ return physicsHair;
+ });
+ }
+ }
+ update(elapsed) {
+ this.physicsHairs.forEach((physicsHair) => physicsHair.update(this.coreModel, elapsed));
+ }
+ }
+ class Live2DPartsParam {
+ constructor(id) {
+ this.id = id;
+ this.paramIndex = -1;
+ this.partsIndex = -1;
+ this.link = [];
+ }
+ initIndex(model) {
+ this.paramIndex = model.getParamIndex("VISIBLE:" + this.id);
+ this.partsIndex = model.getPartsDataIndex(PartsDataID.getID(this.id));
+ model.setParamFloat(this.paramIndex, 1);
+ }
+ }
+ class Live2DPose {
+ constructor(coreModel, json) {
+ this.coreModel = coreModel;
+ this.opacityAnimDuration = 500;
+ this.partsGroups = [];
+ if (json.parts_visible) {
+ this.partsGroups = json.parts_visible.map(({ group }) => group.map(({ id, link }) => {
+ const parts = new Live2DPartsParam(id);
+ if (link) {
+ parts.link = link.map((l) => new Live2DPartsParam(l));
+ }
+ return parts;
+ }));
+ this.init();
+ }
+ }
+ init() {
+ this.partsGroups.forEach((group) => {
+ group.forEach((parts) => {
+ parts.initIndex(this.coreModel);
+ if (parts.paramIndex >= 0) {
+ const visible = this.coreModel.getParamFloat(parts.paramIndex) !== 0;
+ this.coreModel.setPartsOpacity(parts.partsIndex, visible ? 1 : 0);
+ this.coreModel.setParamFloat(parts.paramIndex, visible ? 1 : 0);
+ if (parts.link.length > 0) {
+ parts.link.forEach((p) => p.initIndex(this.coreModel));
+ }
+ }
+ });
+ });
+ }
+ normalizePartsOpacityGroup(partsGroup, dt) {
+ const model = this.coreModel;
+ const phi = 0.5;
+ const maxBackOpacity = 0.15;
+ let visibleOpacity = 1;
+ let visibleIndex = partsGroup.findIndex(({ paramIndex, partsIndex }) => partsIndex >= 0 && model.getParamFloat(paramIndex) !== 0);
+ if (visibleIndex >= 0) {
+ const originalOpacity = model.getPartsOpacity(partsGroup[visibleIndex].partsIndex);
+ visibleOpacity = clamp(originalOpacity + dt / this.opacityAnimDuration, 0, 1);
+ } else {
+ visibleIndex = 0;
+ visibleOpacity = 1;
+ }
+ partsGroup.forEach(({ partsIndex }, index) => {
+ if (partsIndex >= 0) {
+ if (visibleIndex == index) {
+ model.setPartsOpacity(partsIndex, visibleOpacity);
+ } else {
+ let opacity = model.getPartsOpacity(partsIndex);
+ let a1;
+ if (visibleOpacity < phi) {
+ a1 = visibleOpacity * (phi - 1) / phi + 1;
+ } else {
+ a1 = (1 - visibleOpacity) * phi / (1 - phi);
+ }
+ let backOp = (1 - a1) * (1 - visibleOpacity);
+ if (backOp > maxBackOpacity) {
+ a1 = 1 - maxBackOpacity / (1 - visibleOpacity);
+ }
+ if (opacity > a1) {
+ opacity = a1;
+ }
+ model.setPartsOpacity(partsIndex, opacity);
+ }
+ }
+ });
+ }
+ copyOpacity(partsGroup) {
+ const model = this.coreModel;
+ partsGroup.forEach(({ partsIndex, link }) => {
+ if (partsIndex >= 0 && link) {
+ const opacity = model.getPartsOpacity(partsIndex);
+ link.forEach(({ partsIndex: partsIndex2 }) => {
+ if (partsIndex2 >= 0) {
+ model.setPartsOpacity(partsIndex2, opacity);
+ }
+ });
+ }
+ });
+ }
+ update(dt) {
+ this.partsGroups.forEach((partGroup) => {
+ this.normalizePartsOpacityGroup(partGroup, dt);
+ this.copyOpacity(partGroup);
+ });
+ }
+ }
+ Live2DFactory.registerRuntime({
+ version: 2,
+ test(source) {
+ return source instanceof Cubism2ModelSettings || Cubism2ModelSettings.isValidJSON(source);
+ },
+ ready() {
+ return Promise.resolve();
+ },
+ isValidMoc(modelData) {
+ if (modelData.byteLength < 3) {
+ return false;
+ }
+ const view = new Int8Array(modelData, 0, 3);
+ return String.fromCharCode(...view) === "moc";
+ },
+ createModelSettings(json) {
+ return new Cubism2ModelSettings(json);
+ },
+ createCoreModel(data) {
+ const model = Live2DModelWebGL.loadModel(data);
+ const error = Live2D.getError();
+ if (error)
+ throw error;
+ return model;
+ },
+ createInternalModel(coreModel, settings, options) {
+ return new Cubism2InternalModel(coreModel, settings, options);
+ },
+ createPose(coreModel, data) {
+ return new Live2DPose(coreModel, data);
+ },
+ createPhysics(coreModel, data) {
+ return new Live2DPhysics(coreModel, data);
+ }
+ });
+ if (!window.Live2DCubismCore) {
+ throw new Error("Could not find Cubism 4 runtime. This plugin requires live2dcubismcore.js to be loaded.");
+ }
+ class CubismVector2 {
+ constructor(x, y) {
+ this.x = x || 0;
+ this.y = y || 0;
+ }
+ add(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x + vector2.x;
+ ret.y = this.y + vector2.y;
+ return ret;
+ }
+ substract(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x - vector2.x;
+ ret.y = this.y - vector2.y;
+ return ret;
+ }
+ multiply(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x * vector2.x;
+ ret.y = this.y * vector2.y;
+ return ret;
+ }
+ multiplyByScaler(scalar) {
+ return this.multiply(new CubismVector2(scalar, scalar));
+ }
+ division(vector2) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this.x / vector2.x;
+ ret.y = this.y / vector2.y;
+ return ret;
+ }
+ divisionByScalar(scalar) {
+ return this.division(new CubismVector2(scalar, scalar));
+ }
+ getLength() {
+ return Math.sqrt(this.x * this.x + this.y * this.y);
+ }
+ getDistanceWith(a) {
+ return Math.sqrt((this.x - a.x) * (this.x - a.x) + (this.y - a.y) * (this.y - a.y));
+ }
+ dot(a) {
+ return this.x * a.x + this.y * a.y;
+ }
+ normalize() {
+ const length = Math.pow(this.x * this.x + this.y * this.y, 0.5);
+ this.x = this.x / length;
+ this.y = this.y / length;
+ }
+ isEqual(rhs) {
+ return this.x == rhs.x && this.y == rhs.y;
+ }
+ isNotEqual(rhs) {
+ return !this.isEqual(rhs);
+ }
+ }
+ const _CubismMath = class {
+ static range(value, min, max) {
+ if (value < min) {
+ value = min;
+ } else if (value > max) {
+ value = max;
+ }
+ return value;
+ }
+ static sin(x) {
+ return Math.sin(x);
+ }
+ static cos(x) {
+ return Math.cos(x);
+ }
+ static abs(x) {
+ return Math.abs(x);
+ }
+ static sqrt(x) {
+ return Math.sqrt(x);
+ }
+ static cbrt(x) {
+ if (x === 0) {
+ return x;
+ }
+ let cx = x;
+ const isNegativeNumber = cx < 0;
+ if (isNegativeNumber) {
+ cx = -cx;
+ }
+ let ret;
+ if (cx === Infinity) {
+ ret = Infinity;
+ } else {
+ ret = Math.exp(Math.log(cx) / 3);
+ ret = (cx / (ret * ret) + 2 * ret) / 3;
+ }
+ return isNegativeNumber ? -ret : ret;
+ }
+ static getEasingSine(value) {
+ if (value < 0) {
+ return 0;
+ } else if (value > 1) {
+ return 1;
+ }
+ return 0.5 - 0.5 * this.cos(value * Math.PI);
+ }
+ static max(left, right) {
+ return left > right ? left : right;
+ }
+ static min(left, right) {
+ return left > right ? right : left;
+ }
+ static degreesToRadian(degrees) {
+ return degrees / 180 * Math.PI;
+ }
+ static radianToDegrees(radian) {
+ return radian * 180 / Math.PI;
+ }
+ static directionToRadian(from, to) {
+ const q1 = Math.atan2(to.y, to.x);
+ const q2 = Math.atan2(from.y, from.x);
+ let ret = q1 - q2;
+ while (ret < -Math.PI) {
+ ret += Math.PI * 2;
+ }
+ while (ret > Math.PI) {
+ ret -= Math.PI * 2;
+ }
+ return ret;
+ }
+ static directionToDegrees(from, to) {
+ const radian = this.directionToRadian(from, to);
+ let degree = this.radianToDegrees(radian);
+ if (to.x - from.x > 0) {
+ degree = -degree;
+ }
+ return degree;
+ }
+ static radianToDirection(totalAngle) {
+ const ret = new CubismVector2();
+ ret.x = this.sin(totalAngle);
+ ret.y = this.cos(totalAngle);
+ return ret;
+ }
+ static quadraticEquation(a, b, c) {
+ if (this.abs(a) < _CubismMath.Epsilon) {
+ if (this.abs(b) < _CubismMath.Epsilon) {
+ return -c;
+ }
+ return -c / b;
+ }
+ return -(b + this.sqrt(b * b - 4 * a * c)) / (2 * a);
+ }
+ static cardanoAlgorithmForBezier(a, b, c, d) {
+ if (this.sqrt(a) < _CubismMath.Epsilon) {
+ return this.range(this.quadraticEquation(b, c, d), 0, 1);
+ }
+ const ba = b / a;
+ const ca = c / a;
+ const da = d / a;
+ const p = (3 * ca - ba * ba) / 3;
+ const p3 = p / 3;
+ const q = (2 * ba * ba * ba - 9 * ba * ca + 27 * da) / 27;
+ const q2 = q / 2;
+ const discriminant = q2 * q2 + p3 * p3 * p3;
+ const center = 0.5;
+ const threshold = center + 0.01;
+ if (discriminant < 0) {
+ const mp3 = -p / 3;
+ const mp33 = mp3 * mp3 * mp3;
+ const r = this.sqrt(mp33);
+ const t = -q / (2 * r);
+ const cosphi = this.range(t, -1, 1);
+ const phi = Math.acos(cosphi);
+ const crtr = this.cbrt(r);
+ const t1 = 2 * crtr;
+ const root12 = t1 * this.cos(phi / 3) - ba / 3;
+ if (this.abs(root12 - center) < threshold) {
+ return this.range(root12, 0, 1);
+ }
+ const root2 = t1 * this.cos((phi + 2 * Math.PI) / 3) - ba / 3;
+ if (this.abs(root2 - center) < threshold) {
+ return this.range(root2, 0, 1);
+ }
+ const root3 = t1 * this.cos((phi + 4 * Math.PI) / 3) - ba / 3;
+ return this.range(root3, 0, 1);
+ }
+ if (discriminant == 0) {
+ let u12;
+ if (q2 < 0) {
+ u12 = this.cbrt(-q2);
+ } else {
+ u12 = -this.cbrt(q2);
+ }
+ const root12 = 2 * u12 - ba / 3;
+ if (this.abs(root12 - center) < threshold) {
+ return this.range(root12, 0, 1);
+ }
+ const root2 = -u12 - ba / 3;
+ return this.range(root2, 0, 1);
+ }
+ const sd = this.sqrt(discriminant);
+ const u1 = this.cbrt(sd - q2);
+ const v1 = this.cbrt(sd + q2);
+ const root1 = u1 - v1 - ba / 3;
+ return this.range(root1, 0, 1);
+ }
+ constructor() {
+ }
+ };
+ let CubismMath = _CubismMath;
+ CubismMath.Epsilon = 1e-5;
+ class CubismMatrix44 {
+ constructor() {
+ this._tr = new Float32Array(16);
+ this.loadIdentity();
+ }
+ static multiply(a, b, dst) {
+ const c = new Float32Array([
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ]);
+ const n = 4;
+ for (let i = 0; i < n; ++i) {
+ for (let j = 0; j < n; ++j) {
+ for (let k = 0; k < n; ++k) {
+ c[j + i * 4] += a[k + i * 4] * b[j + k * 4];
+ }
+ }
+ }
+ for (let i = 0; i < 16; ++i) {
+ dst[i] = c[i];
+ }
+ }
+ loadIdentity() {
+ const c = new Float32Array([
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ]);
+ this.setMatrix(c);
+ }
+ setMatrix(tr) {
+ for (let i = 0; i < 16; ++i) {
+ this._tr[i] = tr[i];
+ }
+ }
+ getArray() {
+ return this._tr;
+ }
+ getScaleX() {
+ return this._tr[0];
+ }
+ getScaleY() {
+ return this._tr[5];
+ }
+ getTranslateX() {
+ return this._tr[12];
+ }
+ getTranslateY() {
+ return this._tr[13];
+ }
+ transformX(src) {
+ return this._tr[0] * src + this._tr[12];
+ }
+ transformY(src) {
+ return this._tr[5] * src + this._tr[13];
+ }
+ invertTransformX(src) {
+ return (src - this._tr[12]) / this._tr[0];
+ }
+ invertTransformY(src) {
+ return (src - this._tr[13]) / this._tr[5];
+ }
+ translateRelative(x, y) {
+ const tr1 = new Float32Array([
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ x,
+ y,
+ 0,
+ 1
+ ]);
+ CubismMatrix44.multiply(tr1, this._tr, this._tr);
+ }
+ translate(x, y) {
+ this._tr[12] = x;
+ this._tr[13] = y;
+ }
+ translateX(x) {
+ this._tr[12] = x;
+ }
+ translateY(y) {
+ this._tr[13] = y;
+ }
+ scaleRelative(x, y) {
+ const tr1 = new Float32Array([
+ x,
+ 0,
+ 0,
+ 0,
+ 0,
+ y,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1
+ ]);
+ CubismMatrix44.multiply(tr1, this._tr, this._tr);
+ }
+ scale(x, y) {
+ this._tr[0] = x;
+ this._tr[5] = y;
+ }
+ multiplyByMatrix(m) {
+ CubismMatrix44.multiply(m.getArray(), this._tr, this._tr);
+ }
+ clone() {
+ const cloneMatrix = new CubismMatrix44();
+ for (let i = 0; i < this._tr.length; i++) {
+ cloneMatrix._tr[i] = this._tr[i];
+ }
+ return cloneMatrix;
+ }
+ }
+ class CubismRenderer {
+ initialize(model) {
+ this._model = model;
+ }
+ drawModel() {
+ if (this.getModel() == null)
+ return;
+ this.saveProfile();
+ this.doDrawModel();
+ this.restoreProfile();
+ }
+ setMvpMatrix(matrix44) {
+ this._mvpMatrix4x4.setMatrix(matrix44.getArray());
+ }
+ getMvpMatrix() {
+ return this._mvpMatrix4x4;
+ }
+ setModelColor(red, green, blue, alpha) {
+ if (red < 0) {
+ red = 0;
+ } else if (red > 1) {
+ red = 1;
+ }
+ if (green < 0) {
+ green = 0;
+ } else if (green > 1) {
+ green = 1;
+ }
+ if (blue < 0) {
+ blue = 0;
+ } else if (blue > 1) {
+ blue = 1;
+ }
+ if (alpha < 0) {
+ alpha = 0;
+ } else if (alpha > 1) {
+ alpha = 1;
+ }
+ this._modelColor.R = red;
+ this._modelColor.G = green;
+ this._modelColor.B = blue;
+ this._modelColor.A = alpha;
+ }
+ getModelColor() {
+ return Object.assign({}, this._modelColor);
+ }
+ setIsPremultipliedAlpha(enable) {
+ this._isPremultipliedAlpha = enable;
+ }
+ isPremultipliedAlpha() {
+ return this._isPremultipliedAlpha;
+ }
+ setIsCulling(culling) {
+ this._isCulling = culling;
+ }
+ isCulling() {
+ return this._isCulling;
+ }
+ setAnisotropy(n) {
+ this._anisotropy = n;
+ }
+ getAnisotropy() {
+ return this._anisotropy;
+ }
+ getModel() {
+ return this._model;
+ }
+ useHighPrecisionMask(high) {
+ this._useHighPrecisionMask = high;
+ }
+ isUsingHighPrecisionMask() {
+ return this._useHighPrecisionMask;
+ }
+ constructor() {
+ this._isCulling = false;
+ this._isPremultipliedAlpha = false;
+ this._anisotropy = 0;
+ this._modelColor = new CubismTextureColor();
+ this._useHighPrecisionMask = false;
+ this._mvpMatrix4x4 = new CubismMatrix44();
+ this._mvpMatrix4x4.loadIdentity();
+ }
+ }
+ var CubismBlendMode = /* @__PURE__ */ ((CubismBlendMode2) => {
+ CubismBlendMode2[CubismBlendMode2["CubismBlendMode_Normal"] = 0] = "CubismBlendMode_Normal";
+ CubismBlendMode2[CubismBlendMode2["CubismBlendMode_Additive"] = 1] = "CubismBlendMode_Additive";
+ CubismBlendMode2[CubismBlendMode2["CubismBlendMode_Multiplicative"] = 2] = "CubismBlendMode_Multiplicative";
+ return CubismBlendMode2;
+ })(CubismBlendMode || {});
+ class CubismTextureColor {
+ constructor(r = 1, g = 1, b = 1, a = 1) {
+ this.R = r;
+ this.G = g;
+ this.B = b;
+ this.A = a;
+ }
+ }
+ let s_isStarted = false;
+ let s_isInitialized = false;
+ let s_option = void 0;
+ const Constant = {
+ vertexOffset: 0,
+ vertexStep: 2
+ };
+ class CubismFramework {
+ static startUp(option) {
+ if (s_isStarted) {
+ CubismLogInfo("CubismFramework.startUp() is already done.");
+ return s_isStarted;
+ }
+ if (Live2DCubismCore._isStarted) {
+ s_isStarted = true;
+ return true;
+ }
+ Live2DCubismCore._isStarted = true;
+ s_option = option;
+ if (s_option) {
+ Live2DCubismCore.Logging.csmSetLogFunction(s_option.logFunction);
+ }
+ s_isStarted = true;
+ if (s_isStarted) {
+ const version = Live2DCubismCore.Version.csmGetVersion();
+ const major = (version & 4278190080) >> 24;
+ const minor = (version & 16711680) >> 16;
+ const patch = version & 65535;
+ const versionNumber = version;
+ CubismLogInfo(`Live2D Cubism Core version: {0}.{1}.{2} ({3})`, ("00" + major).slice(-2), ("00" + minor).slice(-2), ("0000" + patch).slice(-4), versionNumber);
+ }
+ CubismLogInfo("CubismFramework.startUp() is complete.");
+ return s_isStarted;
+ }
+ static cleanUp() {
+ s_isStarted = false;
+ s_isInitialized = false;
+ s_option = void 0;
+ }
+ static initialize(memorySize = 0) {
+ if (!s_isStarted) {
+ CubismLogWarning("CubismFramework is not started.");
+ return;
+ }
+ if (s_isInitialized) {
+ CubismLogWarning("CubismFramework.initialize() skipped, already initialized.");
+ return;
+ }
+ Live2DCubismCore.Memory.initializeAmountOfMemory(memorySize);
+ s_isInitialized = true;
+ CubismLogInfo("CubismFramework.initialize() is complete.");
+ }
+ static dispose() {
+ if (!s_isStarted) {
+ CubismLogWarning("CubismFramework is not started.");
+ return;
+ }
+ if (!s_isInitialized) {
+ CubismLogWarning("CubismFramework.dispose() skipped, not initialized.");
+ return;
+ }
+ CubismRenderer.staticRelease();
+ s_isInitialized = false;
+ CubismLogInfo("CubismFramework.dispose() is complete.");
+ }
+ static isStarted() {
+ return s_isStarted;
+ }
+ static isInitialized() {
+ return s_isInitialized;
+ }
+ static coreLogFunction(message) {
+ if (!Live2DCubismCore.Logging.csmGetLogFunction()) {
+ return;
+ }
+ Live2DCubismCore.Logging.csmGetLogFunction()(message);
+ }
+ static getLoggingLevel() {
+ if (s_option != null) {
+ return s_option.loggingLevel;
+ }
+ return LogLevel.LogLevel_Off;
+ }
+ constructor() {
+ }
+ }
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
+ LogLevel2[LogLevel2["LogLevel_Verbose"] = 0] = "LogLevel_Verbose";
+ LogLevel2[LogLevel2["LogLevel_Debug"] = 1] = "LogLevel_Debug";
+ LogLevel2[LogLevel2["LogLevel_Info"] = 2] = "LogLevel_Info";
+ LogLevel2[LogLevel2["LogLevel_Warning"] = 3] = "LogLevel_Warning";
+ LogLevel2[LogLevel2["LogLevel_Error"] = 4] = "LogLevel_Error";
+ LogLevel2[LogLevel2["LogLevel_Off"] = 5] = "LogLevel_Off";
+ return LogLevel2;
+ })(LogLevel || {});
+ const CSM_ASSERT = () => {
+ };
+ function CubismLogDebug(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Debug, "[CSM][D]" + fmt + "\n", args);
+ }
+ function CubismLogInfo(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Info, "[CSM][I]" + fmt + "\n", args);
+ }
+ function CubismLogWarning(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Warning, "[CSM][W]" + fmt + "\n", args);
+ }
+ function CubismLogError(fmt, ...args) {
+ CubismDebug.print(LogLevel.LogLevel_Error, "[CSM][E]" + fmt + "\n", args);
+ }
+ class CubismDebug {
+ static print(logLevel, format, args) {
+ if (logLevel < CubismFramework.getLoggingLevel()) {
+ return;
+ }
+ const logPrint = CubismFramework.coreLogFunction;
+ if (!logPrint)
+ return;
+ const buffer = format.replace(/{(\d+)}/g, (m, k) => {
+ return args[k];
+ });
+ logPrint(buffer);
+ }
+ static dumpBytes(logLevel, data, length) {
+ for (let i = 0; i < length; i++) {
+ if (i % 16 == 0 && i > 0)
+ this.print(logLevel, "\n");
+ else if (i % 8 == 0 && i > 0)
+ this.print(logLevel, " ");
+ this.print(logLevel, "{0} ", [data[i] & 255]);
+ }
+ this.print(logLevel, "\n");
+ }
+ constructor() {
+ }
+ }
+ class ACubismMotion {
+ constructor() {
+ this._fadeInSeconds = -1;
+ this._fadeOutSeconds = -1;
+ this._weight = 1;
+ this._offsetSeconds = 0;
+ this._firedEventValues = [];
+ }
+ release() {
+ this._weight = 0;
+ }
+ updateParameters(model, motionQueueEntry, userTimeSeconds) {
+ if (!motionQueueEntry.isAvailable() || motionQueueEntry.isFinished()) {
+ return;
+ }
+ if (!motionQueueEntry.isStarted()) {
+ motionQueueEntry.setIsStarted(true);
+ motionQueueEntry.setStartTime(userTimeSeconds - this._offsetSeconds);
+ motionQueueEntry.setFadeInStartTime(userTimeSeconds);
+ const duration = this.getDuration();
+ if (motionQueueEntry.getEndTime() < 0) {
+ motionQueueEntry.setEndTime(duration <= 0 ? -1 : motionQueueEntry.getStartTime() + duration);
+ }
+ }
+ let fadeWeight = this._weight;
+ const fadeIn = this._fadeInSeconds == 0 ? 1 : CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / this._fadeInSeconds);
+ const fadeOut = this._fadeOutSeconds == 0 || motionQueueEntry.getEndTime() < 0 ? 1 : CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / this._fadeOutSeconds);
+ fadeWeight = fadeWeight * fadeIn * fadeOut;
+ motionQueueEntry.setState(userTimeSeconds, fadeWeight);
+ this.doUpdateParameters(model, userTimeSeconds, fadeWeight, motionQueueEntry);
+ if (motionQueueEntry.getEndTime() > 0 && motionQueueEntry.getEndTime() < userTimeSeconds) {
+ motionQueueEntry.setIsFinished(true);
+ }
+ }
+ setFadeInTime(fadeInSeconds) {
+ this._fadeInSeconds = fadeInSeconds;
+ }
+ setFadeOutTime(fadeOutSeconds) {
+ this._fadeOutSeconds = fadeOutSeconds;
+ }
+ getFadeOutTime() {
+ return this._fadeOutSeconds;
+ }
+ getFadeInTime() {
+ return this._fadeInSeconds;
+ }
+ setWeight(weight) {
+ this._weight = weight;
+ }
+ getWeight() {
+ return this._weight;
+ }
+ getDuration() {
+ return -1;
+ }
+ getLoopDuration() {
+ return -1;
+ }
+ setOffsetTime(offsetSeconds) {
+ this._offsetSeconds = offsetSeconds;
+ }
+ getFiredEvent(beforeCheckTimeSeconds, motionTimeSeconds) {
+ return this._firedEventValues;
+ }
+ setFinishedMotionHandler(onFinishedMotionHandler) {
+ this._onFinishedMotion = onFinishedMotionHandler;
+ }
+ getFinishedMotionHandler() {
+ return this._onFinishedMotion;
+ }
+ isExistModelOpacity() {
+ return false;
+ }
+ getModelOpacityIndex() {
+ return -1;
+ }
+ getModelOpacityId(index) {
+ return void 0;
+ }
+ getModelOpacityValue() {
+ return 1;
+ }
+ }
+ const DefaultFadeTime = 1;
+ class CubismExpressionMotion extends ACubismMotion {
+ constructor() {
+ super();
+ this._parameters = [];
+ }
+ static create(json) {
+ const expression = new CubismExpressionMotion();
+ expression.parse(json);
+ return expression;
+ }
+ doUpdateParameters(model, userTimeSeconds, weight, motionQueueEntry) {
+ for (let i = 0; i < this._parameters.length; ++i) {
+ const parameter = this._parameters[i];
+ switch (parameter.blendType) {
+ case ExpressionBlendType.ExpressionBlendType_Add: {
+ model.addParameterValueById(parameter.parameterId, parameter.value, weight);
+ break;
+ }
+ case ExpressionBlendType.ExpressionBlendType_Multiply: {
+ model.multiplyParameterValueById(parameter.parameterId, parameter.value, weight);
+ break;
+ }
+ case ExpressionBlendType.ExpressionBlendType_Overwrite: {
+ model.setParameterValueById(parameter.parameterId, parameter.value, weight);
+ break;
+ }
+ }
+ }
+ }
+ parse(json) {
+ this.setFadeInTime(json.FadeInTime != void 0 ? json.FadeInTime : DefaultFadeTime);
+ this.setFadeOutTime(json.FadeOutTime != void 0 ? json.FadeOutTime : DefaultFadeTime);
+ const parameterCount = (json.Parameters || []).length;
+ for (let i = 0; i < parameterCount; ++i) {
+ const param = json.Parameters[i];
+ const parameterId = param.Id;
+ const value = param.Value;
+ let blendType;
+ if (!param.Blend || param.Blend === "Add") {
+ blendType = ExpressionBlendType.ExpressionBlendType_Add;
+ } else if (param.Blend === "Multiply") {
+ blendType = ExpressionBlendType.ExpressionBlendType_Multiply;
+ } else if (param.Blend === "Overwrite") {
+ blendType = ExpressionBlendType.ExpressionBlendType_Overwrite;
+ } else {
+ blendType = ExpressionBlendType.ExpressionBlendType_Add;
+ }
+ const item = {
+ parameterId,
+ blendType,
+ value
+ };
+ this._parameters.push(item);
+ }
+ }
+ }
+ var ExpressionBlendType = /* @__PURE__ */ ((ExpressionBlendType2) => {
+ ExpressionBlendType2[ExpressionBlendType2["ExpressionBlendType_Add"] = 0] = "ExpressionBlendType_Add";
+ ExpressionBlendType2[ExpressionBlendType2["ExpressionBlendType_Multiply"] = 1] = "ExpressionBlendType_Multiply";
+ ExpressionBlendType2[ExpressionBlendType2["ExpressionBlendType_Overwrite"] = 2] = "ExpressionBlendType_Overwrite";
+ return ExpressionBlendType2;
+ })(ExpressionBlendType || {});
+ class CubismMotionQueueEntry {
+ constructor() {
+ this._autoDelete = false;
+ this._available = true;
+ this._finished = false;
+ this._started = false;
+ this._startTimeSeconds = -1;
+ this._fadeInStartTimeSeconds = 0;
+ this._endTimeSeconds = -1;
+ this._stateTimeSeconds = 0;
+ this._stateWeight = 0;
+ this._lastEventCheckSeconds = 0;
+ this._motionQueueEntryHandle = this;
+ this._fadeOutSeconds = 0;
+ this._isTriggeredFadeOut = false;
+ }
+ release() {
+ if (this._autoDelete && this._motion) {
+ this._motion.release();
+ }
+ }
+ setFadeOut(fadeOutSeconds) {
+ this._fadeOutSeconds = fadeOutSeconds;
+ this._isTriggeredFadeOut = true;
+ }
+ startFadeOut(fadeOutSeconds, userTimeSeconds) {
+ const newEndTimeSeconds = userTimeSeconds + fadeOutSeconds;
+ this._isTriggeredFadeOut = true;
+ if (this._endTimeSeconds < 0 || newEndTimeSeconds < this._endTimeSeconds) {
+ this._endTimeSeconds = newEndTimeSeconds;
+ }
+ }
+ isFinished() {
+ return this._finished;
+ }
+ isStarted() {
+ return this._started;
+ }
+ getStartTime() {
+ return this._startTimeSeconds;
+ }
+ getFadeInStartTime() {
+ return this._fadeInStartTimeSeconds;
+ }
+ getEndTime() {
+ return this._endTimeSeconds;
+ }
+ setStartTime(startTime) {
+ this._startTimeSeconds = startTime;
+ }
+ setFadeInStartTime(startTime) {
+ this._fadeInStartTimeSeconds = startTime;
+ }
+ setEndTime(endTime) {
+ this._endTimeSeconds = endTime;
+ }
+ setIsFinished(f) {
+ this._finished = f;
+ }
+ setIsStarted(f) {
+ this._started = f;
+ }
+ isAvailable() {
+ return this._available;
+ }
+ setIsAvailable(v) {
+ this._available = v;
+ }
+ setState(timeSeconds, weight) {
+ this._stateTimeSeconds = timeSeconds;
+ this._stateWeight = weight;
+ }
+ getStateTime() {
+ return this._stateTimeSeconds;
+ }
+ getStateWeight() {
+ return this._stateWeight;
+ }
+ getLastCheckEventSeconds() {
+ return this._lastEventCheckSeconds;
+ }
+ setLastCheckEventSeconds(checkSeconds) {
+ this._lastEventCheckSeconds = checkSeconds;
+ }
+ isTriggeredFadeOut() {
+ return this._isTriggeredFadeOut;
+ }
+ getFadeOutSeconds() {
+ return this._fadeOutSeconds;
+ }
+ }
+ class CubismMotionQueueManager {
+ constructor() {
+ this._userTimeSeconds = 0;
+ this._eventCustomData = null;
+ this._motions = [];
+ }
+ release() {
+ for (let i = 0; i < this._motions.length; ++i) {
+ if (this._motions[i]) {
+ this._motions[i].release();
+ }
+ }
+ this._motions = void 0;
+ }
+ startMotion(motion, autoDelete, userTimeSeconds) {
+ if (motion == null) {
+ return InvalidMotionQueueEntryHandleValue;
+ }
+ let motionQueueEntry;
+ for (let i = 0; i < this._motions.length; ++i) {
+ motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ continue;
+ }
+ motionQueueEntry.setFadeOut(motionQueueEntry._motion.getFadeOutTime());
+ }
+ motionQueueEntry = new CubismMotionQueueEntry();
+ motionQueueEntry._autoDelete = autoDelete;
+ motionQueueEntry._motion = motion;
+ this._motions.push(motionQueueEntry);
+ return motionQueueEntry._motionQueueEntryHandle;
+ }
+ isFinished() {
+ let i = 0;
+ while (i < this._motions.length) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ this._motions.splice(i, 1);
+ continue;
+ }
+ const motion = motionQueueEntry._motion;
+ if (motion == null) {
+ motionQueueEntry.release();
+ this._motions.splice(i, 1);
+ continue;
+ }
+ if (!motionQueueEntry.isFinished()) {
+ return false;
+ }
+ i++;
+ }
+ return true;
+ }
+ isFinishedByHandle(motionQueueEntryNumber) {
+ for (let i = 0; i < this._motions.length; i++) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ continue;
+ }
+ if (motionQueueEntry._motionQueueEntryHandle == motionQueueEntryNumber && !motionQueueEntry.isFinished()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ stopAllMotions() {
+ for (let i = 0; i < this._motions.length; i++) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry != null) {
+ motionQueueEntry.release();
+ }
+ }
+ this._motions = [];
+ }
+ getCubismMotionQueueEntry(motionQueueEntryNumber) {
+ return this._motions.find((entry) => entry != null && entry._motionQueueEntryHandle == motionQueueEntryNumber);
+ }
+ setEventCallback(callback, customData = null) {
+ this._eventCallBack = callback;
+ this._eventCustomData = customData;
+ }
+ doUpdateMotion(model, userTimeSeconds) {
+ let updated = false;
+ let i = 0;
+ while (i < this._motions.length) {
+ const motionQueueEntry = this._motions[i];
+ if (motionQueueEntry == null) {
+ this._motions.splice(i, 1);
+ continue;
+ }
+ const motion = motionQueueEntry._motion;
+ if (motion == null) {
+ motionQueueEntry.release();
+ this._motions.splice(i, 1);
+ continue;
+ }
+ motion.updateParameters(model, motionQueueEntry, userTimeSeconds);
+ updated = true;
+ const firedList = motion.getFiredEvent(motionQueueEntry.getLastCheckEventSeconds() - motionQueueEntry.getStartTime(), userTimeSeconds - motionQueueEntry.getStartTime());
+ for (let i2 = 0; i2 < firedList.length; ++i2) {
+ this._eventCallBack(this, firedList[i2], this._eventCustomData);
+ }
+ motionQueueEntry.setLastCheckEventSeconds(userTimeSeconds);
+ if (motionQueueEntry.isFinished()) {
+ motionQueueEntry.release();
+ this._motions.splice(i, 1);
+ } else {
+ if (motionQueueEntry.isTriggeredFadeOut()) {
+ motionQueueEntry.startFadeOut(motionQueueEntry.getFadeOutSeconds(), userTimeSeconds);
+ }
+ i++;
+ }
+ }
+ return updated;
+ }
+ }
+ const InvalidMotionQueueEntryHandleValue = -1;
+ class Cubism4ExpressionManager extends ExpressionManager {
+ constructor(settings, options) {
+ var _a;
+ super(settings, options);
+ this.queueManager = new CubismMotionQueueManager();
+ this.definitions = (_a = settings.expressions) != null ? _a : [];
+ this.init();
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ getExpressionIndex(name) {
+ return this.definitions.findIndex((def) => def.Name === name);
+ }
+ getExpressionFile(definition) {
+ return definition.File;
+ }
+ createExpression(data, definition) {
+ return CubismExpressionMotion.create(data);
+ }
+ _setExpression(motion) {
+ return this.queueManager.startMotion(motion, false, performance.now());
+ }
+ stopAllExpressions() {
+ this.queueManager.stopAllMotions();
+ }
+ updateParameters(model, now) {
+ return this.queueManager.doUpdateMotion(model, now);
+ }
+ }
+ class CubismModelSettingsJson {
+ constructor(json) {
+ this.groups = json.Groups;
+ this.hitAreas = json.HitAreas;
+ this.layout = json.Layout;
+ this.moc = json.FileReferences.Moc;
+ this.expressions = json.FileReferences.Expressions;
+ this.motions = json.FileReferences.Motions;
+ this.textures = json.FileReferences.Textures;
+ this.physics = json.FileReferences.Physics;
+ this.pose = json.FileReferences.Pose;
+ }
+ getEyeBlinkParameters() {
+ var _a, _b;
+ return (_b = (_a = this.groups) == null ? void 0 : _a.find((group) => group.Name === "EyeBlink")) == null ? void 0 : _b.Ids;
+ }
+ getLipSyncParameters() {
+ var _a, _b;
+ return (_b = (_a = this.groups) == null ? void 0 : _a.find((group) => group.Name === "LipSync")) == null ? void 0 : _b.Ids;
+ }
+ }
+ class Cubism4ModelSettings extends ModelSettings {
+ constructor(json) {
+ super(json);
+ if (!Cubism4ModelSettings.isValidJSON(json)) {
+ throw new TypeError("Invalid JSON.");
+ }
+ Object.assign(this, new CubismModelSettingsJson(json));
+ }
+ static isValidJSON(json) {
+ var _a;
+ return !!(json == null ? void 0 : json.FileReferences) && typeof json.FileReferences.Moc === "string" && ((_a = json.FileReferences.Textures) == null ? void 0 : _a.length) > 0 && json.FileReferences.Textures.every((item) => typeof item === "string");
+ }
+ replaceFiles(replace) {
+ super.replaceFiles(replace);
+ if (this.motions) {
+ for (const [group, motions] of Object.entries(this.motions)) {
+ for (let i = 0; i < motions.length; i++) {
+ motions[i].File = replace(motions[i].File, `motions.${group}[${i}].File`);
+ if (motions[i].Sound !== void 0) {
+ motions[i].Sound = replace(motions[i].Sound, `motions.${group}[${i}].Sound`);
+ }
+ }
+ }
+ }
+ if (this.expressions) {
+ for (let i = 0; i < this.expressions.length; i++) {
+ this.expressions[i].File = replace(this.expressions[i].File, `expressions[${i}].File`);
+ }
+ }
+ }
+ }
+ applyMixins(Cubism4ModelSettings, [CubismModelSettingsJson]);
+ var CubismMotionCurveTarget = /* @__PURE__ */ ((CubismMotionCurveTarget2) => {
+ CubismMotionCurveTarget2[CubismMotionCurveTarget2["CubismMotionCurveTarget_Model"] = 0] = "CubismMotionCurveTarget_Model";
+ CubismMotionCurveTarget2[CubismMotionCurveTarget2["CubismMotionCurveTarget_Parameter"] = 1] = "CubismMotionCurveTarget_Parameter";
+ CubismMotionCurveTarget2[CubismMotionCurveTarget2["CubismMotionCurveTarget_PartOpacity"] = 2] = "CubismMotionCurveTarget_PartOpacity";
+ return CubismMotionCurveTarget2;
+ })(CubismMotionCurveTarget || {});
+ var CubismMotionSegmentType = /* @__PURE__ */ ((CubismMotionSegmentType2) => {
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_Linear"] = 0] = "CubismMotionSegmentType_Linear";
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_Bezier"] = 1] = "CubismMotionSegmentType_Bezier";
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_Stepped"] = 2] = "CubismMotionSegmentType_Stepped";
+ CubismMotionSegmentType2[CubismMotionSegmentType2["CubismMotionSegmentType_InverseStepped"] = 3] = "CubismMotionSegmentType_InverseStepped";
+ return CubismMotionSegmentType2;
+ })(CubismMotionSegmentType || {});
+ class CubismMotionPoint {
+ constructor(time = 0, value = 0) {
+ this.time = time;
+ this.value = value;
+ }
+ }
+ class CubismMotionSegment {
+ constructor() {
+ this.basePointIndex = 0;
+ this.segmentType = 0;
+ }
+ }
+ class CubismMotionCurve {
+ constructor() {
+ this.id = "";
+ this.type = 0;
+ this.segmentCount = 0;
+ this.baseSegmentIndex = 0;
+ this.fadeInTime = 0;
+ this.fadeOutTime = 0;
+ }
+ }
+ class CubismMotionEvent {
+ constructor() {
+ this.fireTime = 0;
+ this.value = "";
+ }
+ }
+ class CubismMotionData {
+ constructor() {
+ this.duration = 0;
+ this.loop = false;
+ this.curveCount = 0;
+ this.eventCount = 0;
+ this.fps = 0;
+ this.curves = [];
+ this.segments = [];
+ this.points = [];
+ this.events = [];
+ }
+ }
+ class CubismMotionJson {
+ constructor(json) {
+ this._json = json;
+ }
+ release() {
+ this._json = void 0;
+ }
+ getMotionDuration() {
+ return this._json.Meta.Duration;
+ }
+ isMotionLoop() {
+ return this._json.Meta.Loop || false;
+ }
+ getEvaluationOptionFlag(flagType) {
+ if (EvaluationOptionFlag.EvaluationOptionFlag_AreBeziersRistricted == flagType) {
+ return !!this._json.Meta.AreBeziersRestricted;
+ }
+ return false;
+ }
+ getMotionCurveCount() {
+ return this._json.Meta.CurveCount;
+ }
+ getMotionFps() {
+ return this._json.Meta.Fps;
+ }
+ getMotionTotalSegmentCount() {
+ return this._json.Meta.TotalSegmentCount;
+ }
+ getMotionTotalPointCount() {
+ return this._json.Meta.TotalPointCount;
+ }
+ getMotionFadeInTime() {
+ return this._json.Meta.FadeInTime;
+ }
+ getMotionFadeOutTime() {
+ return this._json.Meta.FadeOutTime;
+ }
+ getMotionCurveTarget(curveIndex) {
+ return this._json.Curves[curveIndex].Target;
+ }
+ getMotionCurveId(curveIndex) {
+ return this._json.Curves[curveIndex].Id;
+ }
+ getMotionCurveFadeInTime(curveIndex) {
+ return this._json.Curves[curveIndex].FadeInTime;
+ }
+ getMotionCurveFadeOutTime(curveIndex) {
+ return this._json.Curves[curveIndex].FadeOutTime;
+ }
+ getMotionCurveSegmentCount(curveIndex) {
+ return this._json.Curves[curveIndex].Segments.length;
+ }
+ getMotionCurveSegment(curveIndex, segmentIndex) {
+ return this._json.Curves[curveIndex].Segments[segmentIndex];
+ }
+ getEventCount() {
+ return this._json.Meta.UserDataCount || 0;
+ }
+ getTotalEventValueSize() {
+ return this._json.Meta.TotalUserDataSize;
+ }
+ getEventTime(userDataIndex) {
+ return this._json.UserData[userDataIndex].Time;
+ }
+ getEventValue(userDataIndex) {
+ return this._json.UserData[userDataIndex].Value;
+ }
+ }
+ var EvaluationOptionFlag = /* @__PURE__ */ ((EvaluationOptionFlag2) => {
+ EvaluationOptionFlag2[EvaluationOptionFlag2["EvaluationOptionFlag_AreBeziersRistricted"] = 0] = "EvaluationOptionFlag_AreBeziersRistricted";
+ return EvaluationOptionFlag2;
+ })(EvaluationOptionFlag || {});
+ const EffectNameEyeBlink = "EyeBlink";
+ const EffectNameLipSync = "LipSync";
+ const TargetNameModel = "Model";
+ const TargetNameParameter = "Parameter";
+ const TargetNamePartOpacity = "PartOpacity";
+ const IdNameOpacity = "Opacity";
+ const UseOldBeziersCurveMotion = false;
+ function lerpPoints(a, b, t) {
+ const result = new CubismMotionPoint();
+ result.time = a.time + (b.time - a.time) * t;
+ result.value = a.value + (b.value - a.value) * t;
+ return result;
+ }
+ function linearEvaluate(points, time) {
+ let t = (time - points[0].time) / (points[1].time - points[0].time);
+ if (t < 0) {
+ t = 0;
+ }
+ return points[0].value + (points[1].value - points[0].value) * t;
+ }
+ function bezierEvaluate(points, time) {
+ let t = (time - points[0].time) / (points[3].time - points[0].time);
+ if (t < 0) {
+ t = 0;
+ }
+ const p01 = lerpPoints(points[0], points[1], t);
+ const p12 = lerpPoints(points[1], points[2], t);
+ const p23 = lerpPoints(points[2], points[3], t);
+ const p012 = lerpPoints(p01, p12, t);
+ const p123 = lerpPoints(p12, p23, t);
+ return lerpPoints(p012, p123, t).value;
+ }
+ function bezierEvaluateCardanoInterpretation(points, time) {
+ const x = time;
+ const x1 = points[0].time;
+ const x2 = points[3].time;
+ const cx1 = points[1].time;
+ const cx2 = points[2].time;
+ const a = x2 - 3 * cx2 + 3 * cx1 - x1;
+ const b = 3 * cx2 - 6 * cx1 + 3 * x1;
+ const c = 3 * cx1 - 3 * x1;
+ const d = x1 - x;
+ const t = CubismMath.cardanoAlgorithmForBezier(a, b, c, d);
+ const p01 = lerpPoints(points[0], points[1], t);
+ const p12 = lerpPoints(points[1], points[2], t);
+ const p23 = lerpPoints(points[2], points[3], t);
+ const p012 = lerpPoints(p01, p12, t);
+ const p123 = lerpPoints(p12, p23, t);
+ return lerpPoints(p012, p123, t).value;
+ }
+ function steppedEvaluate(points, time) {
+ return points[0].value;
+ }
+ function inverseSteppedEvaluate(points, time) {
+ return points[1].value;
+ }
+ function evaluateCurve(motionData, index, time) {
+ const curve = motionData.curves[index];
+ let target = -1;
+ const totalSegmentCount = curve.baseSegmentIndex + curve.segmentCount;
+ let pointPosition = 0;
+ for (let i = curve.baseSegmentIndex; i < totalSegmentCount; ++i) {
+ pointPosition = motionData.segments[i].basePointIndex + (motionData.segments[i].segmentType == CubismMotionSegmentType.CubismMotionSegmentType_Bezier ? 3 : 1);
+ if (motionData.points[pointPosition].time > time) {
+ target = i;
+ break;
+ }
+ }
+ if (target == -1) {
+ return motionData.points[pointPosition].value;
+ }
+ const segment = motionData.segments[target];
+ return segment.evaluate(motionData.points.slice(segment.basePointIndex), time);
+ }
+ class CubismMotion extends ACubismMotion {
+ constructor() {
+ super();
+ this._eyeBlinkParameterIds = [];
+ this._lipSyncParameterIds = [];
+ this._sourceFrameRate = 30;
+ this._loopDurationSeconds = -1;
+ this._isLoop = false;
+ this._isLoopFadeIn = true;
+ this._lastWeight = 0;
+ this._modelOpacity = 1;
+ }
+ static create(json, onFinishedMotionHandler) {
+ const ret = new CubismMotion();
+ ret.parse(json);
+ ret._sourceFrameRate = ret._motionData.fps;
+ ret._loopDurationSeconds = ret._motionData.duration;
+ ret._onFinishedMotion = onFinishedMotionHandler;
+ return ret;
+ }
+ doUpdateParameters(model, userTimeSeconds, fadeWeight, motionQueueEntry) {
+ if (this._modelCurveIdEyeBlink == null) {
+ this._modelCurveIdEyeBlink = EffectNameEyeBlink;
+ }
+ if (this._modelCurveIdLipSync == null) {
+ this._modelCurveIdLipSync = EffectNameLipSync;
+ }
+ if (this._modelCurveIdOpacity == null) {
+ this._modelCurveIdOpacity = IdNameOpacity;
+ }
+ let timeOffsetSeconds = userTimeSeconds - motionQueueEntry.getStartTime();
+ if (timeOffsetSeconds < 0) {
+ timeOffsetSeconds = 0;
+ }
+ let lipSyncValue = Number.MAX_VALUE;
+ let eyeBlinkValue = Number.MAX_VALUE;
+ const MaxTargetSize = 64;
+ let lipSyncFlags = 0;
+ let eyeBlinkFlags = 0;
+ if (this._eyeBlinkParameterIds.length > MaxTargetSize) {
+ CubismLogDebug("too many eye blink targets : {0}", this._eyeBlinkParameterIds.length);
+ }
+ if (this._lipSyncParameterIds.length > MaxTargetSize) {
+ CubismLogDebug("too many lip sync targets : {0}", this._lipSyncParameterIds.length);
+ }
+ const tmpFadeIn = this._fadeInSeconds <= 0 ? 1 : CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / this._fadeInSeconds);
+ const tmpFadeOut = this._fadeOutSeconds <= 0 || motionQueueEntry.getEndTime() < 0 ? 1 : CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / this._fadeOutSeconds);
+ let value;
+ let c, parameterIndex;
+ let time = timeOffsetSeconds;
+ if (this._isLoop) {
+ while (time > this._motionData.duration) {
+ time -= this._motionData.duration;
+ }
+ }
+ const curves = this._motionData.curves;
+ for (c = 0; c < this._motionData.curveCount && curves[c].type == CubismMotionCurveTarget.CubismMotionCurveTarget_Model; ++c) {
+ value = evaluateCurve(this._motionData, c, time);
+ if (curves[c].id == this._modelCurveIdEyeBlink) {
+ eyeBlinkValue = value;
+ } else if (curves[c].id == this._modelCurveIdLipSync) {
+ lipSyncValue = value;
+ } else if (curves[c].id == this._modelCurveIdOpacity) {
+ this._modelOpacity = value;
+ model.setModelOapcity(this.getModelOpacityValue());
+ }
+ }
+ for (; c < this._motionData.curveCount && curves[c].type == CubismMotionCurveTarget.CubismMotionCurveTarget_Parameter; ++c) {
+ parameterIndex = model.getParameterIndex(curves[c].id);
+ if (parameterIndex == -1) {
+ continue;
+ }
+ const sourceValue = model.getParameterValueByIndex(parameterIndex);
+ value = evaluateCurve(this._motionData, c, time);
+ if (eyeBlinkValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._eyeBlinkParameterIds.length && i < MaxTargetSize; ++i) {
+ if (this._eyeBlinkParameterIds[i] == curves[c].id) {
+ value *= eyeBlinkValue;
+ eyeBlinkFlags |= 1 << i;
+ break;
+ }
+ }
+ }
+ if (lipSyncValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._lipSyncParameterIds.length && i < MaxTargetSize; ++i) {
+ if (this._lipSyncParameterIds[i] == curves[c].id) {
+ value += lipSyncValue;
+ lipSyncFlags |= 1 << i;
+ break;
+ }
+ }
+ }
+ let v;
+ if (curves[c].fadeInTime < 0 && curves[c].fadeOutTime < 0) {
+ v = sourceValue + (value - sourceValue) * fadeWeight;
+ } else {
+ let fin;
+ let fout;
+ if (curves[c].fadeInTime < 0) {
+ fin = tmpFadeIn;
+ } else {
+ fin = curves[c].fadeInTime == 0 ? 1 : CubismMath.getEasingSine((userTimeSeconds - motionQueueEntry.getFadeInStartTime()) / curves[c].fadeInTime);
+ }
+ if (curves[c].fadeOutTime < 0) {
+ fout = tmpFadeOut;
+ } else {
+ fout = curves[c].fadeOutTime == 0 || motionQueueEntry.getEndTime() < 0 ? 1 : CubismMath.getEasingSine((motionQueueEntry.getEndTime() - userTimeSeconds) / curves[c].fadeOutTime);
+ }
+ const paramWeight = this._weight * fin * fout;
+ v = sourceValue + (value - sourceValue) * paramWeight;
+ }
+ model.setParameterValueByIndex(parameterIndex, v, 1);
+ }
+ {
+ if (eyeBlinkValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._eyeBlinkParameterIds.length && i < MaxTargetSize; ++i) {
+ const sourceValue = model.getParameterValueById(this._eyeBlinkParameterIds[i]);
+ if (eyeBlinkFlags >> i & 1) {
+ continue;
+ }
+ const v = sourceValue + (eyeBlinkValue - sourceValue) * fadeWeight;
+ model.setParameterValueById(this._eyeBlinkParameterIds[i], v);
+ }
+ }
+ if (lipSyncValue != Number.MAX_VALUE) {
+ for (let i = 0; i < this._lipSyncParameterIds.length && i < MaxTargetSize; ++i) {
+ const sourceValue = model.getParameterValueById(this._lipSyncParameterIds[i]);
+ if (lipSyncFlags >> i & 1) {
+ continue;
+ }
+ const v = sourceValue + (lipSyncValue - sourceValue) * fadeWeight;
+ model.setParameterValueById(this._lipSyncParameterIds[i], v);
+ }
+ }
+ }
+ for (; c < this._motionData.curveCount && curves[c].type == CubismMotionCurveTarget.CubismMotionCurveTarget_PartOpacity; ++c) {
+ value = evaluateCurve(this._motionData, c, time);
+ if (CubismConfig.setOpacityFromMotion) {
+ model.setPartOpacityById(curves[c].id, value);
+ } else {
+ parameterIndex = model.getParameterIndex(curves[c].id);
+ if (parameterIndex == -1) {
+ continue;
+ }
+ model.setParameterValueByIndex(parameterIndex, value);
+ }
+ }
+ if (timeOffsetSeconds >= this._motionData.duration) {
+ if (this._isLoop) {
+ motionQueueEntry.setStartTime(userTimeSeconds);
+ if (this._isLoopFadeIn) {
+ motionQueueEntry.setFadeInStartTime(userTimeSeconds);
+ }
+ } else {
+ if (this._onFinishedMotion) {
+ this._onFinishedMotion(this);
+ }
+ motionQueueEntry.setIsFinished(true);
+ }
+ }
+ this._lastWeight = fadeWeight;
+ }
+ setIsLoop(loop) {
+ this._isLoop = loop;
+ }
+ isLoop() {
+ return this._isLoop;
+ }
+ setIsLoopFadeIn(loopFadeIn) {
+ this._isLoopFadeIn = loopFadeIn;
+ }
+ isLoopFadeIn() {
+ return this._isLoopFadeIn;
+ }
+ getDuration() {
+ return this._isLoop ? -1 : this._loopDurationSeconds;
+ }
+ getLoopDuration() {
+ return this._loopDurationSeconds;
+ }
+ setParameterFadeInTime(parameterId, value) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ curves[i].fadeInTime = value;
+ return;
+ }
+ }
+ }
+ setParameterFadeOutTime(parameterId, value) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ curves[i].fadeOutTime = value;
+ return;
+ }
+ }
+ }
+ getParameterFadeInTime(parameterId) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ return curves[i].fadeInTime;
+ }
+ }
+ return -1;
+ }
+ getParameterFadeOutTime(parameterId) {
+ const curves = this._motionData.curves;
+ for (let i = 0; i < this._motionData.curveCount; ++i) {
+ if (parameterId == curves[i].id) {
+ return curves[i].fadeOutTime;
+ }
+ }
+ return -1;
+ }
+ setEffectIds(eyeBlinkParameterIds, lipSyncParameterIds) {
+ this._eyeBlinkParameterIds = eyeBlinkParameterIds;
+ this._lipSyncParameterIds = lipSyncParameterIds;
+ }
+ release() {
+ this._motionData = void 0;
+ }
+ parse(motionJson) {
+ this._motionData = new CubismMotionData();
+ const json = new CubismMotionJson(motionJson);
+ this._motionData.duration = json.getMotionDuration();
+ this._motionData.loop = json.isMotionLoop();
+ this._motionData.curveCount = json.getMotionCurveCount();
+ this._motionData.fps = json.getMotionFps();
+ this._motionData.eventCount = json.getEventCount();
+ const areBeziersRestructed = json.getEvaluationOptionFlag(EvaluationOptionFlag.EvaluationOptionFlag_AreBeziersRistricted);
+ const fadeInSeconds = json.getMotionFadeInTime();
+ const fadeOutSeconds = json.getMotionFadeOutTime();
+ if (fadeInSeconds !== void 0) {
+ this._fadeInSeconds = fadeInSeconds < 0 ? 1 : fadeInSeconds;
+ } else {
+ this._fadeInSeconds = 1;
+ }
+ if (fadeOutSeconds !== void 0) {
+ this._fadeOutSeconds = fadeOutSeconds < 0 ? 1 : fadeOutSeconds;
+ } else {
+ this._fadeOutSeconds = 1;
+ }
+ this._motionData.curves = Array.from({
+ length: this._motionData.curveCount
+ }).map(() => new CubismMotionCurve());
+ this._motionData.segments = Array.from({
+ length: json.getMotionTotalSegmentCount()
+ }).map(() => new CubismMotionSegment());
+ this._motionData.events = Array.from({
+ length: this._motionData.eventCount
+ }).map(() => new CubismMotionEvent());
+ this._motionData.points = [];
+ let totalPointCount = 0;
+ let totalSegmentCount = 0;
+ for (let curveCount = 0; curveCount < this._motionData.curveCount; ++curveCount) {
+ const curve = this._motionData.curves[curveCount];
+ switch (json.getMotionCurveTarget(curveCount)) {
+ case TargetNameModel:
+ curve.type = CubismMotionCurveTarget.CubismMotionCurveTarget_Model;
+ break;
+ case TargetNameParameter:
+ curve.type = CubismMotionCurveTarget.CubismMotionCurveTarget_Parameter;
+ break;
+ case TargetNamePartOpacity:
+ curve.type = CubismMotionCurveTarget.CubismMotionCurveTarget_PartOpacity;
+ break;
+ default:
+ CubismLogWarning('Warning : Unable to get segment type from Curve! The number of "CurveCount" may be incorrect!');
+ }
+ curve.id = json.getMotionCurveId(curveCount);
+ curve.baseSegmentIndex = totalSegmentCount;
+ const fadeInTime = json.getMotionCurveFadeInTime(curveCount);
+ const fadeOutTime = json.getMotionCurveFadeOutTime(curveCount);
+ curve.fadeInTime = fadeInTime !== void 0 ? fadeInTime : -1;
+ curve.fadeOutTime = fadeOutTime !== void 0 ? fadeOutTime : -1;
+ for (let segmentPosition = 0; segmentPosition < json.getMotionCurveSegmentCount(curveCount); ) {
+ if (segmentPosition == 0) {
+ this._motionData.segments[totalSegmentCount].basePointIndex = totalPointCount;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition), json.getMotionCurveSegment(curveCount, segmentPosition + 1));
+ totalPointCount += 1;
+ segmentPosition += 2;
+ } else {
+ this._motionData.segments[totalSegmentCount].basePointIndex = totalPointCount - 1;
+ }
+ const segment = json.getMotionCurveSegment(curveCount, segmentPosition);
+ switch (segment) {
+ case CubismMotionSegmentType.CubismMotionSegmentType_Linear: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Linear;
+ this._motionData.segments[totalSegmentCount].evaluate = linearEvaluate;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ totalPointCount += 1;
+ segmentPosition += 3;
+ break;
+ }
+ case CubismMotionSegmentType.CubismMotionSegmentType_Bezier: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Bezier;
+ if (areBeziersRestructed || UseOldBeziersCurveMotion) {
+ this._motionData.segments[totalSegmentCount].evaluate = bezierEvaluate;
+ } else {
+ this._motionData.segments[totalSegmentCount].evaluate = bezierEvaluateCardanoInterpretation;
+ }
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ this._motionData.points[totalPointCount + 1] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 3), json.getMotionCurveSegment(curveCount, segmentPosition + 4));
+ this._motionData.points[totalPointCount + 2] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 5), json.getMotionCurveSegment(curveCount, segmentPosition + 6));
+ totalPointCount += 3;
+ segmentPosition += 7;
+ break;
+ }
+ case CubismMotionSegmentType.CubismMotionSegmentType_Stepped: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_Stepped;
+ this._motionData.segments[totalSegmentCount].evaluate = steppedEvaluate;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ totalPointCount += 1;
+ segmentPosition += 3;
+ break;
+ }
+ case CubismMotionSegmentType.CubismMotionSegmentType_InverseStepped: {
+ this._motionData.segments[totalSegmentCount].segmentType = CubismMotionSegmentType.CubismMotionSegmentType_InverseStepped;
+ this._motionData.segments[totalSegmentCount].evaluate = inverseSteppedEvaluate;
+ this._motionData.points[totalPointCount] = new CubismMotionPoint(json.getMotionCurveSegment(curveCount, segmentPosition + 1), json.getMotionCurveSegment(curveCount, segmentPosition + 2));
+ totalPointCount += 1;
+ segmentPosition += 3;
+ break;
+ }
+ }
+ ++curve.segmentCount;
+ ++totalSegmentCount;
+ }
+ this._motionData.curves.push(curve);
+ }
+ for (let userdatacount = 0; userdatacount < json.getEventCount(); ++userdatacount) {
+ this._motionData.events[userdatacount].fireTime = json.getEventTime(userdatacount);
+ this._motionData.events[userdatacount].value = json.getEventValue(userdatacount);
+ }
+ json.release();
+ }
+ getFiredEvent(beforeCheckTimeSeconds, motionTimeSeconds) {
+ this._firedEventValues.length = 0;
+ for (let u = 0; u < this._motionData.eventCount; ++u) {
+ if (this._motionData.events[u].fireTime > beforeCheckTimeSeconds && this._motionData.events[u].fireTime <= motionTimeSeconds) {
+ this._firedEventValues.push(this._motionData.events[u].value);
+ }
+ }
+ return this._firedEventValues;
+ }
+ isExistModelOpacity() {
+ for (let i = 0; i < this._motionData.curveCount; i++) {
+ const curve = this._motionData.curves[i];
+ if (curve.type != CubismMotionCurveTarget.CubismMotionCurveTarget_Model) {
+ continue;
+ }
+ if (curve.id === IdNameOpacity) {
+ return true;
+ }
+ }
+ return false;
+ }
+ getModelOpacityIndex() {
+ if (this.isExistModelOpacity()) {
+ for (let i = 0; i < this._motionData.curveCount; i++) {
+ const curve = this._motionData.curves[i];
+ if (curve.type != CubismMotionCurveTarget.CubismMotionCurveTarget_Model) {
+ continue;
+ }
+ if (curve.id === IdNameOpacity) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+ getModelOpacityId(index) {
+ if (index != -1) {
+ const curve = this._motionData.curves[index];
+ if (curve.type == CubismMotionCurveTarget.CubismMotionCurveTarget_Model) {
+ if (curve.id === IdNameOpacity) {
+ return curve.id;
+ }
+ }
+ }
+ return void 0;
+ }
+ getModelOpacityValue() {
+ return this._modelOpacity;
+ }
+ }
+ class Cubism4MotionManager extends MotionManager {
+ constructor(settings, options) {
+ var _a;
+ super(settings, options);
+ this.groups = { idle: "Idle" };
+ this.motionDataType = "json";
+ this.queueManager = new CubismMotionQueueManager();
+ this.definitions = (_a = settings.motions) != null ? _a : {};
+ this.eyeBlinkIds = settings.getEyeBlinkParameters() || [];
+ this.lipSyncIds = settings.getLipSyncParameters() || [];
+ this.init(options);
+ }
+ init(options) {
+ super.init(options);
+ if (this.settings.expressions) {
+ this.expressionManager = new Cubism4ExpressionManager(this.settings, options);
+ }
+ this.queueManager.setEventCallback((caller, eventValue, customData) => {
+ this.emit("motion:" + eventValue);
+ });
+ }
+ isFinished() {
+ return this.queueManager.isFinished();
+ }
+ _startMotion(motion, onFinish) {
+ motion.setFinishedMotionHandler(onFinish);
+ this.queueManager.stopAllMotions();
+ return this.queueManager.startMotion(motion, false, performance.now());
+ }
+ _stopAllMotions() {
+ this.queueManager.stopAllMotions();
+ }
+ createMotion(data, group, definition) {
+ const motion = CubismMotion.create(data);
+ const json = new CubismMotionJson(data);
+ const defaultFadingDuration = (group === this.groups.idle ? exports2.config.idleMotionFadingDuration : exports2.config.motionFadingDuration) / 1e3;
+ if (json.getMotionFadeInTime() === void 0) {
+ motion.setFadeInTime(definition.FadeInTime > 0 ? definition.FadeInTime : defaultFadingDuration);
+ }
+ if (json.getMotionFadeOutTime() === void 0) {
+ motion.setFadeOutTime(definition.FadeOutTime > 0 ? definition.FadeOutTime : defaultFadingDuration);
+ }
+ motion.setEffectIds(this.eyeBlinkIds, this.lipSyncIds);
+ return motion;
+ }
+ getMotionFile(definition) {
+ return definition.File;
+ }
+ getMotionName(definition) {
+ return definition.File;
+ }
+ getSoundFile(definition) {
+ return definition.Sound;
+ }
+ updateParameters(model, now) {
+ return this.queueManager.doUpdateMotion(model, now);
+ }
+ destroy() {
+ super.destroy();
+ this.queueManager.release();
+ this.queueManager = void 0;
+ }
+ }
+ const ParamAngleX = "ParamAngleX";
+ const ParamAngleY = "ParamAngleY";
+ const ParamAngleZ = "ParamAngleZ";
+ const ParamEyeBallX = "ParamEyeBallX";
+ const ParamEyeBallY = "ParamEyeBallY";
+ const ParamBodyAngleX = "ParamBodyAngleX";
+ const ParamBreath = "ParamBreath";
+ class CubismBreath {
+ constructor() {
+ this._breathParameters = [];
+ this._currentTime = 0;
+ }
+ static create() {
+ return new CubismBreath();
+ }
+ setParameters(breathParameters) {
+ this._breathParameters = breathParameters;
+ }
+ getParameters() {
+ return this._breathParameters;
+ }
+ updateParameters(model, deltaTimeSeconds) {
+ this._currentTime += deltaTimeSeconds;
+ const t = this._currentTime * 2 * 3.14159;
+ for (let i = 0; i < this._breathParameters.length; ++i) {
+ const data = this._breathParameters[i];
+ model.addParameterValueById(data.parameterId, data.offset + data.peak * Math.sin(t / data.cycle), data.weight);
+ }
+ }
+ }
+ class BreathParameterData {
+ constructor(parameterId, offset, peak, cycle, weight) {
+ this.parameterId = parameterId == void 0 ? void 0 : parameterId;
+ this.offset = offset == void 0 ? 0 : offset;
+ this.peak = peak == void 0 ? 0 : peak;
+ this.cycle = cycle == void 0 ? 0 : cycle;
+ this.weight = weight == void 0 ? 0 : weight;
+ }
+ }
+ const _CubismEyeBlink = class {
+ static create(modelSetting) {
+ return new _CubismEyeBlink(modelSetting);
+ }
+ setBlinkingInterval(blinkingInterval) {
+ this._blinkingIntervalSeconds = blinkingInterval;
+ }
+ setBlinkingSetting(closing, closed, opening) {
+ this._closingSeconds = closing;
+ this._closedSeconds = closed;
+ this._openingSeconds = opening;
+ }
+ setParameterIds(parameterIds) {
+ this._parameterIds = parameterIds;
+ }
+ getParameterIds() {
+ return this._parameterIds;
+ }
+ updateParameters(model, deltaTimeSeconds) {
+ this._userTimeSeconds += deltaTimeSeconds;
+ let parameterValue;
+ let t = 0;
+ switch (this._blinkingState) {
+ case EyeState.EyeState_Closing:
+ t = (this._userTimeSeconds - this._stateStartTimeSeconds) / this._closingSeconds;
+ if (t >= 1) {
+ t = 1;
+ this._blinkingState = EyeState.EyeState_Closed;
+ this._stateStartTimeSeconds = this._userTimeSeconds;
+ }
+ parameterValue = 1 - t;
+ break;
+ case EyeState.EyeState_Closed:
+ t = (this._userTimeSeconds - this._stateStartTimeSeconds) / this._closedSeconds;
+ if (t >= 1) {
+ this._blinkingState = EyeState.EyeState_Opening;
+ this._stateStartTimeSeconds = this._userTimeSeconds;
+ }
+ parameterValue = 0;
+ break;
+ case EyeState.EyeState_Opening:
+ t = (this._userTimeSeconds - this._stateStartTimeSeconds) / this._openingSeconds;
+ if (t >= 1) {
+ t = 1;
+ this._blinkingState = EyeState.EyeState_Interval;
+ this._nextBlinkingTime = this.determinNextBlinkingTiming();
+ }
+ parameterValue = t;
+ break;
+ case EyeState.EyeState_Interval:
+ if (this._nextBlinkingTime < this._userTimeSeconds) {
+ this._blinkingState = EyeState.EyeState_Closing;
+ this._stateStartTimeSeconds = this._userTimeSeconds;
+ }
+ parameterValue = 1;
+ break;
+ case EyeState.EyeState_First:
+ default:
+ this._blinkingState = EyeState.EyeState_Interval;
+ this._nextBlinkingTime = this.determinNextBlinkingTiming();
+ parameterValue = 1;
+ break;
+ }
+ if (!_CubismEyeBlink.CloseIfZero) {
+ parameterValue = -parameterValue;
+ }
+ for (let i = 0; i < this._parameterIds.length; ++i) {
+ model.setParameterValueById(this._parameterIds[i], parameterValue);
+ }
+ }
+ constructor(modelSetting) {
+ var _a, _b;
+ this._blinkingState = EyeState.EyeState_First;
+ this._nextBlinkingTime = 0;
+ this._stateStartTimeSeconds = 0;
+ this._blinkingIntervalSeconds = 4;
+ this._closingSeconds = 0.1;
+ this._closedSeconds = 0.05;
+ this._openingSeconds = 0.15;
+ this._userTimeSeconds = 0;
+ this._parameterIds = [];
+ if (modelSetting == null) {
+ return;
+ }
+ this._parameterIds = (_b = (_a = modelSetting.getEyeBlinkParameters()) == null ? void 0 : _a.slice()) != null ? _b : this._parameterIds;
+ }
+ determinNextBlinkingTiming() {
+ const r = Math.random();
+ return this._userTimeSeconds + r * (2 * this._blinkingIntervalSeconds - 1);
+ }
+ };
+ let CubismEyeBlink = _CubismEyeBlink;
+ CubismEyeBlink.CloseIfZero = true;
+ var EyeState = /* @__PURE__ */ ((EyeState2) => {
+ EyeState2[EyeState2["EyeState_First"] = 0] = "EyeState_First";
+ EyeState2[EyeState2["EyeState_Interval"] = 1] = "EyeState_Interval";
+ EyeState2[EyeState2["EyeState_Closing"] = 2] = "EyeState_Closing";
+ EyeState2[EyeState2["EyeState_Closed"] = 3] = "EyeState_Closed";
+ EyeState2[EyeState2["EyeState_Opening"] = 4] = "EyeState_Opening";
+ return EyeState2;
+ })(EyeState || {});
+ class csmRect {
+ constructor(x = 0, y = 0, w = 0, h = 0) {
+ this.x = x;
+ this.y = y;
+ this.width = w;
+ this.height = h;
+ }
+ getCenterX() {
+ return this.x + 0.5 * this.width;
+ }
+ getCenterY() {
+ return this.y + 0.5 * this.height;
+ }
+ getRight() {
+ return this.x + this.width;
+ }
+ getBottom() {
+ return this.y + this.height;
+ }
+ setRect(r) {
+ this.x = r.x;
+ this.y = r.y;
+ this.width = r.width;
+ this.height = r.height;
+ }
+ expand(w, h) {
+ this.x -= w;
+ this.y -= h;
+ this.width += w * 2;
+ this.height += h * 2;
+ }
+ }
+ const ColorChannelCount = 4;
+ const ClippingMaskMaxCountOnDefault = 36;
+ const ClippingMaskMaxCountOnMultiRenderTexture = 32;
+ const ShaderCount = 10;
+ let s_instance;
+ let s_viewport;
+ let s_fbo;
+ class CubismClippingManager_WebGL {
+ getChannelFlagAsColor(channelNo) {
+ return this._channelColors[channelNo];
+ }
+ getMaskRenderTexture() {
+ if (this._maskTexture && this._maskTexture.textures != null) {
+ this._maskTexture.frameNo = this._currentFrameNo;
+ } else {
+ this._maskRenderTextures = [];
+ this._maskColorBuffers = [];
+ const size = this._clippingMaskBufferSize;
+ for (let index = 0; index < this._renderTextureCount; index++) {
+ this._maskColorBuffers.push(this.gl.createTexture());
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this._maskColorBuffers[index]);
+ this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, size, size, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, null);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, null);
+ this._maskRenderTextures.push(this.gl.createFramebuffer());
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this._maskRenderTextures[index]);
+ this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, this._maskColorBuffers[index], 0);
+ }
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, s_fbo);
+ this._maskTexture = new CubismRenderTextureResource(this._currentFrameNo, this._maskRenderTextures);
+ }
+ return this._maskTexture.textures;
+ }
+ setGL(gl) {
+ this.gl = gl;
+ }
+ calcClippedDrawTotalBounds(model, clippingContext) {
+ let clippedDrawTotalMinX = Number.MAX_VALUE;
+ let clippedDrawTotalMinY = Number.MAX_VALUE;
+ let clippedDrawTotalMaxX = Number.MIN_VALUE;
+ let clippedDrawTotalMaxY = Number.MIN_VALUE;
+ const clippedDrawCount = clippingContext._clippedDrawableIndexList.length;
+ for (let clippedDrawableIndex = 0; clippedDrawableIndex < clippedDrawCount; clippedDrawableIndex++) {
+ const drawableIndex = clippingContext._clippedDrawableIndexList[clippedDrawableIndex];
+ const drawableVertexCount = model.getDrawableVertexCount(drawableIndex);
+ const drawableVertexes = model.getDrawableVertices(drawableIndex);
+ let minX = Number.MAX_VALUE;
+ let minY = Number.MAX_VALUE;
+ let maxX = -Number.MAX_VALUE;
+ let maxY = -Number.MAX_VALUE;
+ const loop = drawableVertexCount * Constant.vertexStep;
+ for (let pi = Constant.vertexOffset; pi < loop; pi += Constant.vertexStep) {
+ const x = drawableVertexes[pi];
+ const y = drawableVertexes[pi + 1];
+ if (x < minX) {
+ minX = x;
+ }
+ if (x > maxX) {
+ maxX = x;
+ }
+ if (y < minY) {
+ minY = y;
+ }
+ if (y > maxY) {
+ maxY = y;
+ }
+ }
+ if (minX == Number.MAX_VALUE) {
+ continue;
+ }
+ if (minX < clippedDrawTotalMinX) {
+ clippedDrawTotalMinX = minX;
+ }
+ if (minY < clippedDrawTotalMinY) {
+ clippedDrawTotalMinY = minY;
+ }
+ if (maxX > clippedDrawTotalMaxX) {
+ clippedDrawTotalMaxX = maxX;
+ }
+ if (maxY > clippedDrawTotalMaxY) {
+ clippedDrawTotalMaxY = maxY;
+ }
+ if (clippedDrawTotalMinX == Number.MAX_VALUE) {
+ clippingContext._allClippedDrawRect.x = 0;
+ clippingContext._allClippedDrawRect.y = 0;
+ clippingContext._allClippedDrawRect.width = 0;
+ clippingContext._allClippedDrawRect.height = 0;
+ clippingContext._isUsing = false;
+ } else {
+ clippingContext._isUsing = true;
+ const w = clippedDrawTotalMaxX - clippedDrawTotalMinX;
+ const h = clippedDrawTotalMaxY - clippedDrawTotalMinY;
+ clippingContext._allClippedDrawRect.x = clippedDrawTotalMinX;
+ clippingContext._allClippedDrawRect.y = clippedDrawTotalMinY;
+ clippingContext._allClippedDrawRect.width = w;
+ clippingContext._allClippedDrawRect.height = h;
+ }
+ }
+ }
+ constructor() {
+ this._currentMaskRenderTexture = null;
+ this._currentFrameNo = 0;
+ this._renderTextureCount = 0;
+ this._clippingMaskBufferSize = 256;
+ this._clippingContextListForMask = [];
+ this._clippingContextListForDraw = [];
+ this._channelColors = [];
+ this._tmpBoundsOnModel = new csmRect();
+ this._tmpMatrix = new CubismMatrix44();
+ this._tmpMatrixForMask = new CubismMatrix44();
+ this._tmpMatrixForDraw = new CubismMatrix44();
+ let tmp = new CubismTextureColor();
+ tmp.R = 1;
+ tmp.G = 0;
+ tmp.B = 0;
+ tmp.A = 0;
+ this._channelColors.push(tmp);
+ tmp = new CubismTextureColor();
+ tmp.R = 0;
+ tmp.G = 1;
+ tmp.B = 0;
+ tmp.A = 0;
+ this._channelColors.push(tmp);
+ tmp = new CubismTextureColor();
+ tmp.R = 0;
+ tmp.G = 0;
+ tmp.B = 1;
+ tmp.A = 0;
+ this._channelColors.push(tmp);
+ tmp = new CubismTextureColor();
+ tmp.R = 0;
+ tmp.G = 0;
+ tmp.B = 0;
+ tmp.A = 1;
+ this._channelColors.push(tmp);
+ }
+ release() {
+ var _a;
+ const self2 = this;
+ for (let i = 0; i < this._clippingContextListForMask.length; i++) {
+ if (this._clippingContextListForMask[i]) {
+ (_a = this._clippingContextListForMask[i]) == null ? void 0 : _a.release();
+ }
+ }
+ self2._clippingContextListForMask = void 0;
+ self2._clippingContextListForDraw = void 0;
+ if (this._maskTexture) {
+ for (let i = 0; i < this._maskTexture.textures.length; i++) {
+ this.gl.deleteFramebuffer(this._maskTexture.textures[i]);
+ }
+ this._maskTexture = void 0;
+ }
+ self2._channelColors = void 0;
+ if (this._maskColorBuffers) {
+ for (let index = 0; index < this._maskColorBuffers.length; index++) {
+ this.gl.deleteTexture(this._maskColorBuffers[index]);
+ }
+ }
+ this._maskColorBuffers = void 0;
+ this._maskRenderTextures = void 0;
+ this._clearedFrameBufferflags = void 0;
+ }
+ initialize(model, drawableCount, drawableMasks, drawableMaskCounts, renderTextureCount) {
+ if (renderTextureCount % 1 != 0) {
+ CubismLogWarning("The number of render textures must be specified as an integer. The decimal point is rounded down and corrected to an integer.");
+ renderTextureCount = ~~renderTextureCount;
+ }
+ if (renderTextureCount < 1) {
+ CubismLogWarning("The number of render textures must be an integer greater than or equal to 1. Set the number of render textures to 1.");
+ }
+ this._renderTextureCount = renderTextureCount < 1 ? 1 : renderTextureCount;
+ this._clearedFrameBufferflags = [];
+ for (let i = 0; i < drawableCount; i++) {
+ if (drawableMaskCounts[i] <= 0) {
+ this._clippingContextListForDraw.push(null);
+ continue;
+ }
+ let clippingContext = this.findSameClip(drawableMasks[i], drawableMaskCounts[i]);
+ if (clippingContext == null) {
+ clippingContext = new CubismClippingContext(this, drawableMasks[i], drawableMaskCounts[i]);
+ this._clippingContextListForMask.push(clippingContext);
+ }
+ clippingContext.addClippedDrawable(i);
+ this._clippingContextListForDraw.push(clippingContext);
+ }
+ }
+ setupClippingContext(model, renderer) {
+ this._currentFrameNo++;
+ let usingClipCount = 0;
+ for (let clipIndex = 0; clipIndex < this._clippingContextListForMask.length; clipIndex++) {
+ const cc = this._clippingContextListForMask[clipIndex];
+ this.calcClippedDrawTotalBounds(model, cc);
+ if (cc._isUsing) {
+ usingClipCount++;
+ }
+ }
+ if (usingClipCount > 0) {
+ this.setupLayoutBounds(renderer.isUsingHighPrecisionMask() ? 0 : usingClipCount);
+ if (!renderer.isUsingHighPrecisionMask()) {
+ this.gl.viewport(0, 0, this._clippingMaskBufferSize, this._clippingMaskBufferSize);
+ this._currentMaskRenderTexture = this.getMaskRenderTexture()[0];
+ renderer.preDraw();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this._currentMaskRenderTexture);
+ }
+ if (!this._clearedFrameBufferflags) {
+ this._clearedFrameBufferflags = [];
+ }
+ for (let index = 0; index < this._renderTextureCount; index++) {
+ this._clearedFrameBufferflags[index] = false;
+ }
+ for (let clipIndex = 0; clipIndex < this._clippingContextListForMask.length; clipIndex++) {
+ const clipContext = this._clippingContextListForMask[clipIndex];
+ const allClipedDrawRect = clipContext._allClippedDrawRect;
+ const layoutBoundsOnTex01 = clipContext._layoutBounds;
+ const MARGIN = 0.05;
+ let scaleX = 0;
+ let scaleY = 0;
+ const clipContextRenderTexture = this.getMaskRenderTexture()[clipContext._bufferIndex];
+ if (this._currentMaskRenderTexture != clipContextRenderTexture && !renderer.isUsingHighPrecisionMask()) {
+ this._currentMaskRenderTexture = clipContextRenderTexture;
+ renderer.preDraw();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this._currentMaskRenderTexture);
+ }
+ if (renderer.isUsingHighPrecisionMask()) {
+ const ppu = model.getPixelsPerUnit();
+ const maskPixelSize = clipContext.getClippingManager()._clippingMaskBufferSize;
+ const physicalMaskWidth = layoutBoundsOnTex01.width * maskPixelSize;
+ const physicalMaskHeight = layoutBoundsOnTex01.height * maskPixelSize;
+ this._tmpBoundsOnModel.setRect(allClipedDrawRect);
+ if (this._tmpBoundsOnModel.width * ppu > physicalMaskWidth) {
+ this._tmpBoundsOnModel.expand(allClipedDrawRect.width * MARGIN, 0);
+ scaleX = layoutBoundsOnTex01.width / this._tmpBoundsOnModel.width;
+ } else {
+ scaleX = ppu / physicalMaskWidth;
+ }
+ if (this._tmpBoundsOnModel.height * ppu > physicalMaskHeight) {
+ this._tmpBoundsOnModel.expand(0, allClipedDrawRect.height * MARGIN);
+ scaleY = layoutBoundsOnTex01.height / this._tmpBoundsOnModel.height;
+ } else {
+ scaleY = ppu / physicalMaskHeight;
+ }
+ } else {
+ this._tmpBoundsOnModel.setRect(allClipedDrawRect);
+ this._tmpBoundsOnModel.expand(allClipedDrawRect.width * MARGIN, allClipedDrawRect.height * MARGIN);
+ scaleX = layoutBoundsOnTex01.width / this._tmpBoundsOnModel.width;
+ scaleY = layoutBoundsOnTex01.height / this._tmpBoundsOnModel.height;
+ }
+ {
+ this._tmpMatrix.loadIdentity();
+ {
+ this._tmpMatrix.translateRelative(-1, -1);
+ this._tmpMatrix.scaleRelative(2, 2);
+ }
+ {
+ this._tmpMatrix.translateRelative(layoutBoundsOnTex01.x, layoutBoundsOnTex01.y);
+ this._tmpMatrix.scaleRelative(scaleX, scaleY);
+ this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x, -this._tmpBoundsOnModel.y);
+ }
+ this._tmpMatrixForMask.setMatrix(this._tmpMatrix.getArray());
+ }
+ {
+ this._tmpMatrix.loadIdentity();
+ {
+ this._tmpMatrix.translateRelative(layoutBoundsOnTex01.x, layoutBoundsOnTex01.y);
+ this._tmpMatrix.scaleRelative(scaleX, scaleY);
+ this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x, -this._tmpBoundsOnModel.y);
+ }
+ this._tmpMatrixForDraw.setMatrix(this._tmpMatrix.getArray());
+ }
+ clipContext._matrixForMask.setMatrix(this._tmpMatrixForMask.getArray());
+ clipContext._matrixForDraw.setMatrix(this._tmpMatrixForDraw.getArray());
+ if (!renderer.isUsingHighPrecisionMask()) {
+ const clipDrawCount = clipContext._clippingIdCount;
+ for (let i = 0; i < clipDrawCount; i++) {
+ const clipDrawIndex = clipContext._clippingIdList[i];
+ if (!model.getDrawableDynamicFlagVertexPositionsDidChange(clipDrawIndex)) {
+ continue;
+ }
+ renderer.setIsCulling(model.getDrawableCulling(clipDrawIndex) != false);
+ if (!this._clearedFrameBufferflags[clipContext._bufferIndex]) {
+ this.gl.clearColor(1, 1, 1, 1);
+ this.gl.clear(this.gl.COLOR_BUFFER_BIT);
+ this._clearedFrameBufferflags[clipContext._bufferIndex] = true;
+ }
+ renderer.setClippingContextBufferForMask(clipContext);
+ renderer.drawMesh(model.getDrawableTextureIndex(clipDrawIndex), model.getDrawableVertexIndexCount(clipDrawIndex), model.getDrawableVertexCount(clipDrawIndex), model.getDrawableVertexIndices(clipDrawIndex), model.getDrawableVertices(clipDrawIndex), model.getDrawableVertexUvs(clipDrawIndex), model.getMultiplyColor(clipDrawIndex), model.getScreenColor(clipDrawIndex), model.getDrawableOpacity(clipDrawIndex), CubismBlendMode.CubismBlendMode_Normal, false);
+ }
+ }
+ }
+ if (!renderer.isUsingHighPrecisionMask()) {
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, s_fbo);
+ renderer.setClippingContextBufferForMask(null);
+ this.gl.viewport(s_viewport[0], s_viewport[1], s_viewport[2], s_viewport[3]);
+ }
+ }
+ }
+ findSameClip(drawableMasks, drawableMaskCounts) {
+ for (let i = 0; i < this._clippingContextListForMask.length; i++) {
+ const clippingContext = this._clippingContextListForMask[i];
+ const count = clippingContext._clippingIdCount;
+ if (count != drawableMaskCounts) {
+ continue;
+ }
+ let sameCount = 0;
+ for (let j = 0; j < count; j++) {
+ const clipId = clippingContext._clippingIdList[j];
+ for (let k = 0; k < count; k++) {
+ if (drawableMasks[k] == clipId) {
+ sameCount++;
+ break;
+ }
+ }
+ }
+ if (sameCount == count) {
+ return clippingContext;
+ }
+ }
+ return null;
+ }
+ setupLayoutBounds(usingClipCount) {
+ const useClippingMaskMaxCount = this._renderTextureCount <= 1 ? ClippingMaskMaxCountOnDefault : ClippingMaskMaxCountOnMultiRenderTexture * this._renderTextureCount;
+ if (usingClipCount <= 0 || usingClipCount > useClippingMaskMaxCount) {
+ if (usingClipCount > useClippingMaskMaxCount) {
+ CubismLogError("not supported mask count : {0}\n[Details] render texture count : {1}, mask count : {2}", usingClipCount - useClippingMaskMaxCount, this._renderTextureCount, usingClipCount);
+ }
+ for (let index = 0; index < this._clippingContextListForMask.length; index++) {
+ const clipContext = this._clippingContextListForMask[index];
+ clipContext._layoutChannelNo = 0;
+ clipContext._layoutBounds.x = 0;
+ clipContext._layoutBounds.y = 0;
+ clipContext._layoutBounds.width = 1;
+ clipContext._layoutBounds.height = 1;
+ clipContext._bufferIndex = 0;
+ }
+ return;
+ }
+ const layoutCountMaxValue = this._renderTextureCount <= 1 ? 9 : 8;
+ let countPerSheetDiv = usingClipCount / this._renderTextureCount;
+ let countPerSheetMod = usingClipCount % this._renderTextureCount;
+ countPerSheetDiv = ~~countPerSheetDiv;
+ countPerSheetMod = ~~countPerSheetMod;
+ let div = countPerSheetDiv / ColorChannelCount;
+ let mod = countPerSheetDiv % ColorChannelCount;
+ div = ~~div;
+ mod = ~~mod;
+ let curClipIndex = 0;
+ for (let renderTextureNo = 0; renderTextureNo < this._renderTextureCount; renderTextureNo++) {
+ for (let channelNo = 0; channelNo < ColorChannelCount; channelNo++) {
+ let layoutCount = div + (channelNo < mod ? 1 : 0);
+ const checkChannelNo = mod + 1 >= ColorChannelCount ? 0 : mod + 1;
+ if (layoutCount < layoutCountMaxValue && channelNo == checkChannelNo) {
+ layoutCount += renderTextureNo < countPerSheetMod ? 1 : 0;
+ }
+ if (layoutCount == 0)
+ ;
+ else if (layoutCount == 1) {
+ const clipContext = this._clippingContextListForMask[curClipIndex++];
+ clipContext._layoutChannelNo = channelNo;
+ clipContext._layoutBounds.x = 0;
+ clipContext._layoutBounds.y = 0;
+ clipContext._layoutBounds.width = 1;
+ clipContext._layoutBounds.height = 1;
+ clipContext._bufferIndex = renderTextureNo;
+ } else if (layoutCount == 2) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 2;
+ xpos = ~~xpos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos * 0.5;
+ cc._layoutBounds.y = 0;
+ cc._layoutBounds.width = 0.5;
+ cc._layoutBounds.height = 1;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else if (layoutCount <= 4) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 2;
+ let ypos = i / 2;
+ xpos = ~~xpos;
+ ypos = ~~ypos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos * 0.5;
+ cc._layoutBounds.y = ypos * 0.5;
+ cc._layoutBounds.width = 0.5;
+ cc._layoutBounds.height = 0.5;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else if (layoutCount <= layoutCountMaxValue) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 3;
+ let ypos = i / 3;
+ xpos = ~~xpos;
+ ypos = ~~ypos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos / 3;
+ cc._layoutBounds.y = ypos / 3;
+ cc._layoutBounds.width = 1 / 3;
+ cc._layoutBounds.height = 1 / 3;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else if (CubismConfig.supportMoreMaskDivisions && layoutCount <= 16) {
+ for (let i = 0; i < layoutCount; i++) {
+ let xpos = i % 4;
+ let ypos = i / 4;
+ xpos = ~~xpos;
+ ypos = ~~ypos;
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = channelNo;
+ cc._layoutBounds.x = xpos / 4;
+ cc._layoutBounds.y = ypos / 4;
+ cc._layoutBounds.width = 1 / 4;
+ cc._layoutBounds.height = 1 / 4;
+ cc._bufferIndex = renderTextureNo;
+ }
+ } else {
+ CubismLogError("not supported mask count : {0}\n[Details] render texture count : {1}, mask count : {2}", usingClipCount - useClippingMaskMaxCount, this._renderTextureCount, usingClipCount);
+ for (let index = 0; index < layoutCount; index++) {
+ const cc = this._clippingContextListForMask[curClipIndex++];
+ cc._layoutChannelNo = 0;
+ cc._layoutBounds.x = 0;
+ cc._layoutBounds.y = 0;
+ cc._layoutBounds.width = 1;
+ cc._layoutBounds.height = 1;
+ cc._bufferIndex = 0;
+ }
+ }
+ }
+ }
+ }
+ getColorBuffer() {
+ return this._maskColorBuffers;
+ }
+ getClippingContextListForDraw() {
+ return this._clippingContextListForDraw;
+ }
+ getClippingMaskCount() {
+ return this._clippingContextListForMask.length;
+ }
+ setClippingMaskBufferSize(size) {
+ this._clippingMaskBufferSize = size;
+ }
+ getClippingMaskBufferSize() {
+ return this._clippingMaskBufferSize;
+ }
+ getRenderTextureCount() {
+ return this._renderTextureCount;
+ }
+ }
+ class CubismRenderTextureResource {
+ constructor(frameNo, texture) {
+ this.frameNo = frameNo;
+ this.textures = texture;
+ }
+ }
+ class CubismClippingContext {
+ constructor(manager, clippingDrawableIndices, clipCount) {
+ this._isUsing = false;
+ this._owner = manager;
+ this._clippingIdList = clippingDrawableIndices;
+ this._clippingIdCount = clipCount;
+ this._allClippedDrawRect = new csmRect();
+ this._layoutBounds = new csmRect();
+ this._clippedDrawableIndexList = [];
+ this._matrixForMask = new CubismMatrix44();
+ this._matrixForDraw = new CubismMatrix44();
+ this._bufferIndex = 0;
+ }
+ release() {
+ const self2 = this;
+ self2._layoutBounds = void 0;
+ self2._allClippedDrawRect = void 0;
+ self2._clippedDrawableIndexList = void 0;
+ }
+ addClippedDrawable(drawableIndex) {
+ this._clippedDrawableIndexList.push(drawableIndex);
+ }
+ getClippingManager() {
+ return this._owner;
+ }
+ setGl(gl) {
+ this._owner.setGL(gl);
+ }
+ }
+ class CubismRendererProfile_WebGL {
+ setGlEnable(index, enabled) {
+ if (enabled)
+ this.gl.enable(index);
+ else
+ this.gl.disable(index);
+ }
+ setGlEnableVertexAttribArray(index, enabled) {
+ if (enabled)
+ this.gl.enableVertexAttribArray(index);
+ else
+ this.gl.disableVertexAttribArray(index);
+ }
+ save() {
+ if (this.gl == null) {
+ CubismLogError("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");
+ return;
+ }
+ this._lastArrayBufferBinding = this.gl.getParameter(this.gl.ARRAY_BUFFER_BINDING);
+ this._lastArrayBufferBinding = this.gl.getParameter(this.gl.ELEMENT_ARRAY_BUFFER_BINDING);
+ this._lastProgram = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
+ this._lastActiveTexture = this.gl.getParameter(this.gl.ACTIVE_TEXTURE);
+ this.gl.activeTexture(this.gl.TEXTURE1);
+ this._lastTexture1Binding2D = this.gl.getParameter(this.gl.TEXTURE_BINDING_2D);
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this._lastTexture0Binding2D = this.gl.getParameter(this.gl.TEXTURE_BINDING_2D);
+ this._lastVertexAttribArrayEnabled[0] = this.gl.getVertexAttrib(0, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastVertexAttribArrayEnabled[1] = this.gl.getVertexAttrib(1, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastVertexAttribArrayEnabled[2] = this.gl.getVertexAttrib(2, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastVertexAttribArrayEnabled[3] = this.gl.getVertexAttrib(3, this.gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this._lastScissorTest = this.gl.isEnabled(this.gl.SCISSOR_TEST);
+ this._lastStencilTest = this.gl.isEnabled(this.gl.STENCIL_TEST);
+ this._lastDepthTest = this.gl.isEnabled(this.gl.DEPTH_TEST);
+ this._lastCullFace = this.gl.isEnabled(this.gl.CULL_FACE);
+ this._lastBlend = this.gl.isEnabled(this.gl.BLEND);
+ this._lastFrontFace = this.gl.getParameter(this.gl.FRONT_FACE);
+ this._lastColorMask = this.gl.getParameter(this.gl.COLOR_WRITEMASK);
+ this._lastBlending[0] = this.gl.getParameter(this.gl.BLEND_SRC_RGB);
+ this._lastBlending[1] = this.gl.getParameter(this.gl.BLEND_DST_RGB);
+ this._lastBlending[2] = this.gl.getParameter(this.gl.BLEND_SRC_ALPHA);
+ this._lastBlending[3] = this.gl.getParameter(this.gl.BLEND_DST_ALPHA);
+ this._lastFBO = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING);
+ this._lastViewport = this.gl.getParameter(this.gl.VIEWPORT);
+ }
+ restore() {
+ if (this.gl == null) {
+ CubismLogError("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");
+ return;
+ }
+ this.gl.useProgram(this._lastProgram);
+ this.setGlEnableVertexAttribArray(0, this._lastVertexAttribArrayEnabled[0]);
+ this.setGlEnableVertexAttribArray(1, this._lastVertexAttribArrayEnabled[1]);
+ this.setGlEnableVertexAttribArray(2, this._lastVertexAttribArrayEnabled[2]);
+ this.setGlEnableVertexAttribArray(3, this._lastVertexAttribArrayEnabled[3]);
+ this.setGlEnable(this.gl.SCISSOR_TEST, this._lastScissorTest);
+ this.setGlEnable(this.gl.STENCIL_TEST, this._lastStencilTest);
+ this.setGlEnable(this.gl.DEPTH_TEST, this._lastDepthTest);
+ this.setGlEnable(this.gl.CULL_FACE, this._lastCullFace);
+ this.setGlEnable(this.gl.BLEND, this._lastBlend);
+ this.gl.frontFace(this._lastFrontFace);
+ this.gl.colorMask(this._lastColorMask[0], this._lastColorMask[1], this._lastColorMask[2], this._lastColorMask[3]);
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this._lastArrayBufferBinding);
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this._lastElementArrayBufferBinding);
+ this.gl.activeTexture(this.gl.TEXTURE1);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this._lastTexture1Binding2D);
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this._lastTexture0Binding2D);
+ this.gl.activeTexture(this._lastActiveTexture);
+ this.gl.blendFuncSeparate(this._lastBlending[0], this._lastBlending[1], this._lastBlending[2], this._lastBlending[3]);
+ }
+ setGl(gl) {
+ this.gl = gl;
+ }
+ constructor() {
+ this._lastVertexAttribArrayEnabled = new Array(4);
+ this._lastColorMask = new Array(4);
+ this._lastBlending = new Array(4);
+ this._lastViewport = new Array(4);
+ }
+ }
+ class CubismShader_WebGL {
+ static getInstance() {
+ if (s_instance == null) {
+ s_instance = new CubismShader_WebGL();
+ return s_instance;
+ }
+ return s_instance;
+ }
+ static deleteInstance() {
+ if (s_instance) {
+ s_instance.release();
+ s_instance = void 0;
+ }
+ }
+ constructor() {
+ this._shaderSets = [];
+ }
+ release() {
+ this.releaseShaderProgram();
+ }
+ setupShaderProgram(renderer, textureId, vertexCount, vertexArray, indexArray, uvArray, bufferData, opacity, colorBlendMode, baseColor, multiplyColor, screenColor, isPremultipliedAlpha, matrix4x4, invertedMask) {
+ if (!isPremultipliedAlpha) {
+ CubismLogError("NoPremultipliedAlpha is not allowed");
+ }
+ if (this._shaderSets.length == 0) {
+ this.generateShaders();
+ }
+ let SRC_COLOR;
+ let DST_COLOR;
+ let SRC_ALPHA;
+ let DST_ALPHA;
+ const clippingContextBufferForMask = renderer.getClippingContextBufferForMask();
+ if (clippingContextBufferForMask != null) {
+ const shaderSet = this._shaderSets[ShaderNames.ShaderNames_SetupMask];
+ this.gl.useProgram(shaderSet.shaderProgram);
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, textureId);
+ this.gl.uniform1i(shaderSet.samplerTexture0Location, 0);
+ if (bufferData.vertex == null) {
+ bufferData.vertex = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.vertex);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, vertexArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributePositionLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributePositionLocation, 2, this.gl.FLOAT, false, 0, 0);
+ if (bufferData.uv == null) {
+ bufferData.uv = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.uv);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, uvArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributeTexCoordLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributeTexCoordLocation, 2, this.gl.FLOAT, false, 0, 0);
+ const channelNo = clippingContextBufferForMask._layoutChannelNo;
+ const colorChannel = clippingContextBufferForMask.getClippingManager().getChannelFlagAsColor(channelNo);
+ this.gl.uniform4f(shaderSet.uniformChannelFlagLocation, colorChannel.R, colorChannel.G, colorChannel.B, colorChannel.A);
+ this.gl.uniformMatrix4fv(shaderSet.uniformClipMatrixLocation, false, clippingContextBufferForMask._matrixForMask.getArray());
+ const rect = clippingContextBufferForMask._layoutBounds;
+ this.gl.uniform4f(shaderSet.uniformBaseColorLocation, rect.x * 2 - 1, rect.y * 2 - 1, rect.getRight() * 2 - 1, rect.getBottom() * 2 - 1);
+ this.gl.uniform4f(shaderSet.uniformMultiplyColorLocation, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A);
+ this.gl.uniform4f(shaderSet.uniformScreenColorLocation, screenColor.R, screenColor.G, screenColor.B, screenColor.A);
+ SRC_COLOR = this.gl.ZERO;
+ DST_COLOR = this.gl.ONE_MINUS_SRC_COLOR;
+ SRC_ALPHA = this.gl.ZERO;
+ DST_ALPHA = this.gl.ONE_MINUS_SRC_ALPHA;
+ } else {
+ const clippingContextBufferForDraw = renderer.getClippingContextBufferForDraw();
+ const masked = clippingContextBufferForDraw != null;
+ const offset = masked ? invertedMask ? 2 : 1 : 0;
+ let shaderSet;
+ switch (colorBlendMode) {
+ case CubismBlendMode.CubismBlendMode_Normal:
+ default:
+ shaderSet = this._shaderSets[ShaderNames.ShaderNames_NormalPremultipliedAlpha + offset];
+ SRC_COLOR = this.gl.ONE;
+ DST_COLOR = this.gl.ONE_MINUS_SRC_ALPHA;
+ SRC_ALPHA = this.gl.ONE;
+ DST_ALPHA = this.gl.ONE_MINUS_SRC_ALPHA;
+ break;
+ case CubismBlendMode.CubismBlendMode_Additive:
+ shaderSet = this._shaderSets[ShaderNames.ShaderNames_AddPremultipliedAlpha + offset];
+ SRC_COLOR = this.gl.ONE;
+ DST_COLOR = this.gl.ONE;
+ SRC_ALPHA = this.gl.ZERO;
+ DST_ALPHA = this.gl.ONE;
+ break;
+ case CubismBlendMode.CubismBlendMode_Multiplicative:
+ shaderSet = this._shaderSets[ShaderNames.ShaderNames_MultPremultipliedAlpha + offset];
+ SRC_COLOR = this.gl.DST_COLOR;
+ DST_COLOR = this.gl.ONE_MINUS_SRC_ALPHA;
+ SRC_ALPHA = this.gl.ZERO;
+ DST_ALPHA = this.gl.ONE;
+ break;
+ }
+ this.gl.useProgram(shaderSet.shaderProgram);
+ if (bufferData.vertex == null) {
+ bufferData.vertex = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.vertex);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, vertexArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributePositionLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributePositionLocation, 2, this.gl.FLOAT, false, 0, 0);
+ if (bufferData.uv == null) {
+ bufferData.uv = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, bufferData.uv);
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, uvArray, this.gl.DYNAMIC_DRAW);
+ this.gl.enableVertexAttribArray(shaderSet.attributeTexCoordLocation);
+ this.gl.vertexAttribPointer(shaderSet.attributeTexCoordLocation, 2, this.gl.FLOAT, false, 0, 0);
+ if (clippingContextBufferForDraw != null) {
+ this.gl.activeTexture(this.gl.TEXTURE1);
+ const tex = clippingContextBufferForDraw.getClippingManager().getColorBuffer()[renderer.getClippingContextBufferForDraw()._bufferIndex];
+ this.gl.bindTexture(this.gl.TEXTURE_2D, tex);
+ this.gl.uniform1i(shaderSet.samplerTexture1Location, 1);
+ this.gl.uniformMatrix4fv(shaderSet.uniformClipMatrixLocation, false, clippingContextBufferForDraw._matrixForDraw.getArray());
+ const channelNo = clippingContextBufferForDraw._layoutChannelNo;
+ const colorChannel = clippingContextBufferForDraw.getClippingManager().getChannelFlagAsColor(channelNo);
+ this.gl.uniform4f(shaderSet.uniformChannelFlagLocation, colorChannel.R, colorChannel.G, colorChannel.B, colorChannel.A);
+ }
+ this.gl.activeTexture(this.gl.TEXTURE0);
+ this.gl.bindTexture(this.gl.TEXTURE_2D, textureId);
+ this.gl.uniform1i(shaderSet.samplerTexture0Location, 0);
+ this.gl.uniformMatrix4fv(shaderSet.uniformMatrixLocation, false, matrix4x4.getArray());
+ this.gl.uniform4f(shaderSet.uniformBaseColorLocation, baseColor.R, baseColor.G, baseColor.B, baseColor.A);
+ this.gl.uniform4f(shaderSet.uniformMultiplyColorLocation, multiplyColor.R, multiplyColor.G, multiplyColor.B, multiplyColor.A);
+ this.gl.uniform4f(shaderSet.uniformScreenColorLocation, screenColor.R, screenColor.G, screenColor.B, screenColor.A);
+ }
+ if (bufferData.index == null) {
+ bufferData.index = this.gl.createBuffer();
+ }
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, bufferData.index);
+ this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, indexArray, this.gl.DYNAMIC_DRAW);
+ this.gl.blendFuncSeparate(SRC_COLOR, DST_COLOR, SRC_ALPHA, DST_ALPHA);
+ }
+ releaseShaderProgram() {
+ for (let i = 0; i < this._shaderSets.length; i++) {
+ this.gl.deleteProgram(this._shaderSets[i].shaderProgram);
+ this._shaderSets[i].shaderProgram = 0;
+ }
+ this._shaderSets = [];
+ }
+ generateShaders() {
+ for (let i = 0; i < ShaderCount; i++) {
+ this._shaderSets.push({});
+ }
+ this._shaderSets[0].shaderProgram = this.loadShaderProgram(vertexShaderSrcSetupMask, fragmentShaderSrcsetupMask);
+ this._shaderSets[1].shaderProgram = this.loadShaderProgram(vertexShaderSrc, fragmentShaderSrcPremultipliedAlpha);
+ this._shaderSets[2].shaderProgram = this.loadShaderProgram(vertexShaderSrcMasked, fragmentShaderSrcMaskPremultipliedAlpha);
+ this._shaderSets[3].shaderProgram = this.loadShaderProgram(vertexShaderSrcMasked, fragmentShaderSrcMaskInvertedPremultipliedAlpha);
+ this._shaderSets[4].shaderProgram = this._shaderSets[1].shaderProgram;
+ this._shaderSets[5].shaderProgram = this._shaderSets[2].shaderProgram;
+ this._shaderSets[6].shaderProgram = this._shaderSets[3].shaderProgram;
+ this._shaderSets[7].shaderProgram = this._shaderSets[1].shaderProgram;
+ this._shaderSets[8].shaderProgram = this._shaderSets[2].shaderProgram;
+ this._shaderSets[9].shaderProgram = this._shaderSets[3].shaderProgram;
+ this._shaderSets[0].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[0].shaderProgram, "a_position");
+ this._shaderSets[0].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[0].shaderProgram, "a_texCoord");
+ this._shaderSets[0].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "s_texture0");
+ this._shaderSets[0].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_clipMatrix");
+ this._shaderSets[0].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_channelFlag");
+ this._shaderSets[0].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_baseColor");
+ this._shaderSets[0].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_multiplyColor");
+ this._shaderSets[0].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[0].shaderProgram, "u_screenColor");
+ this._shaderSets[1].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[1].shaderProgram, "a_position");
+ this._shaderSets[1].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[1].shaderProgram, "a_texCoord");
+ this._shaderSets[1].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "s_texture0");
+ this._shaderSets[1].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_matrix");
+ this._shaderSets[1].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_baseColor");
+ this._shaderSets[1].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_multiplyColor");
+ this._shaderSets[1].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[1].shaderProgram, "u_screenColor");
+ this._shaderSets[2].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[2].shaderProgram, "a_position");
+ this._shaderSets[2].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[2].shaderProgram, "a_texCoord");
+ this._shaderSets[2].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "s_texture0");
+ this._shaderSets[2].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "s_texture1");
+ this._shaderSets[2].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_matrix");
+ this._shaderSets[2].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_clipMatrix");
+ this._shaderSets[2].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_channelFlag");
+ this._shaderSets[2].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_baseColor");
+ this._shaderSets[2].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_multiplyColor");
+ this._shaderSets[2].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[2].shaderProgram, "u_screenColor");
+ this._shaderSets[3].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[3].shaderProgram, "a_position");
+ this._shaderSets[3].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[3].shaderProgram, "a_texCoord");
+ this._shaderSets[3].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "s_texture0");
+ this._shaderSets[3].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "s_texture1");
+ this._shaderSets[3].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_matrix");
+ this._shaderSets[3].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_clipMatrix");
+ this._shaderSets[3].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_channelFlag");
+ this._shaderSets[3].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_baseColor");
+ this._shaderSets[3].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_multiplyColor");
+ this._shaderSets[3].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[3].shaderProgram, "u_screenColor");
+ this._shaderSets[4].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[4].shaderProgram, "a_position");
+ this._shaderSets[4].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[4].shaderProgram, "a_texCoord");
+ this._shaderSets[4].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "s_texture0");
+ this._shaderSets[4].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_matrix");
+ this._shaderSets[4].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_baseColor");
+ this._shaderSets[4].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_multiplyColor");
+ this._shaderSets[4].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[4].shaderProgram, "u_screenColor");
+ this._shaderSets[5].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[5].shaderProgram, "a_position");
+ this._shaderSets[5].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[5].shaderProgram, "a_texCoord");
+ this._shaderSets[5].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "s_texture0");
+ this._shaderSets[5].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "s_texture1");
+ this._shaderSets[5].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_matrix");
+ this._shaderSets[5].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_clipMatrix");
+ this._shaderSets[5].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_channelFlag");
+ this._shaderSets[5].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_baseColor");
+ this._shaderSets[5].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_multiplyColor");
+ this._shaderSets[5].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[5].shaderProgram, "u_screenColor");
+ this._shaderSets[6].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[6].shaderProgram, "a_position");
+ this._shaderSets[6].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[6].shaderProgram, "a_texCoord");
+ this._shaderSets[6].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "s_texture0");
+ this._shaderSets[6].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "s_texture1");
+ this._shaderSets[6].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_matrix");
+ this._shaderSets[6].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_clipMatrix");
+ this._shaderSets[6].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_channelFlag");
+ this._shaderSets[6].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_baseColor");
+ this._shaderSets[6].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_multiplyColor");
+ this._shaderSets[6].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[6].shaderProgram, "u_screenColor");
+ this._shaderSets[7].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[7].shaderProgram, "a_position");
+ this._shaderSets[7].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[7].shaderProgram, "a_texCoord");
+ this._shaderSets[7].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "s_texture0");
+ this._shaderSets[7].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_matrix");
+ this._shaderSets[7].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_baseColor");
+ this._shaderSets[7].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_multiplyColor");
+ this._shaderSets[7].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[7].shaderProgram, "u_screenColor");
+ this._shaderSets[8].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[8].shaderProgram, "a_position");
+ this._shaderSets[8].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[8].shaderProgram, "a_texCoord");
+ this._shaderSets[8].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "s_texture0");
+ this._shaderSets[8].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "s_texture1");
+ this._shaderSets[8].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_matrix");
+ this._shaderSets[8].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_clipMatrix");
+ this._shaderSets[8].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_channelFlag");
+ this._shaderSets[8].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_baseColor");
+ this._shaderSets[8].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_multiplyColor");
+ this._shaderSets[8].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[8].shaderProgram, "u_screenColor");
+ this._shaderSets[9].attributePositionLocation = this.gl.getAttribLocation(this._shaderSets[9].shaderProgram, "a_position");
+ this._shaderSets[9].attributeTexCoordLocation = this.gl.getAttribLocation(this._shaderSets[9].shaderProgram, "a_texCoord");
+ this._shaderSets[9].samplerTexture0Location = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "s_texture0");
+ this._shaderSets[9].samplerTexture1Location = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "s_texture1");
+ this._shaderSets[9].uniformMatrixLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_matrix");
+ this._shaderSets[9].uniformClipMatrixLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_clipMatrix");
+ this._shaderSets[9].uniformChannelFlagLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_channelFlag");
+ this._shaderSets[9].uniformBaseColorLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_baseColor");
+ this._shaderSets[9].uniformMultiplyColorLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_multiplyColor");
+ this._shaderSets[9].uniformScreenColorLocation = this.gl.getUniformLocation(this._shaderSets[9].shaderProgram, "u_screenColor");
+ }
+ loadShaderProgram(vertexShaderSource, fragmentShaderSource) {
+ const shaderProgram = this.gl.createProgram();
+ const vertShader = this.compileShaderSource(this.gl.VERTEX_SHADER, vertexShaderSource);
+ if (!vertShader) {
+ CubismLogError("Vertex shader compile error!");
+ return 0;
+ }
+ const fragShader = this.compileShaderSource(this.gl.FRAGMENT_SHADER, fragmentShaderSource);
+ if (!fragShader) {
+ CubismLogError("Vertex shader compile error!");
+ return 0;
+ }
+ this.gl.attachShader(shaderProgram, vertShader);
+ this.gl.attachShader(shaderProgram, fragShader);
+ this.gl.linkProgram(shaderProgram);
+ const linkStatus = this.gl.getProgramParameter(shaderProgram, this.gl.LINK_STATUS);
+ if (!linkStatus) {
+ CubismLogError("Failed to link program: {0}", shaderProgram);
+ this.gl.deleteShader(vertShader);
+ this.gl.deleteShader(fragShader);
+ if (shaderProgram) {
+ this.gl.deleteProgram(shaderProgram);
+ }
+ return 0;
+ }
+ this.gl.deleteShader(vertShader);
+ this.gl.deleteShader(fragShader);
+ return shaderProgram;
+ }
+ compileShaderSource(shaderType, shaderSource) {
+ const source = shaderSource;
+ const shader = this.gl.createShader(shaderType);
+ this.gl.shaderSource(shader, source);
+ this.gl.compileShader(shader);
+ if (!shader) {
+ const log = this.gl.getShaderInfoLog(shader);
+ CubismLogError("Shader compile log: {0} ", log);
+ }
+ const status = this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS);
+ if (!status) {
+ this.gl.deleteShader(shader);
+ return null;
+ }
+ return shader;
+ }
+ setGl(gl) {
+ this.gl = gl;
+ }
+ }
+ var ShaderNames = /* @__PURE__ */ ((ShaderNames2) => {
+ ShaderNames2[ShaderNames2["ShaderNames_SetupMask"] = 0] = "ShaderNames_SetupMask";
+ ShaderNames2[ShaderNames2["ShaderNames_NormalPremultipliedAlpha"] = 1] = "ShaderNames_NormalPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_NormalMaskedPremultipliedAlpha"] = 2] = "ShaderNames_NormalMaskedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_NomralMaskedInvertedPremultipliedAlpha"] = 3] = "ShaderNames_NomralMaskedInvertedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_AddPremultipliedAlpha"] = 4] = "ShaderNames_AddPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_AddMaskedPremultipliedAlpha"] = 5] = "ShaderNames_AddMaskedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_AddMaskedPremultipliedAlphaInverted"] = 6] = "ShaderNames_AddMaskedPremultipliedAlphaInverted";
+ ShaderNames2[ShaderNames2["ShaderNames_MultPremultipliedAlpha"] = 7] = "ShaderNames_MultPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_MultMaskedPremultipliedAlpha"] = 8] = "ShaderNames_MultMaskedPremultipliedAlpha";
+ ShaderNames2[ShaderNames2["ShaderNames_MultMaskedPremultipliedAlphaInverted"] = 9] = "ShaderNames_MultMaskedPremultipliedAlphaInverted";
+ return ShaderNames2;
+ })(ShaderNames || {});
+ const vertexShaderSrcSetupMask = "attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_myPos;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_clipMatrix * a_position; v_myPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}";
+ const fragmentShaderSrcsetupMask = "precision mediump float;varying vec2 v_texCoord;varying vec4 v_myPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;void main(){ float isInside = step(u_baseColor.x, v_myPos.x/v_myPos.w) * step(u_baseColor.y, v_myPos.y/v_myPos.w) * step(v_myPos.x/v_myPos.w, u_baseColor.z) * step(v_myPos.y/v_myPos.w, u_baseColor.w); gl_FragColor = u_channelFlag * texture2D(s_texture0, v_texCoord).a * isInside;}";
+ const vertexShaderSrc = "attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;uniform mat4 u_matrix;void main(){ gl_Position = u_matrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}";
+ const vertexShaderSrcMasked = "attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform mat4 u_matrix;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_matrix * a_position; v_clipPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}";
+ const fragmentShaderSrcPremultipliedAlpha = "precision mediump float;varying vec2 v_texCoord;uniform vec4 u_baseColor;uniform sampler2D s_texture0;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 color = texColor * u_baseColor; gl_FragColor = vec4(color.rgb, color.a);}";
+ const fragmentShaderSrcMaskPremultipliedAlpha = "precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * maskVal; gl_FragColor = col_formask;}";
+ const fragmentShaderSrcMaskInvertedPremultipliedAlpha = "precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_channelFlag;uniform vec4 u_baseColor;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * (1.0 - maskVal); gl_FragColor = col_formask;}";
+ class CubismRenderer_WebGL extends CubismRenderer {
+ constructor() {
+ super();
+ this._clippingContextBufferForMask = null;
+ this._clippingContextBufferForDraw = null;
+ this._rendererProfile = new CubismRendererProfile_WebGL();
+ this.firstDraw = true;
+ this._textures = {};
+ this._sortedDrawableIndexList = [];
+ this._bufferData = {
+ vertex: null,
+ uv: null,
+ index: null
+ };
+ }
+ initialize(model, maskBufferCount = 1) {
+ if (model.isUsingMasking()) {
+ this._clippingManager = new CubismClippingManager_WebGL();
+ this._clippingManager.initialize(model, model.getDrawableCount(), model.getDrawableMasks(), model.getDrawableMaskCounts(), maskBufferCount);
+ }
+ for (let i = model.getDrawableCount() - 1; i >= 0; i--) {
+ this._sortedDrawableIndexList[i] = 0;
+ }
+ super.initialize(model);
+ }
+ bindTexture(modelTextureNo, glTexture) {
+ this._textures[modelTextureNo] = glTexture;
+ }
+ getBindedTextures() {
+ return this._textures;
+ }
+ setClippingMaskBufferSize(size) {
+ if (!this._model.isUsingMasking()) {
+ return;
+ }
+ const renderTextureCount = this._clippingManager.getRenderTextureCount();
+ this._clippingManager.release();
+ this._clippingManager = new CubismClippingManager_WebGL();
+ this._clippingManager.setClippingMaskBufferSize(size);
+ this._clippingManager.initialize(this.getModel(), this.getModel().getDrawableCount(), this.getModel().getDrawableMasks(), this.getModel().getDrawableMaskCounts(), renderTextureCount);
+ }
+ getClippingMaskBufferSize() {
+ return this._model.isUsingMasking() ? this._clippingManager.getClippingMaskBufferSize() : -1;
+ }
+ getRenderTextureCount() {
+ return this._model.isUsingMasking() ? this._clippingManager.getRenderTextureCount() : -1;
+ }
+ release() {
+ var _a, _b, _c;
+ const self2 = this;
+ this._clippingManager.release();
+ self2._clippingManager = void 0;
+ (_a = this.gl) == null ? void 0 : _a.deleteBuffer(this._bufferData.vertex);
+ this._bufferData.vertex = null;
+ (_b = this.gl) == null ? void 0 : _b.deleteBuffer(this._bufferData.uv);
+ this._bufferData.uv = null;
+ (_c = this.gl) == null ? void 0 : _c.deleteBuffer(this._bufferData.index);
+ this._bufferData.index = null;
+ self2._bufferData = void 0;
+ self2._textures = void 0;
+ }
+ doDrawModel() {
+ if (this.gl == null) {
+ CubismLogError("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");
+ return;
+ }
+ if (this._clippingManager != null) {
+ this.preDraw();
+ this._clippingManager.setupClippingContext(this.getModel(), this);
+ }
+ this.preDraw();
+ const drawableCount = this.getModel().getDrawableCount();
+ const renderOrder = this.getModel().getDrawableRenderOrders();
+ for (let i = 0; i < drawableCount; ++i) {
+ const order = renderOrder[i];
+ this._sortedDrawableIndexList[order] = i;
+ }
+ for (let i = 0; i < drawableCount; ++i) {
+ const drawableIndex = this._sortedDrawableIndexList[i];
+ if (!this.getModel().getDrawableDynamicFlagIsVisible(drawableIndex)) {
+ continue;
+ }
+ const clipContext = this._clippingManager != null ? this._clippingManager.getClippingContextListForDraw()[drawableIndex] : null;
+ if (clipContext != null && this.isUsingHighPrecisionMask()) {
+ if (clipContext._isUsing) {
+ this.gl.viewport(0, 0, this._clippingManager.getClippingMaskBufferSize(), this._clippingManager.getClippingMaskBufferSize());
+ this.preDraw();
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, clipContext.getClippingManager().getMaskRenderTexture()[clipContext._bufferIndex]);
+ this.gl.clearColor(1, 1, 1, 1);
+ this.gl.clear(this.gl.COLOR_BUFFER_BIT);
+ }
+ {
+ const clipDrawCount = clipContext._clippingIdCount;
+ for (let index = 0; index < clipDrawCount; index++) {
+ const clipDrawIndex = clipContext._clippingIdList[index];
+ if (!this._model.getDrawableDynamicFlagVertexPositionsDidChange(clipDrawIndex)) {
+ continue;
+ }
+ this.setIsCulling(this._model.getDrawableCulling(clipDrawIndex) != false);
+ this.setClippingContextBufferForMask(clipContext);
+ this.drawMesh(this.getModel().getDrawableTextureIndex(clipDrawIndex), this.getModel().getDrawableVertexIndexCount(clipDrawIndex), this.getModel().getDrawableVertexCount(clipDrawIndex), this.getModel().getDrawableVertexIndices(clipDrawIndex), this.getModel().getDrawableVertices(clipDrawIndex), this.getModel().getDrawableVertexUvs(clipDrawIndex), this.getModel().getMultiplyColor(clipDrawIndex), this.getModel().getScreenColor(clipDrawIndex), this.getModel().getDrawableOpacity(clipDrawIndex), CubismBlendMode.CubismBlendMode_Normal, false);
+ }
+ }
+ {
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, s_fbo);
+ this.setClippingContextBufferForMask(null);
+ this.gl.viewport(s_viewport[0], s_viewport[1], s_viewport[2], s_viewport[3]);
+ this.preDraw();
+ }
+ }
+ this.setClippingContextBufferForDraw(clipContext);
+ this.setIsCulling(this.getModel().getDrawableCulling(drawableIndex));
+ this.drawMesh(this.getModel().getDrawableTextureIndex(drawableIndex), this.getModel().getDrawableVertexIndexCount(drawableIndex), this.getModel().getDrawableVertexCount(drawableIndex), this.getModel().getDrawableVertexIndices(drawableIndex), this.getModel().getDrawableVertices(drawableIndex), this.getModel().getDrawableVertexUvs(drawableIndex), this.getModel().getMultiplyColor(drawableIndex), this.getModel().getScreenColor(drawableIndex), this.getModel().getDrawableOpacity(drawableIndex), this.getModel().getDrawableBlendMode(drawableIndex), this.getModel().getDrawableInvertedMaskBit(drawableIndex));
+ }
+ }
+ drawMesh(textureNo, indexCount, vertexCount, indexArray, vertexArray, uvArray, multiplyColor, screenColor, opacity, colorBlendMode, invertedMask) {
+ if (this.isCulling()) {
+ this.gl.enable(this.gl.CULL_FACE);
+ } else {
+ this.gl.disable(this.gl.CULL_FACE);
+ }
+ this.gl.frontFace(this.gl.CCW);
+ const modelColorRGBA = this.getModelColor();
+ if (this.getClippingContextBufferForMask() == null) {
+ modelColorRGBA.A *= opacity;
+ if (this.isPremultipliedAlpha()) {
+ modelColorRGBA.R *= modelColorRGBA.A;
+ modelColorRGBA.G *= modelColorRGBA.A;
+ modelColorRGBA.B *= modelColorRGBA.A;
+ }
+ }
+ let drawtexture = null;
+ if (this._textures[textureNo] != null) {
+ drawtexture = this._textures[textureNo];
+ }
+ CubismShader_WebGL.getInstance().setupShaderProgram(this, drawtexture, vertexCount, vertexArray, indexArray, uvArray, this._bufferData, opacity, colorBlendMode, modelColorRGBA, multiplyColor, screenColor, this.isPremultipliedAlpha(), this.getMvpMatrix(), invertedMask);
+ this.gl.drawElements(this.gl.TRIANGLES, indexCount, this.gl.UNSIGNED_SHORT, 0);
+ this.gl.useProgram(null);
+ this.setClippingContextBufferForDraw(null);
+ this.setClippingContextBufferForMask(null);
+ }
+ saveProfile() {
+ this._rendererProfile.save();
+ }
+ restoreProfile() {
+ this._rendererProfile.restore();
+ }
+ static doStaticRelease() {
+ CubismShader_WebGL.deleteInstance();
+ }
+ setRenderState(fbo, viewport) {
+ s_fbo = fbo;
+ s_viewport = viewport;
+ }
+ preDraw() {
+ if (this.firstDraw) {
+ this.firstDraw = false;
+ }
+ this.gl.disable(this.gl.SCISSOR_TEST);
+ this.gl.disable(this.gl.STENCIL_TEST);
+ this.gl.disable(this.gl.DEPTH_TEST);
+ this.gl.frontFace(this.gl.CW);
+ this.gl.enable(this.gl.BLEND);
+ this.gl.colorMask(true, true, true, true);
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);
+ if (this.getAnisotropy() > 0 && this._extension) {
+ for (const tex of Object.entries(this._textures)) {
+ this.gl.bindTexture(this.gl.TEXTURE_2D, tex);
+ this.gl.texParameterf(this.gl.TEXTURE_2D, this._extension.TEXTURE_MAX_ANISOTROPY_EXT, this.getAnisotropy());
+ }
+ }
+ }
+ setClippingContextBufferForMask(clip) {
+ this._clippingContextBufferForMask = clip;
+ }
+ getClippingContextBufferForMask() {
+ return this._clippingContextBufferForMask;
+ }
+ setClippingContextBufferForDraw(clip) {
+ this._clippingContextBufferForDraw = clip;
+ }
+ getClippingContextBufferForDraw() {
+ return this._clippingContextBufferForDraw;
+ }
+ startUp(gl) {
+ this.gl = gl;
+ if (this._clippingManager) {
+ this._clippingManager.setGL(gl);
+ }
+ CubismShader_WebGL.getInstance().setGl(gl);
+ this._rendererProfile.setGl(gl);
+ this._extension = this.gl.getExtension("EXT_texture_filter_anisotropic") || this.gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic") || this.gl.getExtension("MOZ_EXT_texture_filter_anisotropic");
+ }
+ }
+ CubismRenderer.staticRelease = () => {
+ CubismRenderer_WebGL.doStaticRelease();
+ };
+ const tempMatrix = new CubismMatrix44();
+ class Cubism4InternalModel extends InternalModel {
+ constructor(coreModel, settings, options) {
+ super();
+ this.lipSync = true;
+ this.breath = CubismBreath.create();
+ this.renderer = new CubismRenderer_WebGL();
+ this.idParamAngleX = ParamAngleX;
+ this.idParamAngleY = ParamAngleY;
+ this.idParamAngleZ = ParamAngleZ;
+ this.idParamEyeBallX = ParamEyeBallX;
+ this.idParamEyeBallY = ParamEyeBallY;
+ this.idParamBodyAngleX = ParamBodyAngleX;
+ this.idParamBreath = ParamBreath;
+ this.pixelsPerUnit = 1;
+ this.centeringTransform = new math.Matrix();
+ this.coreModel = coreModel;
+ this.settings = settings;
+ this.motionManager = new Cubism4MotionManager(settings, options);
+ this.init();
+ }
+ init() {
+ var _a;
+ super.init();
+ if (((_a = this.settings.getEyeBlinkParameters()) == null ? void 0 : _a.length) > 0) {
+ this.eyeBlink = CubismEyeBlink.create(this.settings);
+ }
+ this.breath.setParameters([
+ new BreathParameterData(this.idParamAngleX, 0, 15, 6.5345, 0.5),
+ new BreathParameterData(this.idParamAngleY, 0, 8, 3.5345, 0.5),
+ new BreathParameterData(this.idParamAngleZ, 0, 10, 5.5345, 0.5),
+ new BreathParameterData(this.idParamBodyAngleX, 0, 4, 15.5345, 0.5),
+ new BreathParameterData(this.idParamBreath, 0, 0.5, 3.2345, 0.5)
+ ]);
+ this.renderer.initialize(this.coreModel);
+ this.renderer.setIsPremultipliedAlpha(true);
+ }
+ getSize() {
+ return [this.coreModel.getModel().canvasinfo.CanvasWidth, this.coreModel.getModel().canvasinfo.CanvasHeight];
+ }
+ getLayout() {
+ const layout = {};
+ if (this.settings.layout) {
+ for (const key of Object.keys(this.settings.layout)) {
+ const commonKey = key.charAt(0).toLowerCase() + key.slice(1);
+ layout[commonKey] = this.settings.layout[key];
+ }
+ }
+ return layout;
+ }
+ setupLayout() {
+ super.setupLayout();
+ this.pixelsPerUnit = this.coreModel.getModel().canvasinfo.PixelsPerUnit;
+ this.centeringTransform.scale(this.pixelsPerUnit, this.pixelsPerUnit).translate(this.originalWidth / 2, this.originalHeight / 2);
+ }
+ updateWebGLContext(gl, glContextID) {
+ this.renderer.firstDraw = true;
+ this.renderer._bufferData = {
+ vertex: null,
+ uv: null,
+ index: null
+ };
+ this.renderer.startUp(gl);
+ this.renderer._clippingManager._currentFrameNo = glContextID;
+ this.renderer._clippingManager._maskTexture = void 0;
+ CubismShader_WebGL.getInstance()._shaderSets = [];
+ }
+ bindTexture(index, texture) {
+ this.renderer.bindTexture(index, texture);
+ }
+ getHitAreaDefs() {
+ var _a, _b;
+ return (_b = (_a = this.settings.hitAreas) == null ? void 0 : _a.map((hitArea) => ({
+ id: hitArea.Id,
+ name: hitArea.Name,
+ index: this.coreModel.getDrawableIndex(hitArea.Id)
+ }))) != null ? _b : [];
+ }
+ getDrawableIDs() {
+ return this.coreModel.getDrawableIds();
+ }
+ getDrawableIndex(id) {
+ return this.coreModel.getDrawableIndex(id);
+ }
+ getDrawableVertices(drawIndex) {
+ if (typeof drawIndex === "string") {
+ drawIndex = this.coreModel.getDrawableIndex(drawIndex);
+ if (drawIndex === -1)
+ throw new TypeError("Unable to find drawable ID: " + drawIndex);
+ }
+ const arr = this.coreModel.getDrawableVertices(drawIndex).slice();
+ for (let i = 0; i < arr.length; i += 2) {
+ arr[i] = arr[i] * this.pixelsPerUnit + this.originalWidth / 2;
+ arr[i + 1] = -arr[i + 1] * this.pixelsPerUnit + this.originalHeight / 2;
+ }
+ return arr;
+ }
+ updateTransform(transform) {
+ this.drawingMatrix.copyFrom(this.centeringTransform).prepend(this.localTransform).prepend(transform);
+ }
+ update(dt, now) {
+ var _a, _b, _c, _d;
+ super.update(dt, now);
+ dt /= 1e3;
+ now /= 1e3;
+ const model = this.coreModel;
+ this.emit("beforeMotionUpdate");
+ const motionUpdated = this.motionManager.update(this.coreModel, now);
+ this.emit("afterMotionUpdate");
+ model.saveParameters();
+ (_a = this.motionManager.expressionManager) == null ? void 0 : _a.update(model, now);
+ if (!motionUpdated) {
+ (_b = this.eyeBlink) == null ? void 0 : _b.updateParameters(model, dt);
+ }
+ this.updateFocus();
+ this.updateNaturalMovements(dt * 1e3, now * 1e3);
+ (_c = this.physics) == null ? void 0 : _c.evaluate(model, dt);
+ (_d = this.pose) == null ? void 0 : _d.updateParameters(model, dt);
+ this.emit("beforeModelUpdate");
+ model.update();
+ model.loadParameters();
+ }
+ updateFocus() {
+ this.coreModel.addParameterValueById(this.idParamEyeBallX, this.focusController.x);
+ this.coreModel.addParameterValueById(this.idParamEyeBallY, this.focusController.y);
+ this.coreModel.addParameterValueById(this.idParamAngleX, this.focusController.x * 30);
+ this.coreModel.addParameterValueById(this.idParamAngleY, this.focusController.y * 30);
+ this.coreModel.addParameterValueById(this.idParamAngleZ, this.focusController.x * this.focusController.y * -30);
+ this.coreModel.addParameterValueById(this.idParamBodyAngleX, this.focusController.x * 10);
+ }
+ updateNaturalMovements(dt, now) {
+ var _a;
+ (_a = this.breath) == null ? void 0 : _a.updateParameters(this.coreModel, dt / 1e3);
+ }
+ draw(gl) {
+ const matrix = this.drawingMatrix;
+ const array = tempMatrix.getArray();
+ array[0] = matrix.a;
+ array[1] = matrix.b;
+ array[4] = -matrix.c;
+ array[5] = -matrix.d;
+ array[12] = matrix.tx;
+ array[13] = matrix.ty;
+ this.renderer.setMvpMatrix(tempMatrix);
+ this.renderer.setRenderState(gl.getParameter(gl.FRAMEBUFFER_BINDING), this.viewport);
+ this.renderer.drawModel();
+ }
+ destroy() {
+ super.destroy();
+ this.renderer.release();
+ this.coreModel.release();
+ this.renderer = void 0;
+ this.coreModel = void 0;
+ }
+ }
+ let startupPromise;
+ let startupRetries = 20;
+ function cubism4Ready() {
+ if (CubismFramework.isStarted()) {
+ return Promise.resolve();
+ }
+ startupPromise != null ? startupPromise : startupPromise = new Promise((resolve, reject) => {
+ function startUpWithRetry() {
+ try {
+ startUpCubism4();
+ resolve();
+ } catch (e) {
+ startupRetries--;
+ if (startupRetries < 0) {
+ const err = new Error("Failed to start up Cubism 4 framework.");
+ err.cause = e;
+ reject(err);
+ return;
+ }
+ logger.log("Cubism4", "Startup failed, retrying 10ms later...");
+ setTimeout(startUpWithRetry, 10);
+ }
+ }
+ startUpWithRetry();
+ });
+ return startupPromise;
+ }
+ function startUpCubism4(options) {
+ options = Object.assign({
+ logFunction: console.log,
+ loggingLevel: LogLevel.LogLevel_Verbose
+ }, options);
+ CubismFramework.startUp(options);
+ CubismFramework.initialize();
+ }
+ const Epsilon = 1e-3;
+ const DefaultFadeInSeconds = 0.5;
+ class CubismPose {
+ static create(pose3json) {
+ const ret = new CubismPose();
+ if (typeof pose3json.FadeInTime === "number") {
+ ret._fadeTimeSeconds = pose3json.FadeInTime;
+ if (ret._fadeTimeSeconds <= 0) {
+ ret._fadeTimeSeconds = DefaultFadeInSeconds;
+ }
+ }
+ const poseListInfo = pose3json.Groups;
+ const poseCount = poseListInfo.length;
+ for (let poseIndex = 0; poseIndex < poseCount; ++poseIndex) {
+ const idListInfo = poseListInfo[poseIndex];
+ const idCount = idListInfo.length;
+ let groupCount = 0;
+ for (let groupIndex = 0; groupIndex < idCount; ++groupIndex) {
+ const partInfo = idListInfo[groupIndex];
+ const partData = new PartData();
+ partData.partId = partInfo.Id;
+ const linkListInfo = partInfo.Link;
+ if (linkListInfo) {
+ const linkCount = linkListInfo.length;
+ for (let linkIndex = 0; linkIndex < linkCount; ++linkIndex) {
+ const linkPart = new PartData();
+ linkPart.partId = linkListInfo[linkIndex];
+ partData.link.push(linkPart);
+ }
+ }
+ ret._partGroups.push(partData);
+ ++groupCount;
+ }
+ ret._partGroupCounts.push(groupCount);
+ }
+ return ret;
+ }
+ updateParameters(model, deltaTimeSeconds) {
+ if (model != this._lastModel) {
+ this.reset(model);
+ }
+ this._lastModel = model;
+ if (deltaTimeSeconds < 0) {
+ deltaTimeSeconds = 0;
+ }
+ let beginIndex = 0;
+ for (let i = 0; i < this._partGroupCounts.length; i++) {
+ const partGroupCount = this._partGroupCounts[i];
+ this.doFade(model, deltaTimeSeconds, beginIndex, partGroupCount);
+ beginIndex += partGroupCount;
+ }
+ this.copyPartOpacities(model);
+ }
+ reset(model) {
+ let beginIndex = 0;
+ for (let i = 0; i < this._partGroupCounts.length; ++i) {
+ const groupCount = this._partGroupCounts[i];
+ for (let j = beginIndex; j < beginIndex + groupCount; ++j) {
+ this._partGroups[j].initialize(model);
+ const partsIndex = this._partGroups[j].partIndex;
+ const paramIndex = this._partGroups[j].parameterIndex;
+ if (partsIndex < 0) {
+ continue;
+ }
+ model.setPartOpacityByIndex(partsIndex, j == beginIndex ? 1 : 0);
+ model.setParameterValueByIndex(paramIndex, j == beginIndex ? 1 : 0);
+ for (let k = 0; k < this._partGroups[j].link.length; ++k) {
+ this._partGroups[j].link[k].initialize(model);
+ }
+ }
+ beginIndex += groupCount;
+ }
+ }
+ copyPartOpacities(model) {
+ for (let groupIndex = 0; groupIndex < this._partGroups.length; ++groupIndex) {
+ const partData = this._partGroups[groupIndex];
+ if (partData.link.length == 0) {
+ continue;
+ }
+ const partIndex = this._partGroups[groupIndex].partIndex;
+ const opacity = model.getPartOpacityByIndex(partIndex);
+ for (let linkIndex = 0; linkIndex < partData.link.length; ++linkIndex) {
+ const linkPart = partData.link[linkIndex];
+ const linkPartIndex = linkPart.partIndex;
+ if (linkPartIndex < 0) {
+ continue;
+ }
+ model.setPartOpacityByIndex(linkPartIndex, opacity);
+ }
+ }
+ }
+ doFade(model, deltaTimeSeconds, beginIndex, partGroupCount) {
+ let visiblePartIndex = -1;
+ let newOpacity = 1;
+ const phi = 0.5;
+ const backOpacityThreshold = 0.15;
+ for (let i = beginIndex; i < beginIndex + partGroupCount; ++i) {
+ const partIndex = this._partGroups[i].partIndex;
+ const paramIndex = this._partGroups[i].parameterIndex;
+ if (model.getParameterValueByIndex(paramIndex) > Epsilon) {
+ if (visiblePartIndex >= 0) {
+ break;
+ }
+ visiblePartIndex = i;
+ newOpacity = model.getPartOpacityByIndex(partIndex);
+ newOpacity += deltaTimeSeconds / this._fadeTimeSeconds;
+ if (newOpacity > 1) {
+ newOpacity = 1;
+ }
+ }
+ }
+ if (visiblePartIndex < 0) {
+ visiblePartIndex = 0;
+ newOpacity = 1;
+ }
+ for (let i = beginIndex; i < beginIndex + partGroupCount; ++i) {
+ const partsIndex = this._partGroups[i].partIndex;
+ if (visiblePartIndex == i) {
+ model.setPartOpacityByIndex(partsIndex, newOpacity);
+ } else {
+ let opacity = model.getPartOpacityByIndex(partsIndex);
+ let a1;
+ if (newOpacity < phi) {
+ a1 = newOpacity * (phi - 1) / phi + 1;
+ } else {
+ a1 = (1 - newOpacity) * phi / (1 - phi);
+ }
+ const backOpacity = (1 - a1) * (1 - newOpacity);
+ if (backOpacity > backOpacityThreshold) {
+ a1 = 1 - backOpacityThreshold / (1 - newOpacity);
+ }
+ if (opacity > a1) {
+ opacity = a1;
+ }
+ model.setPartOpacityByIndex(partsIndex, opacity);
+ }
+ }
+ }
+ constructor() {
+ this._fadeTimeSeconds = DefaultFadeInSeconds;
+ this._lastModel = void 0;
+ this._partGroups = [];
+ this._partGroupCounts = [];
+ }
+ }
+ class PartData {
+ constructor(v) {
+ this.parameterIndex = 0;
+ this.partIndex = 0;
+ this.partId = "";
+ this.link = [];
+ if (v != void 0) {
+ this.assignment(v);
+ }
+ }
+ assignment(v) {
+ this.partId = v.partId;
+ this.link = v.link.map((link) => link.clone());
+ return this;
+ }
+ initialize(model) {
+ this.parameterIndex = model.getParameterIndex(this.partId);
+ this.partIndex = model.getPartIndex(this.partId);
+ model.setParameterValueByIndex(this.parameterIndex, 1);
+ }
+ clone() {
+ const clonePartData = new PartData();
+ clonePartData.partId = this.partId;
+ clonePartData.parameterIndex = this.parameterIndex;
+ clonePartData.partIndex = this.partIndex;
+ clonePartData.link = this.link.map((link) => link.clone());
+ return clonePartData;
+ }
+ }
+ class DrawableColorData {
+ constructor(isOverwritten = false, color = new CubismTextureColor()) {
+ this.isOverwritten = isOverwritten;
+ this.Color = color;
+ }
+ }
+ class PartColorData {
+ constructor(isOverwritten = false, color = new CubismTextureColor()) {
+ this.isOverwritten = isOverwritten;
+ this.Color = color;
+ }
+ }
+ class DrawableCullingData {
+ constructor(isOverwritten = false, isCulling = false) {
+ this.isOverwritten = isOverwritten;
+ this.isCulling = isCulling;
+ }
+ }
+ class CubismModel {
+ update() {
+ this._model.update();
+ this._model.drawables.resetDynamicFlags();
+ }
+ getPixelsPerUnit() {
+ if (this._model == null) {
+ return 0;
+ }
+ return this._model.canvasinfo.PixelsPerUnit;
+ }
+ getCanvasWidth() {
+ if (this._model == null) {
+ return 0;
+ }
+ return this._model.canvasinfo.CanvasWidth / this._model.canvasinfo.PixelsPerUnit;
+ }
+ getCanvasHeight() {
+ if (this._model == null) {
+ return 0;
+ }
+ return this._model.canvasinfo.CanvasHeight / this._model.canvasinfo.PixelsPerUnit;
+ }
+ saveParameters() {
+ const parameterCount = this._model.parameters.count;
+ const savedParameterCount = this._savedParameters.length;
+ for (let i = 0; i < parameterCount; ++i) {
+ if (i < savedParameterCount) {
+ this._savedParameters[i] = this._parameterValues[i];
+ } else {
+ this._savedParameters.push(this._parameterValues[i]);
+ }
+ }
+ }
+ getMultiplyColor(index) {
+ if (this.getOverwriteFlagForModelMultiplyColors() || this.getOverwriteFlagForDrawableMultiplyColors(index)) {
+ return this._userMultiplyColors[index].Color;
+ }
+ const color = this.getDrawableMultiplyColor(index);
+ return color;
+ }
+ getScreenColor(index) {
+ if (this.getOverwriteFlagForModelScreenColors() || this.getOverwriteFlagForDrawableScreenColors(index)) {
+ return this._userScreenColors[index].Color;
+ }
+ const color = this.getDrawableScreenColor(index);
+ return color;
+ }
+ setMultiplyColorByTextureColor(index, color) {
+ this.setMultiplyColorByRGBA(index, color.R, color.G, color.B, color.A);
+ }
+ setMultiplyColorByRGBA(index, r, g, b, a = 1) {
+ this._userMultiplyColors[index].Color.R = r;
+ this._userMultiplyColors[index].Color.G = g;
+ this._userMultiplyColors[index].Color.B = b;
+ this._userMultiplyColors[index].Color.A = a;
+ }
+ setScreenColorByTextureColor(index, color) {
+ this.setScreenColorByRGBA(index, color.R, color.G, color.B, color.A);
+ }
+ setScreenColorByRGBA(index, r, g, b, a = 1) {
+ this._userScreenColors[index].Color.R = r;
+ this._userScreenColors[index].Color.G = g;
+ this._userScreenColors[index].Color.B = b;
+ this._userScreenColors[index].Color.A = a;
+ }
+ getPartMultiplyColor(partIndex) {
+ return this._userPartMultiplyColors[partIndex].Color;
+ }
+ getPartScreenColor(partIndex) {
+ return this._userPartScreenColors[partIndex].Color;
+ }
+ setPartColor(partIndex, r, g, b, a, partColors, drawableColors) {
+ partColors[partIndex].Color.R = r;
+ partColors[partIndex].Color.G = g;
+ partColors[partIndex].Color.B = b;
+ partColors[partIndex].Color.A = a;
+ if (partColors[partIndex].isOverwritten) {
+ for (let i = 0; i < this._partChildDrawables[partIndex].length; ++i) {
+ const drawableIndex = this._partChildDrawables[partIndex][i];
+ drawableColors[drawableIndex].Color.R = r;
+ drawableColors[drawableIndex].Color.G = g;
+ drawableColors[drawableIndex].Color.B = b;
+ drawableColors[drawableIndex].Color.A = a;
+ }
+ }
+ }
+ setPartMultiplyColorByTextureColor(partIndex, color) {
+ this.setPartMultiplyColorByRGBA(partIndex, color.R, color.G, color.B, color.A);
+ }
+ setPartMultiplyColorByRGBA(partIndex, r, g, b, a) {
+ this.setPartColor(partIndex, r, g, b, a, this._userPartMultiplyColors, this._userMultiplyColors);
+ }
+ setPartScreenColorByTextureColor(partIndex, color) {
+ this.setPartScreenColorByRGBA(partIndex, color.R, color.G, color.B, color.A);
+ }
+ setPartScreenColorByRGBA(partIndex, r, g, b, a) {
+ this.setPartColor(partIndex, r, g, b, a, this._userPartScreenColors, this._userScreenColors);
+ }
+ getOverwriteFlagForModelMultiplyColors() {
+ return this._isOverwrittenModelMultiplyColors;
+ }
+ getOverwriteFlagForModelScreenColors() {
+ return this._isOverwrittenModelScreenColors;
+ }
+ setOverwriteFlagForModelMultiplyColors(value) {
+ this._isOverwrittenModelMultiplyColors = value;
+ }
+ setOverwriteFlagForModelScreenColors(value) {
+ this._isOverwrittenModelScreenColors = value;
+ }
+ getOverwriteFlagForDrawableMultiplyColors(drawableindex) {
+ return this._userMultiplyColors[drawableindex].isOverwritten;
+ }
+ getOverwriteFlagForDrawableScreenColors(drawableindex) {
+ return this._userScreenColors[drawableindex].isOverwritten;
+ }
+ setOverwriteFlagForDrawableMultiplyColors(drawableindex, value) {
+ this._userMultiplyColors[drawableindex].isOverwritten = value;
+ }
+ setOverwriteFlagForDrawableScreenColors(drawableindex, value) {
+ this._userScreenColors[drawableindex].isOverwritten = value;
+ }
+ getOverwriteColorForPartMultiplyColors(partIndex) {
+ return this._userPartMultiplyColors[partIndex].isOverwritten;
+ }
+ getOverwriteColorForPartScreenColors(partIndex) {
+ return this._userPartScreenColors[partIndex].isOverwritten;
+ }
+ setOverwriteColorForPartColors(partIndex, value, partColors, drawableColors) {
+ partColors[partIndex].isOverwritten = value;
+ for (let i = 0; i < this._partChildDrawables[partIndex].length; ++i) {
+ const drawableIndex = this._partChildDrawables[partIndex][i];
+ drawableColors[drawableIndex].isOverwritten = value;
+ if (value) {
+ drawableColors[drawableIndex].Color.R = partColors[partIndex].Color.R;
+ drawableColors[drawableIndex].Color.G = partColors[partIndex].Color.G;
+ drawableColors[drawableIndex].Color.B = partColors[partIndex].Color.B;
+ drawableColors[drawableIndex].Color.A = partColors[partIndex].Color.A;
+ }
+ }
+ }
+ setOverwriteColorForPartMultiplyColors(partIndex, value) {
+ this._userPartMultiplyColors[partIndex].isOverwritten = value;
+ this.setOverwriteColorForPartColors(partIndex, value, this._userPartMultiplyColors, this._userMultiplyColors);
+ }
+ setOverwriteColorForPartScreenColors(partIndex, value) {
+ this._userPartScreenColors[partIndex].isOverwritten = value;
+ this.setOverwriteColorForPartColors(partIndex, value, this._userPartScreenColors, this._userScreenColors);
+ }
+ getDrawableCulling(drawableIndex) {
+ if (this.getOverwriteFlagForModelCullings() || this.getOverwriteFlagForDrawableCullings(drawableIndex)) {
+ return this._userCullings[drawableIndex].isCulling;
+ }
+ const constantFlags = this._model.drawables.constantFlags;
+ return !Live2DCubismCore.Utils.hasIsDoubleSidedBit(constantFlags[drawableIndex]);
+ }
+ setDrawableCulling(drawableIndex, isCulling) {
+ this._userCullings[drawableIndex].isCulling = isCulling;
+ }
+ getOverwriteFlagForModelCullings() {
+ return this._isOverwrittenCullings;
+ }
+ setOverwriteFlagForModelCullings(isOverwrittenCullings) {
+ this._isOverwrittenCullings = isOverwrittenCullings;
+ }
+ getOverwriteFlagForDrawableCullings(drawableIndex) {
+ return this._userCullings[drawableIndex].isOverwritten;
+ }
+ setOverwriteFlagForDrawableCullings(drawableIndex, isOverwrittenCullings) {
+ this._userCullings[drawableIndex].isOverwritten = isOverwrittenCullings;
+ }
+ getModelOapcity() {
+ return this._modelOpacity;
+ }
+ setModelOapcity(value) {
+ this._modelOpacity = value;
+ }
+ getModel() {
+ return this._model;
+ }
+ getPartIndex(partId) {
+ let partIndex;
+ const partCount = this._model.parts.count;
+ for (partIndex = 0; partIndex < partCount; ++partIndex) {
+ if (partId == this._partIds[partIndex]) {
+ return partIndex;
+ }
+ }
+ if (partId in this._notExistPartId) {
+ return this._notExistPartId[partId];
+ }
+ partIndex = partCount + this._notExistPartId.length;
+ this._notExistPartId[partId] = partIndex;
+ this._notExistPartOpacities[partIndex] = 0;
+ return partIndex;
+ }
+ getPartId(partIndex) {
+ return this._model.parts.ids[partIndex];
+ }
+ getPartCount() {
+ return this._model.parts.count;
+ }
+ setPartOpacityByIndex(partIndex, opacity) {
+ if (partIndex in this._notExistPartOpacities) {
+ this._notExistPartOpacities[partIndex] = opacity;
+ return;
+ }
+ CSM_ASSERT(0 <= partIndex && partIndex < this.getPartCount());
+ this._partOpacities[partIndex] = opacity;
+ }
+ setPartOpacityById(partId, opacity) {
+ const index = this.getPartIndex(partId);
+ if (index < 0) {
+ return;
+ }
+ this.setPartOpacityByIndex(index, opacity);
+ }
+ getPartOpacityByIndex(partIndex) {
+ if (partIndex in this._notExistPartOpacities) {
+ return this._notExistPartOpacities[partIndex];
+ }
+ CSM_ASSERT(0 <= partIndex && partIndex < this.getPartCount());
+ return this._partOpacities[partIndex];
+ }
+ getPartOpacityById(partId) {
+ const index = this.getPartIndex(partId);
+ if (index < 0) {
+ return 0;
+ }
+ return this.getPartOpacityByIndex(index);
+ }
+ getParameterIndex(parameterId) {
+ let parameterIndex;
+ const idCount = this._model.parameters.count;
+ for (parameterIndex = 0; parameterIndex < idCount; ++parameterIndex) {
+ if (parameterId != this._parameterIds[parameterIndex]) {
+ continue;
+ }
+ return parameterIndex;
+ }
+ if (parameterId in this._notExistParameterId) {
+ return this._notExistParameterId[parameterId];
+ }
+ parameterIndex = this._model.parameters.count + Object.keys(this._notExistParameterId).length;
+ this._notExistParameterId[parameterId] = parameterIndex;
+ this._notExistParameterValues[parameterIndex] = 0;
+ return parameterIndex;
+ }
+ getParameterCount() {
+ return this._model.parameters.count;
+ }
+ getParameterType(parameterIndex) {
+ return this._model.parameters.types[parameterIndex];
+ }
+ getParameterMaximumValue(parameterIndex) {
+ return this._model.parameters.maximumValues[parameterIndex];
+ }
+ getParameterMinimumValue(parameterIndex) {
+ return this._model.parameters.minimumValues[parameterIndex];
+ }
+ getParameterDefaultValue(parameterIndex) {
+ return this._model.parameters.defaultValues[parameterIndex];
+ }
+ getParameterValueByIndex(parameterIndex) {
+ if (parameterIndex in this._notExistParameterValues) {
+ return this._notExistParameterValues[parameterIndex];
+ }
+ CSM_ASSERT(0 <= parameterIndex && parameterIndex < this.getParameterCount());
+ return this._parameterValues[parameterIndex];
+ }
+ getParameterValueById(parameterId) {
+ const parameterIndex = this.getParameterIndex(parameterId);
+ return this.getParameterValueByIndex(parameterIndex);
+ }
+ setParameterValueByIndex(parameterIndex, value, weight = 1) {
+ if (parameterIndex in this._notExistParameterValues) {
+ this._notExistParameterValues[parameterIndex] = weight == 1 ? value : this._notExistParameterValues[parameterIndex] * (1 - weight) + value * weight;
+ return;
+ }
+ CSM_ASSERT(0 <= parameterIndex && parameterIndex < this.getParameterCount());
+ if (this._model.parameters.maximumValues[parameterIndex] < value) {
+ value = this._model.parameters.maximumValues[parameterIndex];
+ }
+ if (this._model.parameters.minimumValues[parameterIndex] > value) {
+ value = this._model.parameters.minimumValues[parameterIndex];
+ }
+ this._parameterValues[parameterIndex] = weight == 1 ? value : this._parameterValues[parameterIndex] = this._parameterValues[parameterIndex] * (1 - weight) + value * weight;
+ }
+ setParameterValueById(parameterId, value, weight = 1) {
+ const index = this.getParameterIndex(parameterId);
+ this.setParameterValueByIndex(index, value, weight);
+ }
+ addParameterValueByIndex(parameterIndex, value, weight = 1) {
+ this.setParameterValueByIndex(parameterIndex, this.getParameterValueByIndex(parameterIndex) + value * weight);
+ }
+ addParameterValueById(parameterId, value, weight = 1) {
+ const index = this.getParameterIndex(parameterId);
+ this.addParameterValueByIndex(index, value, weight);
+ }
+ multiplyParameterValueById(parameterId, value, weight = 1) {
+ const index = this.getParameterIndex(parameterId);
+ this.multiplyParameterValueByIndex(index, value, weight);
+ }
+ multiplyParameterValueByIndex(parameterIndex, value, weight = 1) {
+ this.setParameterValueByIndex(parameterIndex, this.getParameterValueByIndex(parameterIndex) * (1 + (value - 1) * weight));
+ }
+ getDrawableIds() {
+ return this._drawableIds.slice();
+ }
+ getDrawableIndex(drawableId) {
+ const drawableCount = this._model.drawables.count;
+ for (let drawableIndex = 0; drawableIndex < drawableCount; ++drawableIndex) {
+ if (this._drawableIds[drawableIndex] == drawableId) {
+ return drawableIndex;
+ }
+ }
+ return -1;
+ }
+ getDrawableCount() {
+ return this._model.drawables.count;
+ }
+ getDrawableId(drawableIndex) {
+ return this._model.drawables.ids[drawableIndex];
+ }
+ getDrawableRenderOrders() {
+ return this._model.drawables.renderOrders;
+ }
+ getDrawableTextureIndices(drawableIndex) {
+ return this.getDrawableTextureIndex(drawableIndex);
+ }
+ getDrawableTextureIndex(drawableIndex) {
+ const textureIndices = this._model.drawables.textureIndices;
+ return textureIndices[drawableIndex];
+ }
+ getDrawableDynamicFlagVertexPositionsDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasVertexPositionsDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableVertexIndexCount(drawableIndex) {
+ return this._model.drawables.indexCounts[drawableIndex];
+ }
+ getDrawableVertexCount(drawableIndex) {
+ return this._model.drawables.vertexCounts[drawableIndex];
+ }
+ getDrawableVertices(drawableIndex) {
+ return this.getDrawableVertexPositions(drawableIndex);
+ }
+ getDrawableVertexIndices(drawableIndex) {
+ return this._model.drawables.indices[drawableIndex];
+ }
+ getDrawableVertexPositions(drawableIndex) {
+ return this._model.drawables.vertexPositions[drawableIndex];
+ }
+ getDrawableVertexUvs(drawableIndex) {
+ return this._model.drawables.vertexUvs[drawableIndex];
+ }
+ getDrawableOpacity(drawableIndex) {
+ return this._model.drawables.opacities[drawableIndex];
+ }
+ getDrawableMultiplyColor(drawableIndex) {
+ const multiplyColors = this._model.drawables.multiplyColors;
+ const index = drawableIndex * 4;
+ const multiplyColor = new CubismTextureColor();
+ multiplyColor.R = multiplyColors[index];
+ multiplyColor.G = multiplyColors[index + 1];
+ multiplyColor.B = multiplyColors[index + 2];
+ multiplyColor.A = multiplyColors[index + 3];
+ return multiplyColor;
+ }
+ getDrawableScreenColor(drawableIndex) {
+ const screenColors = this._model.drawables.screenColors;
+ const index = drawableIndex * 4;
+ const screenColor = new CubismTextureColor();
+ screenColor.R = screenColors[index];
+ screenColor.G = screenColors[index + 1];
+ screenColor.B = screenColors[index + 2];
+ screenColor.A = screenColors[index + 3];
+ return screenColor;
+ }
+ getDrawableParentPartIndex(drawableIndex) {
+ return this._model.drawables.parentPartIndices[drawableIndex];
+ }
+ getDrawableBlendMode(drawableIndex) {
+ const constantFlags = this._model.drawables.constantFlags;
+ return Live2DCubismCore.Utils.hasBlendAdditiveBit(constantFlags[drawableIndex]) ? CubismBlendMode.CubismBlendMode_Additive : Live2DCubismCore.Utils.hasBlendMultiplicativeBit(constantFlags[drawableIndex]) ? CubismBlendMode.CubismBlendMode_Multiplicative : CubismBlendMode.CubismBlendMode_Normal;
+ }
+ getDrawableInvertedMaskBit(drawableIndex) {
+ const constantFlags = this._model.drawables.constantFlags;
+ return Live2DCubismCore.Utils.hasIsInvertedMaskBit(constantFlags[drawableIndex]);
+ }
+ getDrawableMasks() {
+ return this._model.drawables.masks;
+ }
+ getDrawableMaskCounts() {
+ return this._model.drawables.maskCounts;
+ }
+ isUsingMasking() {
+ for (let d = 0; d < this._model.drawables.count; ++d) {
+ if (this._model.drawables.maskCounts[d] <= 0) {
+ continue;
+ }
+ return true;
+ }
+ return false;
+ }
+ getDrawableDynamicFlagIsVisible(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasIsVisibleBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagVisibilityDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasVisibilityDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagOpacityDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasOpacityDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagRenderOrderDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasRenderOrderDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ getDrawableDynamicFlagBlendColorDidChange(drawableIndex) {
+ const dynamicFlags = this._model.drawables.dynamicFlags;
+ return Live2DCubismCore.Utils.hasBlendColorDidChangeBit(dynamicFlags[drawableIndex]);
+ }
+ loadParameters() {
+ let parameterCount = this._model.parameters.count;
+ const savedParameterCount = this._savedParameters.length;
+ if (parameterCount > savedParameterCount) {
+ parameterCount = savedParameterCount;
+ }
+ for (let i = 0; i < parameterCount; ++i) {
+ this._parameterValues[i] = this._savedParameters[i];
+ }
+ }
+ initialize() {
+ this._parameterValues = this._model.parameters.values;
+ this._partOpacities = this._model.parts.opacities;
+ this._parameterMaximumValues = this._model.parameters.maximumValues;
+ this._parameterMinimumValues = this._model.parameters.minimumValues;
+ {
+ const parameterIds = this._model.parameters.ids;
+ const parameterCount = this._model.parameters.count;
+ for (let i = 0; i < parameterCount; ++i) {
+ this._parameterIds.push(parameterIds[i]);
+ }
+ }
+ const partCount = this._model.parts.count;
+ {
+ const partIds = this._model.parts.ids;
+ for (let i = 0; i < partCount; ++i) {
+ this._partIds.push(partIds[i]);
+ }
+ }
+ {
+ const drawableIds = this._model.drawables.ids;
+ const drawableCount = this._model.drawables.count;
+ const userCulling = new DrawableCullingData(false, false);
+ {
+ for (let i = 0; i < partCount; ++i) {
+ const multiplyColor = new CubismTextureColor(1, 1, 1, 1);
+ const screenColor = new CubismTextureColor(0, 0, 0, 1);
+ const userMultiplyColor = new PartColorData(false, multiplyColor);
+ const userScreenColor = new PartColorData(false, screenColor);
+ this._userPartMultiplyColors.push(userMultiplyColor);
+ this._userPartScreenColors.push(userScreenColor);
+ this._partChildDrawables.push([]);
+ }
+ }
+ {
+ for (let i = 0; i < drawableCount; ++i) {
+ const multiplyColor = new CubismTextureColor(1, 1, 1, 1);
+ const screenColor = new CubismTextureColor(0, 0, 0, 1);
+ const userMultiplyColor = new DrawableColorData(false, multiplyColor);
+ const userScreenColor = new DrawableColorData(false, screenColor);
+ this._drawableIds.push(drawableIds[i]);
+ this._userMultiplyColors.push(userMultiplyColor);
+ this._userScreenColors.push(userScreenColor);
+ this._userCullings.push(userCulling);
+ const parentIndex = this.getDrawableParentPartIndex(i);
+ if (parentIndex >= 0) {
+ this._partChildDrawables[parentIndex].push(i);
+ }
+ }
+ }
+ }
+ }
+ constructor(model) {
+ this._model = model;
+ this._savedParameters = [];
+ this._parameterIds = [];
+ this._drawableIds = [];
+ this._partIds = [];
+ this._isOverwrittenModelMultiplyColors = false;
+ this._isOverwrittenModelScreenColors = false;
+ this._isOverwrittenCullings = false;
+ this._modelOpacity = 1;
+ this._userMultiplyColors = [];
+ this._userScreenColors = [];
+ this._userCullings = [];
+ this._userPartMultiplyColors = [];
+ this._userPartScreenColors = [];
+ this._partChildDrawables = [];
+ this._notExistPartId = {};
+ this._notExistParameterId = {};
+ this._notExistParameterValues = {};
+ this._notExistPartOpacities = {};
+ this.initialize();
+ }
+ release() {
+ this._model.release();
+ this._model = void 0;
+ }
+ }
+ class CubismMoc {
+ static create(mocBytes, shouldCheckMocConsistency) {
+ if (shouldCheckMocConsistency) {
+ const consistency = this.hasMocConsistency(mocBytes);
+ if (!consistency) {
+ throw new Error(`Inconsistent MOC3.`);
+ }
+ }
+ const moc = Live2DCubismCore.Moc.fromArrayBuffer(mocBytes);
+ if (moc) {
+ const cubismMoc = new CubismMoc(moc);
+ cubismMoc._mocVersion = Live2DCubismCore.Version.csmGetMocVersion(moc, mocBytes);
+ return cubismMoc;
+ }
+ throw new Error("Failed to CubismMoc.create().");
+ }
+ createModel() {
+ let cubismModel;
+ const model = Live2DCubismCore.Model.fromMoc(this._moc);
+ if (model) {
+ cubismModel = new CubismModel(model);
+ ++this._modelCount;
+ return cubismModel;
+ }
+ throw new Error("Unknown error");
+ }
+ deleteModel(model) {
+ if (model != null) {
+ --this._modelCount;
+ }
+ }
+ constructor(moc) {
+ this._moc = moc;
+ this._modelCount = 0;
+ this._mocVersion = 0;
+ }
+ release() {
+ this._moc._release();
+ this._moc = void 0;
+ }
+ getLatestMocVersion() {
+ return Live2DCubismCore.Version.csmGetLatestMocVersion();
+ }
+ getMocVersion() {
+ return this._mocVersion;
+ }
+ static hasMocConsistency(mocBytes) {
+ const isConsistent = Live2DCubismCore.Moc.prototype.hasMocConsistency(mocBytes);
+ return isConsistent === 1 ? true : false;
+ }
+ }
+ var CubismPhysicsTargetType = /* @__PURE__ */ ((CubismPhysicsTargetType2) => {
+ CubismPhysicsTargetType2[CubismPhysicsTargetType2["CubismPhysicsTargetType_Parameter"] = 0] = "CubismPhysicsTargetType_Parameter";
+ return CubismPhysicsTargetType2;
+ })(CubismPhysicsTargetType || {});
+ var CubismPhysicsSource = /* @__PURE__ */ ((CubismPhysicsSource2) => {
+ CubismPhysicsSource2[CubismPhysicsSource2["CubismPhysicsSource_X"] = 0] = "CubismPhysicsSource_X";
+ CubismPhysicsSource2[CubismPhysicsSource2["CubismPhysicsSource_Y"] = 1] = "CubismPhysicsSource_Y";
+ CubismPhysicsSource2[CubismPhysicsSource2["CubismPhysicsSource_Angle"] = 2] = "CubismPhysicsSource_Angle";
+ return CubismPhysicsSource2;
+ })(CubismPhysicsSource || {});
+ class CubismPhysicsParticle {
+ constructor() {
+ this.initialPosition = new CubismVector2(0, 0);
+ this.position = new CubismVector2(0, 0);
+ this.lastPosition = new CubismVector2(0, 0);
+ this.lastGravity = new CubismVector2(0, 0);
+ this.force = new CubismVector2(0, 0);
+ this.velocity = new CubismVector2(0, 0);
+ }
+ }
+ class CubismPhysicsSubRig {
+ constructor() {
+ this.normalizationPosition = {};
+ this.normalizationAngle = {};
+ }
+ }
+ class CubismPhysicsInput {
+ constructor() {
+ this.source = {};
+ }
+ }
+ class CubismPhysicsOutput {
+ constructor() {
+ this.destination = {};
+ this.translationScale = new CubismVector2(0, 0);
+ }
+ }
+ class CubismPhysicsRig {
+ constructor() {
+ this.settings = [];
+ this.inputs = [];
+ this.outputs = [];
+ this.particles = [];
+ this.gravity = new CubismVector2(0, 0);
+ this.wind = new CubismVector2(0, 0);
+ this.fps = 0;
+ }
+ }
+ class CubismPhysicsJson {
+ constructor(json) {
+ this._json = json;
+ }
+ release() {
+ this._json = void 0;
+ }
+ getGravity() {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this._json.Meta.EffectiveForces.Gravity.X;
+ ret.y = this._json.Meta.EffectiveForces.Gravity.Y;
+ return ret;
+ }
+ getWind() {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this._json.Meta.EffectiveForces.Wind.X;
+ ret.y = this._json.Meta.EffectiveForces.Wind.Y;
+ return ret;
+ }
+ getFps() {
+ return this._json.Meta.Fps || 0;
+ }
+ getSubRigCount() {
+ return this._json.Meta.PhysicsSettingCount;
+ }
+ getTotalInputCount() {
+ return this._json.Meta.TotalInputCount;
+ }
+ getTotalOutputCount() {
+ return this._json.Meta.TotalOutputCount;
+ }
+ getVertexCount() {
+ return this._json.Meta.VertexCount;
+ }
+ getNormalizationPositionMinimumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Position.Minimum;
+ }
+ getNormalizationPositionMaximumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Position.Maximum;
+ }
+ getNormalizationPositionDefaultValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Position.Default;
+ }
+ getNormalizationAngleMinimumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Angle.Minimum;
+ }
+ getNormalizationAngleMaximumValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Angle.Maximum;
+ }
+ getNormalizationAngleDefaultValue(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Normalization.Angle.Default;
+ }
+ getInputCount(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input.length;
+ }
+ getInputWeight(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Weight;
+ }
+ getInputReflect(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Reflect;
+ }
+ getInputType(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Type;
+ }
+ getInputSourceId(physicsSettingIndex, inputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Input[inputIndex].Source.Id;
+ }
+ getOutputCount(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output.length;
+ }
+ getOutputVertexIndex(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].VertexIndex;
+ }
+ getOutputAngleScale(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Scale;
+ }
+ getOutputWeight(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Weight;
+ }
+ getOutputDestinationId(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Destination.Id;
+ }
+ getOutputType(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Type;
+ }
+ getOutputReflect(physicsSettingIndex, outputIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Output[outputIndex].Reflect;
+ }
+ getParticleCount(physicsSettingIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices.length;
+ }
+ getParticleMobility(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Mobility;
+ }
+ getParticleDelay(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Delay;
+ }
+ getParticleAcceleration(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Acceleration;
+ }
+ getParticleRadius(physicsSettingIndex, vertexIndex) {
+ return this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Radius;
+ }
+ getParticlePosition(physicsSettingIndex, vertexIndex) {
+ const ret = new CubismVector2(0, 0);
+ ret.x = this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Position.X;
+ ret.y = this._json.PhysicsSettings[physicsSettingIndex].Vertices[vertexIndex].Position.Y;
+ return ret;
+ }
+ }
+ const PhysicsTypeTagX = "X";
+ const PhysicsTypeTagY = "Y";
+ const PhysicsTypeTagAngle = "Angle";
+ const AirResistance = 5;
+ const MaximumWeight = 100;
+ const MovementThreshold = 1e-3;
+ const MaxDeltaTime = 5;
+ class CubismPhysics {
+ static create(json) {
+ const ret = new CubismPhysics();
+ ret.parse(json);
+ ret._physicsRig.gravity.y = 0;
+ return ret;
+ }
+ static delete(physics) {
+ if (physics != null) {
+ physics.release();
+ }
+ }
+ parse(physicsJson) {
+ this._physicsRig = new CubismPhysicsRig();
+ const json = new CubismPhysicsJson(physicsJson);
+ this._physicsRig.gravity = json.getGravity();
+ this._physicsRig.wind = json.getWind();
+ this._physicsRig.subRigCount = json.getSubRigCount();
+ this._physicsRig.fps = json.getFps();
+ this._currentRigOutputs = [];
+ this._previousRigOutputs = [];
+ let inputIndex = 0, outputIndex = 0, particleIndex = 0;
+ for (let i = 0; i < this._physicsRig.subRigCount; ++i) {
+ const setting = new CubismPhysicsSubRig();
+ setting.normalizationPosition.minimum = json.getNormalizationPositionMinimumValue(i);
+ setting.normalizationPosition.maximum = json.getNormalizationPositionMaximumValue(i);
+ setting.normalizationPosition.defalut = json.getNormalizationPositionDefaultValue(i);
+ setting.normalizationAngle.minimum = json.getNormalizationAngleMinimumValue(i);
+ setting.normalizationAngle.maximum = json.getNormalizationAngleMaximumValue(i);
+ setting.normalizationAngle.defalut = json.getNormalizationAngleDefaultValue(i);
+ setting.inputCount = json.getInputCount(i);
+ setting.baseInputIndex = inputIndex;
+ inputIndex += setting.inputCount;
+ for (let j = 0; j < setting.inputCount; ++j) {
+ const input = new CubismPhysicsInput();
+ input.sourceParameterIndex = -1;
+ input.weight = json.getInputWeight(i, j);
+ input.reflect = json.getInputReflect(i, j);
+ switch (json.getInputType(i, j)) {
+ case PhysicsTypeTagX:
+ input.type = CubismPhysicsSource.CubismPhysicsSource_X;
+ input.getNormalizedParameterValue = getInputTranslationXFromNormalizedParameterValue;
+ break;
+ case PhysicsTypeTagY:
+ input.type = CubismPhysicsSource.CubismPhysicsSource_Y;
+ input.getNormalizedParameterValue = getInputTranslationYFromNormalizedParamterValue;
+ break;
+ case PhysicsTypeTagAngle:
+ input.type = CubismPhysicsSource.CubismPhysicsSource_Angle;
+ input.getNormalizedParameterValue = getInputAngleFromNormalizedParameterValue;
+ break;
+ }
+ input.source.targetType = CubismPhysicsTargetType.CubismPhysicsTargetType_Parameter;
+ input.source.id = json.getInputSourceId(i, j);
+ this._physicsRig.inputs.push(input);
+ }
+ setting.outputCount = json.getOutputCount(i);
+ setting.baseOutputIndex = outputIndex;
+ const currentRigOutput = new PhysicsOutput();
+ const previousRigOutput = new PhysicsOutput();
+ for (let j = 0; j < setting.outputCount; ++j) {
+ currentRigOutput.outputs[j] = 0;
+ previousRigOutput.outputs[j] = 0;
+ let output = this._physicsRig.outputs[outputIndex + j];
+ if (!output) {
+ output = new CubismPhysicsOutput();
+ this._physicsRig.outputs[outputIndex + j] = output;
+ }
+ output.destinationParameterIndex = -1;
+ output.vertexIndex = json.getOutputVertexIndex(i, j);
+ output.angleScale = json.getOutputAngleScale(i, j);
+ output.weight = json.getOutputWeight(i, j);
+ output.destination.targetType = CubismPhysicsTargetType.CubismPhysicsTargetType_Parameter;
+ output.destination.id = json.getOutputDestinationId(i, j);
+ switch (json.getOutputType(i, j)) {
+ case PhysicsTypeTagX:
+ output.type = CubismPhysicsSource.CubismPhysicsSource_X;
+ output.getValue = getOutputTranslationX;
+ output.getScale = getOutputScaleTranslationX;
+ break;
+ case PhysicsTypeTagY:
+ output.type = CubismPhysicsSource.CubismPhysicsSource_Y;
+ output.getValue = getOutputTranslationY;
+ output.getScale = getOutputScaleTranslationY;
+ break;
+ case PhysicsTypeTagAngle:
+ output.type = CubismPhysicsSource.CubismPhysicsSource_Angle;
+ output.getValue = getOutputAngle;
+ output.getScale = getOutputScaleAngle;
+ break;
+ }
+ output.reflect = json.getOutputReflect(i, j);
+ }
+ this._currentRigOutputs.push(currentRigOutput);
+ this._previousRigOutputs.push(previousRigOutput);
+ outputIndex += setting.outputCount;
+ setting.particleCount = json.getParticleCount(i);
+ setting.baseParticleIndex = particleIndex;
+ particleIndex += setting.particleCount;
+ for (let j = 0; j < setting.particleCount; ++j) {
+ const particle = new CubismPhysicsParticle();
+ particle.mobility = json.getParticleMobility(i, j);
+ particle.delay = json.getParticleDelay(i, j);
+ particle.acceleration = json.getParticleAcceleration(i, j);
+ particle.radius = json.getParticleRadius(i, j);
+ particle.position = json.getParticlePosition(i, j);
+ this._physicsRig.particles.push(particle);
+ }
+ this._physicsRig.settings.push(setting);
+ }
+ this.initialize();
+ json.release();
+ }
+ stabilization(model) {
+ var _a, _b, _c, _d;
+ let totalAngle;
+ let weight;
+ let radAngle;
+ let outputValue;
+ const totalTranslation = new CubismVector2();
+ let currentSetting;
+ let currentInputs;
+ let currentOutputs;
+ let currentParticles;
+ let parameterValues;
+ let parameterMaximumValues;
+ let parameterMinimumValues;
+ let parameterDefaultValues;
+ parameterValues = model.getModel().parameters.values;
+ parameterMaximumValues = model.getModel().parameters.maximumValues;
+ parameterMinimumValues = model.getModel().parameters.minimumValues;
+ parameterDefaultValues = model.getModel().parameters.defaultValues;
+ if (((_b = (_a = this._parameterCaches) == null ? void 0 : _a.length) != null ? _b : 0) < model.getParameterCount()) {
+ this._parameterCaches = new Float32Array(model.getParameterCount());
+ }
+ if (((_d = (_c = this._parameterInputCaches) == null ? void 0 : _c.length) != null ? _d : 0) < model.getParameterCount()) {
+ this._parameterInputCaches = new Float32Array(model.getParameterCount());
+ }
+ for (let j = 0; j < model.getParameterCount(); ++j) {
+ this._parameterCaches[j] = parameterValues[j];
+ this._parameterInputCaches[j] = parameterValues[j];
+ }
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ totalAngle = { angle: 0 };
+ totalTranslation.x = 0;
+ totalTranslation.y = 0;
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentInputs = this._physicsRig.inputs.slice(currentSetting.baseInputIndex);
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ currentParticles = this._physicsRig.particles.slice(currentSetting.baseParticleIndex);
+ for (let i = 0; i < currentSetting.inputCount; ++i) {
+ weight = currentInputs[i].weight / MaximumWeight;
+ if (currentInputs[i].sourceParameterIndex == -1) {
+ currentInputs[i].sourceParameterIndex = model.getParameterIndex(currentInputs[i].source.id);
+ }
+ currentInputs[i].getNormalizedParameterValue(totalTranslation, totalAngle, parameterValues[currentInputs[i].sourceParameterIndex], parameterMinimumValues[currentInputs[i].sourceParameterIndex], parameterMaximumValues[currentInputs[i].sourceParameterIndex], parameterDefaultValues[currentInputs[i].sourceParameterIndex], currentSetting.normalizationPosition, currentSetting.normalizationAngle, currentInputs[i].reflect, weight);
+ this._parameterCaches[currentInputs[i].sourceParameterIndex] = parameterValues[currentInputs[i].sourceParameterIndex];
+ }
+ radAngle = CubismMath.degreesToRadian(-totalAngle.angle);
+ totalTranslation.x = totalTranslation.x * CubismMath.cos(radAngle) - totalTranslation.y * CubismMath.sin(radAngle);
+ totalTranslation.y = totalTranslation.x * CubismMath.sin(radAngle) + totalTranslation.y * CubismMath.cos(radAngle);
+ updateParticlesForStabilization(currentParticles, currentSetting.particleCount, totalTranslation, totalAngle.angle, this._options.wind, MovementThreshold * currentSetting.normalizationPosition.maximum);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ const particleIndex = currentOutputs[i].vertexIndex;
+ if (currentOutputs[i].destinationParameterIndex == -1) {
+ currentOutputs[i].destinationParameterIndex = model.getParameterIndex(currentOutputs[i].destination.id);
+ }
+ if (particleIndex < 1 || particleIndex >= currentSetting.particleCount) {
+ continue;
+ }
+ let translation = new CubismVector2();
+ translation = currentParticles[particleIndex].position.substract(currentParticles[particleIndex - 1].position);
+ outputValue = currentOutputs[i].getValue(translation, currentParticles, particleIndex, currentOutputs[i].reflect, this._options.gravity);
+ this._currentRigOutputs[settingIndex].outputs[i] = outputValue;
+ this._previousRigOutputs[settingIndex].outputs[i] = outputValue;
+ const destinationParameterIndex = currentOutputs[i].destinationParameterIndex;
+ const outParameterCaches = !Float32Array.prototype.slice && "subarray" in Float32Array.prototype ? JSON.parse(JSON.stringify(parameterValues.subarray(destinationParameterIndex))) : parameterValues.slice(destinationParameterIndex);
+ updateOutputParameterValue(outParameterCaches, parameterMinimumValues[destinationParameterIndex], parameterMaximumValues[destinationParameterIndex], outputValue, currentOutputs[i]);
+ for (let offset = destinationParameterIndex, outParamIndex = 0; offset < this._parameterCaches.length; offset++, outParamIndex++) {
+ parameterValues[offset] = this._parameterCaches[offset] = outParameterCaches[outParamIndex];
+ }
+ }
+ }
+ }
+ evaluate(model, deltaTimeSeconds) {
+ var _a, _b, _c, _d;
+ let totalAngle;
+ let weight;
+ let radAngle;
+ let outputValue;
+ const totalTranslation = new CubismVector2();
+ let currentSetting;
+ let currentInputs;
+ let currentOutputs;
+ let currentParticles;
+ if (0 >= deltaTimeSeconds) {
+ return;
+ }
+ let parameterValues;
+ let parameterMaximumValues;
+ let parameterMinimumValues;
+ let parameterDefaultValues;
+ let physicsDeltaTime;
+ this._currentRemainTime += deltaTimeSeconds;
+ if (this._currentRemainTime > MaxDeltaTime) {
+ this._currentRemainTime = 0;
+ }
+ parameterValues = model.getModel().parameters.values;
+ parameterMaximumValues = model.getModel().parameters.maximumValues;
+ parameterMinimumValues = model.getModel().parameters.minimumValues;
+ parameterDefaultValues = model.getModel().parameters.defaultValues;
+ if (((_b = (_a = this._parameterCaches) == null ? void 0 : _a.length) != null ? _b : 0) < model.getParameterCount()) {
+ this._parameterCaches = new Float32Array(model.getParameterCount());
+ }
+ if (((_d = (_c = this._parameterInputCaches) == null ? void 0 : _c.length) != null ? _d : 0) < model.getParameterCount()) {
+ this._parameterInputCaches = new Float32Array(model.getParameterCount());
+ for (let j = 0; j < model.getParameterCount(); ++j) {
+ this._parameterInputCaches[j] = parameterValues[j];
+ }
+ }
+ if (this._physicsRig.fps > 0) {
+ physicsDeltaTime = 1 / this._physicsRig.fps;
+ } else {
+ physicsDeltaTime = deltaTimeSeconds;
+ }
+ while (this._currentRemainTime >= physicsDeltaTime) {
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ this._previousRigOutputs[settingIndex].outputs[i] = this._currentRigOutputs[settingIndex].outputs[i];
+ }
+ }
+ const inputWeight = physicsDeltaTime / this._currentRemainTime;
+ for (let j = 0; j < model.getParameterCount(); ++j) {
+ this._parameterCaches[j] = this._parameterInputCaches[j] * (1 - inputWeight) + parameterValues[j] * inputWeight;
+ this._parameterInputCaches[j] = this._parameterCaches[j];
+ }
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ totalAngle = { angle: 0 };
+ totalTranslation.x = 0;
+ totalTranslation.y = 0;
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentInputs = this._physicsRig.inputs.slice(currentSetting.baseInputIndex);
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ currentParticles = this._physicsRig.particles.slice(currentSetting.baseParticleIndex);
+ for (let i = 0; i < currentSetting.inputCount; ++i) {
+ weight = currentInputs[i].weight / MaximumWeight;
+ if (currentInputs[i].sourceParameterIndex == -1) {
+ currentInputs[i].sourceParameterIndex = model.getParameterIndex(currentInputs[i].source.id);
+ }
+ currentInputs[i].getNormalizedParameterValue(totalTranslation, totalAngle, this._parameterCaches[currentInputs[i].sourceParameterIndex], parameterMinimumValues[currentInputs[i].sourceParameterIndex], parameterMaximumValues[currentInputs[i].sourceParameterIndex], parameterDefaultValues[currentInputs[i].sourceParameterIndex], currentSetting.normalizationPosition, currentSetting.normalizationAngle, currentInputs[i].reflect, weight);
+ }
+ radAngle = CubismMath.degreesToRadian(-totalAngle.angle);
+ totalTranslation.x = totalTranslation.x * CubismMath.cos(radAngle) - totalTranslation.y * CubismMath.sin(radAngle);
+ totalTranslation.y = totalTranslation.x * CubismMath.sin(radAngle) + totalTranslation.y * CubismMath.cos(radAngle);
+ updateParticles(currentParticles, currentSetting.particleCount, totalTranslation, totalAngle.angle, this._options.wind, MovementThreshold * currentSetting.normalizationPosition.maximum, physicsDeltaTime, AirResistance);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ const particleIndex = currentOutputs[i].vertexIndex;
+ if (currentOutputs[i].destinationParameterIndex == -1) {
+ currentOutputs[i].destinationParameterIndex = model.getParameterIndex(currentOutputs[i].destination.id);
+ }
+ if (particleIndex < 1 || particleIndex >= currentSetting.particleCount) {
+ continue;
+ }
+ const translation = new CubismVector2();
+ translation.x = currentParticles[particleIndex].position.x - currentParticles[particleIndex - 1].position.x;
+ translation.y = currentParticles[particleIndex].position.y - currentParticles[particleIndex - 1].position.y;
+ outputValue = currentOutputs[i].getValue(translation, currentParticles, particleIndex, currentOutputs[i].reflect, this._options.gravity);
+ this._currentRigOutputs[settingIndex].outputs[i] = outputValue;
+ const destinationParameterIndex = currentOutputs[i].destinationParameterIndex;
+ const outParameterCaches = !Float32Array.prototype.slice && "subarray" in Float32Array.prototype ? JSON.parse(JSON.stringify(this._parameterCaches.subarray(destinationParameterIndex))) : this._parameterCaches.slice(destinationParameterIndex);
+ updateOutputParameterValue(outParameterCaches, parameterMinimumValues[destinationParameterIndex], parameterMaximumValues[destinationParameterIndex], outputValue, currentOutputs[i]);
+ for (let offset = destinationParameterIndex, outParamIndex = 0; offset < this._parameterCaches.length; offset++, outParamIndex++) {
+ this._parameterCaches[offset] = outParameterCaches[outParamIndex];
+ }
+ }
+ }
+ this._currentRemainTime -= physicsDeltaTime;
+ }
+ const alpha = this._currentRemainTime / physicsDeltaTime;
+ this.interpolate(model, alpha);
+ }
+ interpolate(model, weight) {
+ let currentOutputs;
+ let currentSetting;
+ let parameterValues;
+ let parameterMaximumValues;
+ let parameterMinimumValues;
+ parameterValues = model.getModel().parameters.values;
+ parameterMaximumValues = model.getModel().parameters.maximumValues;
+ parameterMinimumValues = model.getModel().parameters.minimumValues;
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ currentSetting = this._physicsRig.settings[settingIndex];
+ currentOutputs = this._physicsRig.outputs.slice(currentSetting.baseOutputIndex);
+ for (let i = 0; i < currentSetting.outputCount; ++i) {
+ if (currentOutputs[i].destinationParameterIndex == -1) {
+ continue;
+ }
+ const destinationParameterIndex = currentOutputs[i].destinationParameterIndex;
+ const outParameterValues = !Float32Array.prototype.slice && "subarray" in Float32Array.prototype ? JSON.parse(JSON.stringify(parameterValues.subarray(destinationParameterIndex))) : parameterValues.slice(destinationParameterIndex);
+ updateOutputParameterValue(outParameterValues, parameterMinimumValues[destinationParameterIndex], parameterMaximumValues[destinationParameterIndex], this._previousRigOutputs[settingIndex].outputs[i] * (1 - weight) + this._currentRigOutputs[settingIndex].outputs[i] * weight, currentOutputs[i]);
+ for (let offset = destinationParameterIndex, outParamIndex = 0; offset < parameterValues.length; offset++, outParamIndex++) {
+ parameterValues[offset] = outParameterValues[outParamIndex];
+ }
+ }
+ }
+ }
+ setOptions(options) {
+ this._options = options;
+ }
+ getOption() {
+ return this._options;
+ }
+ constructor() {
+ this._options = new Options();
+ this._options.gravity.y = -1;
+ this._options.gravity.x = 0;
+ this._options.wind.x = 0;
+ this._options.wind.y = 0;
+ this._currentRigOutputs = [];
+ this._previousRigOutputs = [];
+ this._currentRemainTime = 0;
+ }
+ release() {
+ this._physicsRig = void 0;
+ }
+ initialize() {
+ let strand;
+ let currentSetting;
+ let radius;
+ for (let settingIndex = 0; settingIndex < this._physicsRig.subRigCount; ++settingIndex) {
+ currentSetting = this._physicsRig.settings[settingIndex];
+ strand = this._physicsRig.particles.slice(currentSetting.baseParticleIndex);
+ strand[0].initialPosition = new CubismVector2(0, 0);
+ strand[0].lastPosition = new CubismVector2(strand[0].initialPosition.x, strand[0].initialPosition.y);
+ strand[0].lastGravity = new CubismVector2(0, -1);
+ strand[0].lastGravity.y *= -1;
+ strand[0].velocity = new CubismVector2(0, 0);
+ strand[0].force = new CubismVector2(0, 0);
+ for (let i = 1; i < currentSetting.particleCount; ++i) {
+ radius = new CubismVector2(0, 0);
+ radius.y = strand[i].radius;
+ strand[i].initialPosition = new CubismVector2(strand[i - 1].initialPosition.x + radius.x, strand[i - 1].initialPosition.y + radius.y);
+ strand[i].position = new CubismVector2(strand[i].initialPosition.x, strand[i].initialPosition.y);
+ strand[i].lastPosition = new CubismVector2(strand[i].initialPosition.x, strand[i].initialPosition.y);
+ strand[i].lastGravity = new CubismVector2(0, -1);
+ strand[i].lastGravity.y *= -1;
+ strand[i].velocity = new CubismVector2(0, 0);
+ strand[i].force = new CubismVector2(0, 0);
+ }
+ }
+ }
+ }
+ class Options {
+ constructor() {
+ this.gravity = new CubismVector2(0, 0);
+ this.wind = new CubismVector2(0, 0);
+ }
+ }
+ class PhysicsOutput {
+ constructor() {
+ this.outputs = [];
+ }
+ }
+ function getInputTranslationXFromNormalizedParameterValue(targetTranslation, targetAngle, value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition, normalizationAngle, isInverted, weight) {
+ targetTranslation.x += normalizeParameterValue(value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition.minimum, normalizationPosition.maximum, normalizationPosition.defalut, isInverted) * weight;
+ }
+ function getInputTranslationYFromNormalizedParamterValue(targetTranslation, targetAngle, value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition, normalizationAngle, isInverted, weight) {
+ targetTranslation.y += normalizeParameterValue(value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationPosition.minimum, normalizationPosition.maximum, normalizationPosition.defalut, isInverted) * weight;
+ }
+ function getInputAngleFromNormalizedParameterValue(targetTranslation, targetAngle, value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizaitionPosition, normalizationAngle, isInverted, weight) {
+ targetAngle.angle += normalizeParameterValue(value, parameterMinimumValue, parameterMaximumValue, parameterDefaultValue, normalizationAngle.minimum, normalizationAngle.maximum, normalizationAngle.defalut, isInverted) * weight;
+ }
+ function getOutputTranslationX(translation, particles, particleIndex, isInverted, parentGravity) {
+ let outputValue = translation.x;
+ if (isInverted) {
+ outputValue *= -1;
+ }
+ return outputValue;
+ }
+ function getOutputTranslationY(translation, particles, particleIndex, isInverted, parentGravity) {
+ let outputValue = translation.y;
+ if (isInverted) {
+ outputValue *= -1;
+ }
+ return outputValue;
+ }
+ function getOutputAngle(translation, particles, particleIndex, isInverted, parentGravity) {
+ let outputValue;
+ if (particleIndex >= 2) {
+ parentGravity = particles[particleIndex - 1].position.substract(particles[particleIndex - 2].position);
+ } else {
+ parentGravity = parentGravity.multiplyByScaler(-1);
+ }
+ outputValue = CubismMath.directionToRadian(parentGravity, translation);
+ if (isInverted) {
+ outputValue *= -1;
+ }
+ return outputValue;
+ }
+ function getRangeValue(min, max) {
+ return Math.abs(Math.max(min, max) - Math.min(min, max));
+ }
+ function getDefaultValue(min, max) {
+ const minValue = Math.min(min, max);
+ return minValue + getRangeValue(min, max) / 2;
+ }
+ function getOutputScaleTranslationX(translationScale, angleScale) {
+ return translationScale.x;
+ }
+ function getOutputScaleTranslationY(translationScale, angleScale) {
+ return translationScale.y;
+ }
+ function getOutputScaleAngle(translationScale, angleScale) {
+ return angleScale;
+ }
+ function updateParticles(strand, strandCount, totalTranslation, totalAngle, windDirection, thresholdValue, deltaTimeSeconds, airResistance) {
+ let totalRadian;
+ let delay;
+ let radian;
+ let currentGravity;
+ let direction = new CubismVector2(0, 0);
+ let velocity = new CubismVector2(0, 0);
+ let force = new CubismVector2(0, 0);
+ let newDirection = new CubismVector2(0, 0);
+ strand[0].position = new CubismVector2(totalTranslation.x, totalTranslation.y);
+ totalRadian = CubismMath.degreesToRadian(totalAngle);
+ currentGravity = CubismMath.radianToDirection(totalRadian);
+ currentGravity.normalize();
+ for (let i = 1; i < strandCount; ++i) {
+ strand[i].force = currentGravity.multiplyByScaler(strand[i].acceleration).add(windDirection);
+ strand[i].lastPosition = new CubismVector2(strand[i].position.x, strand[i].position.y);
+ delay = strand[i].delay * deltaTimeSeconds * 30;
+ direction = strand[i].position.substract(strand[i - 1].position);
+ radian = CubismMath.directionToRadian(strand[i].lastGravity, currentGravity) / airResistance;
+ direction.x = CubismMath.cos(radian) * direction.x - direction.y * CubismMath.sin(radian);
+ direction.y = CubismMath.sin(radian) * direction.x + direction.y * CubismMath.cos(radian);
+ strand[i].position = strand[i - 1].position.add(direction);
+ velocity = strand[i].velocity.multiplyByScaler(delay);
+ force = strand[i].force.multiplyByScaler(delay).multiplyByScaler(delay);
+ strand[i].position = strand[i].position.add(velocity).add(force);
+ newDirection = strand[i].position.substract(strand[i - 1].position);
+ newDirection.normalize();
+ strand[i].position = strand[i - 1].position.add(newDirection.multiplyByScaler(strand[i].radius));
+ if (CubismMath.abs(strand[i].position.x) < thresholdValue) {
+ strand[i].position.x = 0;
+ }
+ if (delay != 0) {
+ strand[i].velocity = strand[i].position.substract(strand[i].lastPosition);
+ strand[i].velocity = strand[i].velocity.divisionByScalar(delay);
+ strand[i].velocity = strand[i].velocity.multiplyByScaler(strand[i].mobility);
+ }
+ strand[i].force = new CubismVector2(0, 0);
+ strand[i].lastGravity = new CubismVector2(currentGravity.x, currentGravity.y);
+ }
+ }
+ function updateParticlesForStabilization(strand, strandCount, totalTranslation, totalAngle, windDirection, thresholdValue) {
+ let totalRadian;
+ let currentGravity;
+ let force = new CubismVector2(0, 0);
+ strand[0].position = new CubismVector2(totalTranslation.x, totalTranslation.y);
+ totalRadian = CubismMath.degreesToRadian(totalAngle);
+ currentGravity = CubismMath.radianToDirection(totalRadian);
+ currentGravity.normalize();
+ for (let i = 1; i < strandCount; ++i) {
+ strand[i].force = currentGravity.multiplyByScaler(strand[i].acceleration).add(windDirection);
+ strand[i].lastPosition = new CubismVector2(strand[i].position.x, strand[i].position.y);
+ strand[i].velocity = new CubismVector2(0, 0);
+ force = strand[i].force;
+ force.normalize();
+ force = force.multiplyByScaler(strand[i].radius);
+ strand[i].position = strand[i - 1].position.add(force);
+ if (CubismMath.abs(strand[i].position.x) < thresholdValue) {
+ strand[i].position.x = 0;
+ }
+ strand[i].force = new CubismVector2(0, 0);
+ strand[i].lastGravity = new CubismVector2(currentGravity.x, currentGravity.y);
+ }
+ }
+ function updateOutputParameterValue(parameterValue, parameterValueMinimum, parameterValueMaximum, translation, output) {
+ let outputScale;
+ let value;
+ let weight;
+ outputScale = output.getScale(output.translationScale, output.angleScale);
+ value = translation * outputScale;
+ if (value < parameterValueMinimum) {
+ if (value < output.valueBelowMinimum) {
+ output.valueBelowMinimum = value;
+ }
+ value = parameterValueMinimum;
+ } else if (value > parameterValueMaximum) {
+ if (value > output.valueExceededMaximum) {
+ output.valueExceededMaximum = value;
+ }
+ value = parameterValueMaximum;
+ }
+ weight = output.weight / MaximumWeight;
+ if (weight >= 1) {
+ parameterValue[0] = value;
+ } else {
+ value = parameterValue[0] * (1 - weight) + value * weight;
+ parameterValue[0] = value;
+ }
+ }
+ function normalizeParameterValue(value, parameterMinimum, parameterMaximum, parameterDefault, normalizedMinimum, normalizedMaximum, normalizedDefault, isInverted) {
+ let result = 0;
+ const maxValue = CubismMath.max(parameterMaximum, parameterMinimum);
+ if (maxValue < value) {
+ value = maxValue;
+ }
+ const minValue = CubismMath.min(parameterMaximum, parameterMinimum);
+ if (minValue > value) {
+ value = minValue;
+ }
+ const minNormValue = CubismMath.min(normalizedMinimum, normalizedMaximum);
+ const maxNormValue = CubismMath.max(normalizedMinimum, normalizedMaximum);
+ const middleNormValue = normalizedDefault;
+ const middleValue = getDefaultValue(minValue, maxValue);
+ const paramValue = value - middleValue;
+ switch (Math.sign(paramValue)) {
+ case 1: {
+ const nLength = maxNormValue - middleNormValue;
+ const pLength = maxValue - middleValue;
+ if (pLength != 0) {
+ result = paramValue * (nLength / pLength);
+ result += middleNormValue;
+ }
+ break;
+ }
+ case -1: {
+ const nLength = minNormValue - middleNormValue;
+ const pLength = minValue - middleValue;
+ if (pLength != 0) {
+ result = paramValue * (nLength / pLength);
+ result += middleNormValue;
+ }
+ break;
+ }
+ case 0: {
+ result = middleNormValue;
+ break;
+ }
+ }
+ return isInverted ? result : result * -1;
+ }
+ Live2DFactory.registerRuntime({
+ version: 4,
+ ready: cubism4Ready,
+ test(source) {
+ return source instanceof Cubism4ModelSettings || Cubism4ModelSettings.isValidJSON(source);
+ },
+ isValidMoc(modelData) {
+ if (modelData.byteLength < 4) {
+ return false;
+ }
+ const view = new Int8Array(modelData, 0, 4);
+ return String.fromCharCode(...view) === "MOC3";
+ },
+ createModelSettings(json) {
+ return new Cubism4ModelSettings(json);
+ },
+ createCoreModel(data, options) {
+ const moc = CubismMoc.create(data, !!(options == null ? void 0 : options.checkMocConsistency));
+ try {
+ const model = moc.createModel();
+ model.__moc = moc;
+ return model;
+ } catch (e) {
+ try {
+ moc.release();
+ } catch (ignored) {
+ }
+ throw e;
+ }
+ },
+ createInternalModel(coreModel, settings, options) {
+ const model = new Cubism4InternalModel(coreModel, settings, options);
+ const coreModelWithMoc = coreModel;
+ if (coreModelWithMoc.__moc) {
+ model.__moc = coreModelWithMoc.__moc;
+ delete coreModelWithMoc.__moc;
+ model.once("destroy", releaseMoc);
+ }
+ return model;
+ },
+ createPhysics(coreModel, data) {
+ return CubismPhysics.create(data);
+ },
+ createPose(coreModel, data) {
+ return CubismPose.create(data);
+ }
+ });
+ function releaseMoc() {
+ var _a;
+ (_a = this.__moc) == null ? void 0 : _a.release();
+ }
+ exports2.Cubism2ExpressionManager = Cubism2ExpressionManager;
+ exports2.Cubism2InternalModel = Cubism2InternalModel;
+ exports2.Cubism2ModelSettings = Cubism2ModelSettings;
+ exports2.Cubism2MotionManager = Cubism2MotionManager;
+ exports2.Cubism4ExpressionManager = Cubism4ExpressionManager;
+ exports2.Cubism4InternalModel = Cubism4InternalModel;
+ exports2.Cubism4ModelSettings = Cubism4ModelSettings;
+ exports2.Cubism4MotionManager = Cubism4MotionManager;
+ exports2.ExpressionManager = ExpressionManager;
+ exports2.FileLoader = FileLoader;
+ exports2.FocusController = FocusController;
+ exports2.InteractionMixin = InteractionMixin;
+ exports2.InternalModel = InternalModel;
+ exports2.LOGICAL_HEIGHT = LOGICAL_HEIGHT;
+ exports2.LOGICAL_WIDTH = LOGICAL_WIDTH;
+ exports2.Live2DExpression = Live2DExpression;
+ exports2.Live2DEyeBlink = Live2DEyeBlink;
+ exports2.Live2DFactory = Live2DFactory;
+ exports2.Live2DLoader = Live2DLoader;
+ exports2.Live2DModel = Live2DModel;
+ exports2.Live2DPhysics = Live2DPhysics;
+ exports2.Live2DPose = Live2DPose;
+ exports2.Live2DTransform = Live2DTransform;
+ exports2.ModelSettings = ModelSettings;
+ exports2.MotionManager = MotionManager;
+ exports2.MotionPreloadStrategy = MotionPreloadStrategy;
+ exports2.MotionPriority = MotionPriority;
+ exports2.MotionState = MotionState;
+ exports2.SoundManager = SoundManager;
+ exports2.VERSION = VERSION;
+ exports2.XHRLoader = XHRLoader;
+ exports2.ZipLoader = ZipLoader;
+ exports2.applyMixins = applyMixins;
+ exports2.clamp = clamp;
+ exports2.copyArray = copyArray;
+ exports2.copyProperty = copyProperty;
+ exports2.cubism4Ready = cubism4Ready;
+ exports2.folderName = folderName;
+ exports2.logger = logger;
+ exports2.rand = rand;
+ exports2.remove = remove;
+ exports2.startUpCubism4 = startUpCubism4;
+ Object.defineProperties(exports2, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
+});
diff --git a/dist/index.min.js b/dist/index.min.js
new file mode 100644
index 00000000..72b430f8
--- /dev/null
+++ b/dist/index.min.js
@@ -0,0 +1 @@
+var __pow=Math.pow,__async=(t,e,i)=>new Promise(((s,r)=>{var o=t=>{try{n(i.next(t))}catch(e){r(e)}},a=t=>{try{n(i.throw(t))}catch(e){r(e)}},n=t=>t.done?s(t.value):Promise.resolve(t.value).then(o,a);n((i=i.apply(t,e)).next())}));!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@pixi/utils"),require("@pixi/math"),require("@pixi/core"),require("@pixi/display")):"function"==typeof define&&define.amd?define(["exports","@pixi/utils","@pixi/math","@pixi/core","@pixi/display"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).PIXI=t.PIXI||{},t.PIXI.live2d=t.PIXI.live2d||{}),t.PIXI.utils,t.PIXI,t.PIXI,t.PIXI)}(this,(function(t,e,i,s,r){"use strict";var o,a,n;(a=o||(o={})).supportMoreMaskDivisions=!0,a.setOpacityFromMotion=!1,t.config=void 0,(n=t.config||(t.config={})).LOG_LEVEL_VERBOSE=0,n.LOG_LEVEL_WARNING=1,n.LOG_LEVEL_ERROR=2,n.LOG_LEVEL_NONE=999,n.logLevel=n.LOG_LEVEL_WARNING,n.sound=!0,n.motionSync=!0,n.motionFadingDuration=500,n.idleMotionFadingDuration=2e3,n.expressionFadingDuration=500,n.preserveExpressionOnMotion=!0,n.cubism4=o;const l={log(e,...i){t.config.logLevel<=t.config.LOG_LEVEL_VERBOSE&&console.log(`[${e}]`,...i)},warn(e,...i){t.config.logLevel<=t.config.LOG_LEVEL_WARNING&&console.warn(`[${e}]`,...i)},error(e,...i){t.config.logLevel<=t.config.LOG_LEVEL_ERROR&&console.error(`[${e}]`,...i)}};function h(t,e,i){return ti?i:t}function u(t,e){return Math.random()*(e-t)+t}function d(t,e,i,s,r){const o=e[s];null!==o&&typeof o===t&&(i[r]=o)}function c(t,e,i,s,r){const o=e[s];Array.isArray(o)&&(i[r]=o.filter((e=>null!==e&&typeof e===t)))}function g(t,e){e.forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((i=>{"constructor"!==i&&Object.defineProperty(t.prototype,i,Object.getOwnPropertyDescriptor(e.prototype,i))}))}))}function m(t){let e=t.lastIndexOf("/");return-1!=e&&(t=t.slice(0,e)),e=t.lastIndexOf("/"),-1!==e&&(t=t.slice(e+1)),t}function p(t,e){const i=t.indexOf(e);-1!==i&&t.splice(i,1)}class _ extends e.EventEmitter{constructor(t,e){super(),this.expressions=[],this.reserveExpressionIndex=-1,this.destroyed=!1,this.settings=t,this.tag=`ExpressionManager(${t.name})`}init(){this.defaultExpression=this.createExpression({},void 0),this.currentExpression=this.defaultExpression,this.stopAllExpressions()}loadExpression(t){return __async(this,null,(function*(){if(!this.definitions[t])return void l.warn(this.tag,`Undefined expression at [${t}]`);if(null===this.expressions[t])return void l.warn(this.tag,`Cannot set expression at [${t}] because it's already failed in loading.`);if(this.expressions[t])return this.expressions[t];const e=yield this._loadExpression(t);return this.expressions[t]=e,e}))}_loadExpression(t){throw new Error("Not implemented.")}setRandomExpression(){return __async(this,null,(function*(){if(this.definitions.length){const t=[];for(let e=0;e-1&&tl&&(o*=l/n,a*=l/n),this.vx+=o,this.vy+=a;const h=Math.sqrt(__pow(this.vx,2)+__pow(this.vy,2)),u=.5*(Math.sqrt(__pow(l,2)+8*l*s)-l);h>u&&(this.vx*=u/h,this.vy*=u/h),this.x+=this.vx,this.y+=this.vy}}class x{constructor(t){this.json=t;let e=t.url;if("string"!=typeof e)throw new TypeError("The `url` field in settings JSON must be defined as a string.");this.url=e,this.name=m(this.url)}resolveURL(t){return e.url.resolve(this.url,t)}replaceFiles(t){this.moc=t(this.moc,"moc"),void 0!==this.pose&&(this.pose=t(this.pose,"pose")),void 0!==this.physics&&(this.physics=t(this.physics,"physics"));for(let e=0;e(t.push(e),e))),t}validateFiles(t){const e=(e,i)=>{const s=this.resolveURL(e);if(!t.includes(s)){if(i)throw new Error(`File "${e}" is defined in settings, but doesn't exist in given files`);return!1}return!0};[this.moc,...this.textures].forEach((t=>e(t,!0)));return this.getDefinedFiles().filter((t=>e(t,!1)))}}var y=(t=>(t[t.NONE=0]="NONE",t[t.IDLE=1]="IDLE",t[t.NORMAL=2]="NORMAL",t[t.FORCE=3]="FORCE",t))(y||{});class M{constructor(){this.debug=!1,this.currentPriority=0,this.reservePriority=0}reserve(t,e,i){if(i<=0)return l.log(this.tag,"Cannot start a motion with MotionPriority.NONE."),!1;if(t===this.currentGroup&&e===this.currentIndex)return l.log(this.tag,"Motion is already playing.",this.dump(t,e)),!1;if(t===this.reservedGroup&&e===this.reservedIndex||t===this.reservedIdleGroup&&e===this.reservedIdleIndex)return l.log(this.tag,"Motion is already reserved.",this.dump(t,e)),!1;if(1===i){if(0!==this.currentPriority)return l.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(t,e)),!1;if(void 0!==this.reservedIdleGroup)return l.log(this.tag,"Cannot start idle motion because another idle motion has reserved.",this.dump(t,e)),!1;this.setReservedIdle(t,e)}else{if(i<3){if(i<=this.currentPriority)return l.log(this.tag,"Cannot start motion because another motion is playing as an equivalent or higher priority.",this.dump(t,e)),!1;if(i<=this.reservePriority)return l.log(this.tag,"Cannot start motion because another motion has reserved as an equivalent or higher priority.",this.dump(t,e)),!1}this.setReserved(t,e,i)}return!0}start(t,e,i,s){if(1===s){if(this.setReservedIdle(void 0,void 0),0!==this.currentPriority)return l.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(e,i)),!1}else{if(e!==this.reservedGroup||i!==this.reservedIndex)return l.log(this.tag,"Cannot start motion because another motion has taken the place.",this.dump(e,i)),!1;this.setReserved(void 0,void 0,0)}return!!t&&(this.setCurrent(e,i,s),!0)}complete(){this.setCurrent(void 0,void 0,0)}setCurrent(t,e,i){this.currentPriority=i,this.currentGroup=t,this.currentIndex=e}setReserved(t,e,i){this.reservePriority=i,this.reservedGroup=t,this.reservedIndex=e}setReservedIdle(t,e){this.reservedIdleGroup=t,this.reservedIdleIndex=e}isActive(t,e){return t===this.currentGroup&&e===this.currentIndex||t===this.reservedGroup&&e===this.reservedIndex||t===this.reservedIdleGroup&&e===this.reservedIdleIndex}reset(){this.setCurrent(void 0,void 0,0),this.setReserved(void 0,void 0,0),this.setReservedIdle(void 0,void 0)}shouldRequestIdleMotion(){return void 0===this.currentGroup&&void 0===this.reservedIdleGroup}shouldOverrideExpression(){return!t.config.preserveExpressionOnMotion&&this.currentPriority>1}dump(t,e){if(this.debug){return`\n group = "${t}", index = ${e}\n`+["currentPriority","reservePriority","currentGroup","currentIndex","reservedGroup","reservedIndex","reservedIdleGroup","reservedIdleIndex"].map((t=>"["+t+"] "+this[t])).join("\n")}return""}}class C{static get volume(){return this._volume}static set volume(t){this._volume=(t>1?1:t<0?0:t)||0,this.audios.forEach((t=>t.volume=this._volume))}static add(t,e,i){const s=new Audio(t);return s.volume=this._volume,s.preload="auto",s.autoplay=!0,s.crossOrigin="anonymous",s.addEventListener("ended",(()=>{this.dispose(s),null==e||e()})),s.addEventListener("error",(e=>{this.dispose(s),l.warn("SoundManager",`Error occurred on "${t}"`,e.error),null==i||i(e.error)})),this.audios.push(s),s}static play(t){return new Promise(((e,i)=>{var s;null==(s=t.play())||s.catch((e=>{t.dispatchEvent(new ErrorEvent("error",{error:e})),i(e)})),t.readyState===t.HAVE_ENOUGH_DATA?e():t.addEventListener("canplaythrough",e)}))}static addContext(t){const e=new AudioContext;return this.contexts.push(e),e}static addAnalyzer(t,e){const i=e.createMediaElementSource(t),s=e.createAnalyser();return s.fftSize=256,s.minDecibels=-90,s.maxDecibels=-10,s.smoothingTimeConstant=.85,i.connect(s),s.connect(e.destination),this.analysers.push(s),s}static analyze(t){if(null!=t){let e=new Float32Array(t.fftSize),i=0;t.getFloatTimeDomainData(e);for(const t of e)i+=t*t;return parseFloat(Math.sqrt(i/e.length*20).toFixed(1))}return parseFloat(Math.random().toFixed(1))}static dispose(t){t.pause(),t.removeAttribute("src"),p(this.audios,t)}static destroy(){for(let t=this.contexts.length-1;t>=0;t--)this.contexts[t].close();for(let t=this.audios.length-1;t>=0;t--)this.dispose(this.audios[t])}}C.audios=[],C.analysers=[],C.contexts=[],C._volume=.9;var v=(t=>(t.ALL="ALL",t.IDLE="IDLE",t.NONE="NONE",t))(v||{});class P extends e.EventEmitter{constructor(t,e){super(),this.motionGroups={},this.state=new M,this.playing=!1,this.destroyed=!1,this.settings=t,this.tag=`MotionManager(${t.name})`,this.state.tag=this.tag}init(t){(null==t?void 0:t.idleMotionGroup)&&(this.groups.idle=t.idleMotionGroup),this.setupMotions(t),this.stopAllMotions()}setupMotions(t){for(const i of Object.keys(this.definitions))this.motionGroups[i]=[];let e;switch(null==t?void 0:t.motionPreload){case"NONE":return;case"ALL":e=Object.keys(this.definitions);break;default:e=[this.groups.idle]}for(const i of e)if(this.definitions[i])for(let t=0;t{s&&c.expressionManager&&c.expressionManager.resetExpression(),c.currentAudio=void 0}),(()=>{s&&c.expressionManager&&c.expressionManager.resetExpression(),c.currentAudio=void 0})),this.currentAudio=r;let t=1;void 0!==i&&(t=i),C.volume=t,a=C.addContext(this.currentAudio),this.currentContext=a,o=C.addAnalyzer(this.currentAudio,this.currentContext),this.currentAnalyzer=o}catch(g){l.warn(this.tag,"Failed to create audio",n,g)}if(r){const e=C.play(r).catch((t=>l.warn(this.tag,"Failed to play audio",r.src,t)));t.config.motionSync&&(yield e)}return this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),s&&this.expressionManager&&this.expressionManager.setExpression(s),this.playing=!0,!0}))}startMotion(e,i){return __async(this,arguments,(function*(e,i,s=y.NORMAL,r,o,a){var n;if(this.currentAudio&&!this.currentAudio.ended)return!1;if(!this.state.reserve(e,i,s))return!1;const h=null==(n=this.definitions[e])?void 0:n[i];if(!h)return!1;let u,d,c;if(this.currentAudio&&C.dispose(this.currentAudio),t.config.sound){const t=r&&r.startsWith("data:audio/wav;base64");if(r&&!t){var g=document.createElement("a");g.href=r,r=g.href}const e=r&&(r.startsWith("http")||r.startsWith("blob")),i=this.getSoundFile(h);let s=i;i&&(s=this.settings.resolveURL(i)+"?cache-buster="+(new Date).getTime()),(e||t)&&(s=r);const n=this;if(s)try{u=C.add(s,(()=>{a&&n.expressionManager&&n.expressionManager.resetExpression(),n.currentAudio=void 0}),(()=>{a&&n.expressionManager&&n.expressionManager.resetExpression(),n.currentAudio=void 0})),this.currentAudio=u;let t=1;void 0!==o&&(t=o),C.volume=t,c=C.addContext(this.currentAudio),this.currentContext=c,d=C.addAnalyzer(this.currentAudio,this.currentContext),this.currentAnalyzer=d}catch(p){l.warn(this.tag,"Failed to create audio",i,p)}}const m=yield this.loadMotion(e,i);if(u){s=3;const e=C.play(u).catch((t=>l.warn(this.tag,"Failed to play audio",u.src,t)));t.config.motionSync&&(yield e)}return this.state.start(m,e,i,s)?(this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),l.log(this.tag,"Start motion:",this.getMotionName(h)),this.emit("motionStart",e,i,u),a&&this.expressionManager&&this.expressionManager.setExpression(a),this.playing=!0,this._startMotion(m),!0):(u&&(C.dispose(u),this.currentAudio=void 0),!1)}))}startRandomMotion(t,e,i,s){return __async(this,null,(function*(){const r=this.definitions[t];if(null==r?void 0:r.length){const o=[];for(let e=0;et.index>=0));for(const e of t)this.hitAreas[e.name]=e}hitTest(t,e){return Object.keys(this.hitAreas).filter((i=>this.isHit(i,t,e)))}isHit(t,e,i){if(!this.hitAreas[t])return!1;const s=this.hitAreas[t].index,r=this.getDrawableBounds(s,b);return r.x<=e&&e<=r.x+r.width&&r.y<=i&&i<=r.y+r.height}getDrawableBounds(t,e){const i=this.getDrawableVertices(t);let s=i[0],r=i[0],o=i[1],a=i[1];for(let n=0;n{200!==o.status&&0!==o.status||!o.response?o.onerror():s(o.response)},o.onerror=()=>{l.warn("XHRLoader",`Failed to load resource as ${o.responseType} (Status ${o.status}): ${e}`),r(new w("Network error.",e,o.status))},o.onabort=()=>r(new w("Aborted.",e,o.status,!0)),o.onloadend=()=>{var e;I.allXhrSet.delete(o),t&&(null==(e=I.xhrMap.get(t))||e.delete(o))},o}static cancelXHRs(){var t;null==(t=I.xhrMap.get(this))||t.forEach((t=>{t.abort(),I.allXhrSet.delete(t)})),I.xhrMap.delete(this)}static release(){I.allXhrSet.forEach((t=>t.abort())),I.allXhrSet.clear(),I.xhrMap=new WeakMap}};let T=I;function E(t,e){let i=-1;return function s(r,o){if(o)return Promise.reject(o);if(r<=i)return Promise.reject(new Error("next() called multiple times"));i=r;const a=t[r];if(!a)return Promise.resolve();try{return Promise.resolve(a(e,s.bind(null,r+1)))}catch(n){return Promise.reject(n)}}(0)}T.xhrMap=new WeakMap,T.allXhrSet=new Set,T.loader=(t,e)=>new Promise(((e,i)=>{I.createXHR(t.target,t.settings?t.settings.resolveURL(t.url):t.url,t.type,(i=>{t.result=i,e()}),i).send()}));class L{static load(t){return E(this.middlewares,t).then((()=>t.result))}}L.middlewares=[T.loader];const F="Live2DFactory",A=(t,e)=>__async(this,null,(function*(){if("string"==typeof t.source){const e=yield L.load({url:t.source,type:"json",target:t.live2dModel});e.url=t.source,t.source=e,t.live2dModel.emit("settingsJSONLoaded",e)}return e()})),D=(t,e)=>__async(this,null,(function*(){if(t.source instanceof x)return t.settings=t.source,e();if("object"==typeof t.source){const i=V.findRuntime(t.source);if(i){const s=i.createModelSettings(t.source);return t.settings=s,t.live2dModel.emit("settingsLoaded",s),e()}}throw new TypeError("Unknown settings format.")})),R=(t,e)=>{if(t.settings){const i=V.findRuntime(t.settings);if(i)return i.ready().then(e)}return e()},B=(t,e)=>__async(this,null,(function*(){yield e();const i=t.internalModel;if(i){const e=t.settings,s=V.findRuntime(e);if(s){const r=[];e.pose&&r.push(L.load({settings:e,url:e.pose,type:"json",target:i}).then((e=>{i.pose=s.createPose(i.coreModel,e),t.live2dModel.emit("poseLoaded",i.pose)})).catch((e=>{t.live2dModel.emit("poseLoadError",e),l.warn(F,"Failed to load pose.",e)}))),e.physics&&r.push(L.load({settings:e,url:e.physics,type:"json",target:i}).then((e=>{i.physics=s.createPhysics(i.coreModel,e),t.live2dModel.emit("physicsLoaded",i.physics)})).catch((e=>{t.live2dModel.emit("physicsLoadError",e),l.warn(F,"Failed to load physics.",e)}))),r.length&&(yield Promise.all(r))}}})),O=(t,e)=>__async(this,null,(function*(){if(!t.settings)throw new TypeError("Missing settings.");{const i=t.live2dModel,r=t.settings.textures.map((e=>function(t,e={}){const i={resourceOptions:{crossorigin:e.crossOrigin}};if(s.Texture.fromURL)return s.Texture.fromURL(t,i).catch((t=>{if(t instanceof Error)throw t;const e=new Error("Texture loading error");throw e.event=t,e}));i.resourceOptions.autoLoad=!1;const r=s.Texture.from(t,i);if(r.baseTexture.valid)return Promise.resolve(r);const o=r.baseTexture.resource;return null!=o._live2d_load||(o._live2d_load=new Promise(((t,e)=>{const i=t=>{o.source.removeEventListener("error",i);const s=new Error("Texture loading error");s.event=t,e(s)};o.source.addEventListener("error",i),o.load().then((()=>t(r))).catch(i)}))),o._live2d_load}(t.settings.resolveURL(e),{crossOrigin:t.options.crossOrigin})));if(yield e(),!t.internalModel)throw new TypeError("Missing internal model.");i.internalModel=t.internalModel,i.emit("modelLoaded",t.internalModel),i.textures=yield Promise.all(r),i.emit("textureLoaded",i.textures)}})),k=(t,e)=>__async(this,null,(function*(){const i=t.settings;if(i instanceof x){const s=V.findRuntime(i);if(!s)throw new TypeError("Unknown model settings.");const r=yield L.load({settings:i,url:i.moc,type:"arraybuffer",target:t.live2dModel});if(!s.isValidMoc(r))throw new Error("Invalid moc data");const o=s.createCoreModel(r);return t.internalModel=s.createInternalModel(o,i,t.options),e()}throw new TypeError("Missing settings.")})),U=class{static registerRuntime(t){U.runtimes.push(t),U.runtimes.sort(((t,e)=>e.version-t.version))}static findRuntime(t){for(const e of U.runtimes)if(e.test(t))return e}static setupLive2DModel(t,e,i){return __async(this,null,(function*(){const s=new Promise((e=>t.once("textureLoaded",e))),r=new Promise((e=>t.once("modelLoaded",e))),o=Promise.all([s,r]).then((()=>t.emit("ready")));yield E(U.live2DModelMiddlewares,{live2dModel:t,source:e,options:i||{}}),yield o,t.emit("load")}))}static loadMotion(t,e,i){var s;const r=s=>t.emit("motionLoadError",e,i,s);try{const o=null==(s=t.definitions[e])?void 0:s[i];if(!o)return Promise.resolve(void 0);t.listeners("destroy").includes(U.releaseTasks)||t.once("destroy",U.releaseTasks);let a=U.motionTasksMap.get(t);a||(a={},U.motionTasksMap.set(t,a));let n=a[e];n||(n=[],a[e]=n);const h=t.getMotionFile(o);return null!=n[i]||(n[i]=L.load({url:h,settings:t.settings,type:t.motionDataType,target:t}).then((s=>{var r;const a=null==(r=U.motionTasksMap.get(t))?void 0:r[e];a&&delete a[i];const n=t.createMotion(s,e,o);return t.emit("motionLoaded",e,i,n),n})).catch((e=>{l.warn(t.tag,`Failed to load motion: ${h}\n`,e),r(e)}))),n[i]}catch(o){l.warn(t.tag,`Failed to load motion at "${e}"[${i}]\n`,o),r(o)}return Promise.resolve(void 0)}static loadExpression(t,e){const i=i=>t.emit("expressionLoadError",e,i);try{const s=t.definitions[e];if(!s)return Promise.resolve(void 0);t.listeners("destroy").includes(U.releaseTasks)||t.once("destroy",U.releaseTasks);let r=U.expressionTasksMap.get(t);r||(r=[],U.expressionTasksMap.set(t,r));const o=t.getExpressionFile(s);return null!=r[e]||(r[e]=L.load({url:o,settings:t.settings,type:"json",target:t}).then((i=>{const r=U.expressionTasksMap.get(t);r&&delete r[e];const o=t.createExpression(i,s);return t.emit("expressionLoaded",e,o),o})).catch((e=>{l.warn(t.tag,`Failed to load expression: ${o}\n`,e),i(e)}))),r[e]}catch(s){l.warn(t.tag,`Failed to load expression at [${e}]\n`,s),i(s)}return Promise.resolve(void 0)}static releaseTasks(){this instanceof P?U.motionTasksMap.delete(this):U.expressionTasksMap.delete(this)}};let V=U;V.runtimes=[],V.urlToJSON=A,V.jsonToSettings=D,V.waitUntilReady=R,V.setupOptionals=B,V.setupEssentials=O,V.createInternalModel=k,V.live2DModelMiddlewares=[A,D,R,B,O,k],V.motionTasksMap=new WeakMap,V.expressionTasksMap=new WeakMap,P.prototype._loadMotion=function(t,e){return V.loadMotion(this,t,e)},_.prototype._loadExpression=function(t){return V.loadExpression(this,t)};class N{constructor(){this._autoInteract=!1}get autoInteract(){return this._autoInteract}set autoInteract(t){t!==this._autoInteract&&(t?this.on("pointertap",G,this):this.off("pointertap",G,this),this._autoInteract=t)}registerInteraction(t){t!==this.interactionManager&&(this.unregisterInteraction(),this._autoInteract&&t&&(this.interactionManager=t,t.on("pointermove",X,this)))}unregisterInteraction(){var t;this.interactionManager&&(null==(t=this.interactionManager)||t.off("pointermove",X,this),this.interactionManager=void 0)}}function G(t){this.tap(t.data.global.x,t.data.global.y)}function X(t){this.focus(t.data.global.x,t.data.global.y)}class z extends i.Transform{}const j=new i.Point,W=new i.Matrix;let H;class Y extends r.Container{constructor(t){super(),this.tag="Live2DModel(uninitialized)",this.textures=[],this.transform=new z,this.anchor=new i.ObservablePoint(this.onAnchorChange,this,0,0),this.glContextID=-1,this.elapsedTime=performance.now(),this.deltaTime=0,this._autoUpdate=!1,this.once("modelLoaded",(()=>this.init(t)))}static from(t,e){const i=new this(e);return V.setupLive2DModel(i,t,e).then((()=>i))}static fromSync(t,e){const i=new this(e);return V.setupLive2DModel(i,t,e).then(null==e?void 0:e.onLoad).catch(null==e?void 0:e.onError),i}static registerTicker(t){H=t}get autoUpdate(){return this._autoUpdate}set autoUpdate(t){var e;H||(H=null==(e=window.PIXI)?void 0:e.Ticker),t?this._destroyed||(H?(H.shared.add(this.onTickerUpdate,this),this._autoUpdate=!0):l.warn(this.tag,"No Ticker registered, please call Live2DModel.registerTicker(Ticker).")):(null==H||H.shared.remove(this.onTickerUpdate,this),this._autoUpdate=!1)}init(t){this.tag=`Live2DModel(${this.internalModel.settings.name})`;const e=Object.assign({autoUpdate:!0,autoInteract:!0},t);e.autoInteract&&(this.interactive=!0),this.autoInteract=e.autoInteract,this.autoUpdate=e.autoUpdate}onAnchorChange(){this.pivot.set(this.anchor.x*this.internalModel.width,this.anchor.y*this.internalModel.height)}motion(t,e,i,s,r,o){return void 0===e?this.internalModel.motionManager.startRandomMotion(t,i):this.internalModel.motionManager.startMotion(t,e,i,s,r,o)}resetMotions(){return this.internalModel.motionManager.stopAllMotions()}speak(t,e,i){return this.internalModel.motionManager.speakUp(t,e,i)}stopSpeaking(){return this.internalModel.motionManager.stopSpeaking()}expression(t){return this.internalModel.motionManager.expressionManager?void 0===t?this.internalModel.motionManager.expressionManager.setRandomExpression():this.internalModel.motionManager.expressionManager.setExpression(t):Promise.resolve(!1)}focus(t,e,i=!1){j.x=t,j.y=e,this.toModelPosition(j,j,!0);let s=j.x/this.internalModel.originalWidth*2-1,r=j.y/this.internalModel.originalHeight*2-1,o=Math.atan2(r,s);this.internalModel.focusController.focus(Math.cos(o),-Math.sin(o),i)}tap(t,e){const i=this.hitTest(t,e);i.length&&(l.log(this.tag,"Hit",i),this.emit("hit",i))}hitTest(t,e){return j.x=t,j.y=e,this.toModelPosition(j,j),this.internalModel.hitTest(j.x,j.y)}toModelPosition(t,e=t.clone(),i){return i||(this._recursivePostUpdateTransform(),this.parent?this.displayObjectUpdateTransform():(this.parent=this._tempDisplayObjectParent,this.displayObjectUpdateTransform(),this.parent=null)),this.transform.worldTransform.applyInverse(t,e),this.internalModel.localTransform.applyInverse(e,e),e}containsPoint(t){return this.getBounds(!0).contains(t.x,t.y)}_calculateBounds(){this._bounds.addFrame(this.transform,0,0,this.internalModel.width,this.internalModel.height)}onTickerUpdate(){this.update(H.shared.deltaMS)}update(t){this.deltaTime+=t,this.elapsedTime+=t}_render(t){this.registerInteraction(t.plugins.interaction),t.batch.reset(),t.geometry.reset(),t.shader.reset(),t.state.reset();let e=!1;this.glContextID!==t.CONTEXT_UID&&(this.glContextID=t.CONTEXT_UID,this.internalModel.updateWebGLContext(t.gl,this.glContextID),e=!0);for(let r=0;re.destroy(t.baseTexture))),this.internalModel.destroy(),super.destroy(t)}}g(Y,[N]);const q=class{static resolveURL(t,e){var i;const s=null==(i=q.filesMap[t])?void 0:i[e];if(void 0===s)throw new Error("Cannot find this file from uploaded files: "+e);return s}static upload(t,i){return __async(this,null,(function*(){const s={};for(const r of i.getDefinedFiles()){const o=decodeURI(e.url.resolve(i.url,r)),a=t.find((t=>t.webkitRelativePath===o));a&&(s[r]=URL.createObjectURL(a))}q.filesMap[i._objectURL]=s}))}static createSettings(t){return __async(this,null,(function*(){const e=t.find((t=>t.name.endsWith("model.json")||t.name.endsWith("model3.json")));if(!e)throw new TypeError("Settings file not found");const i=yield q.readText(e),s=JSON.parse(i);s.url=e.webkitRelativePath;const r=V.findRuntime(s);if(!r)throw new Error("Unknown settings JSON");const o=r.createModelSettings(s);return o._objectURL=URL.createObjectURL(e),o}))}static readText(t){return __async(this,null,(function*(){return new Promise(((e,i)=>{const s=new FileReader;s.onload=()=>e(s.result),s.onerror=i,s.readAsText(t,"utf8")}))}))}};let $=q;$.filesMap={},$.factory=(t,e)=>__async(this,null,(function*(){if(Array.isArray(t.source)&&t.source[0]instanceof File){const e=t.source;let i=e.settings;if(i){if(!i._objectURL)throw new Error('"_objectURL" must be specified in ModelSettings')}else i=yield q.createSettings(e);i.validateFiles(e.map((t=>encodeURI(t.webkitRelativePath)))),yield q.upload(e,i),i.resolveURL=function(t){return q.resolveURL(this._objectURL,t)},t.source=i,t.live2dModel.once("modelLoaded",(t=>{t.once("destroy",(function(){const t=this.settings._objectURL;if(URL.revokeObjectURL(t),q.filesMap[t])for(const e of Object.values(q.filesMap[t]))URL.revokeObjectURL(e);delete q.filesMap[t]}))}))}return e()})),V.live2DModelMiddlewares.unshift($.factory);const J=class{static unzip(t,i){return __async(this,null,(function*(){const s=yield J.getFilePaths(t),r=[];for(const t of i.getDefinedFiles()){const o=decodeURI(e.url.resolve(i.url,t));s.includes(o)&&r.push(o)}const o=yield J.getFiles(t,r);for(let t=0;tt.endsWith("model.json")||t.endsWith("model3.json")));if(!e)throw new Error("Settings file not found");const i=yield J.readText(t,e);if(!i)throw new Error("Empty settings file: "+e);const s=JSON.parse(i);s.url=e;const r=V.findRuntime(s);if(!r)throw new Error("Unknown settings JSON");return r.createModelSettings(s)}))}static zipReader(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFilePaths(t){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFiles(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static readText(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static releaseReader(t){}};let Z=J;if(Z.ZIP_PROTOCOL="zip://",Z.uid=0,Z.factory=(t,e)=>__async(this,null,(function*(){const i=t.source;let s,r,o;if("string"==typeof i&&(i.endsWith(".zip")||i.startsWith(J.ZIP_PROTOCOL))?(s=i.startsWith(J.ZIP_PROTOCOL)?i.slice(J.ZIP_PROTOCOL.length):i,r=yield L.load({url:s,type:"blob",target:t.live2dModel})):Array.isArray(i)&&1===i.length&&i[0]instanceof File&&i[0].name.endsWith(".zip")&&(r=i[0],s=URL.createObjectURL(r),o=i.settings),r){if(!r.size)throw new Error("Empty zip file");const e=yield J.zipReader(r,s);o||(o=yield J.createSettings(e)),o._objectURL=J.ZIP_PROTOCOL+J.uid+"/"+o.url;const i=yield J.unzip(e,o);i.settings=o,t.source=i,s.startsWith("blob:")&&t.live2dModel.once("modelLoaded",(t=>{t.once("destroy",(function(){URL.revokeObjectURL(s)}))})),J.releaseReader(e)}return e()})),V.live2DModelMiddlewares.unshift(Z.factory),!window.Live2D)throw new Error("Could not find Cubism 2 runtime. This plugin requires live2d.min.js to be loaded.");const Q=Live2DMotion.prototype.updateParam;Live2DMotion.prototype.updateParam=function(t,e){Q.call(this,t,e),e.isFinished()&&this.onFinishHandler&&(this.onFinishHandler(this),delete this.onFinishHandler)};class K extends AMotion{constructor(e){super(),this.params=[],this.setFadeIn(e.fade_in>0?e.fade_in:t.config.expressionFadingDuration),this.setFadeOut(e.fade_out>0?e.fade_out:t.config.expressionFadingDuration),Array.isArray(e.params)&&e.params.forEach((t=>{const e=t.calc||"add";if("add"===e){const e=t.def||0;t.val-=e}else if("mult"===e){const e=t.def||1;t.val/=e}this.params.push({calc:e,val:t.val,id:t.id})}))}updateParamExe(t,e,i,s){this.params.forEach((e=>{t.setParamFloat(e.id,e.val*i)}))}}class tt extends _{constructor(t,e){var i;super(t,e),this.queueManager=new MotionQueueManager,this.definitions=null!=(i=this.settings.expressions)?i:[],this.init()}isFinished(){return this.queueManager.isFinished()}getExpressionIndex(t){return this.definitions.findIndex((e=>e.name===t))}getExpressionFile(t){return t.file}createExpression(t,e){return new K(t)}_setExpression(t){return this.queueManager.startMotion(t)}stopAllExpressions(){this.queueManager.stopAllMotions()}updateParameters(t,e){return this.queueManager.updateParam(t)}}class et extends P{constructor(t,e){super(t,e),this.groups={idle:"idle"},this.motionDataType="arraybuffer",this.queueManager=new MotionQueueManager,this.definitions=this.settings.motions,this.init(e)}init(t){super.init(t),this.settings.expressions&&(this.expressionManager=new tt(this.settings,t))}isFinished(){return this.queueManager.isFinished()}createMotion(e,i,s){const r=Live2DMotion.loadMotion(e),o=i===this.groups.idle?t.config.idleMotionFadingDuration:t.config.motionFadingDuration;return r.setFadeIn(s.fade_in>0?s.fade_in:o),r.setFadeOut(s.fade_out>0?s.fade_out:o),r}getMotionFile(t){return t.file}getMotionName(t){return t.file}getSoundFile(t){return t.sound}_startMotion(t,e){return t.onFinishHandler=e,this.queueManager.stopAllMotions(),this.queueManager.startMotion(t)}_stopAllMotions(){this.queueManager.stopAllMotions()}updateParameters(t,e){return this.queueManager.updateParam(t)}destroy(){super.destroy(),this.queueManager=void 0}}class it{constructor(t){this.coreModel=t,this.blinkInterval=4e3,this.closingDuration=100,this.closedDuration=50,this.openingDuration=150,this.eyeState=0,this.eyeParamValue=1,this.closedTimer=0,this.nextBlinkTimeLeft=this.blinkInterval,this.leftParam=t.getParamIndex("PARAM_EYE_L_OPEN"),this.rightParam=t.getParamIndex("PARAM_EYE_R_OPEN")}setEyeParams(t){this.eyeParamValue=h(t,0,1),this.coreModel.setParamFloat(this.leftParam,this.eyeParamValue),this.coreModel.setParamFloat(this.rightParam,this.eyeParamValue)}update(t){switch(this.eyeState){case 0:this.nextBlinkTimeLeft-=t,this.nextBlinkTimeLeft<0&&(this.eyeState=1,this.nextBlinkTimeLeft=this.blinkInterval+this.closingDuration+this.closedDuration+this.openingDuration+u(0,2e3));break;case 1:this.setEyeParams(this.eyeParamValue+t/this.closingDuration),this.eyeParamValue<=0&&(this.eyeState=2,this.closedTimer=0);break;case 2:this.closedTimer+=t,this.closedTimer>=this.closedDuration&&(this.eyeState=3);break;case 3:this.setEyeParams(this.eyeParamValue+t/this.openingDuration),this.eyeParamValue>=1&&(this.eyeState=0)}}}const st=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);class rt extends S{constructor(t,e,i){super(),this.textureFlipY=!0,this.drawDataCount=0,this.disableCulling=!1,this.coreModel=t,this.settings=e,this.motionManager=new et(e,i),this.eyeBlink=new it(t),this.eyeballXParamIndex=t.getParamIndex("PARAM_EYE_BALL_X"),this.eyeballYParamIndex=t.getParamIndex("PARAM_EYE_BALL_Y"),this.angleXParamIndex=t.getParamIndex("PARAM_ANGLE_X"),this.angleYParamIndex=t.getParamIndex("PARAM_ANGLE_Y"),this.angleZParamIndex=t.getParamIndex("PARAM_ANGLE_Z"),this.bodyAngleXParamIndex=t.getParamIndex("PARAM_BODY_ANGLE_X"),this.breathParamIndex=t.getParamIndex("PARAM_BREATH"),this.init()}init(){super.init(),this.settings.initParams&&this.settings.initParams.forEach((({id:t,value:e})=>this.coreModel.setParamFloat(t,e))),this.settings.initOpacities&&this.settings.initOpacities.forEach((({id:t,value:e})=>this.coreModel.setPartsOpacity(t,e))),this.coreModel.saveParam();const t=this.coreModel.getModelContext()._$aS;(null==t?void 0:t.length)&&(this.drawDataCount=t.length);let e=this.coreModel.drawParamWebGL.culling;Object.defineProperty(this.coreModel.drawParamWebGL,"culling",{set:t=>e=t,get:()=>!this.disableCulling&&e});const i=this.coreModel.getModelContext().clipManager,s=i.setupClip;i.setupClip=(t,e)=>{s.call(i,t,e),e.gl.viewport(...this.viewport)}}getSize(){return[this.coreModel.getCanvasWidth(),this.coreModel.getCanvasHeight()]}getLayout(){const t={};if(this.settings.layout)for(const e of Object.keys(this.settings.layout)){let i=e;"center_x"===e?i="centerX":"center_y"===e&&(i="centerY"),t[i]=this.settings.layout[e]}return t}updateWebGLContext(t,e){const i=this.coreModel.drawParamWebGL;i.firstDraw=!0,i.setGL(t),i.glno=e;for(const o in i)i.hasOwnProperty(o)&&i[o]instanceof WebGLBuffer&&(i[o]=null);const s=this.coreModel.getModelContext().clipManager;s.curFrameNo=e;const r=t.getParameter(t.FRAMEBUFFER_BINDING);s.getMaskRenderTexture(),t.bindFramebuffer(t.FRAMEBUFFER,r)}bindTexture(t,e){this.coreModel.setTexture(t,e)}getHitAreaDefs(){var t;return(null==(t=this.settings.hitAreas)?void 0:t.map((t=>({id:t.id,name:t.name,index:this.coreModel.getDrawDataIndex(t.id)}))))||[]}getDrawableIDs(){const t=this.coreModel.getModelContext(),e=[];for(let i=0;i0&&t.textures.every((t=>"string"==typeof t))}copy(t){d("string",t,this,"name","name"),d("string",t,this,"pose","pose"),d("string",t,this,"physics","physics"),d("object",t,this,"layout","layout"),d("object",t,this,"motions","motions"),c("object",t,this,"hit_areas","hitAreas"),c("object",t,this,"expressions","expressions"),c("object",t,this,"init_params","initParams"),c("object",t,this,"init_opacities","initOpacities")}replaceFiles(t){super.replaceFiles(t);for(const[e,i]of Object.entries(this.motions))for(let s=0;s{const e=new PhysicsHair;return e.setup(t.setup.length,t.setup.regist,t.setup.mass),t.src.forEach((({id:t,ptype:i,scale:s,weight:r})=>{const o=at[i];o&&e.addSrcParam(o,t,s,r)})),t.targets.forEach((({id:t,ptype:i,scale:s,weight:r})=>{const o=nt[i];o&&e.addTargetParam(o,t,s,r)})),e})))}update(t){this.physicsHairs.forEach((e=>e.update(this.coreModel,t)))}}class ht{constructor(t){this.id=t,this.paramIndex=-1,this.partsIndex=-1,this.link=[]}initIndex(t){this.paramIndex=t.getParamIndex("VISIBLE:"+this.id),this.partsIndex=t.getPartsDataIndex(PartsDataID.getID(this.id)),t.setParamFloat(this.paramIndex,1)}}class ut{constructor(t,e){this.coreModel=t,this.opacityAnimDuration=500,this.partsGroups=[],e.parts_visible&&(this.partsGroups=e.parts_visible.map((({group:t})=>t.map((({id:t,link:e})=>{const i=new ht(t);return e&&(i.link=e.map((t=>new ht(t)))),i})))),this.init())}init(){this.partsGroups.forEach((t=>{t.forEach((t=>{if(t.initIndex(this.coreModel),t.paramIndex>=0){const e=0!==this.coreModel.getParamFloat(t.paramIndex);this.coreModel.setPartsOpacity(t.partsIndex,e?1:0),this.coreModel.setParamFloat(t.paramIndex,e?1:0),t.link.length>0&&t.link.forEach((t=>t.initIndex(this.coreModel)))}}))}))}normalizePartsOpacityGroup(t,e){const i=this.coreModel,s=.5;let r=1,o=t.findIndex((({paramIndex:t,partsIndex:e})=>e>=0&&0!==i.getParamFloat(t)));if(o>=0){const s=i.getPartsOpacity(t[o].partsIndex);r=h(s+e/this.opacityAnimDuration,0,1)}else o=0,r=1;t.forEach((({partsIndex:t},e)=>{if(t>=0)if(o==e)i.setPartsOpacity(t,r);else{let e,o=i.getPartsOpacity(t);e=r.15&&(e=1-.15/(1-r)),o>e&&(o=e),i.setPartsOpacity(t,o)}}))}copyOpacity(t){const e=this.coreModel;t.forEach((({partsIndex:t,link:i})=>{if(t>=0&&i){const s=e.getPartsOpacity(t);i.forEach((({partsIndex:t})=>{t>=0&&e.setPartsOpacity(t,s)}))}}))}update(t){this.partsGroups.forEach((e=>{this.normalizePartsOpacityGroup(e,t),this.copyOpacity(e)}))}}if(V.registerRuntime({version:2,test:t=>t instanceof ot||ot.isValidJSON(t),ready:()=>Promise.resolve(),isValidMoc(t){if(t.byteLength<3)return!1;const e=new Int8Array(t,0,3);return"moc"===String.fromCharCode(...e)},createModelSettings:t=>new ot(t),createCoreModel(t){const e=Live2DModelWebGL.loadModel(t),i=Live2D.getError();if(i)throw i;return e},createInternalModel:(t,e,i)=>new rt(t,e,i),createPose:(t,e)=>new ut(t,e),createPhysics:(t,e)=>new lt(t,e)}),!window.Live2DCubismCore)throw new Error("Could not find Cubism 4 runtime. This plugin requires live2dcubismcore.js to be loaded.");class dt{constructor(t,e){this.x=t||0,this.y=e||0}add(t){const e=new dt(0,0);return e.x=this.x+t.x,e.y=this.y+t.y,e}substract(t){const e=new dt(0,0);return e.x=this.x-t.x,e.y=this.y-t.y,e}multiply(t){const e=new dt(0,0);return e.x=this.x*t.x,e.y=this.y*t.y,e}multiplyByScaler(t){return this.multiply(new dt(t,t))}division(t){const e=new dt(0,0);return e.x=this.x/t.x,e.y=this.y/t.y,e}divisionByScalar(t){return this.division(new dt(t,t))}getLength(){return Math.sqrt(this.x*this.x+this.y*this.y)}getDistanceWith(t){return Math.sqrt((this.x-t.x)*(this.x-t.x)+(this.y-t.y)*(this.y-t.y))}dot(t){return this.x*t.x+this.y*t.y}normalize(){const t=Math.pow(this.x*this.x+this.y*this.y,.5);this.x=this.x/t,this.y=this.y/t}isEqual(t){return this.x==t.x&&this.y==t.y}isNotEqual(t){return!this.isEqual(t)}}const ct=class{static range(t,e,i){return ti&&(t=i),t}static sin(t){return Math.sin(t)}static cos(t){return Math.cos(t)}static abs(t){return Math.abs(t)}static sqrt(t){return Math.sqrt(t)}static cbrt(t){if(0===t)return t;let e=t;const i=e<0;let s;return i&&(e=-e),e===1/0?s=1/0:(s=Math.exp(Math.log(e)/3),s=(e/(s*s)+2*s)/3),i?-s:s}static getEasingSine(t){return t<0?0:t>1?1:.5-.5*this.cos(t*Math.PI)}static max(t,e){return t>e?t:e}static min(t,e){return t>e?e:t}static degreesToRadian(t){return t/180*Math.PI}static radianToDegrees(t){return 180*t/Math.PI}static directionToRadian(t,e){let i=Math.atan2(e.y,e.x)-Math.atan2(t.y,t.x);for(;i<-Math.PI;)i+=2*Math.PI;for(;i>Math.PI;)i-=2*Math.PI;return i}static directionToDegrees(t,e){const i=this.directionToRadian(t,e);let s=this.radianToDegrees(i);return e.x-t.x>0&&(s=-s),s}static radianToDirection(t){const e=new dt;return e.x=this.sin(t),e.y=this.cos(t),e}static quadraticEquation(t,e,i){return this.abs(t)1&&(t=1),e<0?e=0:e>1&&(e=1),i<0?i=0:i>1&&(i=1),s<0?s=0:s>1&&(s=1),this._modelColor.R=t,this._modelColor.G=e,this._modelColor.B=i,this._modelColor.A=s}getModelColor(){return Object.assign({},this._modelColor)}setIsPremultipliedAlpha(t){this._isPremultipliedAlpha=t}isPremultipliedAlpha(){return this._isPremultipliedAlpha}setIsCulling(t){this._isCulling=t}isCulling(){return this._isCulling}setAnisotropy(t){this._anisotropy=t}getAnisotropy(){return this._anisotropy}getModel(){return this._model}useHighPrecisionMask(t){this._useHighPrecisionMask=t}isUsingHighPrecisionMask(){return this._useHighPrecisionMask}constructor(){this._isCulling=!1,this._isPremultipliedAlpha=!1,this._anisotropy=0,this._modelColor=new ft,this._useHighPrecisionMask=!1,this._mvpMatrix4x4=new mt,this._mvpMatrix4x4.loadIdentity()}}var _t=(t=>(t[t.CubismBlendMode_Normal=0]="CubismBlendMode_Normal",t[t.CubismBlendMode_Additive=1]="CubismBlendMode_Additive",t[t.CubismBlendMode_Multiplicative=2]="CubismBlendMode_Multiplicative",t))(_t||{});class ft{constructor(t=1,e=1,i=1,s=1){this.R=t,this.G=e,this.B=i,this.A=s}}let xt,yt=!1,Mt=!1;const Ct=0,vt=2;class Pt{static startUp(t){if(yt)return wt("CubismFramework.startUp() is already done."),yt;if(Live2DCubismCore._isStarted)return yt=!0,!0;if(Live2DCubismCore._isStarted=!0,xt=t,xt&&Live2DCubismCore.Logging.csmSetLogFunction(xt.logFunction),yt=!0,yt){const t=Live2DCubismCore.Version.csmGetVersion(),e=(16711680&t)>>16,i=65535&t,s=t;wt("Live2D Cubism Core version: {0}.{1}.{2} ({3})",("00"+((4278190080&t)>>24)).slice(-2),("00"+e).slice(-2),("0000"+i).slice(-4),s)}return wt("CubismFramework.startUp() is complete."),yt}static cleanUp(){yt=!1,Mt=!1,xt=void 0}static initialize(t=0){yt?Mt?It("CubismFramework.initialize() skipped, already initialized."):(Live2DCubismCore.Memory.initializeAmountOfMemory(t),Mt=!0,wt("CubismFramework.initialize() is complete.")):It("CubismFramework is not started.")}static dispose(){yt?Mt?(pt.staticRelease(),Mt=!1,wt("CubismFramework.dispose() is complete.")):It("CubismFramework.dispose() skipped, not initialized."):It("CubismFramework is not started.")}static isStarted(){return yt}static isInitialized(){return Mt}static coreLogFunction(t){Live2DCubismCore.Logging.csmGetLogFunction()&&Live2DCubismCore.Logging.csmGetLogFunction()(t)}static getLoggingLevel(){return null!=xt?xt.loggingLevel:bt.LogLevel_Off}constructor(){}}var bt=(t=>(t[t.LogLevel_Verbose=0]="LogLevel_Verbose",t[t.LogLevel_Debug=1]="LogLevel_Debug",t[t.LogLevel_Info=2]="LogLevel_Info",t[t.LogLevel_Warning=3]="LogLevel_Warning",t[t.LogLevel_Error=4]="LogLevel_Error",t[t.LogLevel_Off=5]="LogLevel_Off",t))(bt||{});function St(t,...e){Et.print(bt.LogLevel_Debug,"[CSM][D]"+t+"\n",e)}function wt(t,...e){Et.print(bt.LogLevel_Info,"[CSM][I]"+t+"\n",e)}function It(t,...e){Et.print(bt.LogLevel_Warning,"[CSM][W]"+t+"\n",e)}function Tt(t,...e){Et.print(bt.LogLevel_Error,"[CSM][E]"+t+"\n",e)}class Et{static print(t,e,i){if(ti[e])))}static dumpBytes(t,e,i){for(let s=0;s0?this.print(t,"\n"):s%8==0&&s>0&&this.print(t," "),this.print(t,"{0} ",[255&e[s]]);this.print(t,"\n")}constructor(){}}class Lt{constructor(){this._fadeInSeconds=-1,this._fadeOutSeconds=-1,this._weight=1,this._offsetSeconds=0,this._firedEventValues=[]}release(){this._weight=0}updateParameters(t,e,i){if(!e.isAvailable()||e.isFinished())return;if(!e.isStarted()){e.setIsStarted(!0),e.setStartTime(i-this._offsetSeconds),e.setFadeInStartTime(i);const t=this.getDuration();e.getEndTime()<0&&e.setEndTime(t<=0?-1:e.getStartTime()+t)}let s=this._weight;s=s*(0==this._fadeInSeconds?1:gt.getEasingSine((i-e.getFadeInStartTime())/this._fadeInSeconds))*(0==this._fadeOutSeconds||e.getEndTime()<0?1:gt.getEasingSine((e.getEndTime()-i)/this._fadeOutSeconds)),e.setState(i,s),this.doUpdateParameters(t,i,s,e),e.getEndTime()>0&&e.getEndTime()(t[t.ExpressionBlendType_Add=0]="ExpressionBlendType_Add",t[t.ExpressionBlendType_Multiply=1]="ExpressionBlendType_Multiply",t[t.ExpressionBlendType_Overwrite=2]="ExpressionBlendType_Overwrite",t))(At||{});class Dt{constructor(){this._autoDelete=!1,this._available=!0,this._finished=!1,this._started=!1,this._startTimeSeconds=-1,this._fadeInStartTimeSeconds=0,this._endTimeSeconds=-1,this._stateTimeSeconds=0,this._stateWeight=0,this._lastEventCheckSeconds=0,this._motionQueueEntryHandle=this,this._fadeOutSeconds=0,this._isTriggeredFadeOut=!1}release(){this._autoDelete&&this._motion&&this._motion.release()}setFadeOut(t){this._fadeOutSeconds=t,this._isTriggeredFadeOut=!0}startFadeOut(t,e){const i=e+t;this._isTriggeredFadeOut=!0,(this._endTimeSeconds<0||inull!=e&&e._motionQueueEntryHandle==t))}setEventCallback(t,e=null){this._eventCallBack=t,this._eventCustomData=e}doUpdateMotion(t,e){let i=!1,s=0;for(;se.Name===t))}getExpressionFile(t){return t.File}createExpression(t,e){return Ft.create(t)}_setExpression(t){return this.queueManager.startMotion(t,!1,performance.now())}stopAllExpressions(){this.queueManager.stopAllMotions()}updateParameters(t,e){return this.queueManager.doUpdateMotion(t,e)}}class kt{constructor(t){this.groups=t.Groups,this.hitAreas=t.HitAreas,this.layout=t.Layout,this.moc=t.FileReferences.Moc,this.expressions=t.FileReferences.Expressions,this.motions=t.FileReferences.Motions,this.textures=t.FileReferences.Textures,this.physics=t.FileReferences.Physics,this.pose=t.FileReferences.Pose}getEyeBlinkParameters(){var t,e;return null==(e=null==(t=this.groups)?void 0:t.find((t=>"EyeBlink"===t.Name)))?void 0:e.Ids}getLipSyncParameters(){var t,e;return null==(e=null==(t=this.groups)?void 0:t.find((t=>"LipSync"===t.Name)))?void 0:e.Ids}}class Ut extends x{constructor(t){if(super(t),!Ut.isValidJSON(t))throw new TypeError("Invalid JSON.");Object.assign(this,new kt(t))}static isValidJSON(t){var e;return!!(null==t?void 0:t.FileReferences)&&"string"==typeof t.FileReferences.Moc&&(null==(e=t.FileReferences.Textures)?void 0:e.length)>0&&t.FileReferences.Textures.every((t=>"string"==typeof t))}replaceFiles(t){if(super.replaceFiles(t),this.motions)for(const[e,i]of Object.entries(this.motions))for(let s=0;s(t[t.CubismMotionCurveTarget_Model=0]="CubismMotionCurveTarget_Model",t[t.CubismMotionCurveTarget_Parameter=1]="CubismMotionCurveTarget_Parameter",t[t.CubismMotionCurveTarget_PartOpacity=2]="CubismMotionCurveTarget_PartOpacity",t))(Vt||{}),Nt=(t=>(t[t.CubismMotionSegmentType_Linear=0]="CubismMotionSegmentType_Linear",t[t.CubismMotionSegmentType_Bezier=1]="CubismMotionSegmentType_Bezier",t[t.CubismMotionSegmentType_Stepped=2]="CubismMotionSegmentType_Stepped",t[t.CubismMotionSegmentType_InverseStepped=3]="CubismMotionSegmentType_InverseStepped",t))(Nt||{});class Gt{constructor(t=0,e=0){this.time=t,this.value=e}}class Xt{constructor(){this.basePointIndex=0,this.segmentType=0}}class zt{constructor(){this.id="",this.type=0,this.segmentCount=0,this.baseSegmentIndex=0,this.fadeInTime=0,this.fadeOutTime=0}}class jt{constructor(){this.fireTime=0,this.value=""}}class Wt{constructor(){this.duration=0,this.loop=!1,this.curveCount=0,this.eventCount=0,this.fps=0,this.curves=[],this.segments=[],this.points=[],this.events=[]}}class Ht{constructor(t){this._json=t}release(){this._json=void 0}getMotionDuration(){return this._json.Meta.Duration}isMotionLoop(){return this._json.Meta.Loop||!1}getEvaluationOptionFlag(t){return Yt.EvaluationOptionFlag_AreBeziersRistricted==t&&!!this._json.Meta.AreBeziersRestricted}getMotionCurveCount(){return this._json.Meta.CurveCount}getMotionFps(){return this._json.Meta.Fps}getMotionTotalSegmentCount(){return this._json.Meta.TotalSegmentCount}getMotionTotalPointCount(){return this._json.Meta.TotalPointCount}getMotionFadeInTime(){return this._json.Meta.FadeInTime}getMotionFadeOutTime(){return this._json.Meta.FadeOutTime}getMotionCurveTarget(t){return this._json.Curves[t].Target}getMotionCurveId(t){return this._json.Curves[t].Id}getMotionCurveFadeInTime(t){return this._json.Curves[t].FadeInTime}getMotionCurveFadeOutTime(t){return this._json.Curves[t].FadeOutTime}getMotionCurveSegmentCount(t){return this._json.Curves[t].Segments.length}getMotionCurveSegment(t,e){return this._json.Curves[t].Segments[e]}getEventCount(){return this._json.Meta.UserDataCount||0}getTotalEventValueSize(){return this._json.Meta.TotalUserDataSize}getEventTime(t){return this._json.UserData[t].Time}getEventValue(t){return this._json.UserData[t].Value}}var Yt=(t=>(t[t.EvaluationOptionFlag_AreBeziersRistricted=0]="EvaluationOptionFlag_AreBeziersRistricted",t))(Yt||{});const qt="Opacity";function $t(t,e,i){const s=new Gt;return s.time=t.time+(e.time-t.time)*i,s.value=t.value+(e.value-t.value)*i,s}function Jt(t,e){let i=(e-t[0].time)/(t[1].time-t[0].time);return i<0&&(i=0),t[0].value+(t[1].value-t[0].value)*i}function Zt(t,e){let i=(e-t[0].time)/(t[3].time-t[0].time);i<0&&(i=0);const s=$t(t[0],t[1],i),r=$t(t[1],t[2],i),o=$t(t[2],t[3],i),a=$t(s,r,i),n=$t(r,o,i);return $t(a,n,i).value}function Qt(t,e){const i=e,s=t[0].time,r=t[3].time,o=t[1].time,a=t[2].time,n=r-3*a+3*o-s,l=3*a-6*o+3*s,h=3*o-3*s,u=s-i,d=gt.cardanoAlgorithmForBezier(n,l,h,u),c=$t(t[0],t[1],d),g=$t(t[1],t[2],d),m=$t(t[2],t[3],d),p=$t(c,g,d),_=$t(g,m,d);return $t(p,_,d).value}function Kt(t,e){return t[0].value}function te(t,e){return t[1].value}function ee(t,e,i){const s=t.curves[e];let r=-1;const o=s.baseSegmentIndex+s.segmentCount;let a=0;for(let l=s.baseSegmentIndex;li){r=l;break}if(-1==r)return t.points[a].value;const n=t.segments[r];return n.evaluate(t.points.slice(n.basePointIndex),i)}class ie extends Lt{constructor(){super(),this._eyeBlinkParameterIds=[],this._lipSyncParameterIds=[],this._sourceFrameRate=30,this._loopDurationSeconds=-1,this._isLoop=!1,this._isLoopFadeIn=!0,this._lastWeight=0,this._modelOpacity=1}static create(t,e){const i=new ie;return i.parse(t),i._sourceFrameRate=i._motionData.fps,i._loopDurationSeconds=i._motionData.duration,i._onFinishedMotion=e,i}doUpdateParameters(t,e,i,s){null==this._modelCurveIdEyeBlink&&(this._modelCurveIdEyeBlink="EyeBlink"),null==this._modelCurveIdLipSync&&(this._modelCurveIdLipSync="LipSync"),null==this._modelCurveIdOpacity&&(this._modelCurveIdOpacity=qt);let r=e-s.getStartTime();r<0&&(r=0);let a=Number.MAX_VALUE,n=Number.MAX_VALUE;const l=64;let h=0,u=0;this._eyeBlinkParameterIds.length>l&&St("too many eye blink targets : {0}",this._eyeBlinkParameterIds.length),this._lipSyncParameterIds.length>l&&St("too many lip sync targets : {0}",this._lipSyncParameterIds.length);const d=this._fadeInSeconds<=0?1:gt.getEasingSine((e-s.getFadeInStartTime())/this._fadeInSeconds),c=this._fadeOutSeconds<=0||s.getEndTime()<0?1:gt.getEasingSine((s.getEndTime()-e)/this._fadeOutSeconds);let g,m,p,_=r;if(this._isLoop)for(;_>this._motionData.duration;)_-=this._motionData.duration;const f=this._motionData.curves;for(m=0;m>o&1)continue;const s=e+(n-e)*i;t.setParameterValueById(this._eyeBlinkParameterIds[o],s)}if(a!=Number.MAX_VALUE)for(let o=0;o>o&1)continue;const s=e+(a-e)*i;t.setParameterValueById(this._lipSyncParameterIds[o],s)}for(;m=this._motionData.duration&&(this._isLoop?(s.setStartTime(e),this._isLoopFadeIn&&s.setFadeInStartTime(e)):(this._onFinishedMotion&&this._onFinishedMotion(this),s.setIsFinished(!0))),this._lastWeight=i}setIsLoop(t){this._isLoop=t}isLoop(){return this._isLoop}setIsLoopFadeIn(t){this._isLoopFadeIn=t}isLoopFadeIn(){return this._isLoopFadeIn}getDuration(){return this._isLoop?-1:this._loopDurationSeconds}getLoopDuration(){return this._loopDurationSeconds}setParameterFadeInTime(t,e){const i=this._motionData.curves;for(let s=0;snew zt)),this._motionData.segments=Array.from({length:e.getMotionTotalSegmentCount()}).map((()=>new Xt)),this._motionData.events=Array.from({length:this._motionData.eventCount}).map((()=>new jt)),this._motionData.points=[];let o=0,a=0;for(let n=0;nt&&this._motionData.events[i].fireTime<=e&&this._firedEventValues.push(this._motionData.events[i].value);return this._firedEventValues}isExistModelOpacity(){for(let t=0;t{this.emit("motion:"+e)}))}isFinished(){return this.queueManager.isFinished()}_startMotion(t,e){return t.setFinishedMotionHandler(e),this.queueManager.stopAllMotions(),this.queueManager.startMotion(t,!1,performance.now())}_stopAllMotions(){this.queueManager.stopAllMotions()}createMotion(e,i,s){const r=ie.create(e),o=new Ht(e),a=(i===this.groups.idle?t.config.idleMotionFadingDuration:t.config.motionFadingDuration)/1e3;return void 0===o.getMotionFadeInTime()&&r.setFadeInTime(s.FadeInTime>0?s.FadeInTime:a),void 0===o.getMotionFadeOutTime()&&r.setFadeOutTime(s.FadeOutTime>0?s.FadeOutTime:a),r.setEffectIds(this.eyeBlinkIds,this.lipSyncIds),r}getMotionFile(t){return t.File}getMotionName(t){return t.File}getSoundFile(t){return t.Sound}updateParameters(t,e){return this.queueManager.doUpdateMotion(t,e)}destroy(){super.destroy(),this.queueManager.release(),this.queueManager=void 0}}class re{constructor(){this._breathParameters=[],this._currentTime=0}static create(){return new re}setParameters(t){this._breathParameters=t}getParameters(){return this._breathParameters}updateParameters(t,e){this._currentTime+=e;const i=2*this._currentTime*3.14159;for(let s=0;s=1&&(s=1,this._blinkingState=le.EyeState_Closed,this._stateStartTimeSeconds=this._userTimeSeconds),i=1-s;break;case le.EyeState_Closed:s=(this._userTimeSeconds-this._stateStartTimeSeconds)/this._closedSeconds,s>=1&&(this._blinkingState=le.EyeState_Opening,this._stateStartTimeSeconds=this._userTimeSeconds),i=0;break;case le.EyeState_Opening:s=(this._userTimeSeconds-this._stateStartTimeSeconds)/this._openingSeconds,s>=1&&(s=1,this._blinkingState=le.EyeState_Interval,this._nextBlinkingTime=this.determinNextBlinkingTiming()),i=s;break;case le.EyeState_Interval:this._nextBlinkingTime(t[t.EyeState_First=0]="EyeState_First",t[t.EyeState_Interval=1]="EyeState_Interval",t[t.EyeState_Closing=2]="EyeState_Closing",t[t.EyeState_Closed=3]="EyeState_Closed",t[t.EyeState_Opening=4]="EyeState_Opening",t))(le||{});class he{constructor(t=0,e=0,i=0,s=0){this.x=t,this.y=e,this.width=i,this.height=s}getCenterX(){return this.x+.5*this.width}getCenterY(){return this.y+.5*this.height}getRight(){return this.x+this.width}getBottom(){return this.y+this.height}setRect(t){this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height}expand(t,e){this.x-=t,this.y-=e,this.width+=2*t,this.height+=2*e}}let ue,de,ce;class ge{getChannelFlagAsColor(t){return this._channelColors[t]}getMaskRenderTexture(){if(this._maskTexture&&null!=this._maskTexture.textures)this._maskTexture.frameNo=this._currentFrameNo;else{this._maskRenderTextures=[],this._maskColorBuffers=[];const t=this._clippingMaskBufferSize;for(let e=0;ec&&(c=e),ig&&(g=i)}if(u!=Number.MAX_VALUE)if(ur&&(r=c),g>o&&(o=g),i==Number.MAX_VALUE)e._allClippedDrawRect.x=0,e._allClippedDrawRect.y=0,e._allClippedDrawRect.width=0,e._allClippedDrawRect.height=0,e._isUsing=!1;else{e._isUsing=!0;const t=r-i,a=o-s;e._allClippedDrawRect.x=i,e._allClippedDrawRect.y=s,e._allClippedDrawRect.width=t,e._allClippedDrawRect.height=a}}}constructor(){this._currentMaskRenderTexture=null,this._currentFrameNo=0,this._renderTextureCount=0,this._clippingMaskBufferSize=256,this._clippingContextListForMask=[],this._clippingContextListForDraw=[],this._channelColors=[],this._tmpBoundsOnModel=new he,this._tmpMatrix=new mt,this._tmpMatrixForMask=new mt,this._tmpMatrixForDraw=new mt;let t=new ft;t.R=1,t.G=0,t.B=0,t.A=0,this._channelColors.push(t),t=new ft,t.R=0,t.G=1,t.B=0,t.A=0,this._channelColors.push(t),t=new ft,t.R=0,t.G=0,t.B=1,t.A=0,this._channelColors.push(t),t=new ft,t.R=0,t.G=0,t.B=0,t.A=1,this._channelColors.push(t)}release(){var t;const e=this;for(let i=0;i0){this.setupLayoutBounds(e.isUsingHighPrecisionMask()?0:i),e.isUsingHighPrecisionMask()||(this.gl.viewport(0,0,this._clippingMaskBufferSize,this._clippingMaskBufferSize),this._currentMaskRenderTexture=this.getMaskRenderTexture()[0],e.preDraw(),this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,this._currentMaskRenderTexture)),this._clearedFrameBufferflags||(this._clearedFrameBufferflags=[]);for(let t=0;th?(this._tmpBoundsOnModel.expand(r.width*a,0),n=o.width/this._tmpBoundsOnModel.width):n=e/h,this._tmpBoundsOnModel.height*e>u?(this._tmpBoundsOnModel.expand(0,r.height*a),l=o.height/this._tmpBoundsOnModel.height):l=e/u}else this._tmpBoundsOnModel.setRect(r),this._tmpBoundsOnModel.expand(r.width*a,r.height*a),n=o.width/this._tmpBoundsOnModel.width,l=o.height/this._tmpBoundsOnModel.height;if(this._tmpMatrix.loadIdentity(),this._tmpMatrix.translateRelative(-1,-1),this._tmpMatrix.scaleRelative(2,2),this._tmpMatrix.translateRelative(o.x,o.y),this._tmpMatrix.scaleRelative(n,l),this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x,-this._tmpBoundsOnModel.y),this._tmpMatrixForMask.setMatrix(this._tmpMatrix.getArray()),this._tmpMatrix.loadIdentity(),this._tmpMatrix.translateRelative(o.x,o.y),this._tmpMatrix.scaleRelative(n,l),this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x,-this._tmpBoundsOnModel.y),this._tmpMatrixForDraw.setMatrix(this._tmpMatrix.getArray()),s._matrixForMask.setMatrix(this._tmpMatrixForMask.getArray()),s._matrixForDraw.setMatrix(this._tmpMatrixForDraw.getArray()),!e.isUsingHighPrecisionMask()){const i=s._clippingIdCount;for(let r=0;re){t>e&&Tt("not supported mask count : {0}\n[Details] render texture count : {1}, mask count : {2}",t-e,this._renderTextureCount,t);for(let t=0;t=4?0:n+1;if(u(t[t.ShaderNames_SetupMask=0]="ShaderNames_SetupMask",t[t.ShaderNames_NormalPremultipliedAlpha=1]="ShaderNames_NormalPremultipliedAlpha",t[t.ShaderNames_NormalMaskedPremultipliedAlpha=2]="ShaderNames_NormalMaskedPremultipliedAlpha",t[t.ShaderNames_NomralMaskedInvertedPremultipliedAlpha=3]="ShaderNames_NomralMaskedInvertedPremultipliedAlpha",t[t.ShaderNames_AddPremultipliedAlpha=4]="ShaderNames_AddPremultipliedAlpha",t[t.ShaderNames_AddMaskedPremultipliedAlpha=5]="ShaderNames_AddMaskedPremultipliedAlpha",t[t.ShaderNames_AddMaskedPremultipliedAlphaInverted=6]="ShaderNames_AddMaskedPremultipliedAlphaInverted",t[t.ShaderNames_MultPremultipliedAlpha=7]="ShaderNames_MultPremultipliedAlpha",t[t.ShaderNames_MultMaskedPremultipliedAlpha=8]="ShaderNames_MultMaskedPremultipliedAlpha",t[t.ShaderNames_MultMaskedPremultipliedAlphaInverted=9]="ShaderNames_MultMaskedPremultipliedAlphaInverted",t))(xe||{});const ye="attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_myPos;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_clipMatrix * a_position; v_myPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}",Me="precision mediump float;varying vec2 v_texCoord;varying vec4 v_myPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;void main(){ float isInside = step(u_baseColor.x, v_myPos.x/v_myPos.w) * step(u_baseColor.y, v_myPos.y/v_myPos.w) * step(v_myPos.x/v_myPos.w, u_baseColor.z) * step(v_myPos.y/v_myPos.w, u_baseColor.w); gl_FragColor = u_channelFlag * texture2D(s_texture0, v_texCoord).a * isInside;}",Ce="attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;uniform mat4 u_matrix;void main(){ gl_Position = u_matrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}",ve="attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform mat4 u_matrix;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_matrix * a_position; v_clipPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}",Pe="precision mediump float;varying vec2 v_texCoord;uniform vec4 u_baseColor;uniform sampler2D s_texture0;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 color = texColor * u_baseColor; gl_FragColor = vec4(color.rgb, color.a);}",be="precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * maskVal; gl_FragColor = col_formask;}",Se="precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_channelFlag;uniform vec4 u_baseColor;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * (1.0 - maskVal); gl_FragColor = col_formask;}";class we extends pt{constructor(){super(),this._clippingContextBufferForMask=null,this._clippingContextBufferForDraw=null,this._rendererProfile=new _e,this.firstDraw=!0,this._textures={},this._sortedDrawableIndexList=[],this._bufferData={vertex:null,uv:null,index:null}}initialize(t,e=1){t.isUsingMasking()&&(this._clippingManager=new ge,this._clippingManager.initialize(t,t.getDrawableCount(),t.getDrawableMasks(),t.getDrawableMaskCounts(),e));for(let i=t.getDrawableCount()-1;i>=0;i--)this._sortedDrawableIndexList[i]=0;super.initialize(t)}bindTexture(t,e){this._textures[t]=e}getBindedTextures(){return this._textures}setClippingMaskBufferSize(t){if(!this._model.isUsingMasking())return;const e=this._clippingManager.getRenderTextureCount();this._clippingManager.release(),this._clippingManager=new ge,this._clippingManager.setClippingMaskBufferSize(t),this._clippingManager.initialize(this.getModel(),this.getModel().getDrawableCount(),this.getModel().getDrawableMasks(),this.getModel().getDrawableMaskCounts(),e)}getClippingMaskBufferSize(){return this._model.isUsingMasking()?this._clippingManager.getClippingMaskBufferSize():-1}getRenderTextureCount(){return this._model.isUsingMasking()?this._clippingManager.getRenderTextureCount():-1}release(){var t,e,i;const s=this;this._clippingManager.release(),s._clippingManager=void 0,null==(t=this.gl)||t.deleteBuffer(this._bufferData.vertex),this._bufferData.vertex=null,null==(e=this.gl)||e.deleteBuffer(this._bufferData.uv),this._bufferData.uv=null,null==(i=this.gl)||i.deleteBuffer(this._bufferData.index),this._bufferData.index=null,s._bufferData=void 0,s._textures=void 0}doDrawModel(){if(null==this.gl)return void Tt("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");null!=this._clippingManager&&(this.preDraw(),this._clippingManager.setupClippingContext(this.getModel(),this)),this.preDraw();const t=this.getModel().getDrawableCount(),e=this.getModel().getDrawableRenderOrders();for(let i=0;i0&&this._extension)for(const t of Object.entries(this._textures))this.gl.bindTexture(this.gl.TEXTURE_2D,t),this.gl.texParameterf(this.gl.TEXTURE_2D,this._extension.TEXTURE_MAX_ANISOTROPY_EXT,this.getAnisotropy())}setClippingContextBufferForMask(t){this._clippingContextBufferForMask=t}getClippingContextBufferForMask(){return this._clippingContextBufferForMask}setClippingContextBufferForDraw(t){this._clippingContextBufferForDraw=t}getClippingContextBufferForDraw(){return this._clippingContextBufferForDraw}startUp(t){this.gl=t,this._clippingManager&&this._clippingManager.setGL(t),fe.getInstance().setGl(t),this._rendererProfile.setGl(t),this._extension=this.gl.getExtension("EXT_texture_filter_anisotropic")||this.gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic")||this.gl.getExtension("MOZ_EXT_texture_filter_anisotropic")}}pt.staticRelease=()=>{we.doStaticRelease()};const Ie=new mt;class Te extends S{constructor(t,e,s){super(),this.lipSync=!0,this.breath=re.create(),this.renderer=new we,this.idParamAngleX="ParamAngleX",this.idParamAngleY="ParamAngleY",this.idParamAngleZ="ParamAngleZ",this.idParamEyeBallX="ParamEyeBallX",this.idParamEyeBallY="ParamEyeBallY",this.idParamBodyAngleX="ParamBodyAngleX",this.idParamBreath="ParamBreath",this.pixelsPerUnit=1,this.centeringTransform=new i.Matrix,this.coreModel=t,this.settings=e,this.motionManager=new se(e,s),this.init()}init(){var t;super.init(),(null==(t=this.settings.getEyeBlinkParameters())?void 0:t.length)>0&&(this.eyeBlink=ne.create(this.settings)),this.breath.setParameters([new oe(this.idParamAngleX,0,15,6.5345,.5),new oe(this.idParamAngleY,0,8,3.5345,.5),new oe(this.idParamAngleZ,0,10,5.5345,.5),new oe(this.idParamBodyAngleX,0,4,15.5345,.5),new oe(this.idParamBreath,0,.5,3.2345,.5)]),this.renderer.initialize(this.coreModel),this.renderer.setIsPremultipliedAlpha(!0)}getSize(){return[this.coreModel.getModel().canvasinfo.CanvasWidth,this.coreModel.getModel().canvasinfo.CanvasHeight]}getLayout(){const t={};if(this.settings.layout)for(const e of Object.keys(this.settings.layout)){t[e.charAt(0).toLowerCase()+e.slice(1)]=this.settings.layout[e]}return t}setupLayout(){super.setupLayout(),this.pixelsPerUnit=this.coreModel.getModel().canvasinfo.PixelsPerUnit,this.centeringTransform.scale(this.pixelsPerUnit,this.pixelsPerUnit).translate(this.originalWidth/2,this.originalHeight/2)}updateWebGLContext(t,e){this.renderer.firstDraw=!0,this.renderer._bufferData={vertex:null,uv:null,index:null},this.renderer.startUp(t),this.renderer._clippingManager._currentFrameNo=e,this.renderer._clippingManager._maskTexture=void 0,fe.getInstance()._shaderSets=[]}bindTexture(t,e){this.renderer.bindTexture(t,e)}getHitAreaDefs(){var t,e;return null!=(e=null==(t=this.settings.hitAreas)?void 0:t.map((t=>({id:t.Id,name:t.Name,index:this.coreModel.getDrawableIndex(t.Id)}))))?e:[]}getDrawableIDs(){return this.coreModel.getDrawableIds()}getDrawableIndex(t){return this.coreModel.getDrawableIndex(t)}getDrawableVertices(t){if("string"==typeof t&&-1===(t=this.coreModel.getDrawableIndex(t)))throw new TypeError("Unable to find drawable ID: "+t);const e=this.coreModel.getDrawableVertices(t).slice();for(let i=0;i{!function i(){try{Ae(),t()}catch(s){if(Le--,Le<0){const t=new Error("Failed to start up Cubism 4 framework.");return t.cause=s,void e(t)}l.log("Cubism4","Startup failed, retrying 10ms later..."),setTimeout(i,10)}}()}))),Ee)}function Ae(t){t=Object.assign({logFunction:console.log,loggingLevel:bt.LogLevel_Verbose},t),Pt.startUp(t),Pt.initialize()}class De{static create(t){const e=new De;"number"==typeof t.FadeInTime&&(e._fadeTimeSeconds=t.FadeInTime,e._fadeTimeSeconds<=0&&(e._fadeTimeSeconds=.5));const i=t.Groups,s=i.length;for(let r=0;r.001){if(r>=0)break;r=n,o=t.getPartOpacityByIndex(i),o+=e/this._fadeTimeSeconds,o>1&&(o=1)}}r<0&&(r=0,o=1);for(let n=i;n.15&&(i=1-.15/(1-o)),s>i&&(s=i),t.setPartOpacityByIndex(e,s)}}}constructor(){this._fadeTimeSeconds=.5,this._lastModel=void 0,this._partGroups=[],this._partGroupCounts=[]}}class Re{constructor(t){this.parameterIndex=0,this.partIndex=0,this.partId="",this.link=[],null!=t&&this.assignment(t)}assignment(t){return this.partId=t.partId,this.link=t.link.map((t=>t.clone())),this}initialize(t){this.parameterIndex=t.getParameterIndex(this.partId),this.partIndex=t.getPartIndex(this.partId),t.setParameterValueByIndex(this.parameterIndex,1)}clone(){const t=new Re;return t.partId=this.partId,t.parameterIndex=this.parameterIndex,t.partIndex=this.partIndex,t.link=this.link.map((t=>t.clone())),t}}class Be{constructor(t=!1,e=new ft){this.isOverwritten=t,this.Color=e}}class Oe{constructor(t=!1,e=new ft){this.isOverwritten=t,this.Color=e}}class ke{constructor(t=!1,e=!1){this.isOverwritten=t,this.isCulling=e}}class Ue{update(){this._model.update(),this._model.drawables.resetDynamicFlags()}getPixelsPerUnit(){return null==this._model?0:this._model.canvasinfo.PixelsPerUnit}getCanvasWidth(){return null==this._model?0:this._model.canvasinfo.CanvasWidth/this._model.canvasinfo.PixelsPerUnit}getCanvasHeight(){return null==this._model?0:this._model.canvasinfo.CanvasHeight/this._model.canvasinfo.PixelsPerUnit}saveParameters(){const t=this._model.parameters.count,e=this._savedParameters.length;for(let i=0;ie&&(e=this._model.parameters.minimumValues[t]),this._parameterValues[t]=1==i?e:this._parameterValues[t]=this._parameterValues[t]*(1-i)+e*i)}setParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.setParameterValueByIndex(s,e,i)}addParameterValueByIndex(t,e,i=1){this.setParameterValueByIndex(t,this.getParameterValueByIndex(t)+e*i)}addParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.addParameterValueByIndex(s,e,i)}multiplyParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.multiplyParameterValueByIndex(s,e,i)}multiplyParameterValueByIndex(t,e,i=1){this.setParameterValueByIndex(t,this.getParameterValueByIndex(t)*(1+(e-1)*i))}getDrawableIds(){return this._drawableIds.slice()}getDrawableIndex(t){const e=this._model.drawables.count;for(let i=0;ie&&(t=e);for(let i=0;i=0&&this._partChildDrawables[n].push(t)}}}constructor(t){this._model=t,this._savedParameters=[],this._parameterIds=[],this._drawableIds=[],this._partIds=[],this._isOverwrittenModelMultiplyColors=!1,this._isOverwrittenModelScreenColors=!1,this._isOverwrittenCullings=!1,this._modelOpacity=1,this._userMultiplyColors=[],this._userScreenColors=[],this._userCullings=[],this._userPartMultiplyColors=[],this._userPartScreenColors=[],this._partChildDrawables=[],this._notExistPartId={},this._notExistParameterId={},this._notExistParameterValues={},this._notExistPartOpacities={},this.initialize()}release(){this._model.release(),this._model=void 0}}class Ve{static create(t,e){if(e){if(!this.hasMocConsistency(t))throw new Error("Inconsistent MOC3.")}const i=Live2DCubismCore.Moc.fromArrayBuffer(t);if(i){const e=new Ve(i);return e._mocVersion=Live2DCubismCore.Version.csmGetMocVersion(i,t),e}throw new Error("Failed to CubismMoc.create().")}createModel(){let t;const e=Live2DCubismCore.Model.fromMoc(this._moc);if(e)return t=new Ue(e),++this._modelCount,t;throw new Error("Unknown error")}deleteModel(t){null!=t&&--this._modelCount}constructor(t){this._moc=t,this._modelCount=0,this._mocVersion=0}release(){this._moc._release(),this._moc=void 0}getLatestMocVersion(){return Live2DCubismCore.Version.csmGetLatestMocVersion()}getMocVersion(){return this._mocVersion}static hasMocConsistency(t){return 1===Live2DCubismCore.Moc.prototype.hasMocConsistency(t)}}var Ne=(t=>(t[t.CubismPhysicsTargetType_Parameter=0]="CubismPhysicsTargetType_Parameter",t))(Ne||{}),Ge=(t=>(t[t.CubismPhysicsSource_X=0]="CubismPhysicsSource_X",t[t.CubismPhysicsSource_Y=1]="CubismPhysicsSource_Y",t[t.CubismPhysicsSource_Angle=2]="CubismPhysicsSource_Angle",t))(Ge||{});class Xe{constructor(){this.initialPosition=new dt(0,0),this.position=new dt(0,0),this.lastPosition=new dt(0,0),this.lastGravity=new dt(0,0),this.force=new dt(0,0),this.velocity=new dt(0,0)}}class ze{constructor(){this.normalizationPosition={},this.normalizationAngle={}}}class je{constructor(){this.source={}}}class We{constructor(){this.destination={},this.translationScale=new dt(0,0)}}class He{constructor(){this.settings=[],this.inputs=[],this.outputs=[],this.particles=[],this.gravity=new dt(0,0),this.wind=new dt(0,0),this.fps=0}}class Ye{constructor(t){this._json=t}release(){this._json=void 0}getGravity(){const t=new dt(0,0);return t.x=this._json.Meta.EffectiveForces.Gravity.X,t.y=this._json.Meta.EffectiveForces.Gravity.Y,t}getWind(){const t=new dt(0,0);return t.x=this._json.Meta.EffectiveForces.Wind.X,t.y=this._json.Meta.EffectiveForces.Wind.Y,t}getFps(){return this._json.Meta.Fps||0}getSubRigCount(){return this._json.Meta.PhysicsSettingCount}getTotalInputCount(){return this._json.Meta.TotalInputCount}getTotalOutputCount(){return this._json.Meta.TotalOutputCount}getVertexCount(){return this._json.Meta.VertexCount}getNormalizationPositionMinimumValue(t){return this._json.PhysicsSettings[t].Normalization.Position.Minimum}getNormalizationPositionMaximumValue(t){return this._json.PhysicsSettings[t].Normalization.Position.Maximum}getNormalizationPositionDefaultValue(t){return this._json.PhysicsSettings[t].Normalization.Position.Default}getNormalizationAngleMinimumValue(t){return this._json.PhysicsSettings[t].Normalization.Angle.Minimum}getNormalizationAngleMaximumValue(t){return this._json.PhysicsSettings[t].Normalization.Angle.Maximum}getNormalizationAngleDefaultValue(t){return this._json.PhysicsSettings[t].Normalization.Angle.Default}getInputCount(t){return this._json.PhysicsSettings[t].Input.length}getInputWeight(t,e){return this._json.PhysicsSettings[t].Input[e].Weight}getInputReflect(t,e){return this._json.PhysicsSettings[t].Input[e].Reflect}getInputType(t,e){return this._json.PhysicsSettings[t].Input[e].Type}getInputSourceId(t,e){return this._json.PhysicsSettings[t].Input[e].Source.Id}getOutputCount(t){return this._json.PhysicsSettings[t].Output.length}getOutputVertexIndex(t,e){return this._json.PhysicsSettings[t].Output[e].VertexIndex}getOutputAngleScale(t,e){return this._json.PhysicsSettings[t].Output[e].Scale}getOutputWeight(t,e){return this._json.PhysicsSettings[t].Output[e].Weight}getOutputDestinationId(t,e){return this._json.PhysicsSettings[t].Output[e].Destination.Id}getOutputType(t,e){return this._json.PhysicsSettings[t].Output[e].Type}getOutputReflect(t,e){return this._json.PhysicsSettings[t].Output[e].Reflect}getParticleCount(t){return this._json.PhysicsSettings[t].Vertices.length}getParticleMobility(t,e){return this._json.PhysicsSettings[t].Vertices[e].Mobility}getParticleDelay(t,e){return this._json.PhysicsSettings[t].Vertices[e].Delay}getParticleAcceleration(t,e){return this._json.PhysicsSettings[t].Vertices[e].Acceleration}getParticleRadius(t,e){return this._json.PhysicsSettings[t].Vertices[e].Radius}getParticlePosition(t,e){const i=new dt(0,0);return i.x=this._json.PhysicsSettings[t].Vertices[e].Position.X,i.y=this._json.PhysicsSettings[t].Vertices[e].Position.Y,i}}const qe="Angle";class $e{static create(t){const e=new $e;return e.parse(t),e._physicsRig.gravity.y=0,e}static delete(t){null!=t&&t.release()}parse(t){this._physicsRig=new He;const e=new Ye(t);this._physicsRig.gravity=e.getGravity(),this._physicsRig.wind=e.getWind(),this._physicsRig.subRigCount=e.getSubRigCount(),this._physicsRig.fps=e.getFps(),this._currentRigOutputs=[],this._previousRigOutputs=[];let i=0,s=0,r=0;for(let o=0;o=u.particleCount)continue;let s=new dt;s=g[i].position.substract(g[i-1].position),l=c[e].getValue(s,g,i,c[e].reflect,this._options.gravity),this._currentRigOutputs[x].outputs[e]=l,this._previousRigOutputs[x].outputs[e]=l;const r=c[e].destinationParameterIndex,o=!Float32Array.prototype.slice&&"subarray"in Float32Array.prototype?JSON.parse(JSON.stringify(m.subarray(r))):m.slice(r);ui(o,_[r],p[r],l,c[e]);for(let t=r,e=0;t=e)return;if(this._currentRemainTime+=e,this._currentRemainTime>5&&(this._currentRemainTime=0),p=t.getModel().parameters.values,_=t.getModel().parameters.maximumValues,f=t.getModel().parameters.minimumValues,x=t.getModel().parameters.defaultValues,(null!=(s=null==(i=this._parameterCaches)?void 0:i.length)?s:0)0?1/this._physicsRig.fps:e;this._currentRemainTime>=y;){for(let t=0;t=d.particleCount)continue;const r=new dt;r.x=m[s].position.x-m[s-1].position.x,r.y=m[s].position.y-m[s-1].position.y,h=g[e].getValue(r,m,s,g[e].reflect,this._options.gravity),this._currentRigOutputs[i].outputs[e]=h;const o=g[e].destinationParameterIndex,a=!Float32Array.prototype.slice&&"subarray"in Float32Array.prototype?JSON.parse(JSON.stringify(this._parameterCaches.subarray(o))):this._parameterCaches.slice(o);ui(a,f[o],_[o],h,g[e]);for(let t=o,e=0;t=2?e[i-1].position.substract(e[i-2].position):r.multiplyByScaler(-1),o=gt.directionToRadian(r,t),s&&(o*=-1),o}function ri(t,e){return Math.min(t,e)+function(t,e){return Math.abs(Math.max(t,e)-Math.min(t,e))}(t,e)/2}function oi(t,e){return t.x}function ai(t,e){return t.y}function ni(t,e){return e}function li(t,e,i,s,r,o,a,n){let l,h,u,d,c=new dt(0,0),g=new dt(0,0),m=new dt(0,0),p=new dt(0,0);t[0].position=new dt(i.x,i.y),l=gt.degreesToRadian(s),d=gt.radianToDirection(l),d.normalize();for(let _=1;_i&&(a>r.valueExceededMaximum&&(r.valueExceededMaximum=a),a=i),n=r.weight/100,n>=1||(a=t[0]*(1-n)+a*n),t[0]=a}function di(t,e,i,s,r,o,a,n){let l=0;const h=gt.max(i,e);ht&&(t=u);const d=gt.min(r,o),c=gt.max(r,o),g=a,m=ri(u,h),p=t-m;switch(Math.sign(p)){case 1:{const t=c-g,e=h-m;0!=e&&(l=p*(t/e),l+=g);break}case-1:{const t=d-g,e=u-m;0!=e&&(l=p*(t/e),l+=g);break}case 0:l=g}return n?l:-1*l}function ci(){var t;null==(t=this.__moc)||t.release()}V.registerRuntime({version:4,ready:Fe,test:t=>t instanceof Ut||Ut.isValidJSON(t),isValidMoc(t){if(t.byteLength<4)return!1;const e=new Int8Array(t,0,4);return"MOC3"===String.fromCharCode(...e)},createModelSettings:t=>new Ut(t),createCoreModel(t,e){const i=Ve.create(t,!!(null==e?void 0:e.checkMocConsistency));try{const t=i.createModel();return t.__moc=i,t}catch(s){try{i.release()}catch(r){}throw s}},createInternalModel(t,e,i){const s=new Te(t,e,i),r=t;return r.__moc&&(s.__moc=r.__moc,delete r.__moc,s.once("destroy",ci)),s},createPhysics:(t,e)=>$e.create(e),createPose:(t,e)=>De.create(e)}),t.Cubism2ExpressionManager=tt,t.Cubism2InternalModel=rt,t.Cubism2ModelSettings=ot,t.Cubism2MotionManager=et,t.Cubism4ExpressionManager=Ot,t.Cubism4InternalModel=Te,t.Cubism4ModelSettings=Ut,t.Cubism4MotionManager=se,t.ExpressionManager=_,t.FileLoader=$,t.FocusController=f,t.InteractionMixin=N,t.InternalModel=S,t.LOGICAL_HEIGHT=2,t.LOGICAL_WIDTH=2,t.Live2DExpression=K,t.Live2DEyeBlink=it,t.Live2DFactory=V,t.Live2DLoader=L,t.Live2DModel=Y,t.Live2DPhysics=lt,t.Live2DPose=ut,t.Live2DTransform=z,t.ModelSettings=x,t.MotionManager=P,t.MotionPreloadStrategy=v,t.MotionPriority=y,t.MotionState=M,t.SoundManager=C,t.VERSION="0.4.0",t.XHRLoader=T,t.ZipLoader=Z,t.applyMixins=g,t.clamp=h,t.copyArray=c,t.copyProperty=d,t.cubism4Ready=Fe,t.folderName=m,t.logger=l,t.rand=u,t.remove=p,t.startUpCubism4=Ae,Object.defineProperties(t,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
From 3ff3a530435401b90d6114457fd90f713c62c958 Mon Sep 17 00:00:00 2001
From: Ratul Hasan <34002411+RaSan147@users.noreply.github.com>
Date: Fri, 6 Oct 2023 07:08:05 -0700
Subject: [PATCH 03/44] Update index.js links
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index bf5362d4..3b737d88 100644
--- a/README.md
+++ b/README.md
@@ -111,13 +111,13 @@ import { Live2DModel } from 'pixi-live2d-display/cubism4';
-
+
-
+
-
+
```
In this way, all the exported members are available under `PIXI.live2d` namespace, such as `PIXI.live2d.Live2DModel`.
From 8539e76eade7a0782a1edc415844c47ed5ab8749 Mon Sep 17 00:00:00 2001
From: Ratul Hasan <34002411+RaSan147@users.noreply.github.com>
Date: Wed, 11 Oct 2023 19:07:06 -0700
Subject: [PATCH 04/44] Update test.yml
---
.github/workflows/test.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 23098a61..05f658ff 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -11,8 +11,9 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v@v4
with:
+ ref: $GITHUB_REF_NAME
submodules: true
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
From cf0f4c4d357db94a46d4f8ee92b501c7cd9d6479 Mon Sep 17 00:00:00 2001
From: Ratul Hasan <34002411+RaSan147@users.noreply.github.com>
Date: Wed, 11 Oct 2023 19:07:37 -0700
Subject: [PATCH 05/44] Update test.yml
---
.github/workflows/test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 05f658ff..82700897 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -11,7 +11,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v@v4
+ - uses: actions/checkout@v4
with:
ref: $GITHUB_REF_NAME
submodules: true
From f53e25a428e8fac9ad66f51c0113797ccf51b7e8 Mon Sep 17 00:00:00 2001
From: Ratul Hasan <34002411+RaSan147@users.noreply.github.com>
Date: Wed, 11 Oct 2023 19:11:03 -0700
Subject: [PATCH 06/44] Update test.yml
---
.github/workflows/test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 82700897..acc5ce14 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -13,7 +13,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
- ref: $GITHUB_REF_NAME
+ ref: ${{github.ref_name}}
submodules: true
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
From 7deba12460f28ff169ac3f2e71732968480c0fde Mon Sep 17 00:00:00 2001
From: Ratul Hasan <34002411+RaSan147@users.noreply.github.com>
Date: Thu, 12 Oct 2023 10:51:00 +0600
Subject: [PATCH 07/44] Fix Lip sync. Breaking change
voice volume expressions are now optional arg {name: value, ....}
---
README.md | 28 +++++++++++++++------
src/Live2DModel.ts | 34 +++++++++++++++++++------
src/cubism-common/MotionManager.ts | 39 ++++++++++++++++++-----------
src/cubism2/Cubism2InternalModel.ts | 22 +++++++++++++++-
src/cubism2/Cubism2MotionManager.ts | 6 ++++-
src/cubism4/Cubism4InternalModel.ts | 32 ++++++++++++++++-------
6 files changed, 120 insertions(+), 41 deletions(-)
diff --git a/README.md b/README.md
index 3b737d88..091a75ef 100644
--- a/README.md
+++ b/README.md
@@ -111,13 +111,13 @@ import { Live2DModel } from 'pixi-live2d-display/cubism4';
-
+
-
+
-
+
```
In this way, all the exported members are available under `PIXI.live2d` namespace, such as `PIXI.live2d.Live2DModel`.
@@ -175,13 +175,20 @@ var model_proxy; //make a global scale handler to use later
```js
var category_name = "Idle" // name of the morion category
var animation_index = 0 // index of animation under that motion category
-var priority_number = 3 // if you want to keep the current animation going or move to new animation by force
+var priority_number = 3 // if you want to keep the current animation going or move to new animation by force [0: no priority, 1: idle, 2: normal, 3: forced]
var audio_link = "https://cdn.jsdelivr.net/gh/RaSan147/pixi-live2d-display@v1.0.3/playground/test.mp3" //[Optional arg, can be null or empty] [relative or full url path] [mp3 or wav file]
var volume = 1; //[Optional arg, can be null or empty] [0.0 - 1.0]
var expression = 4; //[Optional arg, can be null or empty] [index|name of expression]
+var resetExpression = true; //[Optional arg, can be null or empty] [true|false] [default: true] [if true, expression will be reset to default after animation is over]
-model_proxy.motion(category_name, animation_index, priority_number, audio_link, volume, expression)
+model_proxy.motion(category_name, animation_index, priority_number, {voice: audio_link, volume: volume, expression:expression, resetExpression:resetExpression})
// Note: during this animation with sound, other animation will be ignored, even its forced. Once over, it'll be back to normal
+
+// if you dont want voice, just ignore the option
+model_proxy.motion(category_name, animation_index, priority_number)
+model_proxy.motion(category_name, animation_index, priority_number, {expression:expression, resetExpression:resetExpression})
+model_proxy.motion(category_name, animation_index, priority_number, {expression:expression, resetExpression:false})
+
```
## Lipsync Only
@@ -190,12 +197,17 @@ model_proxy.motion(category_name, animation_index, priority_number, audio_link,
* Demo code
```js
var audio_link = "https://cdn.jsdelivr.net/gh/RaSan147/pixi-live2d-display@v1.0.3/playground/test.mp3" // [relative or full url path] [mp3 or wav file]
-
var volume = 1; // [Optional arg, can be null or empty] [0.0 - 1.0]
-
var expression = 4; // [Optional arg, can be null or empty] [index|name of expression]
+var resetExpression = true; // [Optional arg, can be null or empty] [true|false] [default: true] [if true, expression will be reset to default after animation is over]
+
+model_proxy.speak(audio_link, {volume: volume, expression:expression, resetExpression:resetExpression})
+
+// Or if you want to keep some things default
+model_proxy.speak(audio_link)
+model_proxy.speak(audio_link, {volume: volume})
+model_proxy.speak(audio_link, {expression:expression, resetExpression:resetExpression})
-model_proxy.speak(audio_link, volume, expression)
```
## Suddenly stop audio and lipsync
diff --git a/src/Live2DModel.ts b/src/Live2DModel.ts
index 32e64297..cd867122 100644
--- a/src/Live2DModel.ts
+++ b/src/Live2DModel.ts
@@ -199,16 +199,28 @@ export class Live2DModel extends Conta
* Shorthand to start a motion.
* @param group - The motion group.
* @param index - Index in the motion group.
- * @param priority - The priority to be applied.
+ * @param priority - The priority to be applied. (0: No priority, 1: IDLE, 2:NORMAL, 3:FORCE) (default: 2)
+ * ### OPTIONAL: `{name: value, ...}`
* @param sound - The audio url to file or base64 content
- * @param volume - Volume of the sound (0-1) /*new in 1.0.4*
+ * @param volume - Volume of the sound (0-1) (default: 1)
* @param expression - In case you want to mix up a expression while playing sound (bind with Model.expression())
+ * @param resetExpression - Reset the expression to default after the motion is finished (default: true)
* @return Promise that resolves with true if the motion is successfully started, with false otherwise.
*/
- motion(group: string, index?: number, priority?: MotionPriority, sound?: string, volume?:number, expression?: number | string): Promise {
+ motion(group: string, index: number, {priority=2, sound, volume=1, expression, resetExpression=true}:{priority?: MotionPriority, sound?: string, volume?:number, expression?: number | string, resetExpression?:boolean}={}): Promise {
return index === undefined
- ? this.internalModel.motionManager.startRandomMotion(group, priority)
- : this.internalModel.motionManager.startMotion(group, index, priority, sound, volume, expression);
+ ? this.internalModel.motionManager.startRandomMotion(group, priority, {
+ sound: sound,
+ volume: volume,
+ expression: expression,
+ resetExpression: resetExpression
+ })
+ : this.internalModel.motionManager.startMotion(group, index, priority, {
+ sound: sound,
+ volume: volume,
+ expression: expression,
+ resetExpression: resetExpression
+ });
}
@@ -223,12 +235,18 @@ export class Live2DModel extends Conta
/**
* Shorthand to start speaking a sound with an expression. /*new in 1.0.3*
* @param sound - The audio url to file or base64 content
+ * ### OPTIONAL: {name: value, ...}
* @param volume - Volume of the sound (0-1) /*new in 1.0.4*
* @param expression - In case you want to mix up a expression while playing sound (bind with Model.expression())
+ * @param resetExpression - Reset the expression to default after the motion is finished (default: true)
* @returns Promise that resolves with true if the sound is playing, false if it's not
*/
- speak(sound: string, volume?: number, expression?: number | string): Promise {
- return this.internalModel.motionManager.speakUp(sound, volume, expression);
+ speak(sound: string, {volume=1, expression, resetExpression=true}:{volume?:number, expression?: number | string, resetExpression?:boolean}={}): Promise {
+ return this.internalModel.motionManager.speakUp(sound, {
+ volume: volume,
+ expression: expression,
+ resetExpression: resetExpression
+ });
}
@@ -460,4 +478,4 @@ export class Live2DModel extends Conta
}
}
-applyMixins(Live2DModel, [InteractionMixin]);
+applyMixins(Live2DModel, [InteractionMixin]);
\ No newline at end of file
diff --git a/src/cubism-common/MotionManager.ts b/src/cubism-common/MotionManager.ts
index 62f56d57..47e105d1 100644
--- a/src/cubism-common/MotionManager.ts
+++ b/src/cubism-common/MotionManager.ts
@@ -212,12 +212,13 @@ export abstract class MotionManager extends Even
/**
* Only play sound with lip sync /*new in 1.0.3*
- * @param sound - The audio url to file or base64 content
+ * @param sound - The audio url to file or base64 content
+ * ### OPTIONAL: {name: value, ...}
* @param volume - Volume of the sound (0-1) /*new in 1.0.4*
* @param expression - In case you want to mix up a expression while playing sound (bind with Model.expression())
* @returns Promise that resolves with true if the sound is playing, false if it's not
*/
- async speakUp(sound: string, volume?: number, expression?: number | string) {
+ async speakUp(sound: string, {volume=1, expression, resetExpression=true}:{volume?:number, expression?: number | string, resetExpression?:boolean}={}) {
if (!config.sound) {
return false;
}
@@ -258,9 +259,9 @@ export abstract class MotionManager extends Even
// start to load the audio
audio = SoundManager.add(
file,
- () => {expression && that.expressionManager && that.expressionManager.resetExpression();
+ () => {resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = undefined}, // reset expression when audio is done
- () => {expression && that.expressionManager && that.expressionManager.resetExpression();
+ () => {resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = undefined} // on error
);
this.currentAudio = audio!;
@@ -311,13 +312,15 @@ export abstract class MotionManager extends Even
* Starts a motion as given priority.
* @param group - The motion group.
* @param index - Index in the motion group.
- * @param priority - The priority to be applied.
+ * @param priority - The priority to be applied. default: 2 (NORMAL)
+ * ### OPTIONAL: {name: value, ...}
* @param sound - The audio url to file or base64 content
* @param volume - Volume of the sound (0-1)
* @param expression - In case you want to mix up a expression while playing sound (bind with Model.expression())
+ * @param resetExpression - Reset expression before and after playing sound (default: true)
* @return Promise that resolves with true if the motion is successfully started, with false otherwise.
*/
- async startMotion(group: string, index: number, priority = MotionPriority.NORMAL, sound?: string, volume?: number, expression?: number | string): Promise {
+ async startMotion(group: string, index: number, priority = MotionPriority.NORMAL, {sound=undefined, volume=1, expression=undefined, resetExpression=true}:{sound?: string, volume?:number, expression?: number | string, resetExpression?:boolean}={}): Promise {
// Does not start a new motion if audio is still playing
if(this.currentAudio){
if (!this.currentAudio.ended){
@@ -367,9 +370,9 @@ export abstract class MotionManager extends Even
// start to load the audio
audio = SoundManager.add(
file,
- () => {expression && that.expressionManager && that.expressionManager.resetExpression();
+ () => {resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = undefined}, // reset expression when audio is done
- () => {expression && that.expressionManager && that.expressionManager.resetExpression();
+ () => {resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = undefined} // on error
);
this.currentAudio = audio!;
@@ -416,6 +419,7 @@ export abstract class MotionManager extends Even
return false;
}
+
if (this.state.shouldOverrideExpression()) {
@@ -440,12 +444,15 @@ export abstract class MotionManager extends Even
/**
* Starts a random Motion as given priority.
* @param group - The motion group.
- * @param priority - The priority to be applied.
- * @param sound - The wav url file or base64 content
- * @param volume - Volume of the sound (0-1)
+ * @param priority - The priority to be applied. (default: 1 `IDLE`)
+ * ### OPTIONAL: {name: value, ...}
+ * @param sound - The wav url file or base64 content+
+ * @param volume - Volume of the sound (0-1) (default: 1)
+ * @param expression - In case you want to mix up a expression while playing sound (name/index)
+ * @param resetExpression - Reset expression before and after playing sound (default: true)
* @return Promise that resolves with true if the motion is successfully started, with false otherwise.
*/
- async startRandomMotion(group: string, priority?: MotionPriority, sound?: string, volume?: number): Promise {
+ async startRandomMotion(group: string, priority?:MotionPriority, {sound=undefined, volume=1, expression=undefined, resetExpression=true}:{sound?: string, volume?:number, expression?: number | string, resetExpression?:boolean}={}): Promise {
const groupDefs = this.definitions[group];
if (groupDefs?.length) {
@@ -460,7 +467,11 @@ export abstract class MotionManager extends Even
if (availableIndices.length) {
const index = availableIndices[Math.floor(Math.random() * availableIndices.length)]!;
- return this.startMotion(group, index, priority, sound, volume);
+ return this.startMotion(group, index, priority, {
+ sound: sound,
+ volume: volume,
+ expression: expression,
+ resetExpression: resetExpression});
}
}
@@ -593,4 +604,4 @@ export abstract class MotionManager extends Even
* @return True if the parameters have been actually updated.
*/
protected abstract updateParameters(model: object, now: DOMHighResTimeStamp): boolean;
-}
+}
\ No newline at end of file
diff --git a/src/cubism2/Cubism2InternalModel.ts b/src/cubism2/Cubism2InternalModel.ts
index 3ed36a44..dfa6872e 100644
--- a/src/cubism2/Cubism2InternalModel.ts
+++ b/src/cubism2/Cubism2InternalModel.ts
@@ -5,6 +5,7 @@ import { Cubism2MotionManager } from './Cubism2MotionManager';
import { Live2DEyeBlink } from './Live2DEyeBlink';
import { Live2DPhysics } from './Live2DPhysics';
import { Live2DPose } from './Live2DPose';
+import { clamp } from '@/utils';
// prettier-ignore
const tempMatrixArray = new Float32Array([
@@ -33,9 +34,12 @@ export class Cubism2InternalModel extends InternalModel {
angleZParamIndex: number;
bodyAngleXParamIndex: number;
breathParamIndex: number;
+ mouthFormIndex: number;
textureFlipY = true;
+ lipSync = true;
+
/**
* Number of the drawables in this model.
*/
@@ -62,6 +66,7 @@ export class Cubism2InternalModel extends InternalModel {
this.angleZParamIndex = coreModel.getParamIndex('PARAM_ANGLE_Z');
this.bodyAngleXParamIndex = coreModel.getParamIndex('PARAM_BODY_ANGLE_X');
this.breathParamIndex = coreModel.getParamIndex('PARAM_BREATH');
+ this.mouthFormIndex = coreModel.getParamIndex("PARAM_MOUTH_FORM");
this.init();
}
@@ -217,6 +222,21 @@ export class Cubism2InternalModel extends InternalModel {
this.updateFocus();
this.updateNaturalMovements(dt, now);
+
+ if (this.lipSync && this.motionManager.currentAudio) {
+ let value = this.motionManager.mouthSync();
+ let min_ = 0;
+ let max_ = 1;
+ let weight = 1.2;
+ if (value > 0) {
+ min_ = 0.4;
+ }
+ value = clamp(value * weight, min_, max_);
+
+ for (let i = 0; i < this.motionManager.lipSyncIds.length; ++i) {
+ this.coreModel.setParamFloat(this.coreModel.getParamIndex(this.motionManager.lipSyncIds[i]!), value);
+ }
+ }
this.physics?.update(now);
this.pose?.update(dt);
@@ -277,4 +297,4 @@ export class Cubism2InternalModel extends InternalModel {
// cubism2 core has a super dumb memory management so there's basically nothing much to do to release the model
(this as Partial).coreModel = undefined;
}
-}
+}
\ No newline at end of file
diff --git a/src/cubism2/Cubism2MotionManager.ts b/src/cubism2/Cubism2MotionManager.ts
index 0815afe1..29c7dabc 100644
--- a/src/cubism2/Cubism2MotionManager.ts
+++ b/src/cubism2/Cubism2MotionManager.ts
@@ -15,6 +15,8 @@ export class Cubism2MotionManager extends MotionManager>).queueManager = undefined;
}
-}
+}
\ No newline at end of file
diff --git a/src/cubism4/Cubism4InternalModel.ts b/src/cubism4/Cubism4InternalModel.ts
index 6e3867b6..310b52ca 100644
--- a/src/cubism4/Cubism4InternalModel.ts
+++ b/src/cubism4/Cubism4InternalModel.ts
@@ -10,6 +10,7 @@ import {
ParamBreath,
ParamEyeBallX,
ParamEyeBallY,
+ ParamMouthForm,
} from '@cubism/cubismdefaultparameterid';
import { BreathParameterData, CubismBreath } from '@cubism/effect/cubismbreath';
import { CubismEyeBlink } from '@cubism/effect/cubismeyeblink';
@@ -21,6 +22,7 @@ import { CubismPhysics } from '@cubism/physics/cubismphysics';
import { CubismRenderer_WebGL, CubismShader_WebGL } from '@cubism/rendering/cubismrenderer_webgl';
import { Matrix } from '@pixi/math';
import { Mutable } from '../types/helpers';
+import { clamp } from '@/utils';
const tempMatrix = new CubismMatrix44();
@@ -49,6 +51,7 @@ export class Cubism4InternalModel extends InternalModel {
idParamEyeBallY = ParamEyeBallY;
idParamBodyAngleX = ParamBodyAngleX;
idParamBreath = ParamBreath;
+ idParamMouthForm = ParamMouthForm;
/**
* The model's internal scale, defined in the moc3 file.
@@ -209,14 +212,20 @@ export class Cubism4InternalModel extends InternalModel {
// revert the timestamps to be milliseconds
this.updateNaturalMovements(dt * 1000, now * 1000);
- // TODO: Add lip sync API
- // if (this.lipSync) {
- // const value = 0; // 0 ~ 1
- //
- // for (let i = 0; i < this.lipSyncIds.length; ++i) {
- // model.addParameterValueById(this.lipSyncIds[i], value, 0.8);
- // }
- // }
+ if (this.lipSync && this.motionManager.currentAudio) {
+ let value = this.motionManager.mouthSync();
+ let min_ = 0;
+ let max_ = 1;
+ let weight = 1.2;
+ if (value > 0) {
+ min_ = 0.4;
+ }
+ value = clamp(value * weight, min_, max_);
+
+ for (let i = 0; i < this.motionManager.lipSyncIds.length; ++i) {
+ model.addParameterValueById(this.motionManager.lipSyncIds[i], value, 0.8);
+ }
+ }
this.physics?.evaluate(model, dt);
this.pose?.updateParameters(model, dt);
@@ -236,6 +245,11 @@ export class Cubism4InternalModel extends InternalModel {
this.coreModel.addParameterValueById(this.idParamBodyAngleX, this.focusController.x * 10); // -10 ~ 10
}
+
+ updateFacialEmotion(mouthForm: number) {
+ this.coreModel.addParameterValueById(this.idParamMouthForm, mouthForm); // -1 ~ 1
+ }
+
updateNaturalMovements(dt: DOMHighResTimeStamp, now: DOMHighResTimeStamp) {
this.breath?.updateParameters(this.coreModel, dt / 1000);
}
@@ -266,4 +280,4 @@ export class Cubism4InternalModel extends InternalModel {
(this as Partial).renderer = undefined;
(this as Partial).coreModel = undefined;
}
-}
+}
\ No newline at end of file
From 06bfbd38409bbb13f8591c81860b17ed8eb214a0 Mon Sep 17 00:00:00 2001
From: RaSan147 <34002411+RaSan147@users.noreply.github.com>
Date: Thu, 12 Oct 2023 04:56:17 +0000
Subject: [PATCH 08/44] Automated report
---
dist/cubism2.es.js | 63 +++++++++++++++++++++++++++--------
dist/cubism2.js | 63 +++++++++++++++++++++++++++--------
dist/cubism2.min.js | 2 +-
dist/cubism4.es.js | 64 +++++++++++++++++++++++++++--------
dist/cubism4.js | 64 +++++++++++++++++++++++++++--------
dist/cubism4.min.js | 2 +-
dist/index.es.js | 81 +++++++++++++++++++++++++++++++++++++--------
dist/index.js | 81 +++++++++++++++++++++++++++++++++++++--------
dist/index.min.js | 2 +-
9 files changed, 335 insertions(+), 87 deletions(-)
diff --git a/dist/cubism2.es.js b/dist/cubism2.es.js
index cc571236..edb9ad49 100644
--- a/dist/cubism2.es.js
+++ b/dist/cubism2.es.js
@@ -582,8 +582,8 @@ class MotionManager extends EventEmitter {
_loadMotion(group, index) {
throw new Error("Not implemented.");
}
- speakUp(sound, volume, expression) {
- return __async(this, null, function* () {
+ speakUp(_0) {
+ return __async(this, arguments, function* (sound, { volume = 1, expression, resetExpression = true } = {}) {
if (!config.sound) {
return false;
}
@@ -614,10 +614,10 @@ class MotionManager extends EventEmitter {
if (file) {
try {
audio = SoundManager.add(file, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
}, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
});
this.currentAudio = audio;
@@ -651,7 +651,7 @@ class MotionManager extends EventEmitter {
});
}
startMotion(_0, _1) {
- return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, sound, volume, expression) {
+ return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, { sound = void 0, volume = 1, expression = void 0, resetExpression = true } = {}) {
var _a;
if (this.currentAudio) {
if (!this.currentAudio.ended) {
@@ -691,10 +691,10 @@ class MotionManager extends EventEmitter {
if (file) {
try {
audio = SoundManager.add(file, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
}, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
});
this.currentAudio = audio;
@@ -740,8 +740,8 @@ class MotionManager extends EventEmitter {
return true;
});
}
- startRandomMotion(group, priority, sound, volume) {
- return __async(this, null, function* () {
+ startRandomMotion(_0, _1) {
+ return __async(this, arguments, function* (group, priority, { sound = void 0, volume = 1, expression = void 0, resetExpression = true } = {}) {
const groupDefs = this.definitions[group];
if (groupDefs == null ? void 0 : groupDefs.length) {
const availableIndices = [];
@@ -752,7 +752,12 @@ class MotionManager extends EventEmitter {
}
if (availableIndices.length) {
const index = availableIndices[Math.floor(Math.random() * availableIndices.length)];
- return this.startMotion(group, index, priority, sound, volume);
+ return this.startMotion(group, index, priority, {
+ sound,
+ volume,
+ expression,
+ resetExpression
+ });
}
}
return false;
@@ -1398,14 +1403,28 @@ class Live2DModel extends Container {
onAnchorChange() {
this.pivot.set(this.anchor.x * this.internalModel.width, this.anchor.y * this.internalModel.height);
}
- motion(group, index, priority, sound, volume, expression) {
- return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority) : this.internalModel.motionManager.startMotion(group, index, priority, sound, volume, expression);
+ motion(group, index, { priority = 2, sound, volume = 1, expression, resetExpression = true } = {}) {
+ return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority, {
+ sound,
+ volume,
+ expression,
+ resetExpression
+ }) : this.internalModel.motionManager.startMotion(group, index, priority, {
+ sound,
+ volume,
+ expression,
+ resetExpression
+ });
}
resetMotions() {
return this.internalModel.motionManager.stopAllMotions();
}
- speak(sound, volume, expression) {
- return this.internalModel.motionManager.speakUp(sound, volume, expression);
+ speak(sound, { volume = 1, expression, resetExpression = true } = {}) {
+ return this.internalModel.motionManager.speakUp(sound, {
+ volume,
+ expression,
+ resetExpression
+ });
}
stopSpeaking() {
return this.internalModel.motionManager.stopSpeaking();
@@ -1790,6 +1809,7 @@ class Cubism2MotionManager extends MotionManager {
this.queueManager = new MotionQueueManager();
this.definitions = this.settings.motions;
this.init(options);
+ this.lipSyncIds = ["PARAM_MOUTH_OPEN_Y"];
}
init(options) {
super.init(options);
@@ -1903,6 +1923,7 @@ class Cubism2InternalModel extends InternalModel {
constructor(coreModel, settings, options) {
super();
this.textureFlipY = true;
+ this.lipSync = true;
this.drawDataCount = 0;
this.disableCulling = false;
this.coreModel = coreModel;
@@ -1916,6 +1937,7 @@ class Cubism2InternalModel extends InternalModel {
this.angleZParamIndex = coreModel.getParamIndex("PARAM_ANGLE_Z");
this.bodyAngleXParamIndex = coreModel.getParamIndex("PARAM_BODY_ANGLE_X");
this.breathParamIndex = coreModel.getParamIndex("PARAM_BREATH");
+ this.mouthFormIndex = coreModel.getParamIndex("PARAM_MOUTH_FORM");
this.init();
}
init() {
@@ -2024,6 +2046,19 @@ class Cubism2InternalModel extends InternalModel {
}
this.updateFocus();
this.updateNaturalMovements(dt, now);
+ if (this.lipSync && this.motionManager.currentAudio) {
+ let value = this.motionManager.mouthSync();
+ let min_ = 0;
+ let max_ = 1;
+ let weight = 1.2;
+ if (value > 0) {
+ min_ = 0.4;
+ }
+ value = clamp(value * weight, min_, max_);
+ for (let i = 0; i < this.motionManager.lipSyncIds.length; ++i) {
+ this.coreModel.setParamFloat(this.coreModel.getParamIndex(this.motionManager.lipSyncIds[i]), value);
+ }
+ }
(_c = this.physics) == null ? void 0 : _c.update(now);
(_d = this.pose) == null ? void 0 : _d.update(dt);
this.emit("beforeModelUpdate");
diff --git a/dist/cubism2.js b/dist/cubism2.js
index 4e1b5539..638e2b73 100644
--- a/dist/cubism2.js
+++ b/dist/cubism2.js
@@ -582,8 +582,8 @@ var __async = (__this, __arguments, generator) => {
_loadMotion(group, index) {
throw new Error("Not implemented.");
}
- speakUp(sound, volume, expression) {
- return __async(this, null, function* () {
+ speakUp(_0) {
+ return __async(this, arguments, function* (sound, { volume = 1, expression, resetExpression = true } = {}) {
if (!exports2.config.sound) {
return false;
}
@@ -614,10 +614,10 @@ var __async = (__this, __arguments, generator) => {
if (file) {
try {
audio = SoundManager.add(file, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
}, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
});
this.currentAudio = audio;
@@ -651,7 +651,7 @@ var __async = (__this, __arguments, generator) => {
});
}
startMotion(_0, _1) {
- return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, sound, volume, expression) {
+ return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, { sound = void 0, volume = 1, expression = void 0, resetExpression = true } = {}) {
var _a;
if (this.currentAudio) {
if (!this.currentAudio.ended) {
@@ -691,10 +691,10 @@ var __async = (__this, __arguments, generator) => {
if (file) {
try {
audio = SoundManager.add(file, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
}, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
});
this.currentAudio = audio;
@@ -740,8 +740,8 @@ var __async = (__this, __arguments, generator) => {
return true;
});
}
- startRandomMotion(group, priority, sound, volume) {
- return __async(this, null, function* () {
+ startRandomMotion(_0, _1) {
+ return __async(this, arguments, function* (group, priority, { sound = void 0, volume = 1, expression = void 0, resetExpression = true } = {}) {
const groupDefs = this.definitions[group];
if (groupDefs == null ? void 0 : groupDefs.length) {
const availableIndices = [];
@@ -752,7 +752,12 @@ var __async = (__this, __arguments, generator) => {
}
if (availableIndices.length) {
const index = availableIndices[Math.floor(Math.random() * availableIndices.length)];
- return this.startMotion(group, index, priority, sound, volume);
+ return this.startMotion(group, index, priority, {
+ sound,
+ volume,
+ expression,
+ resetExpression
+ });
}
}
return false;
@@ -1398,14 +1403,28 @@ var __async = (__this, __arguments, generator) => {
onAnchorChange() {
this.pivot.set(this.anchor.x * this.internalModel.width, this.anchor.y * this.internalModel.height);
}
- motion(group, index, priority, sound, volume, expression) {
- return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority) : this.internalModel.motionManager.startMotion(group, index, priority, sound, volume, expression);
+ motion(group, index, { priority = 2, sound, volume = 1, expression, resetExpression = true } = {}) {
+ return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority, {
+ sound,
+ volume,
+ expression,
+ resetExpression
+ }) : this.internalModel.motionManager.startMotion(group, index, priority, {
+ sound,
+ volume,
+ expression,
+ resetExpression
+ });
}
resetMotions() {
return this.internalModel.motionManager.stopAllMotions();
}
- speak(sound, volume, expression) {
- return this.internalModel.motionManager.speakUp(sound, volume, expression);
+ speak(sound, { volume = 1, expression, resetExpression = true } = {}) {
+ return this.internalModel.motionManager.speakUp(sound, {
+ volume,
+ expression,
+ resetExpression
+ });
}
stopSpeaking() {
return this.internalModel.motionManager.stopSpeaking();
@@ -1790,6 +1809,7 @@ var __async = (__this, __arguments, generator) => {
this.queueManager = new MotionQueueManager();
this.definitions = this.settings.motions;
this.init(options);
+ this.lipSyncIds = ["PARAM_MOUTH_OPEN_Y"];
}
init(options) {
super.init(options);
@@ -1903,6 +1923,7 @@ var __async = (__this, __arguments, generator) => {
constructor(coreModel, settings, options) {
super();
this.textureFlipY = true;
+ this.lipSync = true;
this.drawDataCount = 0;
this.disableCulling = false;
this.coreModel = coreModel;
@@ -1916,6 +1937,7 @@ var __async = (__this, __arguments, generator) => {
this.angleZParamIndex = coreModel.getParamIndex("PARAM_ANGLE_Z");
this.bodyAngleXParamIndex = coreModel.getParamIndex("PARAM_BODY_ANGLE_X");
this.breathParamIndex = coreModel.getParamIndex("PARAM_BREATH");
+ this.mouthFormIndex = coreModel.getParamIndex("PARAM_MOUTH_FORM");
this.init();
}
init() {
@@ -2024,6 +2046,19 @@ var __async = (__this, __arguments, generator) => {
}
this.updateFocus();
this.updateNaturalMovements(dt, now);
+ if (this.lipSync && this.motionManager.currentAudio) {
+ let value = this.motionManager.mouthSync();
+ let min_ = 0;
+ let max_ = 1;
+ let weight = 1.2;
+ if (value > 0) {
+ min_ = 0.4;
+ }
+ value = clamp(value * weight, min_, max_);
+ for (let i = 0; i < this.motionManager.lipSyncIds.length; ++i) {
+ this.coreModel.setParamFloat(this.coreModel.getParamIndex(this.motionManager.lipSyncIds[i]), value);
+ }
+ }
(_c = this.physics) == null ? void 0 : _c.update(now);
(_d = this.pose) == null ? void 0 : _d.update(dt);
this.emit("beforeModelUpdate");
diff --git a/dist/cubism2.min.js b/dist/cubism2.min.js
index bf8ea022..9a093c2f 100644
--- a/dist/cubism2.min.js
+++ b/dist/cubism2.min.js
@@ -1 +1 @@
-var __pow=Math.pow,__async=(t,e,s)=>new Promise(((i,r)=>{var o=t=>{try{a(s.next(t))}catch(e){r(e)}},n=t=>{try{a(s.throw(t))}catch(e){r(e)}},a=t=>t.done?i(t.value):Promise.resolve(t.value).then(o,n);a((s=s.apply(t,e)).next())}));!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@pixi/utils"),require("@pixi/math"),require("@pixi/core"),require("@pixi/display")):"function"==typeof define&&define.amd?define(["exports","@pixi/utils","@pixi/math","@pixi/core","@pixi/display"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).PIXI=t.PIXI||{},t.PIXI.live2d=t.PIXI.live2d||{}),t.PIXI.utils,t.PIXI,t.PIXI,t.PIXI)}(this,(function(t,e,s,i,r){"use strict";var o,n,a;(n=o||(o={})).supportMoreMaskDivisions=!0,n.setOpacityFromMotion=!1,t.config=void 0,(a=t.config||(t.config={})).LOG_LEVEL_VERBOSE=0,a.LOG_LEVEL_WARNING=1,a.LOG_LEVEL_ERROR=2,a.LOG_LEVEL_NONE=999,a.logLevel=a.LOG_LEVEL_WARNING,a.sound=!0,a.motionSync=!0,a.motionFadingDuration=500,a.idleMotionFadingDuration=2e3,a.expressionFadingDuration=500,a.preserveExpressionOnMotion=!0,a.cubism4=o;const l={log(e,...s){t.config.logLevel<=t.config.LOG_LEVEL_VERBOSE&&console.log(`[${e}]`,...s)},warn(e,...s){t.config.logLevel<=t.config.LOG_LEVEL_WARNING&&console.warn(`[${e}]`,...s)},error(e,...s){t.config.logLevel<=t.config.LOG_LEVEL_ERROR&&console.error(`[${e}]`,...s)}};function d(t,e,s){return ts?s:t}function h(t,e){return Math.random()*(e-t)+t}function c(t,e,s,i,r){const o=e[i];null!==o&&typeof o===t&&(s[r]=o)}function u(t,e,s,i,r){const o=e[i];Array.isArray(o)&&(s[r]=o.filter((e=>null!==e&&typeof e===t)))}function p(t,e){e.forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((s=>{"constructor"!==s&&Object.defineProperty(t.prototype,s,Object.getOwnPropertyDescriptor(e.prototype,s))}))}))}function g(t){let e=t.lastIndexOf("/");return-1!=e&&(t=t.slice(0,e)),e=t.lastIndexOf("/"),-1!==e&&(t=t.slice(e+1)),t}function m(t,e){const s=t.indexOf(e);-1!==s&&t.splice(s,1)}class f extends e.EventEmitter{constructor(t,e){super(),this.expressions=[],this.reserveExpressionIndex=-1,this.destroyed=!1,this.settings=t,this.tag=`ExpressionManager(${t.name})`}init(){this.defaultExpression=this.createExpression({},void 0),this.currentExpression=this.defaultExpression,this.stopAllExpressions()}loadExpression(t){return __async(this,null,(function*(){if(!this.definitions[t])return void l.warn(this.tag,`Undefined expression at [${t}]`);if(null===this.expressions[t])return void l.warn(this.tag,`Cannot set expression at [${t}] because it's already failed in loading.`);if(this.expressions[t])return this.expressions[t];const e=yield this._loadExpression(t);return this.expressions[t]=e,e}))}_loadExpression(t){throw new Error("Not implemented.")}setRandomExpression(){return __async(this,null,(function*(){if(this.definitions.length){const t=[];for(let e=0;e-1&&tl&&(o*=l/a,n*=l/a),this.vx+=o,this.vy+=n;const d=Math.sqrt(__pow(this.vx,2)+__pow(this.vy,2)),h=.5*(Math.sqrt(__pow(l,2)+8*l*i)-l);d>h&&(this.vx*=h/d,this.vy*=h/d),this.x+=this.vx,this.y+=this.vy}}class x{constructor(t){this.json=t;let e=t.url;if("string"!=typeof e)throw new TypeError("The `url` field in settings JSON must be defined as a string.");this.url=e,this.name=g(this.url)}resolveURL(t){return e.url.resolve(this.url,t)}replaceFiles(t){this.moc=t(this.moc,"moc"),void 0!==this.pose&&(this.pose=t(this.pose,"pose")),void 0!==this.physics&&(this.physics=t(this.physics,"physics"));for(let e=0;e(t.push(e),e))),t}validateFiles(t){const e=(e,s)=>{const i=this.resolveURL(e);if(!t.includes(i)){if(s)throw new Error(`File "${e}" is defined in settings, but doesn't exist in given files`);return!1}return!0};[this.moc,...this.textures].forEach((t=>e(t,!0)));return this.getDefinedFiles().filter((t=>e(t,!1)))}}var M=(t=>(t[t.NONE=0]="NONE",t[t.IDLE=1]="IDLE",t[t.NORMAL=2]="NORMAL",t[t.FORCE=3]="FORCE",t))(M||{});class v{constructor(){this.debug=!1,this.currentPriority=0,this.reservePriority=0}reserve(t,e,s){if(s<=0)return l.log(this.tag,"Cannot start a motion with MotionPriority.NONE."),!1;if(t===this.currentGroup&&e===this.currentIndex)return l.log(this.tag,"Motion is already playing.",this.dump(t,e)),!1;if(t===this.reservedGroup&&e===this.reservedIndex||t===this.reservedIdleGroup&&e===this.reservedIdleIndex)return l.log(this.tag,"Motion is already reserved.",this.dump(t,e)),!1;if(1===s){if(0!==this.currentPriority)return l.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(t,e)),!1;if(void 0!==this.reservedIdleGroup)return l.log(this.tag,"Cannot start idle motion because another idle motion has reserved.",this.dump(t,e)),!1;this.setReservedIdle(t,e)}else{if(s<3){if(s<=this.currentPriority)return l.log(this.tag,"Cannot start motion because another motion is playing as an equivalent or higher priority.",this.dump(t,e)),!1;if(s<=this.reservePriority)return l.log(this.tag,"Cannot start motion because another motion has reserved as an equivalent or higher priority.",this.dump(t,e)),!1}this.setReserved(t,e,s)}return!0}start(t,e,s,i){if(1===i){if(this.setReservedIdle(void 0,void 0),0!==this.currentPriority)return l.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(e,s)),!1}else{if(e!==this.reservedGroup||s!==this.reservedIndex)return l.log(this.tag,"Cannot start motion because another motion has taken the place.",this.dump(e,s)),!1;this.setReserved(void 0,void 0,0)}return!!t&&(this.setCurrent(e,s,i),!0)}complete(){this.setCurrent(void 0,void 0,0)}setCurrent(t,e,s){this.currentPriority=s,this.currentGroup=t,this.currentIndex=e}setReserved(t,e,s){this.reservePriority=s,this.reservedGroup=t,this.reservedIndex=e}setReservedIdle(t,e){this.reservedIdleGroup=t,this.reservedIdleIndex=e}isActive(t,e){return t===this.currentGroup&&e===this.currentIndex||t===this.reservedGroup&&e===this.reservedIndex||t===this.reservedIdleGroup&&e===this.reservedIdleIndex}reset(){this.setCurrent(void 0,void 0,0),this.setReserved(void 0,void 0,0),this.setReservedIdle(void 0,void 0)}shouldRequestIdleMotion(){return void 0===this.currentGroup&&void 0===this.reservedIdleGroup}shouldOverrideExpression(){return!t.config.preserveExpressionOnMotion&&this.currentPriority>1}dump(t,e){if(this.debug){return`\n group = "${t}", index = ${e}\n`+["currentPriority","reservePriority","currentGroup","currentIndex","reservedGroup","reservedIndex","reservedIdleGroup","reservedIdleIndex"].map((t=>"["+t+"] "+this[t])).join("\n")}return""}}class w{static get volume(){return this._volume}static set volume(t){this._volume=(t>1?1:t<0?0:t)||0,this.audios.forEach((t=>t.volume=this._volume))}static add(t,e,s){const i=new Audio(t);return i.volume=this._volume,i.preload="auto",i.autoplay=!0,i.crossOrigin="anonymous",i.addEventListener("ended",(()=>{this.dispose(i),null==e||e()})),i.addEventListener("error",(e=>{this.dispose(i),l.warn("SoundManager",`Error occurred on "${t}"`,e.error),null==s||s(e.error)})),this.audios.push(i),i}static play(t){return new Promise(((e,s)=>{var i;null==(i=t.play())||i.catch((e=>{t.dispatchEvent(new ErrorEvent("error",{error:e})),s(e)})),t.readyState===t.HAVE_ENOUGH_DATA?e():t.addEventListener("canplaythrough",e)}))}static addContext(t){const e=new AudioContext;return this.contexts.push(e),e}static addAnalyzer(t,e){const s=e.createMediaElementSource(t),i=e.createAnalyser();return i.fftSize=256,i.minDecibels=-90,i.maxDecibels=-10,i.smoothingTimeConstant=.85,s.connect(i),i.connect(e.destination),this.analysers.push(i),i}static analyze(t){if(null!=t){let e=new Float32Array(t.fftSize),s=0;t.getFloatTimeDomainData(e);for(const t of e)s+=t*t;return parseFloat(Math.sqrt(s/e.length*20).toFixed(1))}return parseFloat(Math.random().toFixed(1))}static dispose(t){t.pause(),t.removeAttribute("src"),m(this.audios,t)}static destroy(){for(let t=this.contexts.length-1;t>=0;t--)this.contexts[t].close();for(let t=this.audios.length-1;t>=0;t--)this.dispose(this.audios[t])}}w.audios=[],w.analysers=[],w.contexts=[],w._volume=.9;var E=(t=>(t.ALL="ALL",t.IDLE="IDLE",t.NONE="NONE",t))(E||{});class P extends e.EventEmitter{constructor(t,e){super(),this.motionGroups={},this.state=new v,this.playing=!1,this.destroyed=!1,this.settings=t,this.tag=`MotionManager(${t.name})`,this.state.tag=this.tag}init(t){(null==t?void 0:t.idleMotionGroup)&&(this.groups.idle=t.idleMotionGroup),this.setupMotions(t),this.stopAllMotions()}setupMotions(t){for(const s of Object.keys(this.definitions))this.motionGroups[s]=[];let e;switch(null==t?void 0:t.motionPreload){case"NONE":return;case"ALL":e=Object.keys(this.definitions);break;default:e=[this.groups.idle]}for(const s of e)if(this.definitions[s])for(let t=0;t{i&&u.expressionManager&&u.expressionManager.resetExpression(),u.currentAudio=void 0}),(()=>{i&&u.expressionManager&&u.expressionManager.resetExpression(),u.currentAudio=void 0})),this.currentAudio=r;let t=1;void 0!==s&&(t=s),w.volume=t,n=w.addContext(this.currentAudio),this.currentContext=n,o=w.addAnalyzer(this.currentAudio,this.currentContext),this.currentAnalyzer=o}catch(p){l.warn(this.tag,"Failed to create audio",a,p)}if(r){const e=w.play(r).catch((t=>l.warn(this.tag,"Failed to play audio",r.src,t)));t.config.motionSync&&(yield e)}return this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),i&&this.expressionManager&&this.expressionManager.setExpression(i),this.playing=!0,!0}))}startMotion(e,s){return __async(this,arguments,(function*(e,s,i=M.NORMAL,r,o,n){var a;if(this.currentAudio&&!this.currentAudio.ended)return!1;if(!this.state.reserve(e,s,i))return!1;const d=null==(a=this.definitions[e])?void 0:a[s];if(!d)return!1;let h,c,u;if(this.currentAudio&&w.dispose(this.currentAudio),t.config.sound){const t=r&&r.startsWith("data:audio/wav;base64");if(r&&!t){var p=document.createElement("a");p.href=r,r=p.href}const e=r&&(r.startsWith("http")||r.startsWith("blob")),s=this.getSoundFile(d);let i=s;s&&(i=this.settings.resolveURL(s)+"?cache-buster="+(new Date).getTime()),(e||t)&&(i=r);const a=this;if(i)try{h=w.add(i,(()=>{n&&a.expressionManager&&a.expressionManager.resetExpression(),a.currentAudio=void 0}),(()=>{n&&a.expressionManager&&a.expressionManager.resetExpression(),a.currentAudio=void 0})),this.currentAudio=h;let t=1;void 0!==o&&(t=o),w.volume=t,u=w.addContext(this.currentAudio),this.currentContext=u,c=w.addAnalyzer(this.currentAudio,this.currentContext),this.currentAnalyzer=c}catch(m){l.warn(this.tag,"Failed to create audio",s,m)}}const g=yield this.loadMotion(e,s);if(h){i=3;const e=w.play(h).catch((t=>l.warn(this.tag,"Failed to play audio",h.src,t)));t.config.motionSync&&(yield e)}return this.state.start(g,e,s,i)?(this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),l.log(this.tag,"Start motion:",this.getMotionName(d)),this.emit("motionStart",e,s,h),n&&this.expressionManager&&this.expressionManager.setExpression(n),this.playing=!0,this._startMotion(g),!0):(h&&(w.dispose(h),this.currentAudio=void 0),!1)}))}startRandomMotion(t,e,s,i){return __async(this,null,(function*(){const r=this.definitions[t];if(null==r?void 0:r.length){const o=[];for(let e=0;et.index>=0));for(const e of t)this.hitAreas[e.name]=e}hitTest(t,e){return Object.keys(this.hitAreas).filter((s=>this.isHit(s,t,e)))}isHit(t,e,s){if(!this.hitAreas[t])return!1;const i=this.hitAreas[t].index,r=this.getDrawableBounds(i,_);return r.x<=e&&e<=r.x+r.width&&r.y<=s&&s<=r.y+r.height}getDrawableBounds(t,e){const s=this.getDrawableVertices(t);let i=s[0],r=s[0],o=s[1],n=s[1];for(let a=0;a{200!==o.status&&0!==o.status||!o.response?o.onerror():i(o.response)},o.onerror=()=>{l.warn("XHRLoader",`Failed to load resource as ${o.responseType} (Status ${o.status}): ${e}`),r(new L("Network error.",e,o.status))},o.onabort=()=>r(new L("Aborted.",e,o.status,!0)),o.onloadend=()=>{var e;b.allXhrSet.delete(o),t&&(null==(e=b.xhrMap.get(t))||e.delete(o))},o}static cancelXHRs(){var t;null==(t=b.xhrMap.get(this))||t.forEach((t=>{t.abort(),b.allXhrSet.delete(t)})),b.xhrMap.delete(this)}static release(){b.allXhrSet.forEach((t=>t.abort())),b.allXhrSet.clear(),b.xhrMap=new WeakMap}};let T=b;function O(t,e){let s=-1;return function i(r,o){if(o)return Promise.reject(o);if(r<=s)return Promise.reject(new Error("next() called multiple times"));s=r;const n=t[r];if(!n)return Promise.resolve();try{return Promise.resolve(n(e,i.bind(null,r+1)))}catch(a){return Promise.reject(a)}}(0)}T.xhrMap=new WeakMap,T.allXhrSet=new Set,T.loader=(t,e)=>new Promise(((e,s)=>{b.createXHR(t.target,t.settings?t.settings.resolveURL(t.url):t.url,t.type,(s=>{t.result=s,e()}),s).send()}));class A{static load(t){return O(this.middlewares,t).then((()=>t.result))}}A.middlewares=[T.loader];const R="Live2DFactory",F=(t,e)=>__async(this,null,(function*(){if("string"==typeof t.source){const e=yield A.load({url:t.source,type:"json",target:t.live2dModel});e.url=t.source,t.source=e,t.live2dModel.emit("settingsJSONLoaded",e)}return e()})),D=(t,e)=>__async(this,null,(function*(){if(t.source instanceof x)return t.settings=t.source,e();if("object"==typeof t.source){const s=N.findRuntime(t.source);if(s){const i=s.createModelSettings(t.source);return t.settings=i,t.live2dModel.emit("settingsLoaded",i),e()}}throw new TypeError("Unknown settings format.")})),C=(t,e)=>{if(t.settings){const s=N.findRuntime(t.settings);if(s)return s.ready().then(e)}return e()},S=(t,e)=>__async(this,null,(function*(){yield e();const s=t.internalModel;if(s){const e=t.settings,i=N.findRuntime(e);if(i){const r=[];e.pose&&r.push(A.load({settings:e,url:e.pose,type:"json",target:s}).then((e=>{s.pose=i.createPose(s.coreModel,e),t.live2dModel.emit("poseLoaded",s.pose)})).catch((e=>{t.live2dModel.emit("poseLoadError",e),l.warn(R,"Failed to load pose.",e)}))),e.physics&&r.push(A.load({settings:e,url:e.physics,type:"json",target:s}).then((e=>{s.physics=i.createPhysics(s.coreModel,e),t.live2dModel.emit("physicsLoaded",s.physics)})).catch((e=>{t.live2dModel.emit("physicsLoadError",e),l.warn(R,"Failed to load physics.",e)}))),r.length&&(yield Promise.all(r))}}})),k=(t,e)=>__async(this,null,(function*(){if(!t.settings)throw new TypeError("Missing settings.");{const s=t.live2dModel,r=t.settings.textures.map((e=>function(t,e={}){const s={resourceOptions:{crossorigin:e.crossOrigin}};if(i.Texture.fromURL)return i.Texture.fromURL(t,s).catch((t=>{if(t instanceof Error)throw t;const e=new Error("Texture loading error");throw e.event=t,e}));s.resourceOptions.autoLoad=!1;const r=i.Texture.from(t,s);if(r.baseTexture.valid)return Promise.resolve(r);const o=r.baseTexture.resource;return null!=o._live2d_load||(o._live2d_load=new Promise(((t,e)=>{const s=t=>{o.source.removeEventListener("error",s);const i=new Error("Texture loading error");i.event=t,e(i)};o.source.addEventListener("error",s),o.load().then((()=>t(r))).catch(s)}))),o._live2d_load}(t.settings.resolveURL(e),{crossOrigin:t.options.crossOrigin})));if(yield e(),!t.internalModel)throw new TypeError("Missing internal model.");s.internalModel=t.internalModel,s.emit("modelLoaded",t.internalModel),s.textures=yield Promise.all(r),s.emit("textureLoaded",s.textures)}})),G=(t,e)=>__async(this,null,(function*(){const s=t.settings;if(s instanceof x){const i=N.findRuntime(s);if(!i)throw new TypeError("Unknown model settings.");const r=yield A.load({settings:s,url:s.moc,type:"arraybuffer",target:t.live2dModel});if(!i.isValidMoc(r))throw new Error("Invalid moc data");const o=i.createCoreModel(r);return t.internalModel=i.createInternalModel(o,s,t.options),e()}throw new TypeError("Missing settings.")})),U=class{static registerRuntime(t){U.runtimes.push(t),U.runtimes.sort(((t,e)=>e.version-t.version))}static findRuntime(t){for(const e of U.runtimes)if(e.test(t))return e}static setupLive2DModel(t,e,s){return __async(this,null,(function*(){const i=new Promise((e=>t.once("textureLoaded",e))),r=new Promise((e=>t.once("modelLoaded",e))),o=Promise.all([i,r]).then((()=>t.emit("ready")));yield O(U.live2DModelMiddlewares,{live2dModel:t,source:e,options:s||{}}),yield o,t.emit("load")}))}static loadMotion(t,e,s){var i;const r=i=>t.emit("motionLoadError",e,s,i);try{const o=null==(i=t.definitions[e])?void 0:i[s];if(!o)return Promise.resolve(void 0);t.listeners("destroy").includes(U.releaseTasks)||t.once("destroy",U.releaseTasks);let n=U.motionTasksMap.get(t);n||(n={},U.motionTasksMap.set(t,n));let a=n[e];a||(a=[],n[e]=a);const d=t.getMotionFile(o);return null!=a[s]||(a[s]=A.load({url:d,settings:t.settings,type:t.motionDataType,target:t}).then((i=>{var r;const n=null==(r=U.motionTasksMap.get(t))?void 0:r[e];n&&delete n[s];const a=t.createMotion(i,e,o);return t.emit("motionLoaded",e,s,a),a})).catch((e=>{l.warn(t.tag,`Failed to load motion: ${d}\n`,e),r(e)}))),a[s]}catch(o){l.warn(t.tag,`Failed to load motion at "${e}"[${s}]\n`,o),r(o)}return Promise.resolve(void 0)}static loadExpression(t,e){const s=s=>t.emit("expressionLoadError",e,s);try{const i=t.definitions[e];if(!i)return Promise.resolve(void 0);t.listeners("destroy").includes(U.releaseTasks)||t.once("destroy",U.releaseTasks);let r=U.expressionTasksMap.get(t);r||(r=[],U.expressionTasksMap.set(t,r));const o=t.getExpressionFile(i);return null!=r[e]||(r[e]=A.load({url:o,settings:t.settings,type:"json",target:t}).then((s=>{const r=U.expressionTasksMap.get(t);r&&delete r[e];const o=t.createExpression(s,i);return t.emit("expressionLoaded",e,o),o})).catch((e=>{l.warn(t.tag,`Failed to load expression: ${o}\n`,e),s(e)}))),r[e]}catch(i){l.warn(t.tag,`Failed to load expression at [${e}]\n`,i),s(i)}return Promise.resolve(void 0)}static releaseTasks(){this instanceof P?U.motionTasksMap.delete(this):U.expressionTasksMap.delete(this)}};let N=U;N.runtimes=[],N.urlToJSON=F,N.jsonToSettings=D,N.waitUntilReady=C,N.setupOptionals=S,N.setupEssentials=k,N.createInternalModel=G,N.live2DModelMiddlewares=[F,D,C,S,k,G],N.motionTasksMap=new WeakMap,N.expressionTasksMap=new WeakMap,P.prototype._loadMotion=function(t,e){return N.loadMotion(this,t,e)},f.prototype._loadExpression=function(t){return N.loadExpression(this,t)};class j{constructor(){this._autoInteract=!1}get autoInteract(){return this._autoInteract}set autoInteract(t){t!==this._autoInteract&&(t?this.on("pointertap",X,this):this.off("pointertap",X,this),this._autoInteract=t)}registerInteraction(t){t!==this.interactionManager&&(this.unregisterInteraction(),this._autoInteract&&t&&(this.interactionManager=t,t.on("pointermove",H,this)))}unregisterInteraction(){var t;this.interactionManager&&(null==(t=this.interactionManager)||t.off("pointermove",H,this),this.interactionManager=void 0)}}function X(t){this.tap(t.data.global.x,t.data.global.y)}function H(t){this.focus(t.data.global.x,t.data.global.y)}class W extends s.Transform{}const $=new s.Point,q=new s.Matrix;let V;class z extends r.Container{constructor(t){super(),this.tag="Live2DModel(uninitialized)",this.textures=[],this.transform=new W,this.anchor=new s.ObservablePoint(this.onAnchorChange,this,0,0),this.glContextID=-1,this.elapsedTime=performance.now(),this.deltaTime=0,this._autoUpdate=!1,this.once("modelLoaded",(()=>this.init(t)))}static from(t,e){const s=new this(e);return N.setupLive2DModel(s,t,e).then((()=>s))}static fromSync(t,e){const s=new this(e);return N.setupLive2DModel(s,t,e).then(null==e?void 0:e.onLoad).catch(null==e?void 0:e.onError),s}static registerTicker(t){V=t}get autoUpdate(){return this._autoUpdate}set autoUpdate(t){var e;V||(V=null==(e=window.PIXI)?void 0:e.Ticker),t?this._destroyed||(V?(V.shared.add(this.onTickerUpdate,this),this._autoUpdate=!0):l.warn(this.tag,"No Ticker registered, please call Live2DModel.registerTicker(Ticker).")):(null==V||V.shared.remove(this.onTickerUpdate,this),this._autoUpdate=!1)}init(t){this.tag=`Live2DModel(${this.internalModel.settings.name})`;const e=Object.assign({autoUpdate:!0,autoInteract:!0},t);e.autoInteract&&(this.interactive=!0),this.autoInteract=e.autoInteract,this.autoUpdate=e.autoUpdate}onAnchorChange(){this.pivot.set(this.anchor.x*this.internalModel.width,this.anchor.y*this.internalModel.height)}motion(t,e,s,i,r,o){return void 0===e?this.internalModel.motionManager.startRandomMotion(t,s):this.internalModel.motionManager.startMotion(t,e,s,i,r,o)}resetMotions(){return this.internalModel.motionManager.stopAllMotions()}speak(t,e,s){return this.internalModel.motionManager.speakUp(t,e,s)}stopSpeaking(){return this.internalModel.motionManager.stopSpeaking()}expression(t){return this.internalModel.motionManager.expressionManager?void 0===t?this.internalModel.motionManager.expressionManager.setRandomExpression():this.internalModel.motionManager.expressionManager.setExpression(t):Promise.resolve(!1)}focus(t,e,s=!1){$.x=t,$.y=e,this.toModelPosition($,$,!0);let i=$.x/this.internalModel.originalWidth*2-1,r=$.y/this.internalModel.originalHeight*2-1,o=Math.atan2(r,i);this.internalModel.focusController.focus(Math.cos(o),-Math.sin(o),s)}tap(t,e){const s=this.hitTest(t,e);s.length&&(l.log(this.tag,"Hit",s),this.emit("hit",s))}hitTest(t,e){return $.x=t,$.y=e,this.toModelPosition($,$),this.internalModel.hitTest($.x,$.y)}toModelPosition(t,e=t.clone(),s){return s||(this._recursivePostUpdateTransform(),this.parent?this.displayObjectUpdateTransform():(this.parent=this._tempDisplayObjectParent,this.displayObjectUpdateTransform(),this.parent=null)),this.transform.worldTransform.applyInverse(t,e),this.internalModel.localTransform.applyInverse(e,e),e}containsPoint(t){return this.getBounds(!0).contains(t.x,t.y)}_calculateBounds(){this._bounds.addFrame(this.transform,0,0,this.internalModel.width,this.internalModel.height)}onTickerUpdate(){this.update(V.shared.deltaMS)}update(t){this.deltaTime+=t,this.elapsedTime+=t}_render(t){this.registerInteraction(t.plugins.interaction),t.batch.reset(),t.geometry.reset(),t.shader.reset(),t.state.reset();let e=!1;this.glContextID!==t.CONTEXT_UID&&(this.glContextID=t.CONTEXT_UID,this.internalModel.updateWebGLContext(t.gl,this.glContextID),e=!0);for(let r=0;re.destroy(t.baseTexture))),this.internalModel.destroy(),super.destroy(t)}}p(z,[j]);const B=class{static resolveURL(t,e){var s;const i=null==(s=B.filesMap[t])?void 0:s[e];if(void 0===i)throw new Error("Cannot find this file from uploaded files: "+e);return i}static upload(t,s){return __async(this,null,(function*(){const i={};for(const r of s.getDefinedFiles()){const o=decodeURI(e.url.resolve(s.url,r)),n=t.find((t=>t.webkitRelativePath===o));n&&(i[r]=URL.createObjectURL(n))}B.filesMap[s._objectURL]=i}))}static createSettings(t){return __async(this,null,(function*(){const e=t.find((t=>t.name.endsWith("model.json")||t.name.endsWith("model3.json")));if(!e)throw new TypeError("Settings file not found");const s=yield B.readText(e),i=JSON.parse(s);i.url=e.webkitRelativePath;const r=N.findRuntime(i);if(!r)throw new Error("Unknown settings JSON");const o=r.createModelSettings(i);return o._objectURL=URL.createObjectURL(e),o}))}static readText(t){return __async(this,null,(function*(){return new Promise(((e,s)=>{const i=new FileReader;i.onload=()=>e(i.result),i.onerror=s,i.readAsText(t,"utf8")}))}))}};let Y=B;Y.filesMap={},Y.factory=(t,e)=>__async(this,null,(function*(){if(Array.isArray(t.source)&&t.source[0]instanceof File){const e=t.source;let s=e.settings;if(s){if(!s._objectURL)throw new Error('"_objectURL" must be specified in ModelSettings')}else s=yield B.createSettings(e);s.validateFiles(e.map((t=>encodeURI(t.webkitRelativePath)))),yield B.upload(e,s),s.resolveURL=function(t){return B.resolveURL(this._objectURL,t)},t.source=s,t.live2dModel.once("modelLoaded",(t=>{t.once("destroy",(function(){const t=this.settings._objectURL;if(URL.revokeObjectURL(t),B.filesMap[t])for(const e of Object.values(B.filesMap[t]))URL.revokeObjectURL(e);delete B.filesMap[t]}))}))}return e()})),N.live2DModelMiddlewares.unshift(Y.factory);const J=class{static unzip(t,s){return __async(this,null,(function*(){const i=yield J.getFilePaths(t),r=[];for(const t of s.getDefinedFiles()){const o=decodeURI(e.url.resolve(s.url,t));i.includes(o)&&r.push(o)}const o=yield J.getFiles(t,r);for(let t=0;tt.endsWith("model.json")||t.endsWith("model3.json")));if(!e)throw new Error("Settings file not found");const s=yield J.readText(t,e);if(!s)throw new Error("Empty settings file: "+e);const i=JSON.parse(s);i.url=e;const r=N.findRuntime(i);if(!r)throw new Error("Unknown settings JSON");return r.createModelSettings(i)}))}static zipReader(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFilePaths(t){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFiles(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static readText(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static releaseReader(t){}};let Z=J;if(Z.ZIP_PROTOCOL="zip://",Z.uid=0,Z.factory=(t,e)=>__async(this,null,(function*(){const s=t.source;let i,r,o;if("string"==typeof s&&(s.endsWith(".zip")||s.startsWith(J.ZIP_PROTOCOL))?(i=s.startsWith(J.ZIP_PROTOCOL)?s.slice(J.ZIP_PROTOCOL.length):s,r=yield A.load({url:i,type:"blob",target:t.live2dModel})):Array.isArray(s)&&1===s.length&&s[0]instanceof File&&s[0].name.endsWith(".zip")&&(r=s[0],i=URL.createObjectURL(r),o=s.settings),r){if(!r.size)throw new Error("Empty zip file");const e=yield J.zipReader(r,i);o||(o=yield J.createSettings(e)),o._objectURL=J.ZIP_PROTOCOL+J.uid+"/"+o.url;const s=yield J.unzip(e,o);s.settings=o,t.source=s,i.startsWith("blob:")&&t.live2dModel.once("modelLoaded",(t=>{t.once("destroy",(function(){URL.revokeObjectURL(i)}))})),J.releaseReader(e)}return e()})),N.live2DModelMiddlewares.unshift(Z.factory),!window.Live2D)throw new Error("Could not find Cubism 2 runtime. This plugin requires live2d.min.js to be loaded.");const Q=Live2DMotion.prototype.updateParam;Live2DMotion.prototype.updateParam=function(t,e){Q.call(this,t,e),e.isFinished()&&this.onFinishHandler&&(this.onFinishHandler(this),delete this.onFinishHandler)};class K extends AMotion{constructor(e){super(),this.params=[],this.setFadeIn(e.fade_in>0?e.fade_in:t.config.expressionFadingDuration),this.setFadeOut(e.fade_out>0?e.fade_out:t.config.expressionFadingDuration),Array.isArray(e.params)&&e.params.forEach((t=>{const e=t.calc||"add";if("add"===e){const e=t.def||0;t.val-=e}else if("mult"===e){const e=t.def||1;t.val/=e}this.params.push({calc:e,val:t.val,id:t.id})}))}updateParamExe(t,e,s,i){this.params.forEach((e=>{t.setParamFloat(e.id,e.val*s)}))}}class tt extends f{constructor(t,e){var s;super(t,e),this.queueManager=new MotionQueueManager,this.definitions=null!=(s=this.settings.expressions)?s:[],this.init()}isFinished(){return this.queueManager.isFinished()}getExpressionIndex(t){return this.definitions.findIndex((e=>e.name===t))}getExpressionFile(t){return t.file}createExpression(t,e){return new K(t)}_setExpression(t){return this.queueManager.startMotion(t)}stopAllExpressions(){this.queueManager.stopAllMotions()}updateParameters(t,e){return this.queueManager.updateParam(t)}}class et extends P{constructor(t,e){super(t,e),this.groups={idle:"idle"},this.motionDataType="arraybuffer",this.queueManager=new MotionQueueManager,this.definitions=this.settings.motions,this.init(e)}init(t){super.init(t),this.settings.expressions&&(this.expressionManager=new tt(this.settings,t))}isFinished(){return this.queueManager.isFinished()}createMotion(e,s,i){const r=Live2DMotion.loadMotion(e),o=s===this.groups.idle?t.config.idleMotionFadingDuration:t.config.motionFadingDuration;return r.setFadeIn(i.fade_in>0?i.fade_in:o),r.setFadeOut(i.fade_out>0?i.fade_out:o),r}getMotionFile(t){return t.file}getMotionName(t){return t.file}getSoundFile(t){return t.sound}_startMotion(t,e){return t.onFinishHandler=e,this.queueManager.stopAllMotions(),this.queueManager.startMotion(t)}_stopAllMotions(){this.queueManager.stopAllMotions()}updateParameters(t,e){return this.queueManager.updateParam(t)}destroy(){super.destroy(),this.queueManager=void 0}}class st{constructor(t){this.coreModel=t,this.blinkInterval=4e3,this.closingDuration=100,this.closedDuration=50,this.openingDuration=150,this.eyeState=0,this.eyeParamValue=1,this.closedTimer=0,this.nextBlinkTimeLeft=this.blinkInterval,this.leftParam=t.getParamIndex("PARAM_EYE_L_OPEN"),this.rightParam=t.getParamIndex("PARAM_EYE_R_OPEN")}setEyeParams(t){this.eyeParamValue=d(t,0,1),this.coreModel.setParamFloat(this.leftParam,this.eyeParamValue),this.coreModel.setParamFloat(this.rightParam,this.eyeParamValue)}update(t){switch(this.eyeState){case 0:this.nextBlinkTimeLeft-=t,this.nextBlinkTimeLeft<0&&(this.eyeState=1,this.nextBlinkTimeLeft=this.blinkInterval+this.closingDuration+this.closedDuration+this.openingDuration+h(0,2e3));break;case 1:this.setEyeParams(this.eyeParamValue+t/this.closingDuration),this.eyeParamValue<=0&&(this.eyeState=2,this.closedTimer=0);break;case 2:this.closedTimer+=t,this.closedTimer>=this.closedDuration&&(this.eyeState=3);break;case 3:this.setEyeParams(this.eyeParamValue+t/this.openingDuration),this.eyeParamValue>=1&&(this.eyeState=0)}}}const it=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);class rt extends I{constructor(t,e,s){super(),this.textureFlipY=!0,this.drawDataCount=0,this.disableCulling=!1,this.coreModel=t,this.settings=e,this.motionManager=new et(e,s),this.eyeBlink=new st(t),this.eyeballXParamIndex=t.getParamIndex("PARAM_EYE_BALL_X"),this.eyeballYParamIndex=t.getParamIndex("PARAM_EYE_BALL_Y"),this.angleXParamIndex=t.getParamIndex("PARAM_ANGLE_X"),this.angleYParamIndex=t.getParamIndex("PARAM_ANGLE_Y"),this.angleZParamIndex=t.getParamIndex("PARAM_ANGLE_Z"),this.bodyAngleXParamIndex=t.getParamIndex("PARAM_BODY_ANGLE_X"),this.breathParamIndex=t.getParamIndex("PARAM_BREATH"),this.init()}init(){super.init(),this.settings.initParams&&this.settings.initParams.forEach((({id:t,value:e})=>this.coreModel.setParamFloat(t,e))),this.settings.initOpacities&&this.settings.initOpacities.forEach((({id:t,value:e})=>this.coreModel.setPartsOpacity(t,e))),this.coreModel.saveParam();const t=this.coreModel.getModelContext()._$aS;(null==t?void 0:t.length)&&(this.drawDataCount=t.length);let e=this.coreModel.drawParamWebGL.culling;Object.defineProperty(this.coreModel.drawParamWebGL,"culling",{set:t=>e=t,get:()=>!this.disableCulling&&e});const s=this.coreModel.getModelContext().clipManager,i=s.setupClip;s.setupClip=(t,e)=>{i.call(s,t,e),e.gl.viewport(...this.viewport)}}getSize(){return[this.coreModel.getCanvasWidth(),this.coreModel.getCanvasHeight()]}getLayout(){const t={};if(this.settings.layout)for(const e of Object.keys(this.settings.layout)){let s=e;"center_x"===e?s="centerX":"center_y"===e&&(s="centerY"),t[s]=this.settings.layout[e]}return t}updateWebGLContext(t,e){const s=this.coreModel.drawParamWebGL;s.firstDraw=!0,s.setGL(t),s.glno=e;for(const o in s)s.hasOwnProperty(o)&&s[o]instanceof WebGLBuffer&&(s[o]=null);const i=this.coreModel.getModelContext().clipManager;i.curFrameNo=e;const r=t.getParameter(t.FRAMEBUFFER_BINDING);i.getMaskRenderTexture(),t.bindFramebuffer(t.FRAMEBUFFER,r)}bindTexture(t,e){this.coreModel.setTexture(t,e)}getHitAreaDefs(){var t;return(null==(t=this.settings.hitAreas)?void 0:t.map((t=>({id:t.id,name:t.name,index:this.coreModel.getDrawDataIndex(t.id)}))))||[]}getDrawableIDs(){const t=this.coreModel.getModelContext(),e=[];for(let s=0;s0&&t.textures.every((t=>"string"==typeof t))}copy(t){c("string",t,this,"name","name"),c("string",t,this,"pose","pose"),c("string",t,this,"physics","physics"),c("object",t,this,"layout","layout"),c("object",t,this,"motions","motions"),u("object",t,this,"hit_areas","hitAreas"),u("object",t,this,"expressions","expressions"),u("object",t,this,"init_params","initParams"),u("object",t,this,"init_opacities","initOpacities")}replaceFiles(t){super.replaceFiles(t);for(const[e,s]of Object.entries(this.motions))for(let i=0;i{const e=new PhysicsHair;return e.setup(t.setup.length,t.setup.regist,t.setup.mass),t.src.forEach((({id:t,ptype:s,scale:i,weight:r})=>{const o=nt[s];o&&e.addSrcParam(o,t,i,r)})),t.targets.forEach((({id:t,ptype:s,scale:i,weight:r})=>{const o=at[s];o&&e.addTargetParam(o,t,i,r)})),e})))}update(t){this.physicsHairs.forEach((e=>e.update(this.coreModel,t)))}}class dt{constructor(t){this.id=t,this.paramIndex=-1,this.partsIndex=-1,this.link=[]}initIndex(t){this.paramIndex=t.getParamIndex("VISIBLE:"+this.id),this.partsIndex=t.getPartsDataIndex(PartsDataID.getID(this.id)),t.setParamFloat(this.paramIndex,1)}}class ht{constructor(t,e){this.coreModel=t,this.opacityAnimDuration=500,this.partsGroups=[],e.parts_visible&&(this.partsGroups=e.parts_visible.map((({group:t})=>t.map((({id:t,link:e})=>{const s=new dt(t);return e&&(s.link=e.map((t=>new dt(t)))),s})))),this.init())}init(){this.partsGroups.forEach((t=>{t.forEach((t=>{if(t.initIndex(this.coreModel),t.paramIndex>=0){const e=0!==this.coreModel.getParamFloat(t.paramIndex);this.coreModel.setPartsOpacity(t.partsIndex,e?1:0),this.coreModel.setParamFloat(t.paramIndex,e?1:0),t.link.length>0&&t.link.forEach((t=>t.initIndex(this.coreModel)))}}))}))}normalizePartsOpacityGroup(t,e){const s=this.coreModel,i=.5;let r=1,o=t.findIndex((({paramIndex:t,partsIndex:e})=>e>=0&&0!==s.getParamFloat(t)));if(o>=0){const i=s.getPartsOpacity(t[o].partsIndex);r=d(i+e/this.opacityAnimDuration,0,1)}else o=0,r=1;t.forEach((({partsIndex:t},e)=>{if(t>=0)if(o==e)s.setPartsOpacity(t,r);else{let e,o=s.getPartsOpacity(t);e=r.15&&(e=1-.15/(1-r)),o>e&&(o=e),s.setPartsOpacity(t,o)}}))}copyOpacity(t){const e=this.coreModel;t.forEach((({partsIndex:t,link:s})=>{if(t>=0&&s){const i=e.getPartsOpacity(t);s.forEach((({partsIndex:t})=>{t>=0&&e.setPartsOpacity(t,i)}))}}))}update(t){this.partsGroups.forEach((e=>{this.normalizePartsOpacityGroup(e,t),this.copyOpacity(e)}))}}N.registerRuntime({version:2,test:t=>t instanceof ot||ot.isValidJSON(t),ready:()=>Promise.resolve(),isValidMoc(t){if(t.byteLength<3)return!1;const e=new Int8Array(t,0,3);return"moc"===String.fromCharCode(...e)},createModelSettings:t=>new ot(t),createCoreModel(t){const e=Live2DModelWebGL.loadModel(t),s=Live2D.getError();if(s)throw s;return e},createInternalModel:(t,e,s)=>new rt(t,e,s),createPose:(t,e)=>new ht(t,e),createPhysics:(t,e)=>new lt(t,e)}),t.Cubism2ExpressionManager=tt,t.Cubism2InternalModel=rt,t.Cubism2ModelSettings=ot,t.Cubism2MotionManager=et,t.ExpressionManager=f,t.FileLoader=Y,t.FocusController=y,t.InteractionMixin=j,t.InternalModel=I,t.LOGICAL_HEIGHT=2,t.LOGICAL_WIDTH=2,t.Live2DExpression=K,t.Live2DEyeBlink=st,t.Live2DFactory=N,t.Live2DLoader=A,t.Live2DModel=z,t.Live2DPhysics=lt,t.Live2DPose=ht,t.Live2DTransform=W,t.ModelSettings=x,t.MotionManager=P,t.MotionPreloadStrategy=E,t.MotionPriority=M,t.MotionState=v,t.SoundManager=w,t.VERSION="0.4.0",t.XHRLoader=T,t.ZipLoader=Z,t.applyMixins=p,t.clamp=d,t.copyArray=u,t.copyProperty=c,t.folderName=g,t.logger=l,t.rand=h,t.remove=m,Object.defineProperties(t,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
+var __pow=Math.pow,__async=(e,t,s)=>new Promise(((i,r)=>{var o=e=>{try{a(s.next(e))}catch(t){r(t)}},n=e=>{try{a(s.throw(e))}catch(t){r(t)}},a=e=>e.done?i(e.value):Promise.resolve(e.value).then(o,n);a((s=s.apply(e,t)).next())}));!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@pixi/utils"),require("@pixi/math"),require("@pixi/core"),require("@pixi/display")):"function"==typeof define&&define.amd?define(["exports","@pixi/utils","@pixi/math","@pixi/core","@pixi/display"],t):t(((e="undefined"!=typeof globalThis?globalThis:e||self).PIXI=e.PIXI||{},e.PIXI.live2d=e.PIXI.live2d||{}),e.PIXI.utils,e.PIXI,e.PIXI,e.PIXI)}(this,(function(e,t,s,i,r){"use strict";var o,n,a;(n=o||(o={})).supportMoreMaskDivisions=!0,n.setOpacityFromMotion=!1,e.config=void 0,(a=e.config||(e.config={})).LOG_LEVEL_VERBOSE=0,a.LOG_LEVEL_WARNING=1,a.LOG_LEVEL_ERROR=2,a.LOG_LEVEL_NONE=999,a.logLevel=a.LOG_LEVEL_WARNING,a.sound=!0,a.motionSync=!0,a.motionFadingDuration=500,a.idleMotionFadingDuration=2e3,a.expressionFadingDuration=500,a.preserveExpressionOnMotion=!0,a.cubism4=o;const l={log(t,...s){e.config.logLevel<=e.config.LOG_LEVEL_VERBOSE&&console.log(`[${t}]`,...s)},warn(t,...s){e.config.logLevel<=e.config.LOG_LEVEL_WARNING&&console.warn(`[${t}]`,...s)},error(t,...s){e.config.logLevel<=e.config.LOG_LEVEL_ERROR&&console.error(`[${t}]`,...s)}};function d(e,t,s){return es?s:e}function h(e,t){return Math.random()*(t-e)+e}function u(e,t,s,i,r){const o=t[i];null!==o&&typeof o===e&&(s[r]=o)}function c(e,t,s,i,r){const o=t[i];Array.isArray(o)&&(s[r]=o.filter((t=>null!==t&&typeof t===e)))}function p(e,t){t.forEach((t=>{Object.getOwnPropertyNames(t.prototype).forEach((s=>{"constructor"!==s&&Object.defineProperty(e.prototype,s,Object.getOwnPropertyDescriptor(t.prototype,s))}))}))}function g(e){let t=e.lastIndexOf("/");return-1!=t&&(e=e.slice(0,t)),t=e.lastIndexOf("/"),-1!==t&&(e=e.slice(t+1)),e}function m(e,t){const s=e.indexOf(t);-1!==s&&e.splice(s,1)}class f extends t.EventEmitter{constructor(e,t){super(),this.expressions=[],this.reserveExpressionIndex=-1,this.destroyed=!1,this.settings=e,this.tag=`ExpressionManager(${e.name})`}init(){this.defaultExpression=this.createExpression({},void 0),this.currentExpression=this.defaultExpression,this.stopAllExpressions()}loadExpression(e){return __async(this,null,(function*(){if(!this.definitions[e])return void l.warn(this.tag,`Undefined expression at [${e}]`);if(null===this.expressions[e])return void l.warn(this.tag,`Cannot set expression at [${e}] because it's already failed in loading.`);if(this.expressions[e])return this.expressions[e];const t=yield this._loadExpression(e);return this.expressions[e]=t,t}))}_loadExpression(e){throw new Error("Not implemented.")}setRandomExpression(){return __async(this,null,(function*(){if(this.definitions.length){const e=[];for(let t=0;t-1&&el&&(o*=l/a,n*=l/a),this.vx+=o,this.vy+=n;const d=Math.sqrt(__pow(this.vx,2)+__pow(this.vy,2)),h=.5*(Math.sqrt(__pow(l,2)+8*l*i)-l);d>h&&(this.vx*=h/d,this.vy*=h/d),this.x+=this.vx,this.y+=this.vy}}class y{constructor(e){this.json=e;let t=e.url;if("string"!=typeof t)throw new TypeError("The `url` field in settings JSON must be defined as a string.");this.url=t,this.name=g(this.url)}resolveURL(e){return t.url.resolve(this.url,e)}replaceFiles(e){this.moc=e(this.moc,"moc"),void 0!==this.pose&&(this.pose=e(this.pose,"pose")),void 0!==this.physics&&(this.physics=e(this.physics,"physics"));for(let t=0;t(e.push(t),t))),e}validateFiles(e){const t=(t,s)=>{const i=this.resolveURL(t);if(!e.includes(i)){if(s)throw new Error(`File "${t}" is defined in settings, but doesn't exist in given files`);return!1}return!0};[this.moc,...this.textures].forEach((e=>t(e,!0)));return this.getDefinedFiles().filter((e=>t(e,!1)))}}var M=(e=>(e[e.NONE=0]="NONE",e[e.IDLE=1]="IDLE",e[e.NORMAL=2]="NORMAL",e[e.FORCE=3]="FORCE",e))(M||{});class v{constructor(){this.debug=!1,this.currentPriority=0,this.reservePriority=0}reserve(e,t,s){if(s<=0)return l.log(this.tag,"Cannot start a motion with MotionPriority.NONE."),!1;if(e===this.currentGroup&&t===this.currentIndex)return l.log(this.tag,"Motion is already playing.",this.dump(e,t)),!1;if(e===this.reservedGroup&&t===this.reservedIndex||e===this.reservedIdleGroup&&t===this.reservedIdleIndex)return l.log(this.tag,"Motion is already reserved.",this.dump(e,t)),!1;if(1===s){if(0!==this.currentPriority)return l.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(e,t)),!1;if(void 0!==this.reservedIdleGroup)return l.log(this.tag,"Cannot start idle motion because another idle motion has reserved.",this.dump(e,t)),!1;this.setReservedIdle(e,t)}else{if(s<3){if(s<=this.currentPriority)return l.log(this.tag,"Cannot start motion because another motion is playing as an equivalent or higher priority.",this.dump(e,t)),!1;if(s<=this.reservePriority)return l.log(this.tag,"Cannot start motion because another motion has reserved as an equivalent or higher priority.",this.dump(e,t)),!1}this.setReserved(e,t,s)}return!0}start(e,t,s,i){if(1===i){if(this.setReservedIdle(void 0,void 0),0!==this.currentPriority)return l.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(t,s)),!1}else{if(t!==this.reservedGroup||s!==this.reservedIndex)return l.log(this.tag,"Cannot start motion because another motion has taken the place.",this.dump(t,s)),!1;this.setReserved(void 0,void 0,0)}return!!e&&(this.setCurrent(t,s,i),!0)}complete(){this.setCurrent(void 0,void 0,0)}setCurrent(e,t,s){this.currentPriority=s,this.currentGroup=e,this.currentIndex=t}setReserved(e,t,s){this.reservePriority=s,this.reservedGroup=e,this.reservedIndex=t}setReservedIdle(e,t){this.reservedIdleGroup=e,this.reservedIdleIndex=t}isActive(e,t){return e===this.currentGroup&&t===this.currentIndex||e===this.reservedGroup&&t===this.reservedIndex||e===this.reservedIdleGroup&&t===this.reservedIdleIndex}reset(){this.setCurrent(void 0,void 0,0),this.setReserved(void 0,void 0,0),this.setReservedIdle(void 0,void 0)}shouldRequestIdleMotion(){return void 0===this.currentGroup&&void 0===this.reservedIdleGroup}shouldOverrideExpression(){return!e.config.preserveExpressionOnMotion&&this.currentPriority>1}dump(e,t){if(this.debug){return`\n group = "${e}", index = ${t}\n`+["currentPriority","reservePriority","currentGroup","currentIndex","reservedGroup","reservedIndex","reservedIdleGroup","reservedIdleIndex"].map((e=>"["+e+"] "+this[e])).join("\n")}return""}}class E{static get volume(){return this._volume}static set volume(e){this._volume=(e>1?1:e<0?0:e)||0,this.audios.forEach((e=>e.volume=this._volume))}static add(e,t,s){const i=new Audio(e);return i.volume=this._volume,i.preload="auto",i.autoplay=!0,i.crossOrigin="anonymous",i.addEventListener("ended",(()=>{this.dispose(i),null==t||t()})),i.addEventListener("error",(t=>{this.dispose(i),l.warn("SoundManager",`Error occurred on "${e}"`,t.error),null==s||s(t.error)})),this.audios.push(i),i}static play(e){return new Promise(((t,s)=>{var i;null==(i=e.play())||i.catch((t=>{e.dispatchEvent(new ErrorEvent("error",{error:t})),s(t)})),e.readyState===e.HAVE_ENOUGH_DATA?t():e.addEventListener("canplaythrough",t)}))}static addContext(e){const t=new AudioContext;return this.contexts.push(t),t}static addAnalyzer(e,t){const s=t.createMediaElementSource(e),i=t.createAnalyser();return i.fftSize=256,i.minDecibels=-90,i.maxDecibels=-10,i.smoothingTimeConstant=.85,s.connect(i),i.connect(t.destination),this.analysers.push(i),i}static analyze(e){if(null!=e){let t=new Float32Array(e.fftSize),s=0;e.getFloatTimeDomainData(t);for(const e of t)s+=e*e;return parseFloat(Math.sqrt(s/t.length*20).toFixed(1))}return parseFloat(Math.random().toFixed(1))}static dispose(e){e.pause(),e.removeAttribute("src"),m(this.audios,e)}static destroy(){for(let e=this.contexts.length-1;e>=0;e--)this.contexts[e].close();for(let e=this.audios.length-1;e>=0;e--)this.dispose(this.audios[e])}}E.audios=[],E.analysers=[],E.contexts=[],E._volume=.9;var w=(e=>(e.ALL="ALL",e.IDLE="IDLE",e.NONE="NONE",e))(w||{});class P extends t.EventEmitter{constructor(e,t){super(),this.motionGroups={},this.state=new v,this.playing=!1,this.destroyed=!1,this.settings=e,this.tag=`MotionManager(${e.name})`,this.state.tag=this.tag}init(e){(null==e?void 0:e.idleMotionGroup)&&(this.groups.idle=e.idleMotionGroup),this.setupMotions(e),this.stopAllMotions()}setupMotions(e){for(const s of Object.keys(this.definitions))this.motionGroups[s]=[];let t;switch(null==e?void 0:e.motionPreload){case"NONE":return;case"ALL":t=Object.keys(this.definitions);break;default:t=[this.groups.idle]}for(const s of t)if(this.definitions[s])for(let e=0;e{r&&i&&p.expressionManager&&p.expressionManager.resetExpression(),p.currentAudio=void 0}),(()=>{r&&i&&p.expressionManager&&p.expressionManager.resetExpression(),p.currentAudio=void 0})),this.currentAudio=o;let e=1;void 0!==s&&(e=s),E.volume=e,a=E.addContext(this.currentAudio),this.currentContext=a,n=E.addAnalyzer(this.currentAudio,this.currentContext),this.currentAnalyzer=n}catch(g){l.warn(this.tag,"Failed to create audio",d,g)}if(o){const t=E.play(o).catch((e=>l.warn(this.tag,"Failed to play audio",o.src,e)));e.config.motionSync&&(yield t)}return this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),i&&this.expressionManager&&this.expressionManager.setExpression(i),this.playing=!0,!0}))}startMotion(t,s){return __async(this,arguments,(function*(t,s,i=M.NORMAL,{sound:r,volume:o=1,expression:n,resetExpression:a=!0}={}){var d;if(this.currentAudio&&!this.currentAudio.ended)return!1;if(!this.state.reserve(t,s,i))return!1;const h=null==(d=this.definitions[t])?void 0:d[s];if(!h)return!1;let u,c,p;if(this.currentAudio&&E.dispose(this.currentAudio),e.config.sound){const e=r&&r.startsWith("data:audio/wav;base64");if(r&&!e){var g=document.createElement("a");g.href=r,r=g.href}const t=r&&(r.startsWith("http")||r.startsWith("blob")),s=this.getSoundFile(h);let i=s;s&&(i=this.settings.resolveURL(s)+"?cache-buster="+(new Date).getTime()),(t||e)&&(i=r);const d=this;if(i)try{u=E.add(i,(()=>{a&&n&&d.expressionManager&&d.expressionManager.resetExpression(),d.currentAudio=void 0}),(()=>{a&&n&&d.expressionManager&&d.expressionManager.resetExpression(),d.currentAudio=void 0})),this.currentAudio=u;let e=1;void 0!==o&&(e=o),E.volume=e,p=E.addContext(this.currentAudio),this.currentContext=p,c=E.addAnalyzer(this.currentAudio,this.currentContext),this.currentAnalyzer=c}catch(f){l.warn(this.tag,"Failed to create audio",s,f)}}const m=yield this.loadMotion(t,s);if(u){i=3;const t=E.play(u).catch((e=>l.warn(this.tag,"Failed to play audio",u.src,e)));e.config.motionSync&&(yield t)}return this.state.start(m,t,s,i)?(this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),l.log(this.tag,"Start motion:",this.getMotionName(h)),this.emit("motionStart",t,s,u),n&&this.expressionManager&&this.expressionManager.setExpression(n),this.playing=!0,this._startMotion(m),!0):(u&&(E.dispose(u),this.currentAudio=void 0),!1)}))}startRandomMotion(e,t){return __async(this,arguments,(function*(e,t,{sound:s,volume:i=1,expression:r,resetExpression:o=!0}={}){const n=this.definitions[e];if(null==n?void 0:n.length){const a=[];for(let t=0;te.index>=0));for(const t of e)this.hitAreas[t.name]=t}hitTest(e,t){return Object.keys(this.hitAreas).filter((s=>this.isHit(s,e,t)))}isHit(e,t,s){if(!this.hitAreas[e])return!1;const i=this.hitAreas[e].index,r=this.getDrawableBounds(i,_);return r.x<=t&&t<=r.x+r.width&&r.y<=s&&s<=r.y+r.height}getDrawableBounds(e,t){const s=this.getDrawableVertices(e);let i=s[0],r=s[0],o=s[1],n=s[1];for(let a=0;a{200!==o.status&&0!==o.status||!o.response?o.onerror():i(o.response)},o.onerror=()=>{l.warn("XHRLoader",`Failed to load resource as ${o.responseType} (Status ${o.status}): ${t}`),r(new L("Network error.",t,o.status))},o.onabort=()=>r(new L("Aborted.",t,o.status,!0)),o.onloadend=()=>{var t;b.allXhrSet.delete(o),e&&(null==(t=b.xhrMap.get(e))||t.delete(o))},o}static cancelXHRs(){var e;null==(e=b.xhrMap.get(this))||e.forEach((e=>{e.abort(),b.allXhrSet.delete(e)})),b.xhrMap.delete(this)}static release(){b.allXhrSet.forEach((e=>e.abort())),b.allXhrSet.clear(),b.xhrMap=new WeakMap}};let T=b;function O(e,t){let s=-1;return function i(r,o){if(o)return Promise.reject(o);if(r<=s)return Promise.reject(new Error("next() called multiple times"));s=r;const n=e[r];if(!n)return Promise.resolve();try{return Promise.resolve(n(t,i.bind(null,r+1)))}catch(a){return Promise.reject(a)}}(0)}T.xhrMap=new WeakMap,T.allXhrSet=new Set,T.loader=(e,t)=>new Promise(((t,s)=>{b.createXHR(e.target,e.settings?e.settings.resolveURL(e.url):e.url,e.type,(s=>{e.result=s,t()}),s).send()}));class A{static load(e){return O(this.middlewares,e).then((()=>e.result))}}A.middlewares=[T.loader];const R="Live2DFactory",F=(e,t)=>__async(this,null,(function*(){if("string"==typeof e.source){const t=yield A.load({url:e.source,type:"json",target:e.live2dModel});t.url=e.source,e.source=t,e.live2dModel.emit("settingsJSONLoaded",t)}return t()})),D=(e,t)=>__async(this,null,(function*(){if(e.source instanceof y)return e.settings=e.source,t();if("object"==typeof e.source){const s=N.findRuntime(e.source);if(s){const i=s.createModelSettings(e.source);return e.settings=i,e.live2dModel.emit("settingsLoaded",i),t()}}throw new TypeError("Unknown settings format.")})),S=(e,t)=>{if(e.settings){const s=N.findRuntime(e.settings);if(s)return s.ready().then(t)}return t()},C=(e,t)=>__async(this,null,(function*(){yield t();const s=e.internalModel;if(s){const t=e.settings,i=N.findRuntime(t);if(i){const r=[];t.pose&&r.push(A.load({settings:t,url:t.pose,type:"json",target:s}).then((t=>{s.pose=i.createPose(s.coreModel,t),e.live2dModel.emit("poseLoaded",s.pose)})).catch((t=>{e.live2dModel.emit("poseLoadError",t),l.warn(R,"Failed to load pose.",t)}))),t.physics&&r.push(A.load({settings:t,url:t.physics,type:"json",target:s}).then((t=>{s.physics=i.createPhysics(s.coreModel,t),e.live2dModel.emit("physicsLoaded",s.physics)})).catch((t=>{e.live2dModel.emit("physicsLoadError",t),l.warn(R,"Failed to load physics.",t)}))),r.length&&(yield Promise.all(r))}}})),k=(e,t)=>__async(this,null,(function*(){if(!e.settings)throw new TypeError("Missing settings.");{const s=e.live2dModel,r=e.settings.textures.map((t=>function(e,t={}){const s={resourceOptions:{crossorigin:t.crossOrigin}};if(i.Texture.fromURL)return i.Texture.fromURL(e,s).catch((e=>{if(e instanceof Error)throw e;const t=new Error("Texture loading error");throw t.event=e,t}));s.resourceOptions.autoLoad=!1;const r=i.Texture.from(e,s);if(r.baseTexture.valid)return Promise.resolve(r);const o=r.baseTexture.resource;return null!=o._live2d_load||(o._live2d_load=new Promise(((e,t)=>{const s=e=>{o.source.removeEventListener("error",s);const i=new Error("Texture loading error");i.event=e,t(i)};o.source.addEventListener("error",s),o.load().then((()=>e(r))).catch(s)}))),o._live2d_load}(e.settings.resolveURL(t),{crossOrigin:e.options.crossOrigin})));if(yield t(),!e.internalModel)throw new TypeError("Missing internal model.");s.internalModel=e.internalModel,s.emit("modelLoaded",e.internalModel),s.textures=yield Promise.all(r),s.emit("textureLoaded",s.textures)}})),U=(e,t)=>__async(this,null,(function*(){const s=e.settings;if(s instanceof y){const i=N.findRuntime(s);if(!i)throw new TypeError("Unknown model settings.");const r=yield A.load({settings:s,url:s.moc,type:"arraybuffer",target:e.live2dModel});if(!i.isValidMoc(r))throw new Error("Invalid moc data");const o=i.createCoreModel(r);return e.internalModel=i.createInternalModel(o,s,e.options),t()}throw new TypeError("Missing settings.")})),G=class{static registerRuntime(e){G.runtimes.push(e),G.runtimes.sort(((e,t)=>t.version-e.version))}static findRuntime(e){for(const t of G.runtimes)if(t.test(e))return t}static setupLive2DModel(e,t,s){return __async(this,null,(function*(){const i=new Promise((t=>e.once("textureLoaded",t))),r=new Promise((t=>e.once("modelLoaded",t))),o=Promise.all([i,r]).then((()=>e.emit("ready")));yield O(G.live2DModelMiddlewares,{live2dModel:e,source:t,options:s||{}}),yield o,e.emit("load")}))}static loadMotion(e,t,s){var i;const r=i=>e.emit("motionLoadError",t,s,i);try{const o=null==(i=e.definitions[t])?void 0:i[s];if(!o)return Promise.resolve(void 0);e.listeners("destroy").includes(G.releaseTasks)||e.once("destroy",G.releaseTasks);let n=G.motionTasksMap.get(e);n||(n={},G.motionTasksMap.set(e,n));let a=n[t];a||(a=[],n[t]=a);const d=e.getMotionFile(o);return null!=a[s]||(a[s]=A.load({url:d,settings:e.settings,type:e.motionDataType,target:e}).then((i=>{var r;const n=null==(r=G.motionTasksMap.get(e))?void 0:r[t];n&&delete n[s];const a=e.createMotion(i,t,o);return e.emit("motionLoaded",t,s,a),a})).catch((t=>{l.warn(e.tag,`Failed to load motion: ${d}\n`,t),r(t)}))),a[s]}catch(o){l.warn(e.tag,`Failed to load motion at "${t}"[${s}]\n`,o),r(o)}return Promise.resolve(void 0)}static loadExpression(e,t){const s=s=>e.emit("expressionLoadError",t,s);try{const i=e.definitions[t];if(!i)return Promise.resolve(void 0);e.listeners("destroy").includes(G.releaseTasks)||e.once("destroy",G.releaseTasks);let r=G.expressionTasksMap.get(e);r||(r=[],G.expressionTasksMap.set(e,r));const o=e.getExpressionFile(i);return null!=r[t]||(r[t]=A.load({url:o,settings:e.settings,type:"json",target:e}).then((s=>{const r=G.expressionTasksMap.get(e);r&&delete r[t];const o=e.createExpression(s,i);return e.emit("expressionLoaded",t,o),o})).catch((t=>{l.warn(e.tag,`Failed to load expression: ${o}\n`,t),s(t)}))),r[t]}catch(i){l.warn(e.tag,`Failed to load expression at [${t}]\n`,i),s(i)}return Promise.resolve(void 0)}static releaseTasks(){this instanceof P?G.motionTasksMap.delete(this):G.expressionTasksMap.delete(this)}};let N=G;N.runtimes=[],N.urlToJSON=F,N.jsonToSettings=D,N.waitUntilReady=S,N.setupOptionals=C,N.setupEssentials=k,N.createInternalModel=U,N.live2DModelMiddlewares=[F,D,S,C,k,U],N.motionTasksMap=new WeakMap,N.expressionTasksMap=new WeakMap,P.prototype._loadMotion=function(e,t){return N.loadMotion(this,e,t)},f.prototype._loadExpression=function(e){return N.loadExpression(this,e)};class j{constructor(){this._autoInteract=!1}get autoInteract(){return this._autoInteract}set autoInteract(e){e!==this._autoInteract&&(e?this.on("pointertap",X,this):this.off("pointertap",X,this),this._autoInteract=e)}registerInteraction(e){e!==this.interactionManager&&(this.unregisterInteraction(),this._autoInteract&&e&&(this.interactionManager=e,e.on("pointermove",H,this)))}unregisterInteraction(){var e;this.interactionManager&&(null==(e=this.interactionManager)||e.off("pointermove",H,this),this.interactionManager=void 0)}}function X(e){this.tap(e.data.global.x,e.data.global.y)}function H(e){this.focus(e.data.global.x,e.data.global.y)}class W extends s.Transform{}const $=new s.Point,q=new s.Matrix;let V;class Y extends r.Container{constructor(e){super(),this.tag="Live2DModel(uninitialized)",this.textures=[],this.transform=new W,this.anchor=new s.ObservablePoint(this.onAnchorChange,this,0,0),this.glContextID=-1,this.elapsedTime=performance.now(),this.deltaTime=0,this._autoUpdate=!1,this.once("modelLoaded",(()=>this.init(e)))}static from(e,t){const s=new this(t);return N.setupLive2DModel(s,e,t).then((()=>s))}static fromSync(e,t){const s=new this(t);return N.setupLive2DModel(s,e,t).then(null==t?void 0:t.onLoad).catch(null==t?void 0:t.onError),s}static registerTicker(e){V=e}get autoUpdate(){return this._autoUpdate}set autoUpdate(e){var t;V||(V=null==(t=window.PIXI)?void 0:t.Ticker),e?this._destroyed||(V?(V.shared.add(this.onTickerUpdate,this),this._autoUpdate=!0):l.warn(this.tag,"No Ticker registered, please call Live2DModel.registerTicker(Ticker).")):(null==V||V.shared.remove(this.onTickerUpdate,this),this._autoUpdate=!1)}init(e){this.tag=`Live2DModel(${this.internalModel.settings.name})`;const t=Object.assign({autoUpdate:!0,autoInteract:!0},e);t.autoInteract&&(this.interactive=!0),this.autoInteract=t.autoInteract,this.autoUpdate=t.autoUpdate}onAnchorChange(){this.pivot.set(this.anchor.x*this.internalModel.width,this.anchor.y*this.internalModel.height)}motion(e,t,{priority:s=2,sound:i,volume:r=1,expression:o,resetExpression:n=!0}={}){return void 0===t?this.internalModel.motionManager.startRandomMotion(e,s,{sound:i,volume:r,expression:o,resetExpression:n}):this.internalModel.motionManager.startMotion(e,t,s,{sound:i,volume:r,expression:o,resetExpression:n})}resetMotions(){return this.internalModel.motionManager.stopAllMotions()}speak(e,{volume:t=1,expression:s,resetExpression:i=!0}={}){return this.internalModel.motionManager.speakUp(e,{volume:t,expression:s,resetExpression:i})}stopSpeaking(){return this.internalModel.motionManager.stopSpeaking()}expression(e){return this.internalModel.motionManager.expressionManager?void 0===e?this.internalModel.motionManager.expressionManager.setRandomExpression():this.internalModel.motionManager.expressionManager.setExpression(e):Promise.resolve(!1)}focus(e,t,s=!1){$.x=e,$.y=t,this.toModelPosition($,$,!0);let i=$.x/this.internalModel.originalWidth*2-1,r=$.y/this.internalModel.originalHeight*2-1,o=Math.atan2(r,i);this.internalModel.focusController.focus(Math.cos(o),-Math.sin(o),s)}tap(e,t){const s=this.hitTest(e,t);s.length&&(l.log(this.tag,"Hit",s),this.emit("hit",s))}hitTest(e,t){return $.x=e,$.y=t,this.toModelPosition($,$),this.internalModel.hitTest($.x,$.y)}toModelPosition(e,t=e.clone(),s){return s||(this._recursivePostUpdateTransform(),this.parent?this.displayObjectUpdateTransform():(this.parent=this._tempDisplayObjectParent,this.displayObjectUpdateTransform(),this.parent=null)),this.transform.worldTransform.applyInverse(e,t),this.internalModel.localTransform.applyInverse(t,t),t}containsPoint(e){return this.getBounds(!0).contains(e.x,e.y)}_calculateBounds(){this._bounds.addFrame(this.transform,0,0,this.internalModel.width,this.internalModel.height)}onTickerUpdate(){this.update(V.shared.deltaMS)}update(e){this.deltaTime+=e,this.elapsedTime+=e}_render(e){this.registerInteraction(e.plugins.interaction),e.batch.reset(),e.geometry.reset(),e.shader.reset(),e.state.reset();let t=!1;this.glContextID!==e.CONTEXT_UID&&(this.glContextID=e.CONTEXT_UID,this.internalModel.updateWebGLContext(e.gl,this.glContextID),t=!0);for(let r=0;rt.destroy(e.baseTexture))),this.internalModel.destroy(),super.destroy(e)}}p(Y,[j]);const z=class{static resolveURL(e,t){var s;const i=null==(s=z.filesMap[e])?void 0:s[t];if(void 0===i)throw new Error("Cannot find this file from uploaded files: "+t);return i}static upload(e,s){return __async(this,null,(function*(){const i={};for(const r of s.getDefinedFiles()){const o=decodeURI(t.url.resolve(s.url,r)),n=e.find((e=>e.webkitRelativePath===o));n&&(i[r]=URL.createObjectURL(n))}z.filesMap[s._objectURL]=i}))}static createSettings(e){return __async(this,null,(function*(){const t=e.find((e=>e.name.endsWith("model.json")||e.name.endsWith("model3.json")));if(!t)throw new TypeError("Settings file not found");const s=yield z.readText(t),i=JSON.parse(s);i.url=t.webkitRelativePath;const r=N.findRuntime(i);if(!r)throw new Error("Unknown settings JSON");const o=r.createModelSettings(i);return o._objectURL=URL.createObjectURL(t),o}))}static readText(e){return __async(this,null,(function*(){return new Promise(((t,s)=>{const i=new FileReader;i.onload=()=>t(i.result),i.onerror=s,i.readAsText(e,"utf8")}))}))}};let B=z;B.filesMap={},B.factory=(e,t)=>__async(this,null,(function*(){if(Array.isArray(e.source)&&e.source[0]instanceof File){const t=e.source;let s=t.settings;if(s){if(!s._objectURL)throw new Error('"_objectURL" must be specified in ModelSettings')}else s=yield z.createSettings(t);s.validateFiles(t.map((e=>encodeURI(e.webkitRelativePath)))),yield z.upload(t,s),s.resolveURL=function(e){return z.resolveURL(this._objectURL,e)},e.source=s,e.live2dModel.once("modelLoaded",(e=>{e.once("destroy",(function(){const e=this.settings._objectURL;if(URL.revokeObjectURL(e),z.filesMap[e])for(const t of Object.values(z.filesMap[e]))URL.revokeObjectURL(t);delete z.filesMap[e]}))}))}return t()})),N.live2DModelMiddlewares.unshift(B.factory);const J=class{static unzip(e,s){return __async(this,null,(function*(){const i=yield J.getFilePaths(e),r=[];for(const e of s.getDefinedFiles()){const o=decodeURI(t.url.resolve(s.url,e));i.includes(o)&&r.push(o)}const o=yield J.getFiles(e,r);for(let e=0;ee.endsWith("model.json")||e.endsWith("model3.json")));if(!t)throw new Error("Settings file not found");const s=yield J.readText(e,t);if(!s)throw new Error("Empty settings file: "+t);const i=JSON.parse(s);i.url=t;const r=N.findRuntime(i);if(!r)throw new Error("Unknown settings JSON");return r.createModelSettings(i)}))}static zipReader(e,t){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFilePaths(e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFiles(e,t){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static readText(e,t){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static releaseReader(e){}};let Z=J;if(Z.ZIP_PROTOCOL="zip://",Z.uid=0,Z.factory=(e,t)=>__async(this,null,(function*(){const s=e.source;let i,r,o;if("string"==typeof s&&(s.endsWith(".zip")||s.startsWith(J.ZIP_PROTOCOL))?(i=s.startsWith(J.ZIP_PROTOCOL)?s.slice(J.ZIP_PROTOCOL.length):s,r=yield A.load({url:i,type:"blob",target:e.live2dModel})):Array.isArray(s)&&1===s.length&&s[0]instanceof File&&s[0].name.endsWith(".zip")&&(r=s[0],i=URL.createObjectURL(r),o=s.settings),r){if(!r.size)throw new Error("Empty zip file");const t=yield J.zipReader(r,i);o||(o=yield J.createSettings(t)),o._objectURL=J.ZIP_PROTOCOL+J.uid+"/"+o.url;const s=yield J.unzip(t,o);s.settings=o,e.source=s,i.startsWith("blob:")&&e.live2dModel.once("modelLoaded",(e=>{e.once("destroy",(function(){URL.revokeObjectURL(i)}))})),J.releaseReader(t)}return t()})),N.live2DModelMiddlewares.unshift(Z.factory),!window.Live2D)throw new Error("Could not find Cubism 2 runtime. This plugin requires live2d.min.js to be loaded.");const Q=Live2DMotion.prototype.updateParam;Live2DMotion.prototype.updateParam=function(e,t){Q.call(this,e,t),t.isFinished()&&this.onFinishHandler&&(this.onFinishHandler(this),delete this.onFinishHandler)};class K extends AMotion{constructor(t){super(),this.params=[],this.setFadeIn(t.fade_in>0?t.fade_in:e.config.expressionFadingDuration),this.setFadeOut(t.fade_out>0?t.fade_out:e.config.expressionFadingDuration),Array.isArray(t.params)&&t.params.forEach((e=>{const t=e.calc||"add";if("add"===t){const t=e.def||0;e.val-=t}else if("mult"===t){const t=e.def||1;e.val/=t}this.params.push({calc:t,val:e.val,id:e.id})}))}updateParamExe(e,t,s,i){this.params.forEach((t=>{e.setParamFloat(t.id,t.val*s)}))}}class ee extends f{constructor(e,t){var s;super(e,t),this.queueManager=new MotionQueueManager,this.definitions=null!=(s=this.settings.expressions)?s:[],this.init()}isFinished(){return this.queueManager.isFinished()}getExpressionIndex(e){return this.definitions.findIndex((t=>t.name===e))}getExpressionFile(e){return e.file}createExpression(e,t){return new K(e)}_setExpression(e){return this.queueManager.startMotion(e)}stopAllExpressions(){this.queueManager.stopAllMotions()}updateParameters(e,t){return this.queueManager.updateParam(e)}}class te extends P{constructor(e,t){super(e,t),this.groups={idle:"idle"},this.motionDataType="arraybuffer",this.queueManager=new MotionQueueManager,this.definitions=this.settings.motions,this.init(t),this.lipSyncIds=["PARAM_MOUTH_OPEN_Y"]}init(e){super.init(e),this.settings.expressions&&(this.expressionManager=new ee(this.settings,e))}isFinished(){return this.queueManager.isFinished()}createMotion(t,s,i){const r=Live2DMotion.loadMotion(t),o=s===this.groups.idle?e.config.idleMotionFadingDuration:e.config.motionFadingDuration;return r.setFadeIn(i.fade_in>0?i.fade_in:o),r.setFadeOut(i.fade_out>0?i.fade_out:o),r}getMotionFile(e){return e.file}getMotionName(e){return e.file}getSoundFile(e){return e.sound}_startMotion(e,t){return e.onFinishHandler=t,this.queueManager.stopAllMotions(),this.queueManager.startMotion(e)}_stopAllMotions(){this.queueManager.stopAllMotions()}updateParameters(e,t){return this.queueManager.updateParam(e)}destroy(){super.destroy(),this.queueManager=void 0}}class se{constructor(e){this.coreModel=e,this.blinkInterval=4e3,this.closingDuration=100,this.closedDuration=50,this.openingDuration=150,this.eyeState=0,this.eyeParamValue=1,this.closedTimer=0,this.nextBlinkTimeLeft=this.blinkInterval,this.leftParam=e.getParamIndex("PARAM_EYE_L_OPEN"),this.rightParam=e.getParamIndex("PARAM_EYE_R_OPEN")}setEyeParams(e){this.eyeParamValue=d(e,0,1),this.coreModel.setParamFloat(this.leftParam,this.eyeParamValue),this.coreModel.setParamFloat(this.rightParam,this.eyeParamValue)}update(e){switch(this.eyeState){case 0:this.nextBlinkTimeLeft-=e,this.nextBlinkTimeLeft<0&&(this.eyeState=1,this.nextBlinkTimeLeft=this.blinkInterval+this.closingDuration+this.closedDuration+this.openingDuration+h(0,2e3));break;case 1:this.setEyeParams(this.eyeParamValue+e/this.closingDuration),this.eyeParamValue<=0&&(this.eyeState=2,this.closedTimer=0);break;case 2:this.closedTimer+=e,this.closedTimer>=this.closedDuration&&(this.eyeState=3);break;case 3:this.setEyeParams(this.eyeParamValue+e/this.openingDuration),this.eyeParamValue>=1&&(this.eyeState=0)}}}const ie=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);class re extends I{constructor(e,t,s){super(),this.textureFlipY=!0,this.lipSync=!0,this.drawDataCount=0,this.disableCulling=!1,this.coreModel=e,this.settings=t,this.motionManager=new te(t,s),this.eyeBlink=new se(e),this.eyeballXParamIndex=e.getParamIndex("PARAM_EYE_BALL_X"),this.eyeballYParamIndex=e.getParamIndex("PARAM_EYE_BALL_Y"),this.angleXParamIndex=e.getParamIndex("PARAM_ANGLE_X"),this.angleYParamIndex=e.getParamIndex("PARAM_ANGLE_Y"),this.angleZParamIndex=e.getParamIndex("PARAM_ANGLE_Z"),this.bodyAngleXParamIndex=e.getParamIndex("PARAM_BODY_ANGLE_X"),this.breathParamIndex=e.getParamIndex("PARAM_BREATH"),this.mouthFormIndex=e.getParamIndex("PARAM_MOUTH_FORM"),this.init()}init(){super.init(),this.settings.initParams&&this.settings.initParams.forEach((({id:e,value:t})=>this.coreModel.setParamFloat(e,t))),this.settings.initOpacities&&this.settings.initOpacities.forEach((({id:e,value:t})=>this.coreModel.setPartsOpacity(e,t))),this.coreModel.saveParam();const e=this.coreModel.getModelContext()._$aS;(null==e?void 0:e.length)&&(this.drawDataCount=e.length);let t=this.coreModel.drawParamWebGL.culling;Object.defineProperty(this.coreModel.drawParamWebGL,"culling",{set:e=>t=e,get:()=>!this.disableCulling&&t});const s=this.coreModel.getModelContext().clipManager,i=s.setupClip;s.setupClip=(e,t)=>{i.call(s,e,t),t.gl.viewport(...this.viewport)}}getSize(){return[this.coreModel.getCanvasWidth(),this.coreModel.getCanvasHeight()]}getLayout(){const e={};if(this.settings.layout)for(const t of Object.keys(this.settings.layout)){let s=t;"center_x"===t?s="centerX":"center_y"===t&&(s="centerY"),e[s]=this.settings.layout[t]}return e}updateWebGLContext(e,t){const s=this.coreModel.drawParamWebGL;s.firstDraw=!0,s.setGL(e),s.glno=t;for(const o in s)s.hasOwnProperty(o)&&s[o]instanceof WebGLBuffer&&(s[o]=null);const i=this.coreModel.getModelContext().clipManager;i.curFrameNo=t;const r=e.getParameter(e.FRAMEBUFFER_BINDING);i.getMaskRenderTexture(),e.bindFramebuffer(e.FRAMEBUFFER,r)}bindTexture(e,t){this.coreModel.setTexture(e,t)}getHitAreaDefs(){var e;return(null==(e=this.settings.hitAreas)?void 0:e.map((e=>({id:e.id,name:e.name,index:this.coreModel.getDrawDataIndex(e.id)}))))||[]}getDrawableIDs(){const e=this.coreModel.getModelContext(),t=[];for(let s=0;s0&&(t=.4),e=d(e*1.2,t,1);for(let s=0;s0&&e.textures.every((e=>"string"==typeof e))}copy(e){u("string",e,this,"name","name"),u("string",e,this,"pose","pose"),u("string",e,this,"physics","physics"),u("object",e,this,"layout","layout"),u("object",e,this,"motions","motions"),c("object",e,this,"hit_areas","hitAreas"),c("object",e,this,"expressions","expressions"),c("object",e,this,"init_params","initParams"),c("object",e,this,"init_opacities","initOpacities")}replaceFiles(e){super.replaceFiles(e);for(const[t,s]of Object.entries(this.motions))for(let i=0;i{const t=new PhysicsHair;return t.setup(e.setup.length,e.setup.regist,e.setup.mass),e.src.forEach((({id:e,ptype:s,scale:i,weight:r})=>{const o=ne[s];o&&t.addSrcParam(o,e,i,r)})),e.targets.forEach((({id:e,ptype:s,scale:i,weight:r})=>{const o=ae[s];o&&t.addTargetParam(o,e,i,r)})),t})))}update(e){this.physicsHairs.forEach((t=>t.update(this.coreModel,e)))}}class de{constructor(e){this.id=e,this.paramIndex=-1,this.partsIndex=-1,this.link=[]}initIndex(e){this.paramIndex=e.getParamIndex("VISIBLE:"+this.id),this.partsIndex=e.getPartsDataIndex(PartsDataID.getID(this.id)),e.setParamFloat(this.paramIndex,1)}}class he{constructor(e,t){this.coreModel=e,this.opacityAnimDuration=500,this.partsGroups=[],t.parts_visible&&(this.partsGroups=t.parts_visible.map((({group:e})=>e.map((({id:e,link:t})=>{const s=new de(e);return t&&(s.link=t.map((e=>new de(e)))),s})))),this.init())}init(){this.partsGroups.forEach((e=>{e.forEach((e=>{if(e.initIndex(this.coreModel),e.paramIndex>=0){const t=0!==this.coreModel.getParamFloat(e.paramIndex);this.coreModel.setPartsOpacity(e.partsIndex,t?1:0),this.coreModel.setParamFloat(e.paramIndex,t?1:0),e.link.length>0&&e.link.forEach((e=>e.initIndex(this.coreModel)))}}))}))}normalizePartsOpacityGroup(e,t){const s=this.coreModel,i=.5;let r=1,o=e.findIndex((({paramIndex:e,partsIndex:t})=>t>=0&&0!==s.getParamFloat(e)));if(o>=0){const i=s.getPartsOpacity(e[o].partsIndex);r=d(i+t/this.opacityAnimDuration,0,1)}else o=0,r=1;e.forEach((({partsIndex:e},t)=>{if(e>=0)if(o==t)s.setPartsOpacity(e,r);else{let t,o=s.getPartsOpacity(e);t=r.15&&(t=1-.15/(1-r)),o>t&&(o=t),s.setPartsOpacity(e,o)}}))}copyOpacity(e){const t=this.coreModel;e.forEach((({partsIndex:e,link:s})=>{if(e>=0&&s){const i=t.getPartsOpacity(e);s.forEach((({partsIndex:e})=>{e>=0&&t.setPartsOpacity(e,i)}))}}))}update(e){this.partsGroups.forEach((t=>{this.normalizePartsOpacityGroup(t,e),this.copyOpacity(t)}))}}N.registerRuntime({version:2,test:e=>e instanceof oe||oe.isValidJSON(e),ready:()=>Promise.resolve(),isValidMoc(e){if(e.byteLength<3)return!1;const t=new Int8Array(e,0,3);return"moc"===String.fromCharCode(...t)},createModelSettings:e=>new oe(e),createCoreModel(e){const t=Live2DModelWebGL.loadModel(e),s=Live2D.getError();if(s)throw s;return t},createInternalModel:(e,t,s)=>new re(e,t,s),createPose:(e,t)=>new he(e,t),createPhysics:(e,t)=>new le(e,t)}),e.Cubism2ExpressionManager=ee,e.Cubism2InternalModel=re,e.Cubism2ModelSettings=oe,e.Cubism2MotionManager=te,e.ExpressionManager=f,e.FileLoader=B,e.FocusController=x,e.InteractionMixin=j,e.InternalModel=I,e.LOGICAL_HEIGHT=2,e.LOGICAL_WIDTH=2,e.Live2DExpression=K,e.Live2DEyeBlink=se,e.Live2DFactory=N,e.Live2DLoader=A,e.Live2DModel=Y,e.Live2DPhysics=le,e.Live2DPose=he,e.Live2DTransform=W,e.ModelSettings=y,e.MotionManager=P,e.MotionPreloadStrategy=w,e.MotionPriority=M,e.MotionState=v,e.SoundManager=E,e.VERSION="0.4.0",e.XHRLoader=T,e.ZipLoader=Z,e.applyMixins=p,e.clamp=d,e.copyArray=c,e.copyProperty=u,e.folderName=g,e.logger=l,e.rand=h,e.remove=m,Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
diff --git a/dist/cubism4.es.js b/dist/cubism4.es.js
index 6a7e7d7a..ed97897c 100644
--- a/dist/cubism4.es.js
+++ b/dist/cubism4.es.js
@@ -5039,8 +5039,8 @@ class MotionManager extends EventEmitter {
_loadMotion(group, index) {
throw new Error("Not implemented.");
}
- speakUp(sound, volume, expression) {
- return __async(this, null, function* () {
+ speakUp(_0) {
+ return __async(this, arguments, function* (sound, { volume = 1, expression, resetExpression = true } = {}) {
if (!config.sound) {
return false;
}
@@ -5071,10 +5071,10 @@ class MotionManager extends EventEmitter {
if (file) {
try {
audio = SoundManager.add(file, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
}, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
});
this.currentAudio = audio;
@@ -5108,7 +5108,7 @@ class MotionManager extends EventEmitter {
});
}
startMotion(_0, _1) {
- return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, sound, volume, expression) {
+ return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, { sound = void 0, volume = 1, expression = void 0, resetExpression = true } = {}) {
var _a;
if (this.currentAudio) {
if (!this.currentAudio.ended) {
@@ -5148,10 +5148,10 @@ class MotionManager extends EventEmitter {
if (file) {
try {
audio = SoundManager.add(file, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
}, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
});
this.currentAudio = audio;
@@ -5197,8 +5197,8 @@ class MotionManager extends EventEmitter {
return true;
});
}
- startRandomMotion(group, priority, sound, volume) {
- return __async(this, null, function* () {
+ startRandomMotion(_0, _1) {
+ return __async(this, arguments, function* (group, priority, { sound = void 0, volume = 1, expression = void 0, resetExpression = true } = {}) {
const groupDefs = this.definitions[group];
if (groupDefs == null ? void 0 : groupDefs.length) {
const availableIndices = [];
@@ -5209,7 +5209,12 @@ class MotionManager extends EventEmitter {
}
if (availableIndices.length) {
const index = availableIndices[Math.floor(Math.random() * availableIndices.length)];
- return this.startMotion(group, index, priority, sound, volume);
+ return this.startMotion(group, index, priority, {
+ sound,
+ volume,
+ expression,
+ resetExpression
+ });
}
}
return false;
@@ -5855,14 +5860,28 @@ class Live2DModel extends Container {
onAnchorChange() {
this.pivot.set(this.anchor.x * this.internalModel.width, this.anchor.y * this.internalModel.height);
}
- motion(group, index, priority, sound, volume, expression) {
- return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority) : this.internalModel.motionManager.startMotion(group, index, priority, sound, volume, expression);
+ motion(group, index, { priority = 2, sound, volume = 1, expression, resetExpression = true } = {}) {
+ return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority, {
+ sound,
+ volume,
+ expression,
+ resetExpression
+ }) : this.internalModel.motionManager.startMotion(group, index, priority, {
+ sound,
+ volume,
+ expression,
+ resetExpression
+ });
}
resetMotions() {
return this.internalModel.motionManager.stopAllMotions();
}
- speak(sound, volume, expression) {
- return this.internalModel.motionManager.speakUp(sound, volume, expression);
+ speak(sound, { volume = 1, expression, resetExpression = true } = {}) {
+ return this.internalModel.motionManager.speakUp(sound, {
+ volume,
+ expression,
+ resetExpression
+ });
}
stopSpeaking() {
return this.internalModel.motionManager.stopSpeaking();
@@ -6310,6 +6329,7 @@ class Cubism4InternalModel extends InternalModel {
this.idParamEyeBallY = ParamEyeBallY;
this.idParamBodyAngleX = ParamBodyAngleX;
this.idParamBreath = ParamBreath;
+ this.idParamMouthForm = ParamMouthForm;
this.pixelsPerUnit = 1;
this.centeringTransform = new Matrix();
this.coreModel = coreModel;
@@ -6412,6 +6432,19 @@ class Cubism4InternalModel extends InternalModel {
}
this.updateFocus();
this.updateNaturalMovements(dt * 1e3, now * 1e3);
+ if (this.lipSync && this.motionManager.currentAudio) {
+ let value = this.motionManager.mouthSync();
+ let min_ = 0;
+ let max_ = 1;
+ let weight = 1.2;
+ if (value > 0) {
+ min_ = 0.4;
+ }
+ value = clamp(value * weight, min_, max_);
+ for (let i = 0; i < this.motionManager.lipSyncIds.length; ++i) {
+ model.addParameterValueById(this.motionManager.lipSyncIds[i], value, 0.8);
+ }
+ }
(_c = this.physics) == null ? void 0 : _c.evaluate(model, dt);
(_d = this.pose) == null ? void 0 : _d.updateParameters(model, dt);
this.emit("beforeModelUpdate");
@@ -6426,6 +6459,9 @@ class Cubism4InternalModel extends InternalModel {
this.coreModel.addParameterValueById(this.idParamAngleZ, this.focusController.x * this.focusController.y * -30);
this.coreModel.addParameterValueById(this.idParamBodyAngleX, this.focusController.x * 10);
}
+ updateFacialEmotion(mouthForm) {
+ this.coreModel.addParameterValueById(this.idParamMouthForm, mouthForm);
+ }
updateNaturalMovements(dt, now) {
var _a;
(_a = this.breath) == null ? void 0 : _a.updateParameters(this.coreModel, dt / 1e3);
diff --git a/dist/cubism4.js b/dist/cubism4.js
index 1034a6e8..2d4a79b0 100644
--- a/dist/cubism4.js
+++ b/dist/cubism4.js
@@ -5039,8 +5039,8 @@ var __async = (__this, __arguments, generator) => {
_loadMotion(group, index) {
throw new Error("Not implemented.");
}
- speakUp(sound, volume, expression) {
- return __async(this, null, function* () {
+ speakUp(_0) {
+ return __async(this, arguments, function* (sound, { volume = 1, expression, resetExpression = true } = {}) {
if (!exports2.config.sound) {
return false;
}
@@ -5071,10 +5071,10 @@ var __async = (__this, __arguments, generator) => {
if (file) {
try {
audio = SoundManager.add(file, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
}, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
});
this.currentAudio = audio;
@@ -5108,7 +5108,7 @@ var __async = (__this, __arguments, generator) => {
});
}
startMotion(_0, _1) {
- return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, sound, volume, expression) {
+ return __async(this, arguments, function* (group, index, priority = MotionPriority.NORMAL, { sound = void 0, volume = 1, expression = void 0, resetExpression = true } = {}) {
var _a;
if (this.currentAudio) {
if (!this.currentAudio.ended) {
@@ -5148,10 +5148,10 @@ var __async = (__this, __arguments, generator) => {
if (file) {
try {
audio = SoundManager.add(file, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
}, () => {
- expression && that.expressionManager && that.expressionManager.resetExpression();
+ resetExpression && expression && that.expressionManager && that.expressionManager.resetExpression();
that.currentAudio = void 0;
});
this.currentAudio = audio;
@@ -5197,8 +5197,8 @@ var __async = (__this, __arguments, generator) => {
return true;
});
}
- startRandomMotion(group, priority, sound, volume) {
- return __async(this, null, function* () {
+ startRandomMotion(_0, _1) {
+ return __async(this, arguments, function* (group, priority, { sound = void 0, volume = 1, expression = void 0, resetExpression = true } = {}) {
const groupDefs = this.definitions[group];
if (groupDefs == null ? void 0 : groupDefs.length) {
const availableIndices = [];
@@ -5209,7 +5209,12 @@ var __async = (__this, __arguments, generator) => {
}
if (availableIndices.length) {
const index = availableIndices[Math.floor(Math.random() * availableIndices.length)];
- return this.startMotion(group, index, priority, sound, volume);
+ return this.startMotion(group, index, priority, {
+ sound,
+ volume,
+ expression,
+ resetExpression
+ });
}
}
return false;
@@ -5855,14 +5860,28 @@ var __async = (__this, __arguments, generator) => {
onAnchorChange() {
this.pivot.set(this.anchor.x * this.internalModel.width, this.anchor.y * this.internalModel.height);
}
- motion(group, index, priority, sound, volume, expression) {
- return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority) : this.internalModel.motionManager.startMotion(group, index, priority, sound, volume, expression);
+ motion(group, index, { priority = 2, sound, volume = 1, expression, resetExpression = true } = {}) {
+ return index === void 0 ? this.internalModel.motionManager.startRandomMotion(group, priority, {
+ sound,
+ volume,
+ expression,
+ resetExpression
+ }) : this.internalModel.motionManager.startMotion(group, index, priority, {
+ sound,
+ volume,
+ expression,
+ resetExpression
+ });
}
resetMotions() {
return this.internalModel.motionManager.stopAllMotions();
}
- speak(sound, volume, expression) {
- return this.internalModel.motionManager.speakUp(sound, volume, expression);
+ speak(sound, { volume = 1, expression, resetExpression = true } = {}) {
+ return this.internalModel.motionManager.speakUp(sound, {
+ volume,
+ expression,
+ resetExpression
+ });
}
stopSpeaking() {
return this.internalModel.motionManager.stopSpeaking();
@@ -6310,6 +6329,7 @@ var __async = (__this, __arguments, generator) => {
this.idParamEyeBallY = ParamEyeBallY;
this.idParamBodyAngleX = ParamBodyAngleX;
this.idParamBreath = ParamBreath;
+ this.idParamMouthForm = ParamMouthForm;
this.pixelsPerUnit = 1;
this.centeringTransform = new math.Matrix();
this.coreModel = coreModel;
@@ -6412,6 +6432,19 @@ var __async = (__this, __arguments, generator) => {
}
this.updateFocus();
this.updateNaturalMovements(dt * 1e3, now * 1e3);
+ if (this.lipSync && this.motionManager.currentAudio) {
+ let value = this.motionManager.mouthSync();
+ let min_ = 0;
+ let max_ = 1;
+ let weight = 1.2;
+ if (value > 0) {
+ min_ = 0.4;
+ }
+ value = clamp(value * weight, min_, max_);
+ for (let i = 0; i < this.motionManager.lipSyncIds.length; ++i) {
+ model.addParameterValueById(this.motionManager.lipSyncIds[i], value, 0.8);
+ }
+ }
(_c = this.physics) == null ? void 0 : _c.evaluate(model, dt);
(_d = this.pose) == null ? void 0 : _d.updateParameters(model, dt);
this.emit("beforeModelUpdate");
@@ -6426,6 +6459,9 @@ var __async = (__this, __arguments, generator) => {
this.coreModel.addParameterValueById(this.idParamAngleZ, this.focusController.x * this.focusController.y * -30);
this.coreModel.addParameterValueById(this.idParamBodyAngleX, this.focusController.x * 10);
}
+ updateFacialEmotion(mouthForm) {
+ this.coreModel.addParameterValueById(this.idParamMouthForm, mouthForm);
+ }
updateNaturalMovements(dt, now) {
var _a;
(_a = this.breath) == null ? void 0 : _a.updateParameters(this.coreModel, dt / 1e3);
diff --git a/dist/cubism4.min.js b/dist/cubism4.min.js
index 4f1c6e1f..b50a93be 100644
--- a/dist/cubism4.min.js
+++ b/dist/cubism4.min.js
@@ -1 +1 @@
-var __pow=Math.pow,__async=(t,e,i)=>new Promise(((s,r)=>{var o=t=>{try{n(i.next(t))}catch(e){r(e)}},a=t=>{try{n(i.throw(t))}catch(e){r(e)}},n=t=>t.done?s(t.value):Promise.resolve(t.value).then(o,a);n((i=i.apply(t,e)).next())}));!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@pixi/utils"),require("@pixi/math"),require("@pixi/core"),require("@pixi/display")):"function"==typeof define&&define.amd?define(["exports","@pixi/utils","@pixi/math","@pixi/core","@pixi/display"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).PIXI=t.PIXI||{},t.PIXI.live2d=t.PIXI.live2d||{}),t.PIXI.utils,t.PIXI,t.PIXI,t.PIXI)}(this,(function(t,e,i,s,r){"use strict";class o{constructor(){this._breathParameters=[],this._currentTime=0}static create(){return new o}setParameters(t){this._breathParameters=t}getParameters(){return this._breathParameters}updateParameters(t,e){this._currentTime+=e;const i=2*this._currentTime*3.14159;for(let s=0;s=1&&(s=1,this._blinkingState=h.EyeState_Closed,this._stateStartTimeSeconds=this._userTimeSeconds),i=1-s;break;case h.EyeState_Closed:s=(this._userTimeSeconds-this._stateStartTimeSeconds)/this._closedSeconds,s>=1&&(this._blinkingState=h.EyeState_Opening,this._stateStartTimeSeconds=this._userTimeSeconds),i=0;break;case h.EyeState_Opening:s=(this._userTimeSeconds-this._stateStartTimeSeconds)/this._openingSeconds,s>=1&&(s=1,this._blinkingState=h.EyeState_Interval,this._nextBlinkingTime=this.determinNextBlinkingTiming()),i=s;break;case h.EyeState_Interval:this._nextBlinkingTime(t[t.EyeState_First=0]="EyeState_First",t[t.EyeState_Interval=1]="EyeState_Interval",t[t.EyeState_Closing=2]="EyeState_Closing",t[t.EyeState_Closed=3]="EyeState_Closed",t[t.EyeState_Opening=4]="EyeState_Opening",t))(h||{});class u{static create(t){const e=new u;"number"==typeof t.FadeInTime&&(e._fadeTimeSeconds=t.FadeInTime,e._fadeTimeSeconds<=0&&(e._fadeTimeSeconds=.5));const i=t.Groups,s=i.length;for(let r=0;r.001){if(r>=0)break;r=n,o=t.getPartOpacityByIndex(i),o+=e/this._fadeTimeSeconds,o>1&&(o=1)}}r<0&&(r=0,o=1);for(let n=i;n.15&&(i=1-.15/(1-o)),s>i&&(s=i),t.setPartOpacityByIndex(e,s)}}}constructor(){this._fadeTimeSeconds=.5,this._lastModel=void 0,this._partGroups=[],this._partGroupCounts=[]}}class d{constructor(t){this.parameterIndex=0,this.partIndex=0,this.partId="",this.link=[],null!=t&&this.assignment(t)}assignment(t){return this.partId=t.partId,this.link=t.link.map((t=>t.clone())),this}initialize(t){this.parameterIndex=t.getParameterIndex(this.partId),this.partIndex=t.getPartIndex(this.partId),t.setParameterValueByIndex(this.parameterIndex,1)}clone(){const t=new d;return t.partId=this.partId,t.parameterIndex=this.parameterIndex,t.partIndex=this.partIndex,t.link=this.link.map((t=>t.clone())),t}}class c{constructor(t,e){this.x=t||0,this.y=e||0}add(t){const e=new c(0,0);return e.x=this.x+t.x,e.y=this.y+t.y,e}substract(t){const e=new c(0,0);return e.x=this.x-t.x,e.y=this.y-t.y,e}multiply(t){const e=new c(0,0);return e.x=this.x*t.x,e.y=this.y*t.y,e}multiplyByScaler(t){return this.multiply(new c(t,t))}division(t){const e=new c(0,0);return e.x=this.x/t.x,e.y=this.y/t.y,e}divisionByScalar(t){return this.division(new c(t,t))}getLength(){return Math.sqrt(this.x*this.x+this.y*this.y)}getDistanceWith(t){return Math.sqrt((this.x-t.x)*(this.x-t.x)+(this.y-t.y)*(this.y-t.y))}dot(t){return this.x*t.x+this.y*t.y}normalize(){const t=Math.pow(this.x*this.x+this.y*this.y,.5);this.x=this.x/t,this.y=this.y/t}isEqual(t){return this.x==t.x&&this.y==t.y}isNotEqual(t){return!this.isEqual(t)}}const g=class{static range(t,e,i){return ti&&(t=i),t}static sin(t){return Math.sin(t)}static cos(t){return Math.cos(t)}static abs(t){return Math.abs(t)}static sqrt(t){return Math.sqrt(t)}static cbrt(t){if(0===t)return t;let e=t;const i=e<0;let s;return i&&(e=-e),e===1/0?s=1/0:(s=Math.exp(Math.log(e)/3),s=(e/(s*s)+2*s)/3),i?-s:s}static getEasingSine(t){return t<0?0:t>1?1:.5-.5*this.cos(t*Math.PI)}static max(t,e){return t>e?t:e}static min(t,e){return t>e?e:t}static degreesToRadian(t){return t/180*Math.PI}static radianToDegrees(t){return 180*t/Math.PI}static directionToRadian(t,e){let i=Math.atan2(e.y,e.x)-Math.atan2(t.y,t.x);for(;i<-Math.PI;)i+=2*Math.PI;for(;i>Math.PI;)i-=2*Math.PI;return i}static directionToDegrees(t,e){const i=this.directionToRadian(t,e);let s=this.radianToDegrees(i);return e.x-t.x>0&&(s=-s),s}static radianToDirection(t){const e=new c;return e.x=this.sin(t),e.y=this.cos(t),e}static quadraticEquation(t,e,i){return this.abs(t)1&&(t=1),e<0?e=0:e>1&&(e=1),i<0?i=0:i>1&&(i=1),s<0?s=0:s>1&&(s=1),this._modelColor.R=t,this._modelColor.G=e,this._modelColor.B=i,this._modelColor.A=s}getModelColor(){return Object.assign({},this._modelColor)}setIsPremultipliedAlpha(t){this._isPremultipliedAlpha=t}isPremultipliedAlpha(){return this._isPremultipliedAlpha}setIsCulling(t){this._isCulling=t}isCulling(){return this._isCulling}setAnisotropy(t){this._anisotropy=t}getAnisotropy(){return this._anisotropy}getModel(){return this._model}useHighPrecisionMask(t){this._useHighPrecisionMask=t}isUsingHighPrecisionMask(){return this._useHighPrecisionMask}constructor(){this._isCulling=!1,this._isPremultipliedAlpha=!1,this._anisotropy=0,this._modelColor=new y,this._useHighPrecisionMask=!1,this._mvpMatrix4x4=new _,this._mvpMatrix4x4.loadIdentity()}}var f=(t=>(t[t.CubismBlendMode_Normal=0]="CubismBlendMode_Normal",t[t.CubismBlendMode_Additive=1]="CubismBlendMode_Additive",t[t.CubismBlendMode_Multiplicative=2]="CubismBlendMode_Multiplicative",t))(f||{});class y{constructor(t=1,e=1,i=1,s=1){this.R=t,this.G=e,this.B=i,this.A=s}}let C,x=!1,M=!1;const v={vertexOffset:0,vertexStep:2};class P{static startUp(t){if(x)return T("CubismFramework.startUp() is already done."),x;if(Live2DCubismCore._isStarted)return x=!0,!0;if(Live2DCubismCore._isStarted=!0,C=t,C&&Live2DCubismCore.Logging.csmSetLogFunction(C.logFunction),x=!0,x){const t=Live2DCubismCore.Version.csmGetVersion(),e=(16711680&t)>>16,i=65535&t,s=t;T("Live2D Cubism Core version: {0}.{1}.{2} ({3})",("00"+((4278190080&t)>>24)).slice(-2),("00"+e).slice(-2),("0000"+i).slice(-4),s)}return T("CubismFramework.startUp() is complete."),x}static cleanUp(){x=!1,M=!1,C=void 0}static initialize(t=0){x?M?I("CubismFramework.initialize() skipped, already initialized."):(Live2DCubismCore.Memory.initializeAmountOfMemory(t),M=!0,T("CubismFramework.initialize() is complete.")):I("CubismFramework is not started.")}static dispose(){x?M?(p.staticRelease(),M=!1,T("CubismFramework.dispose() is complete.")):I("CubismFramework.dispose() skipped, not initialized."):I("CubismFramework is not started.")}static isStarted(){return x}static isInitialized(){return M}static coreLogFunction(t){Live2DCubismCore.Logging.csmGetLogFunction()&&Live2DCubismCore.Logging.csmGetLogFunction()(t)}static getLoggingLevel(){return null!=C?C.loggingLevel:b.LogLevel_Off}constructor(){}}var b=(t=>(t[t.LogLevel_Verbose=0]="LogLevel_Verbose",t[t.LogLevel_Debug=1]="LogLevel_Debug",t[t.LogLevel_Info=2]="LogLevel_Info",t[t.LogLevel_Warning=3]="LogLevel_Warning",t[t.LogLevel_Error=4]="LogLevel_Error",t[t.LogLevel_Off=5]="LogLevel_Off",t))(b||{});const S=()=>{};function w(t,...e){E.print(b.LogLevel_Debug,"[CSM][D]"+t+"\n",e)}function T(t,...e){E.print(b.LogLevel_Info,"[CSM][I]"+t+"\n",e)}function I(t,...e){E.print(b.LogLevel_Warning,"[CSM][W]"+t+"\n",e)}function L(t,...e){E.print(b.LogLevel_Error,"[CSM][E]"+t+"\n",e)}class E{static print(t,e,i){if(ti[e])))}static dumpBytes(t,e,i){for(let s=0;s0?this.print(t,"\n"):s%8==0&&s>0&&this.print(t," "),this.print(t,"{0} ",[255&e[s]]);this.print(t,"\n")}constructor(){}}class A{constructor(t=!1,e=new y){this.isOverwritten=t,this.Color=e}}class F{constructor(t=!1,e=new y){this.isOverwritten=t,this.Color=e}}class D{constructor(t=!1,e=!1){this.isOverwritten=t,this.isCulling=e}}class B{update(){this._model.update(),this._model.drawables.resetDynamicFlags()}getPixelsPerUnit(){return null==this._model?0:this._model.canvasinfo.PixelsPerUnit}getCanvasWidth(){return null==this._model?0:this._model.canvasinfo.CanvasWidth/this._model.canvasinfo.PixelsPerUnit}getCanvasHeight(){return null==this._model?0:this._model.canvasinfo.CanvasHeight/this._model.canvasinfo.PixelsPerUnit}saveParameters(){const t=this._model.parameters.count,e=this._savedParameters.length;for(let i=0;ie&&(e=this._model.parameters.minimumValues[t]),this._parameterValues[t]=1==i?e:this._parameterValues[t]=this._parameterValues[t]*(1-i)+e*i)}setParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.setParameterValueByIndex(s,e,i)}addParameterValueByIndex(t,e,i=1){this.setParameterValueByIndex(t,this.getParameterValueByIndex(t)+e*i)}addParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.addParameterValueByIndex(s,e,i)}multiplyParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.multiplyParameterValueByIndex(s,e,i)}multiplyParameterValueByIndex(t,e,i=1){this.setParameterValueByIndex(t,this.getParameterValueByIndex(t)*(1+(e-1)*i))}getDrawableIds(){return this._drawableIds.slice()}getDrawableIndex(t){const e=this._model.drawables.count;for(let i=0;ie&&(t=e);for(let i=0;i=0&&this._partChildDrawables[n].push(t)}}}constructor(t){this._model=t,this._savedParameters=[],this._parameterIds=[],this._drawableIds=[],this._partIds=[],this._isOverwrittenModelMultiplyColors=!1,this._isOverwrittenModelScreenColors=!1,this._isOverwrittenCullings=!1,this._modelOpacity=1,this._userMultiplyColors=[],this._userScreenColors=[],this._userCullings=[],this._userPartMultiplyColors=[],this._userPartScreenColors=[],this._partChildDrawables=[],this._notExistPartId={},this._notExistParameterId={},this._notExistParameterValues={},this._notExistPartOpacities={},this.initialize()}release(){this._model.release(),this._model=void 0}}class R{static create(t,e){if(e){if(!this.hasMocConsistency(t))throw new Error("Inconsistent MOC3.")}const i=Live2DCubismCore.Moc.fromArrayBuffer(t);if(i){const e=new R(i);return e._mocVersion=Live2DCubismCore.Version.csmGetMocVersion(i,t),e}throw new Error("Failed to CubismMoc.create().")}createModel(){let t;const e=Live2DCubismCore.Model.fromMoc(this._moc);if(e)return t=new B(e),++this._modelCount,t;throw new Error("Unknown error")}deleteModel(t){null!=t&&--this._modelCount}constructor(t){this._moc=t,this._modelCount=0,this._mocVersion=0}release(){this._moc._release(),this._moc=void 0}getLatestMocVersion(){return Live2DCubismCore.Version.csmGetLatestMocVersion()}getMocVersion(){return this._mocVersion}static hasMocConsistency(t){return 1===Live2DCubismCore.Moc.prototype.hasMocConsistency(t)}}class O{constructor(t,e){this._json=t}release(){this._json=void 0}getUserDataCount(){return this._json.Meta.UserDataCount}getTotalUserDataSize(){return this._json.Meta.TotalUserDataSize}getUserDataTargetType(t){return this._json.UserData[t].Target}getUserDataId(t){return this._json.UserData[t].Id}getUserDataValue(t){return this._json.UserData[t].Value}}class k{static create(t,e){const i=new k;return i.parseUserData(t,e),i}getArtMeshUserDatas(){return this._artMeshUserDataNode}parseUserData(t,e){const i=new O(t,e),s=i.getUserDataCount();for(let r=0;r0&&e.getEndTime()(t[t.ExpressionBlendType_Add=0]="ExpressionBlendType_Add",t[t.ExpressionBlendType_Multiply=1]="ExpressionBlendType_Multiply",t[t.ExpressionBlendType_Overwrite=2]="ExpressionBlendType_Overwrite",t))(G||{});t.CubismConfig=void 0,(N=t.CubismConfig||(t.CubismConfig={})).supportMoreMaskDivisions=!0,N.setOpacityFromMotion=!1;var X=(t=>(t[t.CubismMotionCurveTarget_Model=0]="CubismMotionCurveTarget_Model",t[t.CubismMotionCurveTarget_Parameter=1]="CubismMotionCurveTarget_Parameter",t[t.CubismMotionCurveTarget_PartOpacity=2]="CubismMotionCurveTarget_PartOpacity",t))(X||{}),z=(t=>(t[t.CubismMotionSegmentType_Linear=0]="CubismMotionSegmentType_Linear",t[t.CubismMotionSegmentType_Bezier=1]="CubismMotionSegmentType_Bezier",t[t.CubismMotionSegmentType_Stepped=2]="CubismMotionSegmentType_Stepped",t[t.CubismMotionSegmentType_InverseStepped=3]="CubismMotionSegmentType_InverseStepped",t))(z||{});class j{constructor(t=0,e=0){this.time=t,this.value=e}}class W{constructor(){this.basePointIndex=0,this.segmentType=0}}class H{constructor(){this.id="",this.type=0,this.segmentCount=0,this.baseSegmentIndex=0,this.fadeInTime=0,this.fadeOutTime=0}}class Y{constructor(){this.fireTime=0,this.value=""}}class q{constructor(){this.duration=0,this.loop=!1,this.curveCount=0,this.eventCount=0,this.fps=0,this.curves=[],this.segments=[],this.points=[],this.events=[]}}class ${constructor(t){this._json=t}release(){this._json=void 0}getMotionDuration(){return this._json.Meta.Duration}isMotionLoop(){return this._json.Meta.Loop||!1}getEvaluationOptionFlag(t){return J.EvaluationOptionFlag_AreBeziersRistricted==t&&!!this._json.Meta.AreBeziersRestricted}getMotionCurveCount(){return this._json.Meta.CurveCount}getMotionFps(){return this._json.Meta.Fps}getMotionTotalSegmentCount(){return this._json.Meta.TotalSegmentCount}getMotionTotalPointCount(){return this._json.Meta.TotalPointCount}getMotionFadeInTime(){return this._json.Meta.FadeInTime}getMotionFadeOutTime(){return this._json.Meta.FadeOutTime}getMotionCurveTarget(t){return this._json.Curves[t].Target}getMotionCurveId(t){return this._json.Curves[t].Id}getMotionCurveFadeInTime(t){return this._json.Curves[t].FadeInTime}getMotionCurveFadeOutTime(t){return this._json.Curves[t].FadeOutTime}getMotionCurveSegmentCount(t){return this._json.Curves[t].Segments.length}getMotionCurveSegment(t,e){return this._json.Curves[t].Segments[e]}getEventCount(){return this._json.Meta.UserDataCount||0}getTotalEventValueSize(){return this._json.Meta.TotalUserDataSize}getEventTime(t){return this._json.UserData[t].Time}getEventValue(t){return this._json.UserData[t].Value}}var J=(t=>(t[t.EvaluationOptionFlag_AreBeziersRistricted=0]="EvaluationOptionFlag_AreBeziersRistricted",t))(J||{});const Z="Opacity";function Q(t,e,i){const s=new j;return s.time=t.time+(e.time-t.time)*i,s.value=t.value+(e.value-t.value)*i,s}function K(t,e){let i=(e-t[0].time)/(t[1].time-t[0].time);return i<0&&(i=0),t[0].value+(t[1].value-t[0].value)*i}function tt(t,e){let i=(e-t[0].time)/(t[3].time-t[0].time);i<0&&(i=0);const s=Q(t[0],t[1],i),r=Q(t[1],t[2],i),o=Q(t[2],t[3],i),a=Q(s,r,i),n=Q(r,o,i);return Q(a,n,i).value}function et(t,e){const i=e,s=t[0].time,r=t[3].time,o=t[1].time,a=t[2].time,n=r-3*a+3*o-s,l=3*a-6*o+3*s,h=3*o-3*s,u=s-i,d=m.cardanoAlgorithmForBezier(n,l,h,u),c=Q(t[0],t[1],d),g=Q(t[1],t[2],d),_=Q(t[2],t[3],d),p=Q(c,g,d),f=Q(g,_,d);return Q(p,f,d).value}function it(t,e){return t[0].value}function st(t,e){return t[1].value}function rt(t,e,i){const s=t.curves[e];let r=-1;const o=s.baseSegmentIndex+s.segmentCount;let a=0;for(let l=s.baseSegmentIndex;li){r=l;break}if(-1==r)return t.points[a].value;const n=t.segments[r];return n.evaluate(t.points.slice(n.basePointIndex),i)}class ot extends U{constructor(){super(),this._eyeBlinkParameterIds=[],this._lipSyncParameterIds=[],this._sourceFrameRate=30,this._loopDurationSeconds=-1,this._isLoop=!1,this._isLoopFadeIn=!0,this._lastWeight=0,this._modelOpacity=1}static create(t,e){const i=new ot;return i.parse(t),i._sourceFrameRate=i._motionData.fps,i._loopDurationSeconds=i._motionData.duration,i._onFinishedMotion=e,i}doUpdateParameters(e,i,s,r){null==this._modelCurveIdEyeBlink&&(this._modelCurveIdEyeBlink="EyeBlink"),null==this._modelCurveIdLipSync&&(this._modelCurveIdLipSync="LipSync"),null==this._modelCurveIdOpacity&&(this._modelCurveIdOpacity=Z);let o=i-r.getStartTime();o<0&&(o=0);let a=Number.MAX_VALUE,n=Number.MAX_VALUE;const l=64;let h=0,u=0;this._eyeBlinkParameterIds.length>l&&w("too many eye blink targets : {0}",this._eyeBlinkParameterIds.length),this._lipSyncParameterIds.length>l&&w("too many lip sync targets : {0}",this._lipSyncParameterIds.length);const d=this._fadeInSeconds<=0?1:m.getEasingSine((i-r.getFadeInStartTime())/this._fadeInSeconds),c=this._fadeOutSeconds<=0||r.getEndTime()<0?1:m.getEasingSine((r.getEndTime()-i)/this._fadeOutSeconds);let g,_,p,f=o;if(this._isLoop)for(;f>this._motionData.duration;)f-=this._motionData.duration;const y=this._motionData.curves;for(_=0;_>t&1)continue;const r=i+(n-i)*s;e.setParameterValueById(this._eyeBlinkParameterIds[t],r)}if(a!=Number.MAX_VALUE)for(let t=0;t>t&1)continue;const r=i+(a-i)*s;e.setParameterValueById(this._lipSyncParameterIds[t],r)}for(;_=this._motionData.duration&&(this._isLoop?(r.setStartTime(i),this._isLoopFadeIn&&r.setFadeInStartTime(i)):(this._onFinishedMotion&&this._onFinishedMotion(this),r.setIsFinished(!0))),this._lastWeight=s}setIsLoop(t){this._isLoop=t}isLoop(){return this._isLoop}setIsLoopFadeIn(t){this._isLoopFadeIn=t}isLoopFadeIn(){return this._isLoopFadeIn}getDuration(){return this._isLoop?-1:this._loopDurationSeconds}getLoopDuration(){return this._loopDurationSeconds}setParameterFadeInTime(t,e){const i=this._motionData.curves;for(let s=0;snew H)),this._motionData.segments=Array.from({length:e.getMotionTotalSegmentCount()}).map((()=>new W)),this._motionData.events=Array.from({length:this._motionData.eventCount}).map((()=>new Y)),this._motionData.points=[];let o=0,a=0;for(let n=0;nt&&this._motionData.events[i].fireTime<=e&&this._firedEventValues.push(this._motionData.events[i].value);return this._firedEventValues}isExistModelOpacity(){for(let t=0;tnull!=e&&e._motionQueueEntryHandle==t))}setEventCallback(t,e=null){this._eventCallBack=t,this._eventCustomData=e}doUpdateMotion(t,e){let i=!1,s=0;for(;s(t[t.CubismPhysicsTargetType_Parameter=0]="CubismPhysicsTargetType_Parameter",t))(ht||{}),ut=(t=>(t[t.CubismPhysicsSource_X=0]="CubismPhysicsSource_X",t[t.CubismPhysicsSource_Y=1]="CubismPhysicsSource_Y",t[t.CubismPhysicsSource_Angle=2]="CubismPhysicsSource_Angle",t))(ut||{});class dt{constructor(){this.initialPosition=new c(0,0),this.position=new c(0,0),this.lastPosition=new c(0,0),this.lastGravity=new c(0,0),this.force=new c(0,0),this.velocity=new c(0,0)}}class ct{constructor(){this.normalizationPosition={},this.normalizationAngle={}}}class gt{constructor(){this.source={}}}class mt{constructor(){this.destination={},this.translationScale=new c(0,0)}}class _t{constructor(){this.settings=[],this.inputs=[],this.outputs=[],this.particles=[],this.gravity=new c(0,0),this.wind=new c(0,0),this.fps=0}}class pt{constructor(t){this._json=t}release(){this._json=void 0}getGravity(){const t=new c(0,0);return t.x=this._json.Meta.EffectiveForces.Gravity.X,t.y=this._json.Meta.EffectiveForces.Gravity.Y,t}getWind(){const t=new c(0,0);return t.x=this._json.Meta.EffectiveForces.Wind.X,t.y=this._json.Meta.EffectiveForces.Wind.Y,t}getFps(){return this._json.Meta.Fps||0}getSubRigCount(){return this._json.Meta.PhysicsSettingCount}getTotalInputCount(){return this._json.Meta.TotalInputCount}getTotalOutputCount(){return this._json.Meta.TotalOutputCount}getVertexCount(){return this._json.Meta.VertexCount}getNormalizationPositionMinimumValue(t){return this._json.PhysicsSettings[t].Normalization.Position.Minimum}getNormalizationPositionMaximumValue(t){return this._json.PhysicsSettings[t].Normalization.Position.Maximum}getNormalizationPositionDefaultValue(t){return this._json.PhysicsSettings[t].Normalization.Position.Default}getNormalizationAngleMinimumValue(t){return this._json.PhysicsSettings[t].Normalization.Angle.Minimum}getNormalizationAngleMaximumValue(t){return this._json.PhysicsSettings[t].Normalization.Angle.Maximum}getNormalizationAngleDefaultValue(t){return this._json.PhysicsSettings[t].Normalization.Angle.Default}getInputCount(t){return this._json.PhysicsSettings[t].Input.length}getInputWeight(t,e){return this._json.PhysicsSettings[t].Input[e].Weight}getInputReflect(t,e){return this._json.PhysicsSettings[t].Input[e].Reflect}getInputType(t,e){return this._json.PhysicsSettings[t].Input[e].Type}getInputSourceId(t,e){return this._json.PhysicsSettings[t].Input[e].Source.Id}getOutputCount(t){return this._json.PhysicsSettings[t].Output.length}getOutputVertexIndex(t,e){return this._json.PhysicsSettings[t].Output[e].VertexIndex}getOutputAngleScale(t,e){return this._json.PhysicsSettings[t].Output[e].Scale}getOutputWeight(t,e){return this._json.PhysicsSettings[t].Output[e].Weight}getOutputDestinationId(t,e){return this._json.PhysicsSettings[t].Output[e].Destination.Id}getOutputType(t,e){return this._json.PhysicsSettings[t].Output[e].Type}getOutputReflect(t,e){return this._json.PhysicsSettings[t].Output[e].Reflect}getParticleCount(t){return this._json.PhysicsSettings[t].Vertices.length}getParticleMobility(t,e){return this._json.PhysicsSettings[t].Vertices[e].Mobility}getParticleDelay(t,e){return this._json.PhysicsSettings[t].Vertices[e].Delay}getParticleAcceleration(t,e){return this._json.PhysicsSettings[t].Vertices[e].Acceleration}getParticleRadius(t,e){return this._json.PhysicsSettings[t].Vertices[e].Radius}getParticlePosition(t,e){const i=new c(0,0);return i.x=this._json.PhysicsSettings[t].Vertices[e].Position.X,i.y=this._json.PhysicsSettings[t].Vertices[e].Position.Y,i}}const ft="Angle";class yt{static create(t){const e=new yt;return e.parse(t),e._physicsRig.gravity.y=0,e}static delete(t){null!=t&&t.release()}parse(t){this._physicsRig=new _t;const e=new pt(t);this._physicsRig.gravity=e.getGravity(),this._physicsRig.wind=e.getWind(),this._physicsRig.subRigCount=e.getSubRigCount(),this._physicsRig.fps=e.getFps(),this._currentRigOutputs=[],this._previousRigOutputs=[];let i=0,s=0,r=0;for(let o=0;o=u.particleCount)continue;let s=new c;s=_[i].position.substract(_[i-1].position),l=g[e].getValue(s,_,i,g[e].reflect,this._options.gravity),this._currentRigOutputs[x].outputs[e]=l,this._previousRigOutputs[x].outputs[e]=l;const r=g[e].destinationParameterIndex,o=!Float32Array.prototype.slice&&"subarray"in Float32Array.prototype?JSON.parse(JSON.stringify(p.subarray(r))):p.slice(r);Dt(o,y[r],f[r],l,g[e]);for(let t=r,e=0;t=e)return;if(this._currentRemainTime+=e,this._currentRemainTime>5&&(this._currentRemainTime=0),f=t.getModel().parameters.values,y=t.getModel().parameters.maximumValues,C=t.getModel().parameters.minimumValues,x=t.getModel().parameters.defaultValues,(null!=(s=null==(i=this._parameterCaches)?void 0:i.length)?s:0)0?1/this._physicsRig.fps:e;this._currentRemainTime>=M;){for(let t=0;t=d.particleCount)continue;const r=new c;r.x=p[s].position.x-p[s-1].position.x,r.y=p[s].position.y-p[s-1].position.y,h=_[e].getValue(r,p,s,_[e].reflect,this._options.gravity),this._currentRigOutputs[i].outputs[e]=h;const o=_[e].destinationParameterIndex,a=!Float32Array.prototype.slice&&"subarray"in Float32Array.prototype?JSON.parse(JSON.stringify(this._parameterCaches.subarray(o))):this._parameterCaches.slice(o);Dt(a,C[o],y[o],h,_[e]);for(let t=o,e=0;t=2?e[i-1].position.substract(e[i-2].position):r.multiplyByScaler(-1),o=m.directionToRadian(r,t),s&&(o*=-1),o}function Tt(t,e){return Math.min(t,e)+function(t,e){return Math.abs(Math.max(t,e)-Math.min(t,e))}(t,e)/2}function It(t,e){return t.x}function Lt(t,e){return t.y}function Et(t,e){return e}function At(t,e,i,s,r,o,a,n){let l,h,u,d,g=new c(0,0),_=new c(0,0),p=new c(0,0),f=new c(0,0);t[0].position=new c(i.x,i.y),l=m.degreesToRadian(s),d=m.radianToDirection(l),d.normalize();for(let y=1;yi&&(a>r.valueExceededMaximum&&(r.valueExceededMaximum=a),a=i),n=r.weight/100,n>=1||(a=t[0]*(1-n)+a*n),t[0]=a}function Bt(t,e,i,s,r,o,a,n){let l=0;const h=m.max(i,e);ht&&(t=u);const d=m.min(r,o),c=m.max(r,o),g=a,_=Tt(u,h),p=t-_;switch(Math.sign(p)){case 1:{const t=c-g,e=h-_;0!=e&&(l=p*(t/e),l+=g);break}case-1:{const t=d-g,e=u-_;0!=e&&(l=p*(t/e),l+=g);break}case 0:l=g}return n?l:-1*l}class Rt{constructor(t=0,e=0,i=0,s=0){this.x=t,this.y=e,this.width=i,this.height=s}getCenterX(){return this.x+.5*this.width}getCenterY(){return this.y+.5*this.height}getRight(){return this.x+this.width}getBottom(){return this.y+this.height}setRect(t){this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height}expand(t,e){this.x-=t,this.y-=e,this.width+=2*t,this.height+=2*e}}let Ot,kt,Ut;class Vt{getChannelFlagAsColor(t){return this._channelColors[t]}getMaskRenderTexture(){if(this._maskTexture&&null!=this._maskTexture.textures)this._maskTexture.frameNo=this._currentFrameNo;else{this._maskRenderTextures=[],this._maskColorBuffers=[];const t=this._clippingMaskBufferSize;for(let e=0;ec&&(c=e),ig&&(g=i)}if(u!=Number.MAX_VALUE)if(ur&&(r=c),g>o&&(o=g),i==Number.MAX_VALUE)e._allClippedDrawRect.x=0,e._allClippedDrawRect.y=0,e._allClippedDrawRect.width=0,e._allClippedDrawRect.height=0,e._isUsing=!1;else{e._isUsing=!0;const t=r-i,a=o-s;e._allClippedDrawRect.x=i,e._allClippedDrawRect.y=s,e._allClippedDrawRect.width=t,e._allClippedDrawRect.height=a}}}constructor(){this._currentMaskRenderTexture=null,this._currentFrameNo=0,this._renderTextureCount=0,this._clippingMaskBufferSize=256,this._clippingContextListForMask=[],this._clippingContextListForDraw=[],this._channelColors=[],this._tmpBoundsOnModel=new Rt,this._tmpMatrix=new _,this._tmpMatrixForMask=new _,this._tmpMatrixForDraw=new _;let t=new y;t.R=1,t.G=0,t.B=0,t.A=0,this._channelColors.push(t),t=new y,t.R=0,t.G=1,t.B=0,t.A=0,this._channelColors.push(t),t=new y,t.R=0,t.G=0,t.B=1,t.A=0,this._channelColors.push(t),t=new y,t.R=0,t.G=0,t.B=0,t.A=1,this._channelColors.push(t)}release(){var t;const e=this;for(let i=0;i0){this.setupLayoutBounds(e.isUsingHighPrecisionMask()?0:i),e.isUsingHighPrecisionMask()||(this.gl.viewport(0,0,this._clippingMaskBufferSize,this._clippingMaskBufferSize),this._currentMaskRenderTexture=this.getMaskRenderTexture()[0],e.preDraw(),this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,this._currentMaskRenderTexture)),this._clearedFrameBufferflags||(this._clearedFrameBufferflags=[]);for(let t=0;th?(this._tmpBoundsOnModel.expand(r.width*a,0),n=o.width/this._tmpBoundsOnModel.width):n=e/h,this._tmpBoundsOnModel.height*e>u?(this._tmpBoundsOnModel.expand(0,r.height*a),l=o.height/this._tmpBoundsOnModel.height):l=e/u}else this._tmpBoundsOnModel.setRect(r),this._tmpBoundsOnModel.expand(r.width*a,r.height*a),n=o.width/this._tmpBoundsOnModel.width,l=o.height/this._tmpBoundsOnModel.height;if(this._tmpMatrix.loadIdentity(),this._tmpMatrix.translateRelative(-1,-1),this._tmpMatrix.scaleRelative(2,2),this._tmpMatrix.translateRelative(o.x,o.y),this._tmpMatrix.scaleRelative(n,l),this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x,-this._tmpBoundsOnModel.y),this._tmpMatrixForMask.setMatrix(this._tmpMatrix.getArray()),this._tmpMatrix.loadIdentity(),this._tmpMatrix.translateRelative(o.x,o.y),this._tmpMatrix.scaleRelative(n,l),this._tmpMatrix.translateRelative(-this._tmpBoundsOnModel.x,-this._tmpBoundsOnModel.y),this._tmpMatrixForDraw.setMatrix(this._tmpMatrix.getArray()),s._matrixForMask.setMatrix(this._tmpMatrixForMask.getArray()),s._matrixForDraw.setMatrix(this._tmpMatrixForDraw.getArray()),!e.isUsingHighPrecisionMask()){const i=s._clippingIdCount;for(let r=0;ri){e>i&&L("not supported mask count : {0}\n[Details] render texture count : {1}, mask count : {2}",e-i,this._renderTextureCount,e);for(let t=0;t=4?0:n+1;if(u(t[t.ShaderNames_SetupMask=0]="ShaderNames_SetupMask",t[t.ShaderNames_NormalPremultipliedAlpha=1]="ShaderNames_NormalPremultipliedAlpha",t[t.ShaderNames_NormalMaskedPremultipliedAlpha=2]="ShaderNames_NormalMaskedPremultipliedAlpha",t[t.ShaderNames_NomralMaskedInvertedPremultipliedAlpha=3]="ShaderNames_NomralMaskedInvertedPremultipliedAlpha",t[t.ShaderNames_AddPremultipliedAlpha=4]="ShaderNames_AddPremultipliedAlpha",t[t.ShaderNames_AddMaskedPremultipliedAlpha=5]="ShaderNames_AddMaskedPremultipliedAlpha",t[t.ShaderNames_AddMaskedPremultipliedAlphaInverted=6]="ShaderNames_AddMaskedPremultipliedAlphaInverted",t[t.ShaderNames_MultPremultipliedAlpha=7]="ShaderNames_MultPremultipliedAlpha",t[t.ShaderNames_MultMaskedPremultipliedAlpha=8]="ShaderNames_MultMaskedPremultipliedAlpha",t[t.ShaderNames_MultMaskedPremultipliedAlphaInverted=9]="ShaderNames_MultMaskedPremultipliedAlphaInverted",t))(jt||{});const Wt="attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_myPos;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_clipMatrix * a_position; v_myPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}",Ht="precision mediump float;varying vec2 v_texCoord;varying vec4 v_myPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;void main(){ float isInside = step(u_baseColor.x, v_myPos.x/v_myPos.w) * step(u_baseColor.y, v_myPos.y/v_myPos.w) * step(v_myPos.x/v_myPos.w, u_baseColor.z) * step(v_myPos.y/v_myPos.w, u_baseColor.w); gl_FragColor = u_channelFlag * texture2D(s_texture0, v_texCoord).a * isInside;}",Yt="attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;uniform mat4 u_matrix;void main(){ gl_Position = u_matrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}",qt="attribute vec4 a_position;attribute vec2 a_texCoord;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform mat4 u_matrix;uniform mat4 u_clipMatrix;void main(){ gl_Position = u_matrix * a_position; v_clipPos = u_clipMatrix * a_position; v_texCoord = a_texCoord; v_texCoord.y = 1.0 - v_texCoord.y;}",$t="precision mediump float;varying vec2 v_texCoord;uniform vec4 u_baseColor;uniform sampler2D s_texture0;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 color = texColor * u_baseColor; gl_FragColor = vec4(color.rgb, color.a);}",Jt="precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform vec4 u_baseColor;uniform vec4 u_channelFlag;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * maskVal; gl_FragColor = col_formask;}",Zt="precision mediump float;varying vec2 v_texCoord;varying vec4 v_clipPos;uniform sampler2D s_texture0;uniform sampler2D s_texture1;uniform vec4 u_channelFlag;uniform vec4 u_baseColor;uniform vec4 u_multiplyColor;uniform vec4 u_screenColor;void main(){ vec4 texColor = texture2D(s_texture0, v_texCoord); texColor.rgb = texColor.rgb * u_multiplyColor.rgb; texColor.rgb = (texColor.rgb + u_screenColor.rgb * texColor.a) - (texColor.rgb * u_screenColor.rgb); vec4 col_formask = texColor * u_baseColor; vec4 clipMask = (1.0 - texture2D(s_texture1, v_clipPos.xy / v_clipPos.w)) * u_channelFlag; float maskVal = clipMask.r + clipMask.g + clipMask.b + clipMask.a; col_formask = col_formask * (1.0 - maskVal); gl_FragColor = col_formask;}";class Qt extends p{constructor(){super(),this._clippingContextBufferForMask=null,this._clippingContextBufferForDraw=null,this._rendererProfile=new Xt,this.firstDraw=!0,this._textures={},this._sortedDrawableIndexList=[],this._bufferData={vertex:null,uv:null,index:null}}initialize(t,e=1){t.isUsingMasking()&&(this._clippingManager=new Vt,this._clippingManager.initialize(t,t.getDrawableCount(),t.getDrawableMasks(),t.getDrawableMaskCounts(),e));for(let i=t.getDrawableCount()-1;i>=0;i--)this._sortedDrawableIndexList[i]=0;super.initialize(t)}bindTexture(t,e){this._textures[t]=e}getBindedTextures(){return this._textures}setClippingMaskBufferSize(t){if(!this._model.isUsingMasking())return;const e=this._clippingManager.getRenderTextureCount();this._clippingManager.release(),this._clippingManager=new Vt,this._clippingManager.setClippingMaskBufferSize(t),this._clippingManager.initialize(this.getModel(),this.getModel().getDrawableCount(),this.getModel().getDrawableMasks(),this.getModel().getDrawableMaskCounts(),e)}getClippingMaskBufferSize(){return this._model.isUsingMasking()?this._clippingManager.getClippingMaskBufferSize():-1}getRenderTextureCount(){return this._model.isUsingMasking()?this._clippingManager.getRenderTextureCount():-1}release(){var t,e,i;const s=this;this._clippingManager.release(),s._clippingManager=void 0,null==(t=this.gl)||t.deleteBuffer(this._bufferData.vertex),this._bufferData.vertex=null,null==(e=this.gl)||e.deleteBuffer(this._bufferData.uv),this._bufferData.uv=null,null==(i=this.gl)||i.deleteBuffer(this._bufferData.index),this._bufferData.index=null,s._bufferData=void 0,s._textures=void 0}doDrawModel(){if(null==this.gl)return void L("'gl' is null. WebGLRenderingContext is required.\nPlease call 'CubimRenderer_WebGL.startUp' function.");null!=this._clippingManager&&(this.preDraw(),this._clippingManager.setupClippingContext(this.getModel(),this)),this.preDraw();const t=this.getModel().getDrawableCount(),e=this.getModel().getDrawableRenderOrders();for(let i=0;i0&&this._extension)for(const t of Object.entries(this._textures))this.gl.bindTexture(this.gl.TEXTURE_2D,t),this.gl.texParameterf(this.gl.TEXTURE_2D,this._extension.TEXTURE_MAX_ANISOTROPY_EXT,this.getAnisotropy())}setClippingContextBufferForMask(t){this._clippingContextBufferForMask=t}getClippingContextBufferForMask(){return this._clippingContextBufferForMask}setClippingContextBufferForDraw(t){this._clippingContextBufferForDraw=t}getClippingContextBufferForDraw(){return this._clippingContextBufferForDraw}startUp(t){this.gl=t,this._clippingManager&&this._clippingManager.setGL(t),zt.getInstance().setGl(t),this._rendererProfile.setGl(t),this._extension=this.gl.getExtension("EXT_texture_filter_anisotropic")||this.gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic")||this.gl.getExtension("MOZ_EXT_texture_filter_anisotropic")}}p.staticRelease=()=>{Qt.doStaticRelease()};class Kt{constructor(t){this.groups=t.Groups,this.hitAreas=t.HitAreas,this.layout=t.Layout,this.moc=t.FileReferences.Moc,this.expressions=t.FileReferences.Expressions,this.motions=t.FileReferences.Motions,this.textures=t.FileReferences.Textures,this.physics=t.FileReferences.Physics,this.pose=t.FileReferences.Pose}getEyeBlinkParameters(){var t,e;return null==(e=null==(t=this.groups)?void 0:t.find((t=>"EyeBlink"===t.Name)))?void 0:e.Ids}getLipSyncParameters(){var t,e;return null==(e=null==(t=this.groups)?void 0:t.find((t=>"LipSync"===t.Name)))?void 0:e.Ids}}const te="ParamAngleX",ee="ParamAngleY",ie="ParamAngleZ",se="ParamEyeBallX",re="ParamEyeBallY",oe="ParamBodyAngleX",ae="ParamBreath";var ne;t.config=void 0,(ne=t.config||(t.config={})).LOG_LEVEL_VERBOSE=0,ne.LOG_LEVEL_WARNING=1,ne.LOG_LEVEL_ERROR=2,ne.LOG_LEVEL_NONE=999,ne.logLevel=ne.LOG_LEVEL_WARNING,ne.sound=!0,ne.motionSync=!0,ne.motionFadingDuration=500,ne.idleMotionFadingDuration=2e3,ne.expressionFadingDuration=500,ne.preserveExpressionOnMotion=!0,ne.cubism4=t.CubismConfig;const le={log(e,...i){t.config.logLevel<=t.config.LOG_LEVEL_VERBOSE&&console.log(`[${e}]`,...i)},warn(e,...i){t.config.logLevel<=t.config.LOG_LEVEL_WARNING&&console.warn(`[${e}]`,...i)},error(e,...i){t.config.logLevel<=t.config.LOG_LEVEL_ERROR&&console.error(`[${e}]`,...i)}};function he(t,e,i){return ti?i:t}function ue(t,e){e.forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((i=>{"constructor"!==i&&Object.defineProperty(t.prototype,i,Object.getOwnPropertyDescriptor(e.prototype,i))}))}))}function de(t){let e=t.lastIndexOf("/");return-1!=e&&(t=t.slice(0,e)),e=t.lastIndexOf("/"),-1!==e&&(t=t.slice(e+1)),t}function ce(t,e){const i=t.indexOf(e);-1!==i&&t.splice(i,1)}class ge extends e.EventEmitter{constructor(t,e){super(),this.expressions=[],this.reserveExpressionIndex=-1,this.destroyed=!1,this.settings=t,this.tag=`ExpressionManager(${t.name})`}init(){this.defaultExpression=this.createExpression({},void 0),this.currentExpression=this.defaultExpression,this.stopAllExpressions()}loadExpression(t){return __async(this,null,(function*(){if(!this.definitions[t])return void le.warn(this.tag,`Undefined expression at [${t}]`);if(null===this.expressions[t])return void le.warn(this.tag,`Cannot set expression at [${t}] because it's already failed in loading.`);if(this.expressions[t])return this.expressions[t];const e=yield this._loadExpression(t);return this.expressions[t]=e,e}))}_loadExpression(t){throw new Error("Not implemented.")}setRandomExpression(){return __async(this,null,(function*(){if(this.definitions.length){const t=[];for(let e=0;e-1&&tl&&(o*=l/n,a*=l/n),this.vx+=o,this.vy+=a;const h=Math.sqrt(__pow(this.vx,2)+__pow(this.vy,2)),u=.5*(Math.sqrt(__pow(l,2)+8*l*s)-l);h>u&&(this.vx*=u/h,this.vy*=u/h),this.x+=this.vx,this.y+=this.vy}}class _e{constructor(t){this.json=t;let e=t.url;if("string"!=typeof e)throw new TypeError("The `url` field in settings JSON must be defined as a string.");this.url=e,this.name=de(this.url)}resolveURL(t){return e.url.resolve(this.url,t)}replaceFiles(t){this.moc=t(this.moc,"moc"),void 0!==this.pose&&(this.pose=t(this.pose,"pose")),void 0!==this.physics&&(this.physics=t(this.physics,"physics"));for(let e=0;e(t.push(e),e))),t}validateFiles(t){const e=(e,i)=>{const s=this.resolveURL(e);if(!t.includes(s)){if(i)throw new Error(`File "${e}" is defined in settings, but doesn't exist in given files`);return!1}return!0};[this.moc,...this.textures].forEach((t=>e(t,!0)));return this.getDefinedFiles().filter((t=>e(t,!1)))}}var pe=(t=>(t[t.NONE=0]="NONE",t[t.IDLE=1]="IDLE",t[t.NORMAL=2]="NORMAL",t[t.FORCE=3]="FORCE",t))(pe||{});class fe{constructor(){this.debug=!1,this.currentPriority=0,this.reservePriority=0}reserve(t,e,i){if(i<=0)return le.log(this.tag,"Cannot start a motion with MotionPriority.NONE."),!1;if(t===this.currentGroup&&e===this.currentIndex)return le.log(this.tag,"Motion is already playing.",this.dump(t,e)),!1;if(t===this.reservedGroup&&e===this.reservedIndex||t===this.reservedIdleGroup&&e===this.reservedIdleIndex)return le.log(this.tag,"Motion is already reserved.",this.dump(t,e)),!1;if(1===i){if(0!==this.currentPriority)return le.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(t,e)),!1;if(void 0!==this.reservedIdleGroup)return le.log(this.tag,"Cannot start idle motion because another idle motion has reserved.",this.dump(t,e)),!1;this.setReservedIdle(t,e)}else{if(i<3){if(i<=this.currentPriority)return le.log(this.tag,"Cannot start motion because another motion is playing as an equivalent or higher priority.",this.dump(t,e)),!1;if(i<=this.reservePriority)return le.log(this.tag,"Cannot start motion because another motion has reserved as an equivalent or higher priority.",this.dump(t,e)),!1}this.setReserved(t,e,i)}return!0}start(t,e,i,s){if(1===s){if(this.setReservedIdle(void 0,void 0),0!==this.currentPriority)return le.log(this.tag,"Cannot start idle motion because another motion is playing.",this.dump(e,i)),!1}else{if(e!==this.reservedGroup||i!==this.reservedIndex)return le.log(this.tag,"Cannot start motion because another motion has taken the place.",this.dump(e,i)),!1;this.setReserved(void 0,void 0,0)}return!!t&&(this.setCurrent(e,i,s),!0)}complete(){this.setCurrent(void 0,void 0,0)}setCurrent(t,e,i){this.currentPriority=i,this.currentGroup=t,this.currentIndex=e}setReserved(t,e,i){this.reservePriority=i,this.reservedGroup=t,this.reservedIndex=e}setReservedIdle(t,e){this.reservedIdleGroup=t,this.reservedIdleIndex=e}isActive(t,e){return t===this.currentGroup&&e===this.currentIndex||t===this.reservedGroup&&e===this.reservedIndex||t===this.reservedIdleGroup&&e===this.reservedIdleIndex}reset(){this.setCurrent(void 0,void 0,0),this.setReserved(void 0,void 0,0),this.setReservedIdle(void 0,void 0)}shouldRequestIdleMotion(){return void 0===this.currentGroup&&void 0===this.reservedIdleGroup}shouldOverrideExpression(){return!t.config.preserveExpressionOnMotion&&this.currentPriority>1}dump(t,e){if(this.debug){return`\n group = "${t}", index = ${e}\n`+["currentPriority","reservePriority","currentGroup","currentIndex","reservedGroup","reservedIndex","reservedIdleGroup","reservedIdleIndex"].map((t=>"["+t+"] "+this[t])).join("\n")}return""}}class ye{static get volume(){return this._volume}static set volume(t){this._volume=(t>1?1:t<0?0:t)||0,this.audios.forEach((t=>t.volume=this._volume))}static add(t,e,i){const s=new Audio(t);return s.volume=this._volume,s.preload="auto",s.autoplay=!0,s.crossOrigin="anonymous",s.addEventListener("ended",(()=>{this.dispose(s),null==e||e()})),s.addEventListener("error",(e=>{this.dispose(s),le.warn("SoundManager",`Error occurred on "${t}"`,e.error),null==i||i(e.error)})),this.audios.push(s),s}static play(t){return new Promise(((e,i)=>{var s;null==(s=t.play())||s.catch((e=>{t.dispatchEvent(new ErrorEvent("error",{error:e})),i(e)})),t.readyState===t.HAVE_ENOUGH_DATA?e():t.addEventListener("canplaythrough",e)}))}static addContext(t){const e=new AudioContext;return this.contexts.push(e),e}static addAnalyzer(t,e){const i=e.createMediaElementSource(t),s=e.createAnalyser();return s.fftSize=256,s.minDecibels=-90,s.maxDecibels=-10,s.smoothingTimeConstant=.85,i.connect(s),s.connect(e.destination),this.analysers.push(s),s}static analyze(t){if(null!=t){let e=new Float32Array(t.fftSize),i=0;t.getFloatTimeDomainData(e);for(const t of e)i+=t*t;return parseFloat(Math.sqrt(i/e.length*20).toFixed(1))}return parseFloat(Math.random().toFixed(1))}static dispose(t){t.pause(),t.removeAttribute("src"),ce(this.audios,t)}static destroy(){for(let t=this.contexts.length-1;t>=0;t--)this.contexts[t].close();for(let t=this.audios.length-1;t>=0;t--)this.dispose(this.audios[t])}}ye.audios=[],ye.analysers=[],ye.contexts=[],ye._volume=.9;var Ce=(t=>(t.ALL="ALL",t.IDLE="IDLE",t.NONE="NONE",t))(Ce||{});class xe extends e.EventEmitter{constructor(t,e){super(),this.motionGroups={},this.state=new fe,this.playing=!1,this.destroyed=!1,this.settings=t,this.tag=`MotionManager(${t.name})`,this.state.tag=this.tag}init(t){(null==t?void 0:t.idleMotionGroup)&&(this.groups.idle=t.idleMotionGroup),this.setupMotions(t),this.stopAllMotions()}setupMotions(t){for(const i of Object.keys(this.definitions))this.motionGroups[i]=[];let e;switch(null==t?void 0:t.motionPreload){case"NONE":return;case"ALL":e=Object.keys(this.definitions);break;default:e=[this.groups.idle]}for(const i of e)if(this.definitions[i])for(let t=0;t{s&&d.expressionManager&&d.expressionManager.resetExpression(),d.currentAudio=void 0}),(()=>{s&&d.expressionManager&&d.expressionManager.resetExpression(),d.currentAudio=void 0})),this.currentAudio=r;let t=1;void 0!==i&&(t=i),ye.volume=t,a=ye.addContext(this.currentAudio),this.currentContext=a,o=ye.addAnalyzer(this.currentAudio,this.currentContext),this.currentAnalyzer=o}catch(c){le.warn(this.tag,"Failed to create audio",n,c)}if(r){const e=ye.play(r).catch((t=>le.warn(this.tag,"Failed to play audio",r.src,t)));t.config.motionSync&&(yield e)}return this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),s&&this.expressionManager&&this.expressionManager.setExpression(s),this.playing=!0,!0}))}startMotion(e,i){return __async(this,arguments,(function*(e,i,s=pe.NORMAL,r,o,a){var n;if(this.currentAudio&&!this.currentAudio.ended)return!1;if(!this.state.reserve(e,i,s))return!1;const l=null==(n=this.definitions[e])?void 0:n[i];if(!l)return!1;let h,u,d;if(this.currentAudio&&ye.dispose(this.currentAudio),t.config.sound){const t=r&&r.startsWith("data:audio/wav;base64");if(r&&!t){var c=document.createElement("a");c.href=r,r=c.href}const e=r&&(r.startsWith("http")||r.startsWith("blob")),i=this.getSoundFile(l);let s=i;i&&(s=this.settings.resolveURL(i)+"?cache-buster="+(new Date).getTime()),(e||t)&&(s=r);const n=this;if(s)try{h=ye.add(s,(()=>{a&&n.expressionManager&&n.expressionManager.resetExpression(),n.currentAudio=void 0}),(()=>{a&&n.expressionManager&&n.expressionManager.resetExpression(),n.currentAudio=void 0})),this.currentAudio=h;let t=1;void 0!==o&&(t=o),ye.volume=t,d=ye.addContext(this.currentAudio),this.currentContext=d,u=ye.addAnalyzer(this.currentAudio,this.currentContext),this.currentAnalyzer=u}catch(m){le.warn(this.tag,"Failed to create audio",i,m)}}const g=yield this.loadMotion(e,i);if(h){s=3;const e=ye.play(h).catch((t=>le.warn(this.tag,"Failed to play audio",h.src,t)));t.config.motionSync&&(yield e)}return this.state.start(g,e,i,s)?(this.state.shouldOverrideExpression()&&this.expressionManager&&this.expressionManager.resetExpression(),le.log(this.tag,"Start motion:",this.getMotionName(l)),this.emit("motionStart",e,i,h),a&&this.expressionManager&&this.expressionManager.setExpression(a),this.playing=!0,this._startMotion(g),!0):(h&&(ye.dispose(h),this.currentAudio=void 0),!1)}))}startRandomMotion(t,e,i,s){return __async(this,null,(function*(){const r=this.definitions[t];if(null==r?void 0:r.length){const o=[];for(let e=0;et.index>=0));for(const e of t)this.hitAreas[e.name]=e}hitTest(t,e){return Object.keys(this.hitAreas).filter((i=>this.isHit(i,t,e)))}isHit(t,e,i){if(!this.hitAreas[t])return!1;const s=this.hitAreas[t].index,r=this.getDrawableBounds(s,Me);return r.x<=e&&e<=r.x+r.width&&r.y<=i&&i<=r.y+r.height}getDrawableBounds(t,e){const i=this.getDrawableVertices(t);let s=i[0],r=i[0],o=i[1],a=i[1];for(let n=0;n{200!==o.status&&0!==o.status||!o.response?o.onerror():s(o.response)},o.onerror=()=>{le.warn("XHRLoader",`Failed to load resource as ${o.responseType} (Status ${o.status}): ${e}`),r(new Pe("Network error.",e,o.status))},o.onabort=()=>r(new Pe("Aborted.",e,o.status,!0)),o.onloadend=()=>{var e;be.allXhrSet.delete(o),t&&(null==(e=be.xhrMap.get(t))||e.delete(o))},o}static cancelXHRs(){var t;null==(t=be.xhrMap.get(this))||t.forEach((t=>{t.abort(),be.allXhrSet.delete(t)})),be.xhrMap.delete(this)}static release(){be.allXhrSet.forEach((t=>t.abort())),be.allXhrSet.clear(),be.xhrMap=new WeakMap}};let Se=be;function we(t,e){let i=-1;return function s(r,o){if(o)return Promise.reject(o);if(r<=i)return Promise.reject(new Error("next() called multiple times"));i=r;const a=t[r];if(!a)return Promise.resolve();try{return Promise.resolve(a(e,s.bind(null,r+1)))}catch(n){return Promise.reject(n)}}(0)}Se.xhrMap=new WeakMap,Se.allXhrSet=new Set,Se.loader=(t,e)=>new Promise(((e,i)=>{be.createXHR(t.target,t.settings?t.settings.resolveURL(t.url):t.url,t.type,(i=>{t.result=i,e()}),i).send()}));class Te{static load(t){return we(this.middlewares,t).then((()=>t.result))}}Te.middlewares=[Se.loader];const Ie="Live2DFactory",Le=(t,e)=>__async(this,null,(function*(){if("string"==typeof t.source){const e=yield Te.load({url:t.source,type:"json",target:t.live2dModel});e.url=t.source,t.source=e,t.live2dModel.emit("settingsJSONLoaded",e)}return e()})),Ee=(t,e)=>__async(this,null,(function*(){if(t.source instanceof _e)return t.settings=t.source,e();if("object"==typeof t.source){const i=Oe.findRuntime(t.source);if(i){const s=i.createModelSettings(t.source);return t.settings=s,t.live2dModel.emit("settingsLoaded",s),e()}}throw new TypeError("Unknown settings format.")})),Ae=(t,e)=>{if(t.settings){const i=Oe.findRuntime(t.settings);if(i)return i.ready().then(e)}return e()},Fe=(t,e)=>__async(this,null,(function*(){yield e();const i=t.internalModel;if(i){const e=t.settings,s=Oe.findRuntime(e);if(s){const r=[];e.pose&&r.push(Te.load({settings:e,url:e.pose,type:"json",target:i}).then((e=>{i.pose=s.createPose(i.coreModel,e),t.live2dModel.emit("poseLoaded",i.pose)})).catch((e=>{t.live2dModel.emit("poseLoadError",e),le.warn(Ie,"Failed to load pose.",e)}))),e.physics&&r.push(Te.load({settings:e,url:e.physics,type:"json",target:i}).then((e=>{i.physics=s.createPhysics(i.coreModel,e),t.live2dModel.emit("physicsLoaded",i.physics)})).catch((e=>{t.live2dModel.emit("physicsLoadError",e),le.warn(Ie,"Failed to load physics.",e)}))),r.length&&(yield Promise.all(r))}}})),De=(t,e)=>__async(this,null,(function*(){if(!t.settings)throw new TypeError("Missing settings.");{const i=t.live2dModel,r=t.settings.textures.map((e=>function(t,e={}){const i={resourceOptions:{crossorigin:e.crossOrigin}};if(s.Texture.fromURL)return s.Texture.fromURL(t,i).catch((t=>{if(t instanceof Error)throw t;const e=new Error("Texture loading error");throw e.event=t,e}));i.resourceOptions.autoLoad=!1;const r=s.Texture.from(t,i);if(r.baseTexture.valid)return Promise.resolve(r);const o=r.baseTexture.resource;return null!=o._live2d_load||(o._live2d_load=new Promise(((t,e)=>{const i=t=>{o.source.removeEventListener("error",i);const s=new Error("Texture loading error");s.event=t,e(s)};o.source.addEventListener("error",i),o.load().then((()=>t(r))).catch(i)}))),o._live2d_load}(t.settings.resolveURL(e),{crossOrigin:t.options.crossOrigin})));if(yield e(),!t.internalModel)throw new TypeError("Missing internal model.");i.internalModel=t.internalModel,i.emit("modelLoaded",t.internalModel),i.textures=yield Promise.all(r),i.emit("textureLoaded",i.textures)}})),Be=(t,e)=>__async(this,null,(function*(){const i=t.settings;if(i instanceof _e){const s=Oe.findRuntime(i);if(!s)throw new TypeError("Unknown model settings.");const r=yield Te.load({settings:i,url:i.moc,type:"arraybuffer",target:t.live2dModel});if(!s.isValidMoc(r))throw new Error("Invalid moc data");const o=s.createCoreModel(r);return t.internalModel=s.createInternalModel(o,i,t.options),e()}throw new TypeError("Missing settings.")})),Re=class{static registerRuntime(t){Re.runtimes.push(t),Re.runtimes.sort(((t,e)=>e.version-t.version))}static findRuntime(t){for(const e of Re.runtimes)if(e.test(t))return e}static setupLive2DModel(t,e,i){return __async(this,null,(function*(){const s=new Promise((e=>t.once("textureLoaded",e))),r=new Promise((e=>t.once("modelLoaded",e))),o=Promise.all([s,r]).then((()=>t.emit("ready")));yield we(Re.live2DModelMiddlewares,{live2dModel:t,source:e,options:i||{}}),yield o,t.emit("load")}))}static loadMotion(t,e,i){var s;const r=s=>t.emit("motionLoadError",e,i,s);try{const o=null==(s=t.definitions[e])?void 0:s[i];if(!o)return Promise.resolve(void 0);t.listeners("destroy").includes(Re.releaseTasks)||t.once("destroy",Re.releaseTasks);let a=Re.motionTasksMap.get(t);a||(a={},Re.motionTasksMap.set(t,a));let n=a[e];n||(n=[],a[e]=n);const l=t.getMotionFile(o);return null!=n[i]||(n[i]=Te.load({url:l,settings:t.settings,type:t.motionDataType,target:t}).then((s=>{var r;const a=null==(r=Re.motionTasksMap.get(t))?void 0:r[e];a&&delete a[i];const n=t.createMotion(s,e,o);return t.emit("motionLoaded",e,i,n),n})).catch((e=>{le.warn(t.tag,`Failed to load motion: ${l}\n`,e),r(e)}))),n[i]}catch(o){le.warn(t.tag,`Failed to load motion at "${e}"[${i}]\n`,o),r(o)}return Promise.resolve(void 0)}static loadExpression(t,e){const i=i=>t.emit("expressionLoadError",e,i);try{const s=t.definitions[e];if(!s)return Promise.resolve(void 0);t.listeners("destroy").includes(Re.releaseTasks)||t.once("destroy",Re.releaseTasks);let r=Re.expressionTasksMap.get(t);r||(r=[],Re.expressionTasksMap.set(t,r));const o=t.getExpressionFile(s);return null!=r[e]||(r[e]=Te.load({url:o,settings:t.settings,type:"json",target:t}).then((i=>{const r=Re.expressionTasksMap.get(t);r&&delete r[e];const o=t.createExpression(i,s);return t.emit("expressionLoaded",e,o),o})).catch((e=>{le.warn(t.tag,`Failed to load expression: ${o}\n`,e),i(e)}))),r[e]}catch(s){le.warn(t.tag,`Failed to load expression at [${e}]\n`,s),i(s)}return Promise.resolve(void 0)}static releaseTasks(){this instanceof xe?Re.motionTasksMap.delete(this):Re.expressionTasksMap.delete(this)}};let Oe=Re;Oe.runtimes=[],Oe.urlToJSON=Le,Oe.jsonToSettings=Ee,Oe.waitUntilReady=Ae,Oe.setupOptionals=Fe,Oe.setupEssentials=De,Oe.createInternalModel=Be,Oe.live2DModelMiddlewares=[Le,Ee,Ae,Fe,De,Be],Oe.motionTasksMap=new WeakMap,Oe.expressionTasksMap=new WeakMap,xe.prototype._loadMotion=function(t,e){return Oe.loadMotion(this,t,e)},ge.prototype._loadExpression=function(t){return Oe.loadExpression(this,t)};class ke{constructor(){this._autoInteract=!1}get autoInteract(){return this._autoInteract}set autoInteract(t){t!==this._autoInteract&&(t?this.on("pointertap",Ue,this):this.off("pointertap",Ue,this),this._autoInteract=t)}registerInteraction(t){t!==this.interactionManager&&(this.unregisterInteraction(),this._autoInteract&&t&&(this.interactionManager=t,t.on("pointermove",Ve,this)))}unregisterInteraction(){var t;this.interactionManager&&(null==(t=this.interactionManager)||t.off("pointermove",Ve,this),this.interactionManager=void 0)}}function Ue(t){this.tap(t.data.global.x,t.data.global.y)}function Ve(t){this.focus(t.data.global.x,t.data.global.y)}class Ne extends i.Transform{}const Ge=new i.Point,Xe=new i.Matrix;let ze;class je extends r.Container{constructor(t){super(),this.tag="Live2DModel(uninitialized)",this.textures=[],this.transform=new Ne,this.anchor=new i.ObservablePoint(this.onAnchorChange,this,0,0),this.glContextID=-1,this.elapsedTime=performance.now(),this.deltaTime=0,this._autoUpdate=!1,this.once("modelLoaded",(()=>this.init(t)))}static from(t,e){const i=new this(e);return Oe.setupLive2DModel(i,t,e).then((()=>i))}static fromSync(t,e){const i=new this(e);return Oe.setupLive2DModel(i,t,e).then(null==e?void 0:e.onLoad).catch(null==e?void 0:e.onError),i}static registerTicker(t){ze=t}get autoUpdate(){return this._autoUpdate}set autoUpdate(t){var e;ze||(ze=null==(e=window.PIXI)?void 0:e.Ticker),t?this._destroyed||(ze?(ze.shared.add(this.onTickerUpdate,this),this._autoUpdate=!0):le.warn(this.tag,"No Ticker registered, please call Live2DModel.registerTicker(Ticker).")):(null==ze||ze.shared.remove(this.onTickerUpdate,this),this._autoUpdate=!1)}init(t){this.tag=`Live2DModel(${this.internalModel.settings.name})`;const e=Object.assign({autoUpdate:!0,autoInteract:!0},t);e.autoInteract&&(this.interactive=!0),this.autoInteract=e.autoInteract,this.autoUpdate=e.autoUpdate}onAnchorChange(){this.pivot.set(this.anchor.x*this.internalModel.width,this.anchor.y*this.internalModel.height)}motion(t,e,i,s,r,o){return void 0===e?this.internalModel.motionManager.startRandomMotion(t,i):this.internalModel.motionManager.startMotion(t,e,i,s,r,o)}resetMotions(){return this.internalModel.motionManager.stopAllMotions()}speak(t,e,i){return this.internalModel.motionManager.speakUp(t,e,i)}stopSpeaking(){return this.internalModel.motionManager.stopSpeaking()}expression(t){return this.internalModel.motionManager.expressionManager?void 0===t?this.internalModel.motionManager.expressionManager.setRandomExpression():this.internalModel.motionManager.expressionManager.setExpression(t):Promise.resolve(!1)}focus(t,e,i=!1){Ge.x=t,Ge.y=e,this.toModelPosition(Ge,Ge,!0);let s=Ge.x/this.internalModel.originalWidth*2-1,r=Ge.y/this.internalModel.originalHeight*2-1,o=Math.atan2(r,s);this.internalModel.focusController.focus(Math.cos(o),-Math.sin(o),i)}tap(t,e){const i=this.hitTest(t,e);i.length&&(le.log(this.tag,"Hit",i),this.emit("hit",i))}hitTest(t,e){return Ge.x=t,Ge.y=e,this.toModelPosition(Ge,Ge),this.internalModel.hitTest(Ge.x,Ge.y)}toModelPosition(t,e=t.clone(),i){return i||(this._recursivePostUpdateTransform(),this.parent?this.displayObjectUpdateTransform():(this.parent=this._tempDisplayObjectParent,this.displayObjectUpdateTransform(),this.parent=null)),this.transform.worldTransform.applyInverse(t,e),this.internalModel.localTransform.applyInverse(e,e),e}containsPoint(t){return this.getBounds(!0).contains(t.x,t.y)}_calculateBounds(){this._bounds.addFrame(this.transform,0,0,this.internalModel.width,this.internalModel.height)}onTickerUpdate(){this.update(ze.shared.deltaMS)}update(t){this.deltaTime+=t,this.elapsedTime+=t}_render(t){this.registerInteraction(t.plugins.interaction),t.batch.reset(),t.geometry.reset(),t.shader.reset(),t.state.reset();let e=!1;this.glContextID!==t.CONTEXT_UID&&(this.glContextID=t.CONTEXT_UID,this.internalModel.updateWebGLContext(t.gl,this.glContextID),e=!0);for(let r=0;re.destroy(t.baseTexture))),this.internalModel.destroy(),super.destroy(t)}}ue(je,[ke]);const We=class{static resolveURL(t,e){var i;const s=null==(i=We.filesMap[t])?void 0:i[e];if(void 0===s)throw new Error("Cannot find this file from uploaded files: "+e);return s}static upload(t,i){return __async(this,null,(function*(){const s={};for(const r of i.getDefinedFiles()){const o=decodeURI(e.url.resolve(i.url,r)),a=t.find((t=>t.webkitRelativePath===o));a&&(s[r]=URL.createObjectURL(a))}We.filesMap[i._objectURL]=s}))}static createSettings(t){return __async(this,null,(function*(){const e=t.find((t=>t.name.endsWith("model.json")||t.name.endsWith("model3.json")));if(!e)throw new TypeError("Settings file not found");const i=yield We.readText(e),s=JSON.parse(i);s.url=e.webkitRelativePath;const r=Oe.findRuntime(s);if(!r)throw new Error("Unknown settings JSON");const o=r.createModelSettings(s);return o._objectURL=URL.createObjectURL(e),o}))}static readText(t){return __async(this,null,(function*(){return new Promise(((e,i)=>{const s=new FileReader;s.onload=()=>e(s.result),s.onerror=i,s.readAsText(t,"utf8")}))}))}};let He=We;He.filesMap={},He.factory=(t,e)=>__async(this,null,(function*(){if(Array.isArray(t.source)&&t.source[0]instanceof File){const e=t.source;let i=e.settings;if(i){if(!i._objectURL)throw new Error('"_objectURL" must be specified in ModelSettings')}else i=yield We.createSettings(e);i.validateFiles(e.map((t=>encodeURI(t.webkitRelativePath)))),yield We.upload(e,i),i.resolveURL=function(t){return We.resolveURL(this._objectURL,t)},t.source=i,t.live2dModel.once("modelLoaded",(t=>{t.once("destroy",(function(){const t=this.settings._objectURL;if(URL.revokeObjectURL(t),We.filesMap[t])for(const e of Object.values(We.filesMap[t]))URL.revokeObjectURL(e);delete We.filesMap[t]}))}))}return e()})),Oe.live2DModelMiddlewares.unshift(He.factory);const Ye=class{static unzip(t,i){return __async(this,null,(function*(){const s=yield Ye.getFilePaths(t),r=[];for(const t of i.getDefinedFiles()){const o=decodeURI(e.url.resolve(i.url,t));s.includes(o)&&r.push(o)}const o=yield Ye.getFiles(t,r);for(let t=0;tt.endsWith("model.json")||t.endsWith("model3.json")));if(!e)throw new Error("Settings file not found");const i=yield Ye.readText(t,e);if(!i)throw new Error("Empty settings file: "+e);const s=JSON.parse(i);s.url=e;const r=Oe.findRuntime(s);if(!r)throw new Error("Unknown settings JSON");return r.createModelSettings(s)}))}static zipReader(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFilePaths(t){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static getFiles(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static readText(t,e){return __async(this,null,(function*(){throw new Error("Not implemented")}))}static releaseReader(t){}};let qe=Ye;if(qe.ZIP_PROTOCOL="zip://",qe.uid=0,qe.factory=(t,e)=>__async(this,null,(function*(){const i=t.source;let s,r,o;if("string"==typeof i&&(i.endsWith(".zip")||i.startsWith(Ye.ZIP_PROTOCOL))?(s=i.startsWith(Ye.ZIP_PROTOCOL)?i.slice(Ye.ZIP_PROTOCOL.length):i,r=yield Te.load({url:s,type:"blob",target:t.live2dModel})):Array.isArray(i)&&1===i.length&&i[0]instanceof File&&i[0].name.endsWith(".zip")&&(r=i[0],s=URL.createObjectURL(r),o=i.settings),r){if(!r.size)throw new Error("Empty zip file");const e=yield Ye.zipReader(r,s);o||(o=yield Ye.createSettings(e)),o._objectURL=Ye.ZIP_PROTOCOL+Ye.uid+"/"+o.url;const i=yield Ye.unzip(e,o);i.settings=o,t.source=i,s.startsWith("blob:")&&t.live2dModel.once("modelLoaded",(t=>{t.once("destroy",(function(){URL.revokeObjectURL(s)}))})),Ye.releaseReader(e)}return e()})),Oe.live2DModelMiddlewares.unshift(qe.factory),!window.Live2DCubismCore)throw new Error("Could not find Cubism 4 runtime. This plugin requires live2dcubismcore.js to be loaded.");class $e extends ge{constructor(t,e){var i;super(t,e),this.queueManager=new nt,this.definitions=null!=(i=t.expressions)?i:[],this.init()}isFinished(){return this.queueManager.isFinished()}getExpressionIndex(t){return this.definitions.findIndex((e=>e.Name===t))}getExpressionFile(t){return t.File}createExpression(t,e){return V.create(t)}_setExpression(t){return this.queueManager.startMotion(t,!1,performance.now())}stopAllExpressions(){this.queueManager.stopAllMotions()}updateParameters(t,e){return this.queueManager.doUpdateMotion(t,e)}}class Je extends _e{constructor(t){if(super(t),!Je.isValidJSON(t))throw new TypeError("Invalid JSON.");Object.assign(this,new Kt(t))}static isValidJSON(t){var e;return!!(null==t?void 0:t.FileReferences)&&"string"==typeof t.FileReferences.Moc&&(null==(e=t.FileReferences.Textures)?void 0:e.length)>0&&t.FileReferences.Textures.every((t=>"string"==typeof t))}replaceFiles(t){if(super.replaceFiles(t),this.motions)for(const[e,i]of Object.entries(this.motions))for(let s=0;s{this.emit("motion:"+e)}))}isFinished(){return this.queueManager.isFinished()}_startMotion(t,e){return t.setFinishedMotionHandler(e),this.queueManager.stopAllMotions(),this.queueManager.startMotion(t,!1,performance.now())}_stopAllMotions(){this.queueManager.stopAllMotions()}createMotion(e,i,s){const r=ot.create(e),o=new $(e),a=(i===this.groups.idle?t.config.idleMotionFadingDuration:t.config.motionFadingDuration)/1e3;return void 0===o.getMotionFadeInTime()&&r.setFadeInTime(s.FadeInTime>0?s.FadeInTime:a),void 0===o.getMotionFadeOutTime()&&r.setFadeOutTime(s.FadeOutTime>0?s.FadeOutTime:a),r.setEffectIds(this.eyeBlinkIds,this.lipSyncIds),r}getMotionFile(t){return t.File}getMotionName(t){return t.File}getSoundFile(t){return t.Sound}updateParameters(t,e){return this.queueManager.doUpdateMotion(t,e)}destroy(){super.destroy(),this.queueManager.release(),this.queueManager=void 0}}const Qe=new _;class Ke extends ve{constructor(t,e,s){super(),this.lipSync=!0,this.breath=o.create(),this.renderer=new Qt,this.idParamAngleX=te,this.idParamAngleY=ee,this.idParamAngleZ=ie,this.idParamEyeBallX=se,this.idParamEyeBallY=re,this.idParamBodyAngleX=oe,this.idParamBreath=ae,this.pixelsPerUnit=1,this.centeringTransform=new i.Matrix,this.coreModel=t,this.settings=e,this.motionManager=new Ze(e,s),this.init()}init(){var t;super.init(),(null==(t=this.settings.getEyeBlinkParameters())?void 0:t.length)>0&&(this.eyeBlink=l.create(this.settings)),this.breath.setParameters([new a(this.idParamAngleX,0,15,6.5345,.5),new a(this.idParamAngleY,0,8,3.5345,.5),new a(this.idParamAngleZ,0,10,5.5345,.5),new a(this.idParamBodyAngleX,0,4,15.5345,.5),new a(this.idParamBreath,0,.5,3.2345,.5)]),this.renderer.initialize(this.coreModel),this.renderer.setIsPremultipliedAlpha(!0)}getSize(){return[this.coreModel.getModel().canvasinfo.CanvasWidth,this.coreModel.getModel().canvasinfo.CanvasHeight]}getLayout(){const t={};if(this.settings.layout)for(const e of Object.keys(this.settings.layout)){t[e.charAt(0).toLowerCase()+e.slice(1)]=this.settings.layout[e]}return t}setupLayout(){super.setupLayout(),this.pixelsPerUnit=this.coreModel.getModel().canvasinfo.PixelsPerUnit,this.centeringTransform.scale(this.pixelsPerUnit,this.pixelsPerUnit).translate(this.originalWidth/2,this.originalHeight/2)}updateWebGLContext(t,e){this.renderer.firstDraw=!0,this.renderer._bufferData={vertex:null,uv:null,index:null},this.renderer.startUp(t),this.renderer._clippingManager._currentFrameNo=e,this.renderer._clippingManager._maskTexture=void 0,zt.getInstance()._shaderSets=[]}bindTexture(t,e){this.renderer.bindTexture(t,e)}getHitAreaDefs(){var t,e;return null!=(e=null==(t=this.settings.hitAreas)?void 0:t.map((t=>({id:t.Id,name:t.Name,index:this.coreModel.getDrawableIndex(t.Id)}))))?e:[]}getDrawableIDs(){return this.coreModel.getDrawableIds()}getDrawableIndex(t){return this.coreModel.getDrawableIndex(t)}getDrawableVertices(t){if("string"==typeof t&&-1===(t=this.coreModel.getDrawableIndex(t)))throw new TypeError("Unable to find drawable ID: "+t);const e=this.coreModel.getDrawableVertices(t).slice();for(let i=0;i{!function i(){try{si(),t()}catch(s){if(ei--,ei<0){const t=new Error("Failed to start up Cubism 4 framework.");return t.cause=s,void e(t)}le.log("Cubism4","Startup failed, retrying 10ms later..."),setTimeout(i,10)}}()}))),ti)}function si(t){t=Object.assign({logFunction:console.log,loggingLevel:b.LogLevel_Verbose},t),P.startUp(t),P.initialize()}function ri(){var t;null==(t=this.__moc)||t.release()}Oe.registerRuntime({version:4,ready:ii,test:t=>t instanceof Je||Je.isValidJSON(t),isValidMoc(t){if(t.byteLength<4)return!1;const e=new Int8Array(t,0,4);return"MOC3"===String.fromCharCode(...e)},createModelSettings:t=>new Je(t),createCoreModel(t,e){const i=R.create(t,!!(null==e?void 0:e.checkMocConsistency));try{const t=i.createModel();return t.__moc=i,t}catch(s){try{i.release()}catch(r){}throw s}},createInternalModel(t,e,i){const s=new Ke(t,e,i),r=t;return r.__moc&&(s.__moc=r.__moc,delete r.__moc,s.once("destroy",ri)),s},createPhysics:(t,e)=>yt.create(e),createPose:(t,e)=>u.create(e)}),t.ACubismMotion=U,t.BreathParameterData=a,t.CSM_ASSERT=S,t.Constant=v,t.Cubism4ExpressionManager=$e,t.Cubism4InternalModel=Ke,t.Cubism4ModelSettings=Je,t.Cubism4MotionManager=Ze,t.CubismBlendMode=f,t.CubismBreath=o,t.CubismClippingContext=Gt,t.CubismClippingManager_WebGL=Vt,t.CubismDebug=E,t.CubismExpressionMotion=V,t.CubismEyeBlink=l,t.CubismFramework=P,t.CubismLogDebug=w,t.CubismLogError=L,t.CubismLogInfo=T,t.CubismLogVerbose=function(t,...e){E.print(b.LogLevel_Verbose,"[CSM][V]"+t+"\n",e)},t.CubismLogWarning=I,t.CubismMath=m,t.CubismMatrix44=_,t.CubismMoc=R,t.CubismModel=B,t.CubismModelSettingsJson=Kt,t.CubismModelUserData=k,t.CubismModelUserDataJson=O,t.CubismMotion=ot,t.CubismMotionCurve=H,t.CubismMotionCurveTarget=X,t.CubismMotionData=q,t.CubismMotionEvent=Y,t.CubismMotionJson=$,t.CubismMotionManager=class extends nt{constructor(){super(),this._currentPriority=0,this._reservePriority=0}getCurrentPriority(){return this._currentPriority}getReservePriority(){return this._reservePriority}setReservePriority(t){this._reservePriority=t}startMotionPriority(t,e,i){return i==this._reservePriority&&(this._reservePriority=0),this._currentPriority=i,super.startMotion(t,e,this._userTimeSeconds)}updateMotion(t,e){this._userTimeSeconds+=e;const i=super.doUpdateMotion(t,this._userTimeSeconds);return this.isFinished()&&(this._currentPriority=0),i}reserveMotion(t){return!(t<=this._reservePriority||t<=this._currentPriority)&&(this._reservePriority=t,!0)}},t.CubismMotionPoint=j,t.CubismMotionQueueEntry=at,t.CubismMotionQueueManager=nt,t.CubismMotionSegment=W,t.CubismMotionSegmentType=z,t.CubismPhysics=yt,t.CubismPhysicsInput=gt,t.CubismPhysicsJson=pt,t.CubismPhysicsOutput=mt,t.CubismPhysicsParticle=dt,t.CubismPhysicsRig=_t,t.CubismPhysicsSource=ut,t.CubismPhysicsSubRig=ct,t.CubismPhysicsTargetType=ht,t.CubismPose=u,t.CubismRenderTextureResource=Nt,t.CubismRenderer=p,t.CubismRendererProfile_WebGL=Xt,t.CubismRenderer_WebGL=Qt,t.CubismShader_WebGL=zt,t.CubismTextureColor=y,t.CubismVector2=c,t.DrawableColorData=A,t.DrawableCullingData=D,t.EvaluationOptionFlag=J,t.ExpressionBlendType=G,t.ExpressionManager=ge,t.EyeState=h,t.FileLoader=He,t.FocusController=me,t.HitAreaBody="Body",t.HitAreaHead="Head",t.HitAreaPrefix="HitArea",t.InteractionMixin=ke,t.InternalModel=ve,t.InvalidMotionQueueEntryHandleValue=lt,t.LOGICAL_HEIGHT=2,t.LOGICAL_WIDTH=2,t.Live2DFactory=Oe,t.Live2DLoader=Te,t.Live2DModel=je,t.Live2DTransform=Ne,t.LogLevel=b,t.ModelSettings=_e,t.MotionManager=xe,t.MotionPreloadStrategy=Ce,t.MotionPriority=pe,t.MotionState=fe,t.Options=Ct,t.ParamAngleX=te,t.ParamAngleY=ee,t.ParamAngleZ=ie,t.ParamArmLA="ParamArmLA",t.ParamArmLB="ParamArmLB",t.ParamArmRA="ParamArmRA",t.ParamArmRB="ParamArmRB",t.ParamBaseX="ParamBaseX",t.ParamBaseY="ParamBaseY",t.ParamBodyAngleX=oe,t.ParamBodyAngleY="ParamBodyAngleY",t.ParamBodyAngleZ="ParamBodyAngleZ",t.ParamBreath=ae,t.ParamBrowLAngle="ParamBrowLAngle",t.ParamBrowLForm="ParamBrowLForm",t.ParamBrowLX="ParamBrowLX",t.ParamBrowLY="ParamBrowLY",t.ParamBrowRAngle="ParamBrowRAngle",t.ParamBrowRForm="ParamBrowRForm",t.ParamBrowRX="ParamBrowRX",t.ParamBrowRY="ParamBrowRY",t.ParamBustX="ParamBustX",t.ParamBustY="ParamBustY",t.ParamCheek="ParamCheek",t.ParamEyeBallForm="ParamEyeBallForm",t.ParamEyeBallX=se,t.ParamEyeBallY=re,t.ParamEyeLOpen="ParamEyeLOpen",t.ParamEyeLSmile="ParamEyeLSmile",t.ParamEyeROpen="ParamEyeROpen",t.ParamEyeRSmile="ParamEyeRSmile",t.ParamHairBack="ParamHairBack",t.ParamHairFluffy="ParamHairFluffy",t.ParamHairFront="ParamHairFront",t.ParamHairSide="ParamHairSide",t.ParamHandL="ParamHandL",t.ParamHandR="ParamHandR",t.ParamMouthForm="ParamMouthForm",t.ParamMouthOpenY="ParamMouthOpenY",t.ParamNONE="NONE:",t.ParamShoulderY="ParamShoulderY",t.PartColorData=F,t.PartData=d,t.PartsArmLPrefix="Parts01ArmL_",t.PartsArmPrefix="Parts01Arm_",t.PartsArmRPrefix="Parts01ArmR_",t.PartsIdCore="Parts01Core",t.PhysicsJsonEffectiveForces=class{constructor(){this.gravity=new c(0,0),this.wind=new c(0,0)}},t.PhysicsOutput=xt,t.ShaderNames=jt,t.SoundManager=ye,t.VERSION="0.4.0",t.XHRLoader=Se,t.ZipLoader=qe,t.applyMixins=ue,t.clamp=he,t.copyArray=function(t,e,i,s,r){const o=e[s];Array.isArray(o)&&(i[r]=o.filter((e=>null!==e&&typeof e===t)))},t.copyProperty=function(t,e,i,s,r){const o=e[s];null!==o&&typeof o===t&&(i[r]=o)},t.csmRect=Rt,t.cubism4Ready=ii,t.folderName=de,t.fragmentShaderSrcMaskInvertedPremultipliedAlpha=Zt,t.fragmentShaderSrcMaskPremultipliedAlpha=Jt,t.fragmentShaderSrcPremultipliedAlpha=$t,t.fragmentShaderSrcsetupMask=Ht,t.logger=le,t.rand=function(t,e){return Math.random()*(e-t)+t},t.remove=ce,t.startUpCubism4=si,t.vertexShaderSrc=Yt,t.vertexShaderSrcMasked=qt,t.vertexShaderSrcSetupMask=Wt,Object.defineProperties(t,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
+var __pow=Math.pow,__async=(t,e,i)=>new Promise(((s,r)=>{var o=t=>{try{n(i.next(t))}catch(e){r(e)}},a=t=>{try{n(i.throw(t))}catch(e){r(e)}},n=t=>t.done?s(t.value):Promise.resolve(t.value).then(o,a);n((i=i.apply(t,e)).next())}));!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@pixi/utils"),require("@pixi/math"),require("@pixi/core"),require("@pixi/display")):"function"==typeof define&&define.amd?define(["exports","@pixi/utils","@pixi/math","@pixi/core","@pixi/display"],e):e(((t="undefined"!=typeof globalThis?globalThis:t||self).PIXI=t.PIXI||{},t.PIXI.live2d=t.PIXI.live2d||{}),t.PIXI.utils,t.PIXI,t.PIXI,t.PIXI)}(this,(function(t,e,i,s,r){"use strict";class o{constructor(){this._breathParameters=[],this._currentTime=0}static create(){return new o}setParameters(t){this._breathParameters=t}getParameters(){return this._breathParameters}updateParameters(t,e){this._currentTime+=e;const i=2*this._currentTime*3.14159;for(let s=0;s=1&&(s=1,this._blinkingState=h.EyeState_Closed,this._stateStartTimeSeconds=this._userTimeSeconds),i=1-s;break;case h.EyeState_Closed:s=(this._userTimeSeconds-this._stateStartTimeSeconds)/this._closedSeconds,s>=1&&(this._blinkingState=h.EyeState_Opening,this._stateStartTimeSeconds=this._userTimeSeconds),i=0;break;case h.EyeState_Opening:s=(this._userTimeSeconds-this._stateStartTimeSeconds)/this._openingSeconds,s>=1&&(s=1,this._blinkingState=h.EyeState_Interval,this._nextBlinkingTime=this.determinNextBlinkingTiming()),i=s;break;case h.EyeState_Interval:this._nextBlinkingTime(t[t.EyeState_First=0]="EyeState_First",t[t.EyeState_Interval=1]="EyeState_Interval",t[t.EyeState_Closing=2]="EyeState_Closing",t[t.EyeState_Closed=3]="EyeState_Closed",t[t.EyeState_Opening=4]="EyeState_Opening",t))(h||{});class u{static create(t){const e=new u;"number"==typeof t.FadeInTime&&(e._fadeTimeSeconds=t.FadeInTime,e._fadeTimeSeconds<=0&&(e._fadeTimeSeconds=.5));const i=t.Groups,s=i.length;for(let r=0;r.001){if(r>=0)break;r=n,o=t.getPartOpacityByIndex(i),o+=e/this._fadeTimeSeconds,o>1&&(o=1)}}r<0&&(r=0,o=1);for(let n=i;n.15&&(i=1-.15/(1-o)),s>i&&(s=i),t.setPartOpacityByIndex(e,s)}}}constructor(){this._fadeTimeSeconds=.5,this._lastModel=void 0,this._partGroups=[],this._partGroupCounts=[]}}class d{constructor(t){this.parameterIndex=0,this.partIndex=0,this.partId="",this.link=[],null!=t&&this.assignment(t)}assignment(t){return this.partId=t.partId,this.link=t.link.map((t=>t.clone())),this}initialize(t){this.parameterIndex=t.getParameterIndex(this.partId),this.partIndex=t.getPartIndex(this.partId),t.setParameterValueByIndex(this.parameterIndex,1)}clone(){const t=new d;return t.partId=this.partId,t.parameterIndex=this.parameterIndex,t.partIndex=this.partIndex,t.link=this.link.map((t=>t.clone())),t}}class c{constructor(t,e){this.x=t||0,this.y=e||0}add(t){const e=new c(0,0);return e.x=this.x+t.x,e.y=this.y+t.y,e}substract(t){const e=new c(0,0);return e.x=this.x-t.x,e.y=this.y-t.y,e}multiply(t){const e=new c(0,0);return e.x=this.x*t.x,e.y=this.y*t.y,e}multiplyByScaler(t){return this.multiply(new c(t,t))}division(t){const e=new c(0,0);return e.x=this.x/t.x,e.y=this.y/t.y,e}divisionByScalar(t){return this.division(new c(t,t))}getLength(){return Math.sqrt(this.x*this.x+this.y*this.y)}getDistanceWith(t){return Math.sqrt((this.x-t.x)*(this.x-t.x)+(this.y-t.y)*(this.y-t.y))}dot(t){return this.x*t.x+this.y*t.y}normalize(){const t=Math.pow(this.x*this.x+this.y*this.y,.5);this.x=this.x/t,this.y=this.y/t}isEqual(t){return this.x==t.x&&this.y==t.y}isNotEqual(t){return!this.isEqual(t)}}const g=class{static range(t,e,i){return ti&&(t=i),t}static sin(t){return Math.sin(t)}static cos(t){return Math.cos(t)}static abs(t){return Math.abs(t)}static sqrt(t){return Math.sqrt(t)}static cbrt(t){if(0===t)return t;let e=t;const i=e<0;let s;return i&&(e=-e),e===1/0?s=1/0:(s=Math.exp(Math.log(e)/3),s=(e/(s*s)+2*s)/3),i?-s:s}static getEasingSine(t){return t<0?0:t>1?1:.5-.5*this.cos(t*Math.PI)}static max(t,e){return t>e?t:e}static min(t,e){return t>e?e:t}static degreesToRadian(t){return t/180*Math.PI}static radianToDegrees(t){return 180*t/Math.PI}static directionToRadian(t,e){let i=Math.atan2(e.y,e.x)-Math.atan2(t.y,t.x);for(;i<-Math.PI;)i+=2*Math.PI;for(;i>Math.PI;)i-=2*Math.PI;return i}static directionToDegrees(t,e){const i=this.directionToRadian(t,e);let s=this.radianToDegrees(i);return e.x-t.x>0&&(s=-s),s}static radianToDirection(t){const e=new c;return e.x=this.sin(t),e.y=this.cos(t),e}static quadraticEquation(t,e,i){return this.abs(t)1&&(t=1),e<0?e=0:e>1&&(e=1),i<0?i=0:i>1&&(i=1),s<0?s=0:s>1&&(s=1),this._modelColor.R=t,this._modelColor.G=e,this._modelColor.B=i,this._modelColor.A=s}getModelColor(){return Object.assign({},this._modelColor)}setIsPremultipliedAlpha(t){this._isPremultipliedAlpha=t}isPremultipliedAlpha(){return this._isPremultipliedAlpha}setIsCulling(t){this._isCulling=t}isCulling(){return this._isCulling}setAnisotropy(t){this._anisotropy=t}getAnisotropy(){return this._anisotropy}getModel(){return this._model}useHighPrecisionMask(t){this._useHighPrecisionMask=t}isUsingHighPrecisionMask(){return this._useHighPrecisionMask}constructor(){this._isCulling=!1,this._isPremultipliedAlpha=!1,this._anisotropy=0,this._modelColor=new y,this._useHighPrecisionMask=!1,this._mvpMatrix4x4=new p,this._mvpMatrix4x4.loadIdentity()}}var f=(t=>(t[t.CubismBlendMode_Normal=0]="CubismBlendMode_Normal",t[t.CubismBlendMode_Additive=1]="CubismBlendMode_Additive",t[t.CubismBlendMode_Multiplicative=2]="CubismBlendMode_Multiplicative",t))(f||{});class y{constructor(t=1,e=1,i=1,s=1){this.R=t,this.G=e,this.B=i,this.A=s}}let x,C=!1,M=!1;const v={vertexOffset:0,vertexStep:2};class P{static startUp(t){if(C)return T("CubismFramework.startUp() is already done."),C;if(Live2DCubismCore._isStarted)return C=!0,!0;if(Live2DCubismCore._isStarted=!0,x=t,x&&Live2DCubismCore.Logging.csmSetLogFunction(x.logFunction),C=!0,C){const t=Live2DCubismCore.Version.csmGetVersion(),e=(16711680&t)>>16,i=65535&t,s=t;T("Live2D Cubism Core version: {0}.{1}.{2} ({3})",("00"+((4278190080&t)>>24)).slice(-2),("00"+e).slice(-2),("0000"+i).slice(-4),s)}return T("CubismFramework.startUp() is complete."),C}static cleanUp(){C=!1,M=!1,x=void 0}static initialize(t=0){C?M?I("CubismFramework.initialize() skipped, already initialized."):(Live2DCubismCore.Memory.initializeAmountOfMemory(t),M=!0,T("CubismFramework.initialize() is complete.")):I("CubismFramework is not started.")}static dispose(){C?M?(_.staticRelease(),M=!1,T("CubismFramework.dispose() is complete.")):I("CubismFramework.dispose() skipped, not initialized."):I("CubismFramework is not started.")}static isStarted(){return C}static isInitialized(){return M}static coreLogFunction(t){Live2DCubismCore.Logging.csmGetLogFunction()&&Live2DCubismCore.Logging.csmGetLogFunction()(t)}static getLoggingLevel(){return null!=x?x.loggingLevel:b.LogLevel_Off}constructor(){}}var b=(t=>(t[t.LogLevel_Verbose=0]="LogLevel_Verbose",t[t.LogLevel_Debug=1]="LogLevel_Debug",t[t.LogLevel_Info=2]="LogLevel_Info",t[t.LogLevel_Warning=3]="LogLevel_Warning",t[t.LogLevel_Error=4]="LogLevel_Error",t[t.LogLevel_Off=5]="LogLevel_Off",t))(b||{});const S=()=>{};function w(t,...e){L.print(b.LogLevel_Debug,"[CSM][D]"+t+"\n",e)}function T(t,...e){L.print(b.LogLevel_Info,"[CSM][I]"+t+"\n",e)}function I(t,...e){L.print(b.LogLevel_Warning,"[CSM][W]"+t+"\n",e)}function E(t,...e){L.print(b.LogLevel_Error,"[CSM][E]"+t+"\n",e)}class L{static print(t,e,i){if(ti[e])))}static dumpBytes(t,e,i){for(let s=0;s0?this.print(t,"\n"):s%8==0&&s>0&&this.print(t," "),this.print(t,"{0} ",[255&e[s]]);this.print(t,"\n")}constructor(){}}class A{constructor(t=!1,e=new y){this.isOverwritten=t,this.Color=e}}class F{constructor(t=!1,e=new y){this.isOverwritten=t,this.Color=e}}class D{constructor(t=!1,e=!1){this.isOverwritten=t,this.isCulling=e}}class B{update(){this._model.update(),this._model.drawables.resetDynamicFlags()}getPixelsPerUnit(){return null==this._model?0:this._model.canvasinfo.PixelsPerUnit}getCanvasWidth(){return null==this._model?0:this._model.canvasinfo.CanvasWidth/this._model.canvasinfo.PixelsPerUnit}getCanvasHeight(){return null==this._model?0:this._model.canvasinfo.CanvasHeight/this._model.canvasinfo.PixelsPerUnit}saveParameters(){const t=this._model.parameters.count,e=this._savedParameters.length;for(let i=0;ie&&(e=this._model.parameters.minimumValues[t]),this._parameterValues[t]=1==i?e:this._parameterValues[t]=this._parameterValues[t]*(1-i)+e*i)}setParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.setParameterValueByIndex(s,e,i)}addParameterValueByIndex(t,e,i=1){this.setParameterValueByIndex(t,this.getParameterValueByIndex(t)+e*i)}addParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.addParameterValueByIndex(s,e,i)}multiplyParameterValueById(t,e,i=1){const s=this.getParameterIndex(t);this.multiplyParameterValueByIndex(s,e,i)}multiplyParameterValueByIndex(t,e,i=1){this.setParameterValueByIndex(t,this.getParameterValueByIndex(t)*(1+(e-1)*i))}getDrawableIds(){return this._drawableIds.slice()}getDrawableIndex(t){const e=this._model.drawables.count;for(let i=0;ie&&(t=e);for(let i=0;i=0&&this._partChildDrawables[n].push(t)}}}constructor(t){this._model=t,this._savedParameters=[],this._parameterIds=[],this._drawableIds=[],this._partIds=[],this._isOverwrittenModelMultiplyColors=!1,this._isOverwrittenModelScreenColors=!1,this._isOverwrittenCullings=!1,this._modelOpacity=1,this._userMultiplyColors=[],this._userScreenColors=[],this._userCullings=[],this._userPartMultiplyColors=[],this._userPartScreenColors=[],this._partChildDrawables=[],this._notExistPartId={},this._notExistParameterId={},this._notExistParameterValues={},this._notExistPartOpacities={},this.initialize()}release(){this._model.release(),this._model=void 0}}class R{static create(t,e){if(e){if(!this.hasMocConsistency(t))throw new Error("Inconsistent MOC3.")}const i=Live2DCubismCore.Moc.fromArrayBuffer(t);if(i){const e=new R(i);return e._mocVersion=Live2DCubismCore.Version.csmGetMocVersion(i,t),e}throw new Error("Failed to CubismMoc.create().")}createModel(){let t;const e=Live2DCubismCore.Model.fromMoc(this._moc);if(e)return t=new B(e),++this._modelCount,t;throw new Error("Unknown error")}deleteModel(t){null!=t&&--this._modelCount}constructor(t){this._moc=t,this._modelCount=0,this._mocVersion=0}release(){this._moc._release(),this._moc=void 0}getLatestMocVersion(){return Live2DCubismCore.Version.csmGetLatestMocVersion()}getMocVersion(){return this._mocVersion}static hasMocConsistency(t){return 1===Live2DCubismCore.Moc.prototype.hasMocConsistency(t)}}class O{constructor(t,e){this._json=t}release(){this._json=void 0}getUserDataCount(){return this._json.Meta.UserDataCount}getTotalUserDataSize(){return this._json.Meta.TotalUserDataSize}getUserDataTargetType(t){return this._json.UserData[t].Target}getUserDataId(t){return this._json.UserData[t].Id}getUserDataValue(t){return this._json.UserData[t].Value}}class k{static create(t,e){const i=new k;return i.parseUserData(t,e),i}getArtMeshUserDatas(){return this._artMeshUserDataNode}parseUserData(t,e){const i=new O(t,e),s=i.getUserDataCount();for(let r=0;r0&&e.getEndTime()(t[t.ExpressionBlendType_Add=0]="ExpressionBlendType_Add",t[t.ExpressionBlendType_Multiply=1]="ExpressionBlendType_Multiply",t[t.ExpressionBlendType_Overwrite=2]="ExpressionBlendType_Overwrite",t))(G||{});t.CubismConfig=void 0,(N=t.CubismConfig||(t.CubismConfig={})).supportMoreMaskDivisions=!0,N.setOpacityFromMotion=!1;var X=(t=>(t[t.CubismMotionCurveTarget_Model=0]="CubismMotionCurveTarget_Model",t[t.CubismMotionCurveTarget_Parameter=1]="CubismMotionCurveTarget_Parameter",t[t.CubismMotionCurveTarget_PartOpacity=2]="CubismMotionCurveTarget_PartOpacity",t))(X||{}),z=(t=>(t[t.CubismMotionSegmentType_Linear=0]="CubismMotionSegmentType_Linear",t[t.CubismMotionSegmentType_Bezier=1]="CubismMotionSegmentType_Bezier",t[t.CubismMotionSegmentType_Stepped=2]="CubismMotionSegmentType_Stepped",t[t.CubismMotionSegmentType_InverseStepped=3]="CubismMotionSegmentType_InverseStepped",t))(z||{});class j{constructor(t=0,e=0){this.time=t,this.value=e}}class W{constructor(){this.basePointIndex=0,this.segmentType=0}}class H{constructor(){this.id="",this.type=0,this.segmentCount=0,this.baseSegmentIndex=0,this.fadeInTime=0,this.fadeOutTime=0}}class Y{constructor(){this.fireTime=0,this.value=""}}class q{constructor(){this.duration=0,this.loop=!1,this.curveCount=0,this.eventCount=0,this.fps=0,this.curves=[],this.segments=[],this.points=[],this.events=[]}}class ${constructor(t){this._json=t}release(){this._json=void 0}getMotionDuration(){return this._json.Meta.Duration}isMotionLoop(){return this._json.Meta.Loop||!1}getEvaluationOptionFlag(t){return J.EvaluationOptionFlag_AreBeziersRistricted==t&&!!this._json.Meta.AreBeziersRestricted}getMotionCurveCount(){return this._json.Meta.CurveCount}getMotionFps(){return this._json.Meta.Fps}getMotionTotalSegmentCount(){return this._json.Meta.TotalSegmentCount}getMotionTotalPointCount(){return this._json.Meta.TotalPointCount}getMotionFadeInTime(){return this._json.Meta.FadeInTime}getMotionFadeOutTime(){return this._json.Meta.FadeOutTime}getMotionCurveTarget(t){return this._json.Curves[t].Target}getMotionCurveId(t){return this._json.Curves[t].Id}getMotionCurveFadeInTime(t){return this._json.Curves[t].FadeInTime}getMotionCurveFadeOutTime(t){return this._json.Curves[t].FadeOutTime}getMotionCurveSegmentCount(t){return this._json.Curves[t].Segments.length}getMotionCurveSegment(t,e){return this._json.Curves[t].Segments[e]}getEventCount(){return this._json.Meta.UserDataCount||0}getTotalEventValueSize(){return this._json.Meta.TotalUserDataSize}getEventTime(t){return this._json.UserData[t].Time}getEventValue(t){return this._json.UserData[t].Value}}var J=(t=>(t[t.EvaluationOptionFlag_AreBeziersRistricted=0]="EvaluationOptionFlag_AreBeziersRistricted",t))(J||{});const Z="Opacity";function Q(t,e,i){const s=new j;return s.time=t.time+(e.time-t.time)*i,s.value=t.value+(e.value-t.value)*i,s}function K(t,e){let i=(e-t[0].time)/(t[1].time-t[0].time);return i<0&&(i=0),t[0].value+(t[1].value-t[0].value)*i}function tt(t,e){let i=(e-t[0].time)/(t[3].time-t[0].time);i<0&&(i=0);const s=Q(t[0],t[1],i),r=Q(t[1],t[2],i),o=Q(t[2],t[3],i),a=Q(s,r,i),n=Q(r,o,i);return Q(a,n,i).value}function et(t,e){const i=e,s=t[0].time,r=t[3].time,o=t[1].time,a=t[2].time,n=r-3*a+3*o-s,l=3*a-6*o+3*s,h=3*o-3*s,u=s-i,d=m.cardanoAlgorithmForBezier(n,l,h,u),c=Q(t[0],t[1],d),g=Q(t[1],t[2],d),p=Q(t[2],t[3],d),_=Q(c,g,d),f=Q(g,p,d);return Q(_,f,d).value}function it(t,e){return t[0].value}function st(t,e){return t[1].value}function rt(t,e,i){const s=t.curves[e];let r=-1;const o=s.baseSegmentIndex+s.segmentCount;let a=0;for(let l=s.baseSegmentIndex;li){r=l;break}if(-1==r)return t.points[a].value;const n=t.segments[r];return n.evaluate(t.points.slice(n.basePointIndex),i)}class ot extends U{constructor(){super(),this._eyeBlinkParameterIds=[],this._lipSyncParameterIds=[],this._sourceFrameRate=30,this._loopDurationSeconds=-1,this._isLoop=!1,this._isLoopFadeIn=!0,this._lastWeight=0,this._modelOpacity=1}static create(t,e){const i=new ot;return i.parse(t),i._sourceFrameRate=i._motionData.fps,i._loopDurationSeconds=i._motionData.duration,i._onFinishedMotion=e,i}doUpdateParameters(e,i,s,r){null==this._modelCurveIdEyeBlink&&(this._modelCurveIdEyeBlink="EyeBlink"),null==this._modelCurveIdLipSync&&(this._modelCurveIdLipSync="LipSync"),null==this._modelCurveIdOpacity&&(this._modelCurveIdOpacity=Z);let o=i-r.getStartTime();o<0&&(o=0);let a=Number.MAX_VALUE,n=Number.MAX_VALUE;const l=64;let h=0,u=0;this._eyeBlinkParameterIds.length>l&&w("too many eye blink targets : {0}",this._eyeBlinkParameterIds.length),this._lipSyncParameterIds.length>l&&w("too many lip sync targets : {0}",this._lipSyncParameterIds.length);const d=this._fadeInSeconds<=0?1:m.getEasingSine((i-r.getFadeInStartTime())/this._fadeInSeconds),c=this._fadeOutSeconds<=0||r.getEndTime()<0?1:m.getEasingSine((r.getEndTime()-i)/this._fadeOutSeconds);let g,p,_,f=o;if(this._isLoop)for(;f>this._motionData.duration;)f-=this._motionData.duration;const y=this._motionData.curves;for(p=0;p>t&1)continue;const r=i+(n-i)*s;e.setParameterValueById(this._eyeBlinkParameterIds[t],r)}if(a!=Number.MAX_VALUE)for(let t=0;t>t&1)continue;const r=i+(a-i)*s;e.setParameterValueById(this._lipSyncParameterIds[t],r)}for(;p=this._motionData.duration&&(this._isLoop?(r.setStartTime(i),this._isLoopFadeIn&&r.setFadeInStartTime(i)):(this._onFinishedMotion&&this._onFinishedMotion(this),r.setIsFinished(!0))),this._lastWeight=s}setIsLoop(t){this._isLoop=t}isLoop(){return this._isLoop}setIsLoopFadeIn(t){this._isLoopFadeIn=t}isLoopFadeIn(){return this._isLoopFadeIn}getDuration(){return this._isLoop?-1:this._loopDurationSeconds}getLoopDuration(){return this._loopDurationSeconds}setParameterFadeInTime(t,e){const i=this._motionData.curves;for(let s=0;snew H)),this._motionData.segments=Array.from({length:e.getMotionTotalSegmentCount()}).map((()=>new W)),this._motionData.events=Array.from({length:this._motionData.eventCount}).map((()=>new Y)),this._motionData.points=[];let o=0,a=0;for(let n=0;n