/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
import { Live2DCubismFramework as live2dcubismframework } from '../Framework/src/live2dcubismframework';
import { Live2DCubismFramework as cubismid } from '../Framework/src/id/cubismid';
import { Live2DCubismFramework as cubismusermodel } from '../Framework/src/model/cubismusermodel';
import { Live2DCubismFramework as icubismmodelsetting } from '../Framework/src/icubismmodelsetting';
import { Live2DCubismFramework as cubismmodelsettingjson } from '../Framework/src/cubismmodelsettingjson';
import { Live2DCubismFramework as cubismdefaultparameterid } from '../Framework/src/cubismdefaultparameterid';
import { Live2DCubismFramework as acubismmotion } from '../Framework/src/motion/acubismmotion';
import { Live2DCubismFramework as cubismeyeblink } from '../Framework/src/effect/cubismeyeblink';
import { Live2DCubismFramework as cubismbreath } from '../Framework/src/effect/cubismbreath';
import { Live2DCubismFramework as csmvector } from '../Framework/src/type/csmvector';
import { Live2DCubismFramework as csmmap } from '../Framework/src/type/csmmap';
import { Live2DCubismFramework as cubismmatrix44 } from '../Framework/src/math/cubismmatrix44';
import { Live2DCubismFramework as cubismmotion } from '../Framework/src/motion/cubismmotion';
import { Live2DCubismFramework as cubismmotionqueuemanager } from '../Framework/src/motion/cubismmotionqueuemanager';
import { Live2DCubismFramework as csmstring } from '../Framework/src/type/csmstring';
import { Live2DCubismFramework as csmrect } from '../Framework/src/type/csmrectf';
import { CubismLogInfo } from '../Framework/src/utils/cubismdebug';
import csmRect = csmrect.csmRect;
import csmString = csmstring.csmString;
import InvalidMotionQueueEntryHandleValue = cubismmotionqueuemanager.InvalidMotionQueueEntryHandleValue;
import CubismMotionQueueEntryHandle = cubismmotionqueuemanager.CubismMotionQueueEntryHandle;
import CubismMotion = cubismmotion.CubismMotion;
import CubismMatrix44 = cubismmatrix44.CubismMatrix44;
import csmMap = csmmap.csmMap;
import csmVector = csmvector.csmVector;
import CubismBreath = cubismbreath.CubismBreath;
import BreathParameterData = cubismbreath.BreathParameterData;
import CubismEyeBlink = cubismeyeblink.CubismEyeBlink;
import ACubismMotion = acubismmotion.ACubismMotion;
import FinishedMotionCallback = acubismmotion.FinishedMotionCallback;
import CubismFramework = live2dcubismframework.CubismFramework;
import CubismIdHandle = cubismid.CubismIdHandle;
import CubismUserModel = cubismusermodel.CubismUserModel;
import ICubismModelSetting = icubismmodelsetting.ICubismModelSetting;
import CubismModelSettingJson = cubismmodelsettingjson.CubismModelSettingJson;
import CubismDefaultParameterId = cubismdefaultparameterid;
import { LAppPal } from './lapppal';
import { gl, canvas, frameBuffer, LAppDelegate } from './lappdelegate';
import { TextureInfo } from './lapptexturemanager';
import * as LAppDefine from './lappdefine';
import 'whatwg-fetch';
enum LoadStep {
LoadAssets,
LoadModel,
WaitLoadModel,
LoadExpression,
WaitLoadExpression,
LoadPhysics,
WaitLoadPhysics,
LoadPose,
WaitLoadPose,
SetupEyeBlink,
SetupBreath,
LoadUserData,
WaitLoadUserData,
SetupEyeBlinkIds,
SetupLipSyncIds,
SetupLayout,
LoadMotion,
WaitLoadMotion,
CompleteInitialize,
CompleteSetupModel,
LoadTexture,
WaitLoadTexture,
CompleteSetup
}
/**
* ユーザーが実際に使用するモデルの実装クラス
* モデル生成、機能コンポーネント生成、更新処理とレンダリングの呼び出しを行う。
*/
export class LAppModel extends CubismUserModel {
/**
* model3.jsonが置かれたディレクトリとファイルパスからモデルを生成する
* @param dir
* @param fileName
*/
public loadAssets(dir: string, fileName: string): void {
console.log('资源路径',dir)
this._modelHomeDir = dir;
fetch(`${this._modelHomeDir}${fileName}`)
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
const setting: ICubismModelSetting = new CubismModelSettingJson(
arrayBuffer,
arrayBuffer.byteLength
);
// ステートを更新
this._state = LoadStep.LoadModel;
// 結果を保存
this.setupModel(setting);
});
}
/**
* model3.jsonからモデルを生成する。
* model3.jsonの記述に従ってモデル生成、モーション、物理演算などのコンポーネント生成を行う。
*
* @param setting ICubismModelSettingのインスタンス
*/
private setupModel(setting: ICubismModelSetting): void {
this._updating = true;
this._initialized = false;
this._modelSetting = setting;
// CubismModel
if (this._modelSetting.getModelFileName() != '') {
const modelFileName = this._modelSetting.getModelFileName();
fetch(`${this._modelHomeDir}${modelFileName}`)
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
this.loadModel(arrayBuffer);
this._state = LoadStep.LoadExpression;
// callback
loadCubismExpression();
});
this._state = LoadStep.WaitLoadModel;
} else {
LAppPal.printMessage('Model data does not exist.');
}
// Expression
const loadCubismExpression = (): void => {
if (this._modelSetting.getExpressionCount() > 0) {
const count: number = this._modelSetting.getExpressionCount();
for (let i = 0; i < count; i++) {
const expressionName = this._modelSetting.getExpressionName(i);
const expressionFileName = this._modelSetting.getExpressionFileName(
i
);
fetch(`${this._modelHomeDir}${expressionFileName}`)
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
const motion: ACubismMotion = this.loadExpression(
arrayBuffer,
arrayBuffer.byteLength,
expressionName
);
if (this._expressions.getValue(expressionName) != null) {
ACubismMotion.delete(
this._expressions.getValue(expressionName)
);
this._expressions.setValue(expressionName, null);
}
this._expressions.setValue(expressionName, motion);
this._expressionCount++;
if (this._expressionCount >= count) {
this._state = LoadStep.LoadPhysics;
// callback
loadCubismPhysics();
}
});
}
this._state = LoadStep.WaitLoadExpression;
} else {
this._state = LoadStep.LoadPhysics;
// callback
loadCubismPhysics();
}
};
// Physics
const loadCubismPhysics = (): void => {
if (this._modelSetting.getPhysicsFileName() != '') {
const physicsFileName = this._modelSetting.getPhysicsFileName();
fetch(`${this._modelHomeDir}${physicsFileName}`)
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
this.loadPhysics(arrayBuffer, arrayBuffer.byteLength);
this._state = LoadStep.LoadPose;
// callback
loadCubismPose();
});
this._state = LoadStep.WaitLoadPhysics;
} else {
this._state = LoadStep.LoadPose;
// callback
loadCubismPose();
}
};
// Pose
const loadCubismPose = (): void => {
if (this._modelSetting.getPoseFileName() != '') {
const poseFileName = this._modelSetting.getPoseFileName();
fetch(`${this._modelHomeDir}${poseFileName}`)
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
this.loadPose(arrayBuffer, arrayBuffer.byteLength);
this._state = LoadStep.SetupEyeBlink;
// callback
setupEyeBlink();
});
this._state = LoadStep.WaitLoadPose;
} else {
this._state = LoadStep.SetupEyeBlink;
// callback
setupEyeBlink();
}
};
// EyeBlink
const setupEyeBlink = (): void => {
if (this._modelSetting.getEyeBlinkParameterCount() > 0) {
this._eyeBlink = CubismEyeBlink.create(this._modelSetting);
this._state = LoadStep.SetupBreath;
}
// callback
setupBreath();
};
// Breath
const setupBreath = (): void => {
this._breath = CubismBreath.create();
const breathParameters: csmVector = new csmVector();
breathParameters.pushBack(
new BreathParameterData(this._idParamAngleX, 0.0, 15.0, 6.5345, 0.5)
);
breathParameters.pushBack(
new BreathParameterData(this._idParamAngleY, 0.0, 8.0, 3.5345, 0.5)
);
breathParameters.pushBack(
new BreathParameterData(this._idParamAngleZ, 0.0, 10.0, 5.5345, 0.5)
);
breathParameters.pushBack(
new BreathParameterData(this._idParamBodyAngleX, 0.0, 4.0, 15.5345, 0.5)
);
breathParameters.pushBack(
new BreathParameterData(
CubismFramework.getIdManager().getId(
CubismDefaultParameterId.ParamBreath
),
0.0,
0.5,
3.2345,
0.5
)
);
this._breath.setParameters(breathParameters);
this._state = LoadStep.LoadUserData;
// callback
loadUserData();
};
// UserData
const loadUserData = (): void => {
if (this._modelSetting.getUserDataFile() != '') {
const userDataFile = this._modelSetting.getUserDataFile();
fetch(`${this._modelHomeDir}${userDataFile}`)
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
this.loadUserData(arrayBuffer, arrayBuffer.byteLength);
this._state = LoadStep.SetupEyeBlinkIds;
// callback
setupEyeBlinkIds();
});
this._state = LoadStep.WaitLoadUserData;
} else {
this._state = LoadStep.SetupEyeBlinkIds;
// callback
setupEyeBlinkIds();
}
};
// EyeBlinkIds
const setupEyeBlinkIds = (): void => {
const eyeBlinkIdCount: number = this._modelSetting.getEyeBlinkParameterCount();
for (let i = 0; i < eyeBlinkIdCount; ++i) {
this._eyeBlinkIds.pushBack(
this._modelSetting.getEyeBlinkParameterId(i)
);
}
this._state = LoadStep.SetupLipSyncIds;
// callback
setupLipSyncIds();
};
// LipSyncIds
const setupLipSyncIds = (): void => {
const lipSyncIdCount = this._modelSetting.getLipSyncParameterCount();
for (let i = 0; i < lipSyncIdCount; ++i) {
this._lipSyncIds.pushBack(this._modelSetting.getLipSyncParameterId(i));
}
this._state = LoadStep.SetupLayout;
// callback
setupLayout();
};
// Layout
const setupLayout = (): void => {
const layout: csmMap = new csmMap();
this._modelSetting.getLayoutMap(layout);
this._modelMatrix.setupFromLayout(layout);
this._state = LoadStep.LoadMotion;
// callback
loadCubismMotion();
};
// Motion
const loadCubismMotion = (): void => {
document.getElementById('live2d-hidden').style.display='block'
this._state = LoadStep.WaitLoadMotion;
this._model.saveParameters();
this._allMotionCount = 0;
this._motionCount = 0;
const group: string[] = [];
const motionGroupCount: number = this._modelSetting.getMotionGroupCount();
// モーションの総数を求める
for (let i = 0; i < motionGroupCount; i++) {
group[i] = this._modelSetting.getMotionGroupName(i);
this._allMotionCount += this._modelSetting.getMotionCount(group[i]);
}
// モーションの読み込み
// 装入动作
for (let i = 0; i < motionGroupCount; i++) {
this.preLoadMotionGroup(group[i]);
}
// モーションがない場合
if (motionGroupCount == 0) {
this._state = LoadStep.LoadTexture;
// 全てのモーションを停止する
this._motionManager.stopAllMotions();
this._updating = false;
this._initialized = true;
this.createRenderer();
this.setupTextures();
this.getRenderer().startUp(gl);
}
};
}
/**
* テクスチャユニットにテクスチャをロードする
*/
private setupTextures(): void {
// iPhoneでのアルファ品質向上のためTypescriptではpremultipliedAlphaを採用
const usePremultiply = true;
if (this._state == LoadStep.LoadTexture) {
// テクスチャ読み込み用
const textureCount: number = this._modelSetting.getTextureCount();
for (
let modelTextureNumber = 0;
modelTextureNumber < textureCount;
modelTextureNumber++
) {
// テクスチャ名が空文字だった場合はロード・バインド処理をスキップ
if (this._modelSetting.getTextureFileName(modelTextureNumber) == '') {
continue;
}
// WebGLのテクスチャユニットにテクスチャをロードする
// 在WebGL的纹理单元中加载纹理
let texturePath = this._modelSetting.getTextureFileName(
modelTextureNumber
);
texturePath = this._modelHomeDir + texturePath;
// ロード完了時に呼び出すコールバック関数
// 加载完成时调用的回调函数
const onLoad = (textureInfo: TextureInfo): void => {
this.getRenderer().bindTexture(modelTextureNumber, textureInfo.id);
this._textureCount++;
if (this._textureCount >= textureCount) {
// ロード完了
this._state = LoadStep.CompleteSetup;
}
};
// 読み込み
LAppDelegate.getInstance()
.getTextureManager()
.createTextureFromPngFile(texturePath, usePremultiply, onLoad);
this.getRenderer().setIsPremultipliedAlpha(usePremultiply);
}
this._state = LoadStep.WaitLoadTexture;
}
}
/**
* レンダラを再構築する
*/
public reloadRenderer(): void {
this.deleteRenderer();
this.createRenderer();
this.setupTextures();
}
/**
* 更新
*/
public update(): void {
if (this._state != LoadStep.CompleteSetup) return;
const deltaTimeSeconds: number = LAppPal.getDeltaTime();
this._userTimeSeconds += deltaTimeSeconds;
this._dragManager.update(deltaTimeSeconds);
this._dragX = this._dragManager.getX();
this._dragY = this._dragManager.getY();
// モーションによるパラメータ更新の有無
let motionUpdated = false;
//--------------------------------------------------------------------------
this._model.loadParameters(); // 前回セーブされた状態をロード
if (this._motionManager.isFinished()) {
this.startRandomMotion(
LAppDefine.MotionGroupIdle,
LAppDefine.PriorityIdle
);
// 在没有动作的运行的情况下,从待机动作中随机运行抽取,命运抽牌啦啦啦^ ^
let lucky = Math.floor(Math.random() * 1000 + 100);
if (lucky == 999) {
this.startRandomMotion(
LAppDefine.MotionGroupIdle,
LAppDefine.PriorityIdle
);
} else if (lucky == 888) {
this.startRandomMotion(
LAppDefine.MotionGroupDefault,
LAppDefine.PriorityIdle
);
}
} else {
motionUpdated = this._motionManager.updateMotion(
this._model,
deltaTimeSeconds
); // 更新动作
}
this._model.saveParameters(); // 状態を保存
//--------------------------------------------------------------------------
// まばたき
if (!motionUpdated) {
if (this._eyeBlink != null) {
// メインモーションの更新がないとき
this._eyeBlink.updateParameters(this._model, deltaTimeSeconds); // 目パチ
}
}
if (this._expressionManager != null) {
this._expressionManager.updateMotion(this._model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
}
// ドラッグによる変化
// ドラッグによる顔の向きの調整
this._model.addParameterValueById(this._idParamAngleX, this._dragX * 30); // -30から30の値を加える
this._model.addParameterValueById(this._idParamAngleY, this._dragY * 30);
this._model.addParameterValueById(
this._idParamAngleZ,
this._dragX * this._dragY * -30
);
// ドラッグによる体の向きの調整
this._model.addParameterValueById(
this._idParamBodyAngleX,
this._dragX * 10
); // -10から10の値を加える
// ドラッグによる目の向きの調整
this._model.addParameterValueById(this._idParamEyeBallX, this._dragX); // -1から1の値を加える
this._model.addParameterValueById(this._idParamEyeBallY, this._dragY);
// 呼吸など
if (this._breath != null) {
this._breath.updateParameters(this._model, deltaTimeSeconds);
}
// 物理演算の設定
if (this._physics != null) {
this._physics.evaluate(this._model, deltaTimeSeconds);
}
// リップシンクの設定
if (this._lipsync) {
const value = 0; // リアルタイムでリップシンクを行う場合、システムから音量を取得して、0~1の範囲で値を入力します。
for (let i = 0; i < this._lipSyncIds.getSize(); ++i) {
this._model.addParameterValueById(this._lipSyncIds.at(i), value, 0.8);
}
}
// ポーズの設定
if (this._pose != null) {
this._pose.updateParameters(this._model, deltaTimeSeconds);
}
this._model.update();
}
/**
* 引数で指定したモーションの再生を開始する
* @param group モーショングループ名
* @param no グループ内の番号
* @param priority 優先度
* @param onFinishedMotionHandler モーション再生終了時に呼び出されるコールバック関数
* @return 開始したモーションの識別番号を返す。個別のモーションが終了したか否かを判定するisFinished()の引数で使用する。開始できない時は[-1]
*/
public startMotion(
group: string,
no: number,
priority: number,
onFinishedMotionHandler?: FinishedMotionCallback
): CubismMotionQueueEntryHandle {
if (priority == LAppDefine.PriorityForce) {
this._motionManager.setReservePriority(priority);
} else if (!this._motionManager.reserveMotion(priority)) {
if (this._debugMode) {
LAppPal.printMessage("[APP]can't start motion.");
}
return InvalidMotionQueueEntryHandleValue;
}
const motionFileName = this._modelSetting.getMotionFileName(group, no);
// ex) idle_0
const name = `${group}_${no}`;
let motion: CubismMotion = this._motions.getValue(name) as CubismMotion;
let autoDelete = false;
if (motion == null) {
fetch(`${this._modelHomeDir}${motionFileName}`)
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
motion = this.loadMotion(
arrayBuffer,
arrayBuffer.byteLength,
null,
onFinishedMotionHandler
);
let fadeTime: number = this._modelSetting.getMotionFadeInTimeValue(
group,
no
);
if (fadeTime >= 0.0) {
motion.setFadeInTime(fadeTime);
}
fadeTime = this._modelSetting.getMotionFadeOutTimeValue(group, no);
if (fadeTime >= 0.0) {
motion.setFadeOutTime(fadeTime);
}
motion.setEffectIds(this._eyeBlinkIds, this._lipSyncIds);
autoDelete = true; // 終了時にメモリから削除
});
} else {
motion.setFinishedMotionHandler(onFinishedMotionHandler);
}
if (this._debugMode) {
LAppPal.printMessage(`[APP]start motion: [${group}_${no}`);
}
return this._motionManager.startMotionPriority(
motion,
autoDelete,
priority
);
}
/**
* ランダムに選ばれたモーションの再生を開始する。
* @param group モーショングループ名
* @param priority 優先度
* @param onFinishedMotionHandler モーション再生終了時に呼び出されるコールバック関数
* @param onFinishedMotionHandler 动作再生结束时调用的回呼函数
* @return 開始したモーションの識別番号を返す。個別のモーションが終了したか否かを判定するisFinished()の引数で使用する。開始できない時は[-1]
* @return 返回开始动作的识别号码。用于判定个别动作是否结束的isFinished()参数。无法开始时[-1]
*/
public startRandomMotion(
group: string,
priority: number,
onFinishedMotionHandler?: FinishedMotionCallback
): CubismMotionQueueEntryHandle {
if (this._modelSetting.getMotionCount(group) == 0) {
return InvalidMotionQueueEntryHandleValue;
}
const no: number = Math.floor(
Math.random() * this._modelSetting.getMotionCount(group)
);
return this.startMotion(group, no, priority, onFinishedMotionHandler);
}
/**
* 引数で指定した表情モーションをセットする
*
* @param expressionId 表情モーションのID
*/
public setExpression(expressionId: string): void {
const motion: ACubismMotion = this._expressions.getValue(expressionId);
if (this._debugMode) {
LAppPal.printMessage(`[APP]expression: [${expressionId}]`);
}
if (motion != null) {
this._expressionManager.startMotionPriority(
motion,
false,
LAppDefine.PriorityForce
);
} else {
if (this._debugMode) {
LAppPal.printMessage(`[APP]expression[${expressionId}] is null`);
}
}
}
/**
* ランダムに選ばれた表情モーションをセットする
*/
public setRandomExpression(): void {
if (this._expressions.getSize() == 0) {
return;
}
const no: number = Math.floor(Math.random() * this._expressions.getSize());
for (let i = 0; i < this._expressions.getSize(); i++) {
if (i == no) {
const name: string = this._expressions._keyValues[i].first;
this.setExpression(name);
return;
}
}
}
/**
* イベントの発火を受け取る
*/
public motionEventFired(eventValue: csmString): void {
CubismLogInfo('{0} is fired on LAppModel!!', eventValue.s);
}
/**
* 当たり判定テスト
* 指定IDの頂点リストから矩形を計算し、座標をが矩形範囲内か判定する。
* 根据指定ID的顶点列表计算矩形,判定坐标是否在矩形范围内。
*
* @param hitArenaName 当たり判定をテストする対象のID
* @param x 判定を行うX座標
* @param y 判定を行うY座標
*/
public hitTest(hitArenaName: string, x: number, y: number): boolean {
// 透明時は当たり判定無し。
if (this._opacity < 1) {
return false;
}
const count: number = this._modelSetting.getHitAreasCount();
for (let i = 0; i < count; i++) {
if (this._modelSetting.getHitAreaName(i) == hitArenaName) {
const drawId: CubismIdHandle = this._modelSetting.getHitAreaId(i);
return this.isHit(drawId, x, y);
}
}
return false;
}
/**
* モーションデータをグループ名から一括でロードする。
* モーションデータの名前は内部でModelSettingから取得する。
* 从组合名称中统一加载动作数据。
* 动作数据的名称在内部从ModelSetting取得。
*
* @param group モーションデータのグループ名
* group动作数据的组名称
*/
public preLoadMotionGroup(group: string): void {
for (let i = 0; i < this._modelSetting.getMotionCount(group); i++) {
const motionFileName = this._modelSetting.getMotionFileName(group, i);
// ex) idle_0
const name = `${group}_${i}`;
if (this._debugMode) {
LAppPal.printMessage(
`[APP]load motion: ${motionFileName} => [${name}]`
);
}
fetch(`${this._modelHomeDir}${motionFileName}`)
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
const tmpMotion: CubismMotion = this.loadMotion(
arrayBuffer,
arrayBuffer.byteLength,
name
);
let fadeTime = this._modelSetting.getMotionFadeInTimeValue(group, i);
if (fadeTime >= 0.0) {
tmpMotion.setFadeInTime(fadeTime);
}
fadeTime = this._modelSetting.getMotionFadeOutTimeValue(group, i);
if (fadeTime >= 0.0) {
tmpMotion.setFadeOutTime(fadeTime);
}
tmpMotion.setEffectIds(this._eyeBlinkIds, this._lipSyncIds);
if (this._motions.getValue(name) != null) {
ACubismMotion.delete(this._motions.getValue(name));
}
this._motions.setValue(name, tmpMotion);
this._motionCount++;
// console.log('this._motionCount',this._motionCount)
// console.log('this._allMotionCount',this._allMotionCount)
if (this._motionCount >= this._allMotionCount) {
this._state = LoadStep.LoadTexture;
// 全てのモーションを停止する
document.getElementById('live2d-hidden').style.display='none'
if(this._motionManager){
this._motionManager.stopAllMotions();
this.createRenderer();
this.setupTextures();
this.getRenderer().startUp(gl);
}
this._updating = false;
this._initialized = true;
// this.createRenderer();
// this.setupTextures();
// this.getRenderer().startUp(gl);
document.getElementById('live2d').style.visibility='visible'
}
});
}
}
/**
* すべてのモーションデータを解放する。
*/
public releaseMotions(): void {
this._motions.clear();
}
/**
* 全ての表情データを解放する。
*/
public releaseExpressions(): void {
this._expressions.clear();
}
/**
* モデルを描画する処理。モデルを描画する空間のView-Projection行列を渡す。
*/
public doDraw(): void {
if (this._model == null) return;
// キャンバスサイズを渡す
const viewport: number[] = [0, 0, canvas.width, canvas.height];
this.getRenderer().setRenderState(frameBuffer, viewport);
this.getRenderer().drawModel();
}
/**
* モデルを描画する処理。モデルを描画する空間のView-Projection行列を渡す。
*/
public draw(matrix: CubismMatrix44): void {
if (this._model == null) {
return;
}
// 各読み込み終了後
if (this._state == LoadStep.CompleteSetup) {
matrix.multiplyByMatrix(this._modelMatrix);
this.getRenderer().setMvpMatrix(matrix);
this.doDraw();
}
}
/**
* コンストラクタ
*/
public constructor() {
super();
this._modelSetting = null;
this._modelHomeDir = null;
this._userTimeSeconds = 0.0;
this._eyeBlinkIds = new csmVector();
this._lipSyncIds = new csmVector();
this._motions = new csmMap();
this._expressions = new csmMap();
this._hitArea = new csmVector();
this._userArea = new csmVector();
this._idParamAngleX = CubismFramework.getIdManager().getId(
CubismDefaultParameterId.ParamAngleX
);
this._idParamAngleY = CubismFramework.getIdManager().getId(
CubismDefaultParameterId.ParamAngleY
);
this._idParamAngleZ = CubismFramework.getIdManager().getId(
CubismDefaultParameterId.ParamAngleZ
);
this._idParamEyeBallX = CubismFramework.getIdManager().getId(
CubismDefaultParameterId.ParamEyeBallX
);
this._idParamEyeBallY = CubismFramework.getIdManager().getId(
CubismDefaultParameterId.ParamEyeBallY
);
this._idParamBodyAngleX = CubismFramework.getIdManager().getId(
CubismDefaultParameterId.ParamBodyAngleX
);
this._state = LoadStep.LoadAssets;
this._expressionCount = 0;
this._textureCount = 0;
this._motionCount = 0;
this._allMotionCount = 0;
}
_modelSetting: ICubismModelSetting; // モデルセッティング情報
_modelHomeDir: string; // モデルセッティングが置かれたディレクトリ
_userTimeSeconds: number; // デルタ時間の積算値[秒]
_eyeBlinkIds: csmVector; // モデルに設定された瞬き機能用パラメータID
_lipSyncIds: csmVector; // モデルに設定されたリップシンク機能用パラメータID
_motions: csmMap; // 読み込まれているモーションのリスト
_expressions: csmMap; // 読み込まれている表情のリスト
_hitArea: csmVector;
_userArea: csmVector;
_idParamAngleX: CubismIdHandle; // パラメータID: ParamAngleX
_idParamAngleY: CubismIdHandle; // パラメータID: ParamAngleY
_idParamAngleZ: CubismIdHandle; // パラメータID: ParamAngleZ
_idParamEyeBallX: CubismIdHandle; // パラメータID: ParamEyeBallX
_idParamEyeBallY: CubismIdHandle; // パラメータID: ParamEyeBAllY
_idParamBodyAngleX: CubismIdHandle; // パラメータID: ParamBodyAngleX
_state: number; // 現在のステータス管理用
_expressionCount: number; // 表情データカウント
_textureCount: number; // テクスチャカウント
_motionCount: number; // モーションデータカウント
_allMotionCount: number; // モーション総数
}