关于模型(Java)
最終更新: 2023年1月26日
关于编辑模型信息
模型信息基本上是在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; }