关于模型(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;
}