关于模型(Java)

最終更新: 2023年1月26日

此页面适用于Cubism 4.2及更早版本的旧版本。 点击此处查看最新页面

关于编辑模型信息

模型信息基本上是在Cubism Editor的模型工作区中创建的。
.moc3文件中记录了相对于参数的顶点等动作。
附加到其他物理模拟、图形网格的用户数据等作为单独的文件输出,.model3.json文件记录模型相关的所有文件参考。

这些可以在输出.moc3文件的同时输出。“输出嵌入数据”
您还可以使用Cubism Viewer(for OW)追加动态、表情文件和姿势文件的内置设置。

使用Framework从.model3.json文件导入

使用Framework导入时,从.model3.json文件中提取模型所需的信息,然后考虑将维护和使用继承CubismUserModel类的副本。

// Java
final String dir = "example/";
final String fileName = "example.model3.json";
final String jsonpath = dir + fileName;

byte[] buffer = createBuffer(jsonpath);
ICubismModelSetting setting = new CubismModelSettingJson(buffer);

ICubismModelSetting类中提取的各元素都可以通过CubismUserModel.load~~系函数进行导入。

// Java
// Cubism Model
if (setting.getModelFileName() == ""){
    String path = setting.getModelFileName();
    path = dir + path;
  
    if (debugMode){
        LAppPal.printLog("[APP]create model" + setting.getModelFileName());
    }
  
    byte[] buffer = createBuffer(path);
    loadModel(buffer);
}

通过遵循范例中LAppmodel.loadAssets函数的以下函数的流程,从.model3.json文件加载的整体流程很容易理解。

  • LAppModel.setupModel函数
  • CubismUserModel.createRenderer函数
  • LAppModel.setupTextures函数

创建副本(导入.moc3文件)

首先,将.moc3文件导入到内存记忆中。
将导入缓冲区传递给CubismMoc.create函数,并首先创建一个CubismMoc副本。
然后调用CubismMoc.createModel函数来创建一个CubismModel副本。
从这个CubismModel副本中,您可以操作参数并获取绘图信息等。

CubismMoc.createModel函数统计CubismMoc内部函数生成的Model数,当CubismMoc被放弃时,需要放弃该CubismMoc生成的所有CubismModel。

// Java
String path = "example.moc3";
path = dir + path;

byte[] buffer = createBuffer(path);
CubismMoc moc = CubismMoc.create(buffer);
CubismModel model = moc.createModel();

图形环境关联

Framework使用从CubismRenderer类派生的类,以便模型的纹理信息不依赖于图形API。
所有与模型相关的图形相关信息都由CubismRenderer类的派生类管理。
SDK for Java R1 alpha1时只支持Android,所以不需要管理派生类,但是考虑到以后可能追加图形API以及与现有SDK的规范统一,规范如下跟随。

首先,使用RendererType枚举指定要生成的图形环境类型,并将其作为CubismUserModel.createRenderer函数的参数调用。
(SDK for Java R1 alpha1仅支持Android。)
在createRenderer函数内部,生成了参数对应的图形API的派生类,通过CubismRenderer.initialize函数注册CubismModel副本,将CubismRenderer副本和CubismModel副本关联起来。

// Java
public void setupRenderer(CubismRenderer renderer, int maskBufferCount) {
    this.renderer = renderer;
 
    this.renderer.initialize(model, maskBufferCount);
}

纹理关联

Framework中模型的纹理由CubismRenderer类的派生类管理。
Android OpenGL ES 2.0处理使用CubismRendererAndroid类中的CubismRendererAndroid.bindTexture函数注册,该类是CubismRenderer类的派生类。
第一个参数可以通过模型纹理编号和Editor上的纹理集编号来确认。
第二个参数是纹理在OpenGL ES 2.0中的管理编号。

// Java
// 将纹理读取到Android OpenGL ES 2.0纹理单元中
String texturePath = modelSetting.getTextureFileName(modelTextureNumber);
texturepath = modelHomeDir + texturePath;
LAppTextureManager.textureInfo texture = LAppDelegate.getInstance().getTextureManager().createTextureFromPngFile(texturePath);
final int glTextureNumber = texture.id;

this.<CubismRendererAndroid>getRenderer().bindTexture(modelTextureNumber, glTextureNumber);

指定显示位置和大小

您可以通过到目前为止的设置绘制模型,但在很多情况下,显示位置和比例尺相差太大,无法在画面上显示。
有关CubismModel.getDrawableVertexPositions函数返回的顶点范围,请参考“DrawableVertexPositions范围”
使用CubismModelMatrix类、CubismModel.getCanvasWidth函数和CubismModel.getCanvasHeight函数来调整大小。

// Java
// modelMatrix在LAppModel类中定义为CubismModelMatrix类型
modelMatrix = CubismModelMatrix.create(model.getCanvasWidth(), model.getCanvasHeight());

这个矩阵在绘制前乘以Projection矩阵,作为MVP矩阵传递给渲染器。

// Java
public void onUpdate() {
    int width = LAppDelegate.getInstance().getWindowWidth();
    int height = LAppDelegate.getInstance().getWindowHeight();
    ...
    CubismMatrix4x4 projectionMatrix = CubismMatrix4x4.create();
    ...
    projectionMatrix.scale(1.0f, (float) height / (float) width);
    ...
    model.draw(projectionMatrix);
}
// Java
public void draw(CubismMatrix4x4 matrix) {
    ...
    matrix.multiplyByMatrix(modelMatrix);
    this.<CubismRendererAndroid>getRenderer().setMvpMatrix(matrix);
    ...
}

顶点更新

执行CubismModel.update函数,将CubismModel副本相对的参数操作应用在图形网格的顶点上。

// Java)
model.update()

绘制

绘制不是从CubismModel副本执行的,而是被指示给关联的渲染器。

// Java
this.<CubismRendererAndroid>getRenderer.drawModel();

放弃

放弃副本需要在放弃所有CubismModel后,放弃CubismMoc。
要保持此顺序,请使用CubismMoc.deleteModel删除来放弃CubismModel。
如果您不经由该函数,由于CubismMoc内部确认的模型数量不匹配,您将收到警告。

// Java
protected void delete() {
    if (moc == null || model == null) {
        return;
    }
    moc.deleteModel(model);

    moc.delete();
    model.close();
    renderer.close();

    moc = null;
    model = null;
    renderer = null;
}
// Java
public void delete() {
    assert (modelCount == 0);
    if (moc != null) {
        moc.close();
    }
    moc = null;
}

public void deleteModel(CubismModel model) {
    model.close();
    modelCount--;
}

在CubismModel类中使用模型中不存在的参数ID

在CubismModel类的参数和部件不透明度的操作中,可以处理.moc文件中不存在ID的功能。
该功能被CubismMotion类、CubismPose类等使用,使用它创建新结构时,请注意您使用的ID,避免与现有功能冲突。
另外,请注意使用解读Framework时也会创建的参数与其他功能联动的可能性。
* 访问不存在的最大值、最小值和初始值时会出现错误。

新创建从参数ID生成参数Index时不存在的参数。

// Java
public int getParameterIndex(CubismId parameterId) {
    final CubismParameterView parameterView = model.findParameterView(parameterId.getString());
    if (parameterView != null) {
        return parameterView.getIndex();
    }

    // If the parameter does not exist in the model, it searches for it in the non-existent parameter ID list and returns its index.
    if (notExistParameterIds.containsKey(parameterId)) {
        final Integer index = notExistParameterIds.get(parameterId);
        assert index != null;
        return index;
    }

    // If the parameter does not exist in the non-existent parameter ID list, add newly the element.
    final int parameterCount = parameterValues.length;
    final int parameterIndex = parameterCount + notExistParameterIds.size();
    notExistParameterIds.put(parameterId, parameterIndex);
    notExistParameterIndices.add(parameterIndex);

    float[] tmp = new float[notExistParameterIndices.size()];
    System.arraycopy(notExistParameterValues, 0, tmp, 0, notExistParameterIndices.size() - 1);
    tmp[notExistParameterIndices.size() - 1] = 0.0f;
    notExistParameterValues = new float[notExistParameterIndices.size()];
    System.arraycopy(tmp, 0, notExistParameterValues, 0, notExistParameterIndices.size());

    return parameterIndex;
}
请问这篇文章对您有帮助吗?
关于本报道,敬请提出您的意见及要求。