モデルについて(Web)

最終更新: 2019年11月7日

モデル情報の編集について

モデル情報は基本的にModelerで作成されます。
パラメータに対する頂点などの動きは.moc3ファイルに記録されます。
その他の物理演算やアートメッシュにつけられるユーザデータなどは別のファイルとして出力され、
モデルに関するすべてのファイルの参照を記録しておくものが.model3.jsonファイルになります。

Modelerから.moc3ファイルの出力を行う際に同時に出力ができます。「組み込み用データの書き出し」
また、Cubism Viewer (for OW)を使うことで、モーションや表情ファイル、ポーズファイルの組み込み設定を追加することができます。

Frameworkを使った.model3.jsonファイルからの読み込み

Frameworkを利用した読み込みでは、モデルに必要な情報を.model3.jsonファイルから抽出して、
CubismUserModelクラスを継承したインスタンスを整備して利用することを想定しています。

// TypeScript
const dir: string = "example/";
const fileName: string = "example.model3.json";
const path: string = dir + fileName;

fetch(path).then(
    (response) =>
    {
        return response.arrayBuffer();
    }
).then(
    (arrayBuffer) =>
    {
        let buffer: ArrayBuffer = arrayBuffer;
        let size = buffer.byteLength;
        let setting: ICubismModelSetting = new CubismModelSettingJson(buffer, size);
        deleteBuffer(buffer, path);
// 省略
    }

ICubismModelSettingクラスに抽出した各要素はCubismUserModel.load~~系関数で読み込むことができます。

// TypeScript

// bufferは.model3.jsonのArrayBuffer
this.loadModel(buffer);

.model3.jsonファイルからの全体的なロードの流れはサンプル内のLAppModel.loadAssets関数から
LAppModel.setupModel関数、CubismUserModel.createRenderer関数、LAppModel.setupTextures関数の流れを追っていくと把握しやすいです。


インスタンスの作成(.moc3ファイルの読み込み)

始めに.moc3ファイルをメモリ上に読み込みます。
読み込んだバッファとサイズをCubismMoc.create関数に渡し、まずはCubismMocインスタンスを作成します。
次にCubismMoc.createModel関数を呼び出してCubismModelインスタンスを作成します。
このCubismModelインスタンスからパラメータの操作や描画のための情報取得などを行います。

// TypeScript

// buffer は .moc3 の ArrayBuffer
this._moc = CubismMoc.create(buffer);
this._model = this._moc.createModel();

グラフィック環境の関連付け

Frameworkはモデルのテクスチャ情報をグラフィックスAPIに依存させないためにCubismRendererクラスからの派生クラスを使っています。
モデルに関連するグラフィック関連の情報はすべてCubismRendererクラスからの派生クラスが管理します。
CubismRendererクラスからのグラフィックスAPIに対する派生クラスを生成し、
CubismRenderer_WebGL.initialize関数でCubismModelインスタンスを登録することでCubismRendererインスタンスとCubismModelインスタンスが紐づけされます。

// TypeScript
let renderer: CubismRenderer_WebGL = new CubismRenderer_WebGL();

renderer.initialize(model);

テクスチャの関連付け

Frameworkでモデルが持つテクスチャはCubismRendererクラスの派生クラスが管理します。
しかしその機能はグラフィックスAPIへの依存を避けるため、CubismRendererクラスにそのメソッドの登録はされていません。
対象とするグラフィックスAPIによってメソッドの仕様の変化に注意してください。
WebGLの処理ではCubismRendererクラスの派生CubismRenderer_WebGLクラス内のCubismRenderer_WebGL.bindTexture関数を使って登録しています。
一つ目の引数はモデルのテクスチャ番号、Editor上ではテクスチャアトラスの番号で確認できます。
二つ目の引数はテクスチャのWebGLでの管理番号です。

下の例はWebGLでのテクスチャの読み込みです。

// TypeScript
// WebGLのテクスチャユニットにテクスチャをロードする
let texturePath = this._modelSetting.getTextureFileName(modelTextureNumber);
texturePath = this._modelHomeDir + texturePath;

img[modelTextureNumber] = new Image();
img[modelTextureNumber].onload = () =>
{
    // テクスチャオブジェクトの作成
    let tex: WebGLTexture = gl.createTexture();

    // テクスチャを選択
    gl.bindTexture(gl.TEXTURE_2D, tex);

    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);

    // Premult処理を行わせる 
    if(usePremultiply)
    {
        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
    }

    // テクスチャにピクセルを書き込む
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,
                  gl.UNSIGNED_BYTE, img[modelTextureNumber]);

    // ミップマップを生成
    gl.generateMipmap(gl.TEXTURE_2D);

    this.getRenderer().bindTexture(modelTextureNumber, tex);
}
img[modelTextureNumber].src = texturePath;

this.getRenderer().setIsPremultipliedAlpha(usePremultiply);

表示位置と大きさの指定

これまでの設定を行えば、モデルを描画することはできますが
多くの場合表示位置や縮尺が違いすぎてそのままでは画面には表示されません。
csmGetDrawableVertexPositions関数で返ってくる頂点範囲に関しては「DrawableVertexPositionsの範囲」をご覧ください。
サイズを調整するためにCubismModelMatrixクラスとCubismModel.getCanvasWidth関数、getCanvasHeight関数をつかいます。

// TypeScript
let modelMatrix: CubismModelMatrix =
  new CubismModelMatrix(this._model.getCanvasWidth(),
                        this._model.getCanvasHeight());

この行列は描画前にProjectionマトリクスに乗算されてMVPマトリクスとしてレンダラーに渡されます。

// TypeScript
let projectionMatrix: CubismMatrix44 = new CubismMatrix44();
projectionMatrix.scale(1, window.width / window.height);
projectionMatrix.multiplyByMatrix(modelMatrix);

this.getRenderer().setMvpMatrix(projectionMatrix);
this.getRenderer().drawModel();

頂点の更新

CubismModelインスタンスに対するパラメータ操作をアートメッシュの頂点に反映するためにCubismModel.update関数を実行します。

// TypeScript
model.update();

描画

描画はCubismModelインスタンスからは実行せず、紐づけされているレンダラーに命令しておこないます。

// TypeScript
let projectionMatrix: CubismMatrix44 = new CubismMatrix44();
projectionMatrix.scale(1, window.width / window.height);
projectionMatrix.multiplyByMatrix(modelMatrix);

this.getRenderer().setMvpMatrix(projectionMatrix);

this.getRenderer().drawModel();

CubismModelクラスでモデルに存在しないパラメータIDを使う

CubismModelクラスのパラメータ、パーツ不透明度の操作では、.moc3ファイルに存在しないIDでも取り扱いを行う機能があります。
この機能はCubismMotionクラス、CubismPoseクラスなどが利用しており、
利用して新たな機構を作成するときには既存の機能と衝突しないように使用するIDを注意してください。
また、Frameworkを読み解くときにも作成されたパラメータを使って他の機能と連携している可能性について留意してください。
※存在しない最大値、最小値、初期値へのアクセスはエラーが発生します

// TypeScript
// CubismModel
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;
}
この記事はお役に立ちましたか?
はいいいえ
この記事に関するご意見・
ご要望をお聞かせください。