关于模型(Java)

最終更新: 2023年1月26日

关于编辑模型信息

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

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

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

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 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);
// 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);
// 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~~系函数进行导入。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 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);
}
// 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); }
// 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。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Java
String path = "example.moc3";
path = dir + path;
byte[] buffer = createBuffer(path);
CubismMoc moc = CubismMoc.create(buffer);
CubismModel model = moc.createModel();
// Java String path = "example.moc3"; path = dir + path; byte[] buffer = createBuffer(path); CubismMoc moc = CubismMoc.create(buffer); CubismModel model = moc.createModel();
// 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副本关联起来。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Java
public void setupRenderer(CubismRenderer renderer, int maskBufferCount) {
this.renderer = renderer;
this.renderer.initialize(model, maskBufferCount);
}
// Java public void setupRenderer(CubismRenderer renderer, int maskBufferCount) { this.renderer = renderer; this.renderer.initialize(model, maskBufferCount); }
// 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中的管理编号。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 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);
// 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);
// 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函数来调整大小。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Java
// modelMatrix在LAppModel类中定义为CubismModelMatrix类型
modelMatrix = CubismModelMatrix.create(model.getCanvasWidth(), model.getCanvasHeight());
// Java // modelMatrix在LAppModel类中定义为CubismModelMatrix类型 modelMatrix = CubismModelMatrix.create(model.getCanvasWidth(), model.getCanvasHeight());
// Java
// modelMatrix在LAppModel类中定义为CubismModelMatrix类型
modelMatrix = CubismModelMatrix.create(model.getCanvasWidth(), model.getCanvasHeight());

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 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 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 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);
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Java
public void draw(CubismMatrix4x4 matrix) {
...
matrix.multiplyByMatrix(modelMatrix);
this.<CubismRendererAndroid>getRenderer().setMvpMatrix(matrix);
...
}
// Java public void draw(CubismMatrix4x4 matrix) { ... matrix.multiplyByMatrix(modelMatrix); this.<CubismRendererAndroid>getRenderer().setMvpMatrix(matrix); ... }
// Java
public void draw(CubismMatrix4x4 matrix) {
    ...
    matrix.multiplyByMatrix(modelMatrix);
    this.<CubismRendererAndroid>getRenderer().setMvpMatrix(matrix);
    ...
}

顶点更新

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Java)
model.update()
// Java) model.update()
// Java)
model.update()

绘制

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Java
this.<CubismRendererAndroid>getRenderer.drawModel();
// Java this.<CubismRendererAndroid>getRenderer.drawModel();
// Java
this.<CubismRendererAndroid>getRenderer.drawModel();

放弃

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 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 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
protected void delete() {
    if (moc == null || model == null) {
        return;
    }
    moc.deleteModel(model);

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

    moc = null;
    model = null;
    renderer = null;
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// Java
public void delete() {
assert (modelCount == 0);
if (moc != null) {
moc.close();
}
moc = null;
}
public void deleteModel(CubismModel model) {
model.close();
modelCount--;
}
// Java public void delete() { assert (modelCount == 0); if (moc != null) { moc.close(); } moc = null; } public void deleteModel(CubismModel model) { model.close(); modelCount--; }
// 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时不存在的参数。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 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;
}
// 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; }
// 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;
}
请问这篇文章对您有帮助吗?
关于本报道,敬请提出您的意见及要求。