Update to Cubism 4 SDK for Web R5 beta3
parent
375c664d63
commit
55b7a9233e
|
@ -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/).
|
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
|
## [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.
|
* 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.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.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
|
[4-r.4]: https://github.com/Live2D/CubismWebFramework/compare/4-r.3...4-r.4
|
||||||
|
|
|
@ -646,11 +646,23 @@ export class CubismModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @deprecated
|
||||||
|
* 関数名が誤っていたため、代替となる getDrawableTextureIndex を追加し、この関数は非推奨となりました。
|
||||||
|
*
|
||||||
* Drawableのテクスチャインデックスリストの取得
|
* Drawableのテクスチャインデックスリストの取得
|
||||||
* @param drawableIndex Drawableのインデックス
|
* @param drawableIndex Drawableのインデックス
|
||||||
* @return drawableのテクスチャインデックスリスト
|
* @return drawableのテクスチャインデックスリスト
|
||||||
*/
|
*/
|
||||||
public getDrawableTextureIndices(drawableIndex: number): number {
|
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;
|
const textureIndices: Int32Array = this._model.drawables.textureIndices;
|
||||||
return textureIndices[drawableIndex];
|
return textureIndices[drawableIndex];
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
import { CubismMath } from '../math/cubismmath';
|
import { CubismMath } from '../math/cubismmath';
|
||||||
import { CubismVector2 } from '../math/cubismvector2';
|
import { CubismVector2 } from '../math/cubismvector2';
|
||||||
|
import { csmVector } from '../type/csmvector';
|
||||||
import { CubismModel } from '../model/cubismmodel';
|
import { CubismModel } from '../model/cubismmodel';
|
||||||
import {
|
import {
|
||||||
CubismPhysicsInput,
|
CubismPhysicsInput,
|
||||||
|
@ -34,6 +35,9 @@ const MaximumWeight = 100.0;
|
||||||
// Constant of threshold of movement.
|
// Constant of threshold of movement.
|
||||||
const MovementThreshold = 0.001;
|
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をパースする。
|
* physics3.jsonをパースする。
|
||||||
* @param physicsJson physics3.jsonが読み込まれているバッファ
|
* @param physicsJson physics3.jsonが読み込まれているバッファ
|
||||||
|
@ -268,6 +82,8 @@ export class CubismPhysics {
|
||||||
this._physicsRig.wind = json.getWind();
|
this._physicsRig.wind = json.getWind();
|
||||||
this._physicsRig.subRigCount = json.getSubRigCount();
|
this._physicsRig.subRigCount = json.getSubRigCount();
|
||||||
|
|
||||||
|
this._physicsRig.fps = json.getFps();
|
||||||
|
|
||||||
this._physicsRig.settings.updateSize(
|
this._physicsRig.settings.updateSize(
|
||||||
this._physicsRig.subRigCount,
|
this._physicsRig.subRigCount,
|
||||||
CubismPhysicsSubRig,
|
CubismPhysicsSubRig,
|
||||||
|
@ -289,6 +105,9 @@ export class CubismPhysics {
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this._currentRigOutputs.clear();
|
||||||
|
this._previousRigOutputs.clear();
|
||||||
|
|
||||||
let inputIndex = 0,
|
let inputIndex = 0,
|
||||||
outputIndex = 0,
|
outputIndex = 0,
|
||||||
particleIndex = 0;
|
particleIndex = 0;
|
||||||
|
@ -352,6 +171,18 @@ export class CubismPhysics {
|
||||||
this._physicsRig.settings.at(i).outputCount = json.getOutputCount(i);
|
this._physicsRig.settings.at(i).outputCount = json.getOutputCount(i);
|
||||||
this._physicsRig.settings.at(i).baseOutputIndex = outputIndex;
|
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) {
|
for (let j = 0; j < this._physicsRig.settings.at(i).outputCount; ++j) {
|
||||||
this._physicsRig.outputs.at(outputIndex + j).destinationParameterIndex =
|
this._physicsRig.outputs.at(outputIndex + j).destinationParameterIndex =
|
||||||
-1;
|
-1;
|
||||||
|
@ -422,6 +253,345 @@ export class CubismPhysics {
|
||||||
json = null;
|
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<PhysicsOutput>();
|
||||||
|
this._previousRigOutputs = new csmVector<PhysicsOutput>();
|
||||||
|
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].velocity = new CubismVector2(0.0, 0.0);
|
||||||
strand[0].force = 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) {
|
for (let i = 1; i < currentSetting.particleCount; ++i) {
|
||||||
radius = new CubismVector2(0.0, 0.0);
|
radius = new CubismVector2(0.0, 0.0);
|
||||||
radius.y = strand[i].radius;
|
radius.y = strand[i].radius;
|
||||||
|
@ -475,6 +645,13 @@ export class CubismPhysics {
|
||||||
|
|
||||||
_physicsRig: CubismPhysicsRig; // 物理演算のデータ
|
_physicsRig: CubismPhysicsRig; // 物理演算のデータ
|
||||||
_options: Options; // オプション
|
_options: Options; // オプション
|
||||||
|
|
||||||
|
_currentRigOutputs: csmVector<PhysicsOutput>; ///< 最新の振り子計算の結果
|
||||||
|
_previousRigOutputs: csmVector<PhysicsOutput>; ///< 一つ前の振り子計算の結果
|
||||||
|
|
||||||
|
_currentRemainTime: number; ///< 物理演算が処理していない時間
|
||||||
|
|
||||||
|
_parameterCache: Float32Array; ///< Evaluateで利用するパラメータのキャッシュ
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -490,6 +667,17 @@ export class Options {
|
||||||
wind: CubismVector2; // 風の方向
|
wind: CubismVector2; // 風の方向
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* パラメータに適用する前の物理演算の出力結果
|
||||||
|
*/
|
||||||
|
export class PhysicsOutput {
|
||||||
|
constructor() {
|
||||||
|
this.output = new csmVector<number>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
output: csmVector<number>; // 物理演算出力結果
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets sign.
|
* Gets sign.
|
||||||
*
|
*
|
||||||
|
|
|
@ -208,6 +208,7 @@ export class CubismPhysicsRig {
|
||||||
this.particles = new csmVector<CubismPhysicsParticle>();
|
this.particles = new csmVector<CubismPhysicsParticle>();
|
||||||
this.gravity = new CubismVector2(0, 0);
|
this.gravity = new CubismVector2(0, 0);
|
||||||
this.wind = new CubismVector2(0, 0);
|
this.wind = new CubismVector2(0, 0);
|
||||||
|
this.fps = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
subRigCount: number; // 物理演算の物理点の個数
|
subRigCount: number; // 物理演算の物理点の個数
|
||||||
|
@ -217,6 +218,7 @@ export class CubismPhysicsRig {
|
||||||
particles: csmVector<CubismPhysicsParticle>; // 物理演算の物理点のリスト
|
particles: csmVector<CubismPhysicsParticle>; // 物理演算の物理点のリスト
|
||||||
gravity: CubismVector2; // 重力
|
gravity: CubismVector2; // 重力
|
||||||
wind: CubismVector2; // 風
|
wind: CubismVector2; // 風
|
||||||
|
fps: number; //物理演算動作FPS
|
||||||
}
|
}
|
||||||
|
|
||||||
// Namespace definition for compatibility.
|
// Namespace definition for compatibility.
|
||||||
|
|
|
@ -27,6 +27,7 @@ const PhysicsSettingCount = 'PhysicsSettingCount';
|
||||||
const Gravity = 'Gravity';
|
const Gravity = 'Gravity';
|
||||||
const Wind = 'Wind';
|
const Wind = 'Wind';
|
||||||
const VertexCount = 'VertexCount';
|
const VertexCount = 'VertexCount';
|
||||||
|
const Fps = 'Fps';
|
||||||
|
|
||||||
// PhysicsSettings
|
// PhysicsSettings
|
||||||
const PhysicsSettings = 'PhysicsSettings';
|
const PhysicsSettings = 'PhysicsSettings';
|
||||||
|
@ -120,6 +121,18 @@ export class CubismPhysicsJson {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物理演算設定FPSの取得
|
||||||
|
* @return 物理演算設定FPS
|
||||||
|
*/
|
||||||
|
public getFps(): number {
|
||||||
|
return this._json
|
||||||
|
.getRoot()
|
||||||
|
.getValueByString(Meta)
|
||||||
|
.getValueByString(Fps)
|
||||||
|
.toFloat(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 物理店の管理の個数の取得
|
* 物理店の管理の個数の取得
|
||||||
* @return 物理店の管理の個数
|
* @return 物理店の管理の個数
|
||||||
|
|
|
@ -502,7 +502,7 @@ export class CubismClippingManager_WebGL {
|
||||||
// チャンネルも切り替える必要がある(A,R,G,B)
|
// チャンネルも切り替える必要がある(A,R,G,B)
|
||||||
renderer.setClippingContextBufferForMask(clipContext);
|
renderer.setClippingContextBufferForMask(clipContext);
|
||||||
renderer.drawMesh(
|
renderer.drawMesh(
|
||||||
model.getDrawableTextureIndices(clipDrawIndex),
|
model.getDrawableTextureIndex(clipDrawIndex),
|
||||||
model.getDrawableVertexIndexCount(clipDrawIndex),
|
model.getDrawableVertexIndexCount(clipDrawIndex),
|
||||||
model.getDrawableVertexCount(clipDrawIndex),
|
model.getDrawableVertexCount(clipDrawIndex),
|
||||||
model.getDrawableVertexIndices(clipDrawIndex),
|
model.getDrawableVertexIndices(clipDrawIndex),
|
||||||
|
@ -2115,7 +2115,7 @@ export class CubismRenderer_WebGL extends CubismRenderer {
|
||||||
this.setIsCulling(this.getModel().getDrawableCulling(drawableIndex));
|
this.setIsCulling(this.getModel().getDrawableCulling(drawableIndex));
|
||||||
|
|
||||||
this.drawMesh(
|
this.drawMesh(
|
||||||
this.getModel().getDrawableTextureIndices(drawableIndex),
|
this.getModel().getDrawableTextureIndex(drawableIndex),
|
||||||
this.getModel().getDrawableVertexIndexCount(drawableIndex),
|
this.getModel().getDrawableVertexIndexCount(drawableIndex),
|
||||||
this.getModel().getDrawableVertexCount(drawableIndex),
|
this.getModel().getDrawableVertexCount(drawableIndex),
|
||||||
this.getModel().getDrawableVertexIndices(drawableIndex),
|
this.getModel().getDrawableVertexIndices(drawableIndex),
|
||||||
|
|
Loading…
Reference in New Issue