关于模型(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使用从CubismRenderer类派生的类,以便模型的纹理信息不依赖于图形API。
所有与模型相关的图形相关信息都由CubismRenderer类的派生类管理。
从CubismRenderer类中生成图形API的派生类,
并通过使用CubismRenderer_WebGL.initialize函数注册CubismModel副本,关联CubismRenderer副本和CubismModel副本。

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

renderer.initialize(model);

纹理关联

Framework中模型的纹理由CubismRenderer类的派生类管理。
但是,该方法没有在CubismRenderer类中注册,因为该功能避免了对图形API的依赖。
请注意,方法规格会根据对象图形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]);

    // 生成Mipmap
    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.update函数,将CubismModel副本相对的参数操作应用在图形网格的顶点上。

// 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;
}
关于本报道,敬请提出您的意见及要求。