UNPKG

phaser3-rex-plugins

Version:
819 lines (715 loc) 26.8 kB
/** * 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 { CubismIdHandle } from '../id/cubismid'; import { CubismFramework } from '../live2dcubismframework'; import { CubismBlendMode } from '../rendering/cubismrenderer'; import { csmMap } from '../type/csmmap'; import { csmVector } from '../type/csmvector'; import { CSM_ASSERT } from '../utils/cubismdebug'; /** * モデル * * Mocデータから生成されるモデルのクラス。 */ export class CubismModel { /** * モデルのパラメータの更新 */ public update(): void { // Update model this._model.update(); this._model.drawables.resetDynamicFlags(); } /** * キャンバスの幅を取得する */ public getCanvasWidth(): number { if (this._model == null) { return 0.0; } return ( this._model.canvasinfo.CanvasWidth / this._model.canvasinfo.PixelsPerUnit ); } /** * キャンバスの高さを取得する */ public getCanvasHeight(): number { if (this._model == null) { return 0.0; } return ( this._model.canvasinfo.CanvasHeight / this._model.canvasinfo.PixelsPerUnit ); } /** * パラメータを保存する */ public saveParameters(): void { const parameterCount: number = this._model.parameters.count; const savedParameterCount: number = this._savedParameters.getSize(); for (let i = 0; i < parameterCount; ++i) { if (i < savedParameterCount) { this._savedParameters.set(i, this._parameterValues[i]); } else { this._savedParameters.pushBack(this._parameterValues[i]); } } } /** * モデルを取得 */ public getModel(): Live2DCubismCore.Model { return this._model; } /** * パーツのインデックスを取得 * @param partId パーツのID * @return パーツのインデックス */ public getPartIndex(partId: CubismIdHandle): number { let partIndex: number; const partCount: number = this._model.parts.count; for (partIndex = 0; partIndex < partCount; ++partIndex) { if (partId == this._partIds.at(partIndex)) { return partIndex; } } // モデルに存在していない場合、非存在パーツIDリスト内にあるかを検索し、そのインデックスを返す if (this._notExistPartId.isExist(partId)) { return this._notExistPartId.getValue(partId); } // 非存在パーツIDリストにない場合、新しく要素を追加する partIndex = partCount + this._notExistPartId.getSize(); this._notExistPartId.setValue(partId, partIndex); this._notExistPartOpacities.appendKey(partIndex); return partIndex; } /** * パーツの個数の取得 * @return パーツの個数 */ public getPartCount(): number { const partCount: number = this._model.parts.count; return partCount; } /** * パーツの不透明度の設定(Index) * @param partIndex パーツのインデックス * @param opacity 不透明度 */ public setPartOpacityByIndex(partIndex: number, opacity: number): void { if (this._notExistPartOpacities.isExist(partIndex)) { this._notExistPartOpacities.setValue(partIndex, opacity); return; } // インデックスの範囲内検知 CSM_ASSERT(0 <= partIndex && partIndex < this.getPartCount()); this._partOpacities[partIndex] = opacity; } /** * パーツの不透明度の設定(Id) * @param partId パーツのID * @param opacity パーツの不透明度 */ public setPartOpacityById(partId: CubismIdHandle, opacity: number): void { // 高速化のためにPartIndexを取得できる機構になっているが、外部からの設定の時は呼び出し頻度が低いため不要 const index: number = this.getPartIndex(partId); if (index < 0) { return; // パーツがないのでスキップ } this.setPartOpacityByIndex(index, opacity); } /** * パーツの不透明度の取得(index) * @param partIndex パーツのインデックス * @return パーツの不透明度 */ public getPartOpacityByIndex(partIndex: number): number { if (this._notExistPartOpacities.isExist(partIndex)) { // モデルに存在しないパーツIDの場合、非存在パーツリストから不透明度を返す。 return this._notExistPartOpacities.getValue(partIndex); } // インデックスの範囲内検知 CSM_ASSERT(0 <= partIndex && partIndex < this.getPartCount()); return this._partOpacities[partIndex]; } /** * パーツの不透明度の取得(id) * @param partId パーツのId * @return パーツの不透明度 */ public getPartOpacityById(partId: CubismIdHandle): number { // 高速化のためにPartIndexを取得できる機構になっているが、外部からの設定の時は呼び出し頻度が低いため不要 const index: number = this.getPartIndex(partId); if (index < 0) { return 0; // パーツが無いのでスキップ } return this.getPartOpacityByIndex(index); } /** * パラメータのインデックスの取得 * @param パラメータID * @return パラメータのインデックス */ public getParameterIndex(parameterId: CubismIdHandle): number { let parameterIndex: number; const idCount: number = this._model.parameters.count; for (parameterIndex = 0; parameterIndex < idCount; ++parameterIndex) { if (parameterId != this._parameterIds.at(parameterIndex)) { continue; } return parameterIndex; } // モデルに存在していない場合、非存在パラメータIDリスト内を検索し、そのインデックスを返す if (this._notExistParameterId.isExist(parameterId)) { return this._notExistParameterId.getValue(parameterId); } // 非存在パラメータIDリストにない場合新しく要素を追加する parameterIndex = this._model.parameters.count + this._notExistParameterId.getSize(); this._notExistParameterId.setValue(parameterId, parameterIndex); this._notExistParameterValues.appendKey(parameterIndex); return parameterIndex; } /** * パラメータの個数の取得 * @return パラメータの個数 */ public getParameterCount(): number { return this._model.parameters.count; } /** * パラメータの最大値の取得 * @param parameterIndex パラメータのインデックス * @return パラメータの最大値 */ public getParameterMaximumValue(parameterIndex: number): number { return this._model.parameters.maximumValues[parameterIndex]; } /** * パラメータの最小値の取得 * @param parameterIndex パラメータのインデックス * @return パラメータの最小値 */ public getParameterMinimumValue(parameterIndex: number): number { return this._model.parameters.minimumValues[parameterIndex]; } /** * パラメータのデフォルト値の取得 * @param parameterIndex パラメータのインデックス * @return パラメータのデフォルト値 */ public getParameterDefaultValue(parameterIndex: number): number { return this._model.parameters.defaultValues[parameterIndex]; } /** * パラメータの値の取得 * @param parameterIndex パラメータのインデックス * @return パラメータの値 */ public getParameterValueByIndex(parameterIndex: number): number { if (this._notExistParameterValues.isExist(parameterIndex)) { return this._notExistParameterValues.getValue(parameterIndex); } // インデックスの範囲内検知 CSM_ASSERT( 0 <= parameterIndex && parameterIndex < this.getParameterCount() ); return this._parameterValues[parameterIndex]; } /** * パラメータの値の取得 * @param parameterId パラメータのID * @return パラメータの値 */ public getParameterValueById(parameterId: CubismIdHandle): number { // 高速化のためにparameterIndexを取得できる機構になっているが、外部からの設定の時は呼び出し頻度が低いため不要 const parameterIndex: number = this.getParameterIndex(parameterId); return this.getParameterValueByIndex(parameterIndex); } /** * パラメータの値の設定 * @param parameterIndex パラメータのインデックス * @param value パラメータの値 * @param weight 重み */ public setParameterValueByIndex( parameterIndex: number, value: number, weight = 1.0 ): void { if (this._notExistParameterValues.isExist(parameterIndex)) { this._notExistParameterValues.setValue( parameterIndex, weight == 1 ? value : this._notExistParameterValues.getValue(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); } /** * パラメータの値の設定 * @param parameterId パラメータのID * @param value パラメータの値 * @param weight 重み */ public setParameterValueById( parameterId: CubismIdHandle, value: number, weight = 1.0 ): void { const index: number = this.getParameterIndex(parameterId); this.setParameterValueByIndex(index, value, weight); } /** * パラメータの値の加算(index) * @param parameterIndex パラメータインデックス * @param value 加算する値 * @param weight 重み */ public addParameterValueByIndex( parameterIndex: number, value: number, weight = 1.0 ): void { this.setParameterValueByIndex( parameterIndex, this.getParameterValueByIndex(parameterIndex) + value * weight ); } /** * パラメータの値の加算(id) * @param parameterId パラメータID * @param value 加算する値 * @param weight 重み */ public addParameterValueById( parameterId: any, value: number, weight = 1.0 ): void { const index: number = this.getParameterIndex(parameterId); this.addParameterValueByIndex(index, value, weight); } /** * パラメータの値の乗算 * @param parameterId パラメータのID * @param value 乗算する値 * @param weight 重み */ public multiplyParameterValueById( parameterId: CubismIdHandle, value: number, weight = 1.0 ): void { const index: number = this.getParameterIndex(parameterId); this.multiplyParameterValueByIndex(index, value, weight); } /** * パラメータの値の乗算 * @param parameterIndex パラメータのインデックス * @param value 乗算する値 * @param weight 重み */ public multiplyParameterValueByIndex( parameterIndex: number, value: number, weight = 1.0 ): void { this.setParameterValueByIndex( parameterIndex, this.getParameterValueByIndex(parameterIndex) * (1.0 + (value - 1.0) * weight) ); } /** * Drawableのインデックスの取得 * @param drawableId DrawableのID * @return Drawableのインデックス */ public getDrawableIndex(drawableId: CubismIdHandle): number { const drawableCount = this._model.drawables.count; for ( let drawableIndex = 0; drawableIndex < drawableCount; ++drawableIndex ) { if (this._drawableIds.at(drawableIndex) == drawableId) { return drawableIndex; } } return -1; } /** * Drawableの個数の取得 * @return drawableの個数 */ public getDrawableCount(): number { const drawableCount = this._model.drawables.count; return drawableCount; } /** * DrawableのIDを取得する * @param drawableIndex Drawableのインデックス * @return drawableのID */ public getDrawableId(drawableIndex: number): CubismIdHandle { const parameterIds: string[] = this._model.drawables.ids; return CubismFramework.getIdManager().getId(parameterIds[drawableIndex]); } /** * Drawableの描画順リストの取得 * @return Drawableの描画順リスト */ public getDrawableRenderOrders(): Int32Array { const renderOrders: Int32Array = this._model.drawables.renderOrders; return renderOrders; } /** * Drawableのテクスチャインデックスリストの取得 * @param drawableIndex Drawableのインデックス * @return drawableのテクスチャインデックスリスト */ public getDrawableTextureIndices(drawableIndex: number): number { const textureIndices: Int32Array = this._model.drawables.textureIndices; return textureIndices[drawableIndex]; } /** * DrawableのVertexPositionsの変化情報の取得 * * 直近のCubismModel.update関数でDrawableの頂点情報が変化したかを取得する。 * * @param drawableIndex Drawableのインデックス * @retval true Drawableの頂点情報が直近のCubismModel.update関数で変化した * @retval false Drawableの頂点情報が直近のCubismModel.update関数で変化していない */ public getDrawableDynamicFlagVertexPositionsDidChange( drawableIndex: number ): boolean { const dynamicFlags: Uint8Array = this._model.drawables.dynamicFlags; return Live2DCubismCore.Utils.hasVertexPositionsDidChangeBit( dynamicFlags[drawableIndex] ); } /** * Drawableの頂点インデックスの個数の取得 * @param drawableIndex Drawableのインデックス * @return drawableの頂点インデックスの個数 */ public getDrawableVertexIndexCount(drawableIndex: number): number { const indexCounts: Int32Array = this._model.drawables.indexCounts; return indexCounts[drawableIndex]; } /** * Drawableの頂点の個数の取得 * @param drawableIndex Drawableのインデックス * @return drawableの頂点の個数 */ public getDrawableVertexCount(drawableIndex: number): number { const vertexCounts = this._model.drawables.vertexCounts; return vertexCounts[drawableIndex]; } /** * Drawableの頂点リストの取得 * @param drawableIndex drawableのインデックス * @return drawableの頂点リスト */ public getDrawableVertices(drawableIndex: number): Float32Array { return this.getDrawableVertexPositions(drawableIndex); } /** * Drawableの頂点インデックスリストの取得 * @param drarableIndex Drawableのインデックス * @return drawableの頂点インデックスリスト */ public getDrawableVertexIndices(drawableIndex: number): Uint16Array { const indicesArray: Uint16Array[] = this._model.drawables.indices; return indicesArray[drawableIndex]; } /** * Drawableの頂点リストの取得 * @param drawableIndex Drawableのインデックス * @return drawableの頂点リスト */ public getDrawableVertexPositions(drawableIndex: number): Float32Array { const verticesArray: Float32Array[] = this._model.drawables.vertexPositions; return verticesArray[drawableIndex]; } /** * Drawableの頂点のUVリストの取得 * @param drawableIndex Drawableのインデックス * @return drawableの頂点UVリスト */ public getDrawableVertexUvs(drawableIndex: number): Float32Array { const uvsArray: Float32Array[] = this._model.drawables.vertexUvs; return uvsArray[drawableIndex]; } /** * Drawableの不透明度の取得 * @param drawableIndex Drawableのインデックス * @return drawableの不透明度 */ public getDrawableOpacity(drawableIndex: number): number { const opacities: Float32Array = this._model.drawables.opacities; return opacities[drawableIndex]; } /** * Drawableのカリング情報の取得 * @param drawableIndex Drawableのインデックス * @return drawableのカリング情報 */ public getDrawableCulling(drawableIndex: number): boolean { const constantFlags = this._model.drawables.constantFlags; return !Live2DCubismCore.Utils.hasIsDoubleSidedBit( constantFlags[drawableIndex] ); } /** * Drawableのブレンドモードを取得 * @param drawableIndex Drawableのインデックス * @return drawableのブレンドモード */ public getDrawableBlendMode(drawableIndex: number): CubismBlendMode { 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; } /** * Drawableのマスクの反転使用の取得 * * Drawableのマスク使用時の反転設定を取得する。 * マスクを使用しない場合は無視される。 * * @param drawableIndex Drawableのインデックス * @return Drawableの反転設定 */ public getDrawableInvertedMaskBit(drawableIndex: number): boolean { const constantFlags: Uint8Array = this._model.drawables.constantFlags; return Live2DCubismCore.Utils.hasIsInvertedMaskBit( constantFlags[drawableIndex] ); } /** * Drawableのクリッピングマスクリストの取得 * @return Drawableのクリッピングマスクリスト */ public getDrawableMasks(): Int32Array[] { const masks: Int32Array[] = this._model.drawables.masks; return masks; } /** * Drawableのクリッピングマスクの個数リストの取得 * @return Drawableのクリッピングマスクの個数リスト */ public getDrawableMaskCounts(): Int32Array { const maskCounts: Int32Array = this._model.drawables.maskCounts; return maskCounts; } /** * クリッピングマスクの使用状態 * * @return true クリッピングマスクを使用している * @return false クリッピングマスクを使用していない */ public isUsingMasking(): boolean { for (let d = 0; d < this._model.drawables.count; ++d) { if (this._model.drawables.maskCounts[d] <= 0) { continue; } return true; } return false; } /** * Drawableの表示情報を取得する * * @param drawableIndex Drawableのインデックス * @return true Drawableが表示 * @return false Drawableが非表示 */ public getDrawableDynamicFlagIsVisible(drawableIndex: number): boolean { const dynamicFlags: Uint8Array = this._model.drawables.dynamicFlags; return Live2DCubismCore.Utils.hasIsVisibleBit(dynamicFlags[drawableIndex]); } /** * DrawableのDrawOrderの変化情報の取得 * * 直近のCubismModel.update関数でdrawableのdrawOrderが変化したかを取得する。 * drawOrderはartMesh上で指定する0から1000の情報 * @param drawableIndex drawableのインデックス * @return true drawableの不透明度が直近のCubismModel.update関数で変化した * @return false drawableの不透明度が直近のCubismModel.update関数で変化している */ public getDrawableDynamicFlagVisibilityDidChange( drawableIndex: number ): boolean { const dynamicFlags: Uint8Array = this._model.drawables.dynamicFlags; return Live2DCubismCore.Utils.hasVisibilityDidChangeBit( dynamicFlags[drawableIndex] ); } /** * Drawableの不透明度の変化情報の取得 * * 直近のCubismModel.update関数でdrawableの不透明度が変化したかを取得する。 * * @param drawableIndex drawableのインデックス * @return true Drawableの不透明度が直近のCubismModel.update関数で変化した * @return false Drawableの不透明度が直近のCubismModel.update関数で変化してない */ public getDrawableDynamicFlagOpacityDidChange( drawableIndex: number ): boolean { const dynamicFlags: Uint8Array = this._model.drawables.dynamicFlags; return Live2DCubismCore.Utils.hasOpacityDidChangeBit( dynamicFlags[drawableIndex] ); } /** * Drawableの描画順序の変化情報の取得 * * 直近のCubismModel.update関数でDrawableの描画の順序が変化したかを取得する。 * * @param drawableIndex Drawableのインデックス * @return true Drawableの描画の順序が直近のCubismModel.update関数で変化した * @return false Drawableの描画の順序が直近のCubismModel.update関数で変化してない */ public getDrawableDynamicFlagRenderOrderDidChange( drawableIndex: number ): boolean { const dynamicFlags: Uint8Array = this._model.drawables.dynamicFlags; return Live2DCubismCore.Utils.hasRenderOrderDidChangeBit( dynamicFlags[drawableIndex] ); } /** * 保存されたパラメータの読み込み */ public loadParameters(): void { let parameterCount: number = this._model.parameters.count; const savedParameterCount: number = this._savedParameters.getSize(); if (parameterCount > savedParameterCount) { parameterCount = savedParameterCount; } for (let i = 0; i < parameterCount; ++i) { this._parameterValues[i] = this._savedParameters.at(i); } } /** * 初期化する */ public initialize(): void { CSM_ASSERT(this._model); 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: string[] = this._model.parameters.ids; const parameterCount: number = this._model.parameters.count; this._parameterIds.prepareCapacity(parameterCount); for (let i = 0; i < parameterCount; ++i) { this._parameterIds.pushBack( CubismFramework.getIdManager().getId(parameterIds[i]) ); } } { const partIds: string[] = this._model.parts.ids; const partCount: number = this._model.parts.count; this._partIds.prepareCapacity(partCount); for (let i = 0; i < partCount; ++i) { this._partIds.pushBack( CubismFramework.getIdManager().getId(partIds[i]) ); } } { const drawableIds: string[] = this._model.drawables.ids; const drawableCount: number = this._model.drawables.count; this._drawableIds.prepareCapacity(drawableCount); for (let i = 0; i < drawableCount; ++i) { this._drawableIds.pushBack( CubismFramework.getIdManager().getId(drawableIds[i]) ); } } } /** * コンストラクタ * @param model モデル */ public constructor(model: Live2DCubismCore.Model) { this._model = model; this._parameterValues = null; this._parameterMaximumValues = null; this._parameterMinimumValues = null; this._partOpacities = null; this._savedParameters = new csmVector<number>(); this._parameterIds = new csmVector<CubismIdHandle>(); this._drawableIds = new csmVector<CubismIdHandle>(); this._partIds = new csmVector<CubismIdHandle>(); this._notExistPartId = new csmMap<CubismIdHandle, number>(); this._notExistParameterId = new csmMap<CubismIdHandle, number>(); this._notExistParameterValues = new csmMap<number, number>(); this._notExistPartOpacities = new csmMap<number, number>(); } /** * デストラクタ相当の処理 */ public release(): void { this._model.release(); this._model = null; } private _notExistPartOpacities: csmMap<number, number>; // 存在していないパーツの不透明度のリスト private _notExistPartId: csmMap<CubismIdHandle, number>; // 存在していないパーツIDのリスト private _notExistParameterValues: csmMap<number, number>; // 存在していないパラメータの値のリスト private _notExistParameterId: csmMap<CubismIdHandle, number>; // 存在していないパラメータIDのリスト private _savedParameters: csmVector<number>; // 保存されたパラメータ private _model: Live2DCubismCore.Model; // モデル private _parameterValues: Float32Array; // パラメータの値のリスト private _parameterMaximumValues: Float32Array; // パラメータの最大値のリスト private _parameterMinimumValues: Float32Array; // パラメータの最小値のリスト private _partOpacities: Float32Array; // パーツの不透明度のリスト private _parameterIds: csmVector<CubismIdHandle>; private _partIds: csmVector<CubismIdHandle>; private _drawableIds: csmVector<CubismIdHandle>; } // Namespace definition for compatibility. import * as $ from './cubismmodel'; // eslint-disable-next-line @typescript-eslint/no-namespace export namespace Live2DCubismFramework { export const CubismModel = $.CubismModel; export type CubismModel = $.CubismModel; }