From 55b7a9233e908456d16b8e4aa06c350b8859f591 Mon Sep 17 00:00:00 2001 From: wada Date: Thu, 16 Jun 2022 11:48:09 +0900 Subject: [PATCH] Update to Cubism 4 SDK for Web R5 beta3 --- CHANGELOG.md | 9 + src/model/cubismmodel.ts | 12 + src/physics/cubismphysics.ts | 570 +++++++++++++++++--------- src/physics/cubismphysicsinternal.ts | 2 + src/physics/cubismphysicsjson.ts | 13 + src/rendering/cubismrenderer_webgl.ts | 4 +- 6 files changed, 417 insertions(+), 193 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4468e6..24eaccb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [4-r.5-beta.3] - 2022-06-16 + +### Fixed + +* `getDrawableTextureIndices` function in `CubismModel` has been renamed to `getDrawableTextureIndex` because the name was not correct. + * `getDrawableTextureIndices` function is marked as deprecated. +* Fix physics system behaviour when exists Physics Fps Setting in .physics3.json. + ## [4-r.5-beta.2] - 2022-06-02 @@ -89,6 +97,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Reformat code using Prettier and ESLint. +[4-r.5-beta.3]: https://github.com/Live2D/CubismWebFramework/compare/4-r.5-beta.2...4-r.5-beta.3 [4-r.5-beta.2]: https://github.com/Live2D/CubismWebFramework/compare/4-r.5-beta.1...4-r.5-beta.2 [4-r.5-beta.1]: https://github.com/Live2D/CubismWebFramework/compare/4-r.4...4-r.5-beta.1 [4-r.4]: https://github.com/Live2D/CubismWebFramework/compare/4-r.3...4-r.4 diff --git a/src/model/cubismmodel.ts b/src/model/cubismmodel.ts index 9db5b84..f03d280 100644 --- a/src/model/cubismmodel.ts +++ b/src/model/cubismmodel.ts @@ -646,11 +646,23 @@ export class CubismModel { } /** + * @deprecated + * 関数名が誤っていたため、代替となる getDrawableTextureIndex を追加し、この関数は非推奨となりました。 + * * Drawableのテクスチャインデックスリストの取得 * @param drawableIndex Drawableのインデックス * @return drawableのテクスチャインデックスリスト */ public getDrawableTextureIndices(drawableIndex: number): number { + return this.getDrawableTextureIndex(drawableIndex); + } + + /** + * Drawableのテクスチャインデックスの取得 + * @param drawableIndex Drawableのインデックス + * @return drawableのテクスチャインデックス + */ + public getDrawableTextureIndex(drawableIndex: number): number { const textureIndices: Int32Array = this._model.drawables.textureIndices; return textureIndices[drawableIndex]; } diff --git a/src/physics/cubismphysics.ts b/src/physics/cubismphysics.ts index 646a9b0..17d5e18 100644 --- a/src/physics/cubismphysics.ts +++ b/src/physics/cubismphysics.ts @@ -7,6 +7,7 @@ import { CubismMath } from '../math/cubismmath'; import { CubismVector2 } from '../math/cubismvector2'; +import { csmVector } from '../type/csmvector'; import { CubismModel } from '../model/cubismmodel'; import { CubismPhysicsInput, @@ -34,6 +35,9 @@ const MaximumWeight = 100.0; // Constant of threshold of movement. const MovementThreshold = 0.001; +// Constant of maximum allowed delta time +const MaxDeltaTime = 5.0; + /** * 物理演算クラス */ @@ -64,196 +68,6 @@ export class CubismPhysics { } } - /** - * 物理演算の評価 - * @param model 物理演算の結果を適用するモデル - * @param deltaTimeSeconds デルタ時間[秒] - */ - public evaluate(model: CubismModel, deltaTimeSeconds: number): void { - let totalAngle: { angle: number }; - let weight: number; - let radAngle: number; - let outputValue: number; - const totalTranslation: CubismVector2 = new CubismVector2(); - let currentSetting: CubismPhysicsSubRig; - let currentInput: CubismPhysicsInput[]; - let currentOutput: CubismPhysicsOutput[]; - let currentParticles: CubismPhysicsParticle[]; - - let parameterValue: Float32Array; - let parameterMaximumValue: Float32Array; - let parameterMinimumValue: Float32Array; - let parameterDefaultValue: Float32Array; - - parameterValue = model.getModel().parameters.values; - parameterMaximumValue = model.getModel().parameters.maximumValues; - parameterMinimumValue = model.getModel().parameters.minimumValues; - parameterDefaultValue = model.getModel().parameters.defaultValues; - - for ( - let settingIndex = 0; - settingIndex < this._physicsRig.subRigCount; - ++settingIndex - ) { - totalAngle = { angle: 0.0 }; - totalTranslation.x = 0.0; - totalTranslation.y = 0.0; - currentSetting = this._physicsRig.settings.at(settingIndex); - currentInput = this._physicsRig.inputs.get(currentSetting.baseInputIndex); - currentOutput = this._physicsRig.outputs.get( - currentSetting.baseOutputIndex - ); - currentParticles = this._physicsRig.particles.get( - currentSetting.baseParticleIndex - ); - - // Load input parameters - for (let i = 0; i < currentSetting.inputCount; ++i) { - weight = currentInput[i].weight / MaximumWeight; - - if (currentInput[i].sourceParameterIndex == -1) { - currentInput[i].sourceParameterIndex = model.getParameterIndex( - currentInput[i].source.id - ); - } - - currentInput[i].getNormalizedParameterValue( - totalTranslation, - totalAngle, - parameterValue[currentInput[i].sourceParameterIndex], - parameterMinimumValue[currentInput[i].sourceParameterIndex], - parameterMaximumValue[currentInput[i].sourceParameterIndex], - parameterDefaultValue[currentInput[i].sourceParameterIndex], - currentSetting.normalizationPosition, - currentSetting.normalizationAngle, - currentInput[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); - - // Calculate particles position. - updateParticles( - currentParticles, - currentSetting.particleCount, - totalTranslation, - totalAngle.angle, - this._options.wind, - MovementThreshold * currentSetting.normalizationPosition.maximum, - deltaTimeSeconds, - AirResistance - ); - - // Update output parameters. - for (let i = 0; i < currentSetting.outputCount; ++i) { - const particleIndex = currentOutput[i].vertexIndex; - - if ( - particleIndex < 1 || - particleIndex >= currentSetting.particleCount - ) { - break; - } - - if (currentOutput[i].destinationParameterIndex == -1) { - currentOutput[i].destinationParameterIndex = model.getParameterIndex( - currentOutput[i].destination.id - ); - } - - const translation: CubismVector2 = 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 = currentOutput[i].getValue( - translation, - currentParticles, - particleIndex, - currentOutput[i].reflect, - this._options.gravity - ); - - const destinationParameterIndex: number = - currentOutput[i].destinationParameterIndex; - const outParameterValue: Float32Array = - !Float32Array.prototype.slice && 'subarray' in Float32Array.prototype - ? JSON.parse( - JSON.stringify( - parameterValue.subarray(destinationParameterIndex) - ) - ) // 値渡しするため、JSON.parse, JSON.stringify - : parameterValue.slice(destinationParameterIndex); - - updateOutputParameterValue( - outParameterValue, - parameterMinimumValue[destinationParameterIndex], - parameterMaximumValue[destinationParameterIndex], - outputValue, - currentOutput[i] - ); - - // 値を反映 - for ( - let offset: number = destinationParameterIndex, outParamIndex = 0; - offset < parameterValue.length; - offset++, outParamIndex++ - ) { - parameterValue[offset] = outParameterValue[outParamIndex]; - } - } - } - } - - /** - * オプションの設定 - * @param options オプション - */ - public setOptions(options: Options): void { - this._options = options; - } - - /** - * オプションの取得 - * @return オプション - */ - public getOption(): Options { - return this._options; - } - - /** - * コンストラクタ - */ - public constructor() { - this._physicsRig = null; - - // set default options - this._options = new Options(); - this._options.gravity.y = -1.0; - this._options.gravity.x = 0; - this._options.wind.x = 0; - this._options.wind.y = 0; - } - - /** - * デストラクタ相当の処理 - */ - public release(): void { - this._physicsRig = void 0; - this._physicsRig = null; - } - /** * physics3.jsonをパースする。 * @param physicsJson physics3.jsonが読み込まれているバッファ @@ -268,6 +82,8 @@ export class CubismPhysics { this._physicsRig.wind = json.getWind(); this._physicsRig.subRigCount = json.getSubRigCount(); + this._physicsRig.fps = json.getFps(); + this._physicsRig.settings.updateSize( this._physicsRig.subRigCount, CubismPhysicsSubRig, @@ -289,6 +105,9 @@ export class CubismPhysics { true ); + this._currentRigOutputs.clear(); + this._previousRigOutputs.clear(); + let inputIndex = 0, outputIndex = 0, particleIndex = 0; @@ -352,6 +171,18 @@ export class CubismPhysics { this._physicsRig.settings.at(i).outputCount = json.getOutputCount(i); this._physicsRig.settings.at(i).baseOutputIndex = outputIndex; + let currentRigOutput = new PhysicsOutput(); + currentRigOutput.output.resize( + this._physicsRig.settings.at(i).outputCount + ); + this._currentRigOutputs.pushBack(currentRigOutput); + + let previousRigOutput = new PhysicsOutput(); + previousRigOutput.output.resize( + this._physicsRig.settings.at(i).outputCount + ); + this._previousRigOutputs.pushBack(previousRigOutput); + for (let j = 0; j < this._physicsRig.settings.at(i).outputCount; ++j) { this._physicsRig.outputs.at(outputIndex + j).destinationParameterIndex = -1; @@ -422,6 +253,345 @@ export class CubismPhysics { json = null; } + /** + * 物理演算の評価 + * + * Pendulum interpolation weights + * + * 振り子の計算結果は保存され、パラメータへの出力は保存された前回の結果で補間されます。 + * The result of the pendulum calculation is saved and + * the output to the parameters is interpolated with the saved previous result of the pendulum calculation. + * + * 図で示すと[1]と[2]で補間されます。 + * The figure shows the interpolation between [1] and [2]. + * + * 補間の重みは最新の振り子計算タイミングと次回のタイミングの間で見た現在時間で決定する。 + * The weight of the interpolation are determined by the current time seen between + * the latest pendulum calculation timing and the next timing. + * + * 図で示すと[2]と[4]の間でみた(3)の位置の重みになる。 + * Figure shows the weight of position (3) as seen between [2] and [4]. + * + * 解釈として振り子計算のタイミングと重み計算のタイミングがズレる。 + * As an interpretation, the pendulum calculation and weights are misaligned. + * + * physics3.jsonにFPS情報が存在しない場合は常に前の振り子状態で設定される。 + * If there is no FPS information in physics3.json, it is always set in the previous pendulum state. + * + * この仕様は補間範囲を逸脱したことが原因の震えたような見た目を回避を目的にしている。 + * The purpose of this specification is to avoid the quivering appearance caused by deviations from the interpolation range. + * + * ------------ time --------------> + * + * |+++++|------| <- weight + * ==[1]====#=====[2]---(3)----(4) + * ^ output contents + * + * 1:_previousRigOutputs + * 2:_currentRigOutputs + * 3:_currentRemainTime (now rendering) + * 4:next particles timing + * @param model 物理演算の結果を適用するモデル + * @param deltaTimeSeconds デルタ時間[秒] + */ + public evaluate(model: CubismModel, deltaTimeSeconds: number): void { + let totalAngle: { angle: number }; + let weight: number; + let radAngle: number; + let outputValue: number; + const totalTranslation: CubismVector2 = new CubismVector2(); + let currentSetting: CubismPhysicsSubRig; + let currentInput: CubismPhysicsInput[]; + let currentOutput: CubismPhysicsOutput[]; + let currentParticles: CubismPhysicsParticle[]; + + if (0.0 >= deltaTimeSeconds) { + return; + } + + let parameterValue: Float32Array; + let parameterMaximumValue: Float32Array; + let parameterMinimumValue: Float32Array; + let parameterDefaultValue: Float32Array; + + let physicsDeltaTime: number; + this._currentRemainTime += deltaTimeSeconds; + if (this._currentRemainTime > MaxDeltaTime) { + this._currentRemainTime = 0.0; + } + + parameterValue = model.getModel().parameters.values; + parameterMaximumValue = model.getModel().parameters.maximumValues; + parameterMinimumValue = model.getModel().parameters.minimumValues; + parameterDefaultValue = model.getModel().parameters.defaultValues; + + this._parameterCache = new Float32Array(model.getParameterCount()); + + if (this._physicsRig.fps > 0.0) { + physicsDeltaTime = 1.0 / this._physicsRig.fps; + } else { + physicsDeltaTime = deltaTimeSeconds; + } + + while (this._currentRemainTime >= physicsDeltaTime) { + // copyRigOutputs _currentRigOutputs to _previousRigOutputs + for ( + let settingIndex = 0; + settingIndex < this._physicsRig.subRigCount; + ++settingIndex + ) { + currentSetting = this._physicsRig.settings.at(settingIndex); + currentOutput = this._physicsRig.outputs.get( + currentSetting.baseOutputIndex + ); + for (let i = 0; i < currentSetting.outputCount; ++i) { + this._previousRigOutputs.at(settingIndex).output[i] = + this._currentRigOutputs.at(settingIndex).output[i]; + } + } + + for (let j = 0; j < model.getParameterCount(); ++j) { + this._parameterCache[j] = parameterValue[j]; + } + + for ( + let settingIndex = 0; + settingIndex < this._physicsRig.subRigCount; + ++settingIndex + ) { + totalAngle = { angle: 0.0 }; + totalTranslation.x = 0.0; + totalTranslation.y = 0.0; + currentSetting = this._physicsRig.settings.at(settingIndex); + currentInput = this._physicsRig.inputs.get( + currentSetting.baseInputIndex + ); + currentOutput = this._physicsRig.outputs.get( + currentSetting.baseOutputIndex + ); + currentParticles = this._physicsRig.particles.get( + currentSetting.baseParticleIndex + ); + + // Load input parameters + for (let i = 0; i < currentSetting.inputCount; ++i) { + weight = currentInput[i].weight / MaximumWeight; + + if (currentInput[i].sourceParameterIndex == -1) { + currentInput[i].sourceParameterIndex = model.getParameterIndex( + currentInput[i].source.id + ); + } + + currentInput[i].getNormalizedParameterValue( + totalTranslation, + totalAngle, + this._parameterCache[currentInput[i].sourceParameterIndex], + parameterMinimumValue[currentInput[i].sourceParameterIndex], + parameterMaximumValue[currentInput[i].sourceParameterIndex], + parameterDefaultValue[currentInput[i].sourceParameterIndex], + currentSetting.normalizationPosition, + currentSetting.normalizationAngle, + currentInput[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); + + // Calculate particles position. + updateParticles( + currentParticles, + currentSetting.particleCount, + totalTranslation, + totalAngle.angle, + this._options.wind, + MovementThreshold * currentSetting.normalizationPosition.maximum, + physicsDeltaTime, + AirResistance + ); + + // Update output parameters. + for (let i = 0; i < currentSetting.outputCount; ++i) { + const particleIndex = currentOutput[i].vertexIndex; + + if ( + particleIndex < 1 || + particleIndex >= currentSetting.particleCount + ) { + break; + } + + if (currentOutput[i].destinationParameterIndex == -1) { + currentOutput[i].destinationParameterIndex = + model.getParameterIndex(currentOutput[i].destination.id); + } + + const translation: CubismVector2 = 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 = currentOutput[i].getValue( + translation, + currentParticles, + particleIndex, + currentOutput[i].reflect, + this._options.gravity + ); + + this._currentRigOutputs.at(settingIndex).output[i] = outputValue; + + const destinationParameterIndex: number = + currentOutput[i].destinationParameterIndex; + const outParameterCache: Float32Array = + !Float32Array.prototype.slice && + 'subarray' in Float32Array.prototype + ? JSON.parse( + JSON.stringify( + this._parameterCache.subarray(destinationParameterIndex) + ) + ) // 値渡しするため、JSON.parse, JSON.stringify + : this._parameterCache.slice(destinationParameterIndex); + + updateOutputParameterValue( + outParameterCache, + parameterMinimumValue[destinationParameterIndex], + parameterMaximumValue[destinationParameterIndex], + outputValue, + currentOutput[i] + ); + + // 値を反映 + for ( + let offset: number = destinationParameterIndex, outParamIndex = 0; + offset < this._parameterCache.length; + offset++, outParamIndex++ + ) { + this._parameterCache[offset] = outParameterCache[outParamIndex]; + } + } + } + this._currentRemainTime -= physicsDeltaTime; + } + + const alpha: number = this._currentRemainTime / physicsDeltaTime; + this.interpolate(model, alpha); + } + + /** + * 物理演算結果の適用 + * 振り子演算の最新の結果と一つ前の結果から指定した重みで適用する。 + * @param model 物理演算の結果を適用するモデル + * @param weight 最新結果の重み + */ + public interpolate(model: CubismModel, weight: number): void { + let currentOutput: CubismPhysicsOutput[]; + let currentSetting: CubismPhysicsSubRig; + let parameterValue: Float32Array; + let parameterMaximumValue: Float32Array; + let parameterMinimumValue: Float32Array; + + parameterValue = model.getModel().parameters.values; + parameterMaximumValue = model.getModel().parameters.maximumValues; + parameterMinimumValue = model.getModel().parameters.minimumValues; + + for ( + let settingIndex = 0; + settingIndex < this._physicsRig.subRigCount; + ++settingIndex + ) { + currentSetting = this._physicsRig.settings.at(settingIndex); + currentOutput = this._physicsRig.outputs.get( + currentSetting.baseOutputIndex + ); + + // Load input parameters. + for (let i = 0; i < currentSetting.outputCount; ++i) { + const destinationParameterIndex: number = + currentOutput[i].destinationParameterIndex; + const outParameterValue: Float32Array = + !Float32Array.prototype.slice && 'subarray' in Float32Array.prototype + ? JSON.parse( + JSON.stringify( + parameterValue.subarray(destinationParameterIndex) + ) + ) // 値渡しするため、JSON.parse, JSON.stringify + : parameterValue.slice(destinationParameterIndex); + + updateOutputParameterValue( + outParameterValue, + parameterMinimumValue[destinationParameterIndex], + parameterMaximumValue[destinationParameterIndex], + this._previousRigOutputs.at(settingIndex).output[i] * (1 - weight) + + this._currentRigOutputs.at(settingIndex).output[i] * weight, + currentOutput[i] + ); + + // 値を反映 + for ( + let offset: number = destinationParameterIndex, outParamIndex = 0; + offset < parameterValue.length; + offset++, outParamIndex++ + ) { + parameterValue[offset] = outParameterValue[outParamIndex]; + } + } + } + } + + /** + * オプションの設定 + * @param options オプション + */ + public setOptions(options: Options): void { + this._options = options; + } + + /** + * オプションの取得 + * @return オプション + */ + public getOption(): Options { + return this._options; + } + + /** + * コンストラクタ + */ + public constructor() { + this._physicsRig = null; + + // set default options + this._options = new Options(); + this._options.gravity.y = -1.0; + this._options.gravity.x = 0.0; + this._options.wind.x = 0.0; + this._options.wind.y = 0.0; + this._currentRigOutputs = new csmVector(); + this._previousRigOutputs = new csmVector(); + this._currentRemainTime = 0.0; + this._parameterCache = null; + } + + /** + * デストラクタ相当の処理 + */ + public release(): void { + this._physicsRig = void 0; + this._physicsRig = null; + } + /** * 初期化する */ @@ -449,7 +619,7 @@ export class CubismPhysics { strand[0].velocity = new CubismVector2(0.0, 0.0); strand[0].force = new CubismVector2(0.0, 0.0); - // Initialize paritcles. + // Initialize particles. for (let i = 1; i < currentSetting.particleCount; ++i) { radius = new CubismVector2(0.0, 0.0); radius.y = strand[i].radius; @@ -475,6 +645,13 @@ export class CubismPhysics { _physicsRig: CubismPhysicsRig; // 物理演算のデータ _options: Options; // オプション + + _currentRigOutputs: csmVector; ///< 最新の振り子計算の結果 + _previousRigOutputs: csmVector; ///< 一つ前の振り子計算の結果 + + _currentRemainTime: number; ///< 物理演算が処理していない時間 + + _parameterCache: Float32Array; ///< Evaluateで利用するパラメータのキャッシュ } /** @@ -490,6 +667,17 @@ export class Options { wind: CubismVector2; // 風の方向 } +/** + * パラメータに適用する前の物理演算の出力結果 + */ +export class PhysicsOutput { + constructor() { + this.output = new csmVector(0); + } + + output: csmVector; // 物理演算出力結果 +} + /** * Gets sign. * diff --git a/src/physics/cubismphysicsinternal.ts b/src/physics/cubismphysicsinternal.ts index ad17206..fbbea21 100644 --- a/src/physics/cubismphysicsinternal.ts +++ b/src/physics/cubismphysicsinternal.ts @@ -208,6 +208,7 @@ export class CubismPhysicsRig { this.particles = new csmVector(); this.gravity = new CubismVector2(0, 0); this.wind = new CubismVector2(0, 0); + this.fps = 0.0; } subRigCount: number; // 物理演算の物理点の個数 @@ -217,6 +218,7 @@ export class CubismPhysicsRig { particles: csmVector; // 物理演算の物理点のリスト gravity: CubismVector2; // 重力 wind: CubismVector2; // 風 + fps: number; //物理演算動作FPS } // Namespace definition for compatibility. diff --git a/src/physics/cubismphysicsjson.ts b/src/physics/cubismphysicsjson.ts index 35c4529..fda18d1 100644 --- a/src/physics/cubismphysicsjson.ts +++ b/src/physics/cubismphysicsjson.ts @@ -27,6 +27,7 @@ const PhysicsSettingCount = 'PhysicsSettingCount'; const Gravity = 'Gravity'; const Wind = 'Wind'; const VertexCount = 'VertexCount'; +const Fps = 'Fps'; // PhysicsSettings const PhysicsSettings = 'PhysicsSettings'; @@ -120,6 +121,18 @@ export class CubismPhysicsJson { return ret; } + /** + * 物理演算設定FPSの取得 + * @return 物理演算設定FPS + */ + public getFps(): number { + return this._json + .getRoot() + .getValueByString(Meta) + .getValueByString(Fps) + .toFloat(0.0); + } + /** * 物理店の管理の個数の取得 * @return 物理店の管理の個数 diff --git a/src/rendering/cubismrenderer_webgl.ts b/src/rendering/cubismrenderer_webgl.ts index 294c3da..12bd538 100644 --- a/src/rendering/cubismrenderer_webgl.ts +++ b/src/rendering/cubismrenderer_webgl.ts @@ -502,7 +502,7 @@ export class CubismClippingManager_WebGL { // チャンネルも切り替える必要がある(A,R,G,B) renderer.setClippingContextBufferForMask(clipContext); renderer.drawMesh( - model.getDrawableTextureIndices(clipDrawIndex), + model.getDrawableTextureIndex(clipDrawIndex), model.getDrawableVertexIndexCount(clipDrawIndex), model.getDrawableVertexCount(clipDrawIndex), model.getDrawableVertexIndices(clipDrawIndex), @@ -2115,7 +2115,7 @@ export class CubismRenderer_WebGL extends CubismRenderer { this.setIsCulling(this.getModel().getDrawableCulling(drawableIndex)); this.drawMesh( - this.getModel().getDrawableTextureIndices(drawableIndex), + this.getModel().getDrawableTextureIndex(drawableIndex), this.getModel().getDrawableVertexIndexCount(drawableIndex), this.getModel().getDrawableVertexCount(drawableIndex), this.getModel().getDrawableVertexIndices(drawableIndex),