如何直接使用CubismJavaFramework

最終更新: 2022年10月6日

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

Cubism SDK for Java中包含的范例项目使用CubismJavaFramework(SDK包/Framework/以下)来处理Cubism模型。
在创建处理Cubism模型的项目时,基于范例项目使用为宜,但在现有应用程序或用户自己的引擎等中实装时,有些情况需要直接处理CubismJavaFramework的API。
但是,由于包中包含的范例项目功能强大,因此仅参考它并不容易理解和区分结构。

下面,我们将介绍以上述用户为对象,直接调用CubismFramework处理模型的最小片段。

CubismFramework周期

使用CubismFramework的步骤如下:

  1. CubismFramework的原始化
  2. 获取模型文件路径
  3. 导入模型
  4. 更新处理
  5. 放弃模型
  6. CubismFramework退出处理

1. CubismFramework的原始化

CubismFramework的原始化处理如下所示。

CubismFramework使用CubismFramework.startUp()进行原始化。
Cubism SDK for Native将分配器(ICubismAllocator)作为第一参数,但Cubism SDK for Java不使用它。

public class LAppDelegate{
    public void onSurfaceCreated() {
        ...
        // Initialize Cubism SDK framework
        CubismFramework.initialize();

        // 着色器的原始化
        _view.initializeShader();
    }

    private LAppDelegate() {
        ...
        // 设置记录输出级别。在LogLevel.VERBOSE的情况下,输出详细记录。
        _cubismOption = new CubismFramework.Option();
        _cubismOption.logFunction = new LAppPal.PrintLogFunction();
        _cubismOption.loggingLevel = LAppDefine.cubismLoggingLevel;

        CubismFramework.cleanUp();
        // 设置CubismJavaFramework原始化所需的参数。
        CubismFramework.startUp(_cubismOption);
    }
  
    private CubismFramework.Option _cubismOption;
}
Tips

原始化时只调用一次CubismFramework.initialize(),然后跳过连续调用,除非CubismFramework被放弃。
但是,一旦CubismFramework被放弃,再次对其进行原始化时将调用CubismFramework::Initialize()。

2. 获取模型文件路径

对于Cubism的嵌入数据集,各相对路径都在.model3.json中描述。
可以直接指定一个MOC3文件或者纹理进行导入,但基本上推荐从.model3.json获取路径并导入。

要解析.model3.json,请使用CubismFramework的CubismModelSettingJson类。

public class LAppModel{
    ...
    private static byte[] createBuffer(final String path) {
        if (LAppDefine.DEBUG_LOG_ENABLE) {
            LAppPal.printLog("create buffer: " + path);
        }
        return LAppPal.loadFileAsBytes(path);
    }
}
// 导入model3.json
final String modelSettingJsonPath = _modelHomeDir + modelSettingJsonName;
byte[] buffer = createBuffer(modelSettingJsonPath);
ICubismModelSetting setting = new CubismModelSettingJson(buffer);

// 获取model3.json中描述的模型路径
String moc3Path = _modelSetting.getModelFileName();
moc3Path = _modelHomeDir + moc3Path;

3. 导入模型

模型通过CubismModel接口进行导入。

CubismModel的副本由CubismJavaFramework中的CubismUserModel._model持有。
使用时,建议从继承CubismUserModel的类中处理。
还可以在外部管理诸如纹理、动态和表情动态等资源。

作为一个例子,这里我们将说明使用继承CubismUserModel的CubismUserModelExtend。

// 创建模型的副本
CubismUserModelExtend userModel = new CubismUserModelExtend();

// 导入moc3文件
buffer = CreateBuffer(moc3Path);
userModel.loadModel(mocBuffer);


要导入的MOC3文件的路径可以通过上面介绍的.model3.json获取,表情、物理模拟、姿势、眨眼、口形同步、用户数据和动态路径也可以从.model3.json取。
在SDK范例中,这些是在导入模型的同时导入的。
各导入方法请参考以下内容。

Tips

上面的代码片段基于在画面上显示1个模型的假设。
如果要同时在画面上显示多个模型,请创建与要显示的模型一样多的CubismUserModel派生类的副本。

4. 更新处理

Cubism模型的更新处理是通过调用CubismModel的接口CubismModel.update()来完成的,方法和模型原始化一样。
当CubismModel.update()被调用时,将进行Cubism Core更新处理,从目前为止设置的参数和部件的值更新顶点信息。

public class CubismUserModelExtend{
    public void update() {
        // 参数操作
        _model.setParameterValue(CubismFramework.getIdManager().getId("ParamAngleX"), value);

        // 部件不透明度操作
        _model.setPartOpacity(CubismFramework.getIdManager().getId("PartArmL"), opacity);

        // 更新模型顶点信息
        _model.update();
    }
}

在更新处理中,视线跟踪、物理模拟、动态播放等必须在update()之前进行。

CubismModel.update()之后,即使操作参数值也不应用。
之后如果再次调用CubismModel.update()则会应用,但是建议把这个处理合二为一,因为负载比较高。

// 应用在顶点上
_model.setParameterValue(CubismFramework.getIdManager().getId("ParamAngleX"), value);

// 更新模型顶点信息
_model.update();

// 不应用在顶点上
_model.setParameterValue(CubismFramework.getIdManager().getId("ParamAngleX"), value);


播放动态的CubismMotionManager.updateMotion()会覆盖所有用于播放动态的ID参数值。
因此,在该处理之前对参数值的任何操作都将被CubismMotionManager.updateMotion()覆盖。
建议先进行动态播放处理,再进行视线跟踪等的值操作及物理模拟等。

// 将正在播放的动态应用到模型中
_motionManager.updateMotion(_model, deltaTimeSeconds);

// 视线跟踪等的值操作和物理模拟处理

// 更新模型顶点信息
_model.update();


此外,如果所有的参数都没有用于要播放的动态、或者如果因为动态播放停止等而没有操作参数值,则在前一帧中执行的值操作的结果将保留。
因此,后续的相对参数值操作可能会导致意外结果。
通过在模型中应用动态的处理前后调用CubismModel.loadParameter()、CubismModel.saveParameters(),可以重置之后执行的相对值操作。

// 将所有参数的值恢复到保存时的状态
_model.loadParameters();

// 将正在播放的动态应用到模型中
_motionManager.updateMotion(_model, deltaTimeSeconds);

// 保存所有参数的值
_model.saveParameters();

// 相对值操作处理

// 更新模型顶点信息
_model.update();


视线追踪、物理模拟、动态播放等处理本身请参考各文档。

通过将使用物理模拟、_model.update函数更新的顶点信息等传递给渲染器,可以在屏幕上绘制Cubism模型。

5. 放弃模型

Cubism SDK for Java基本上将资源的释放留给垃圾回收,但在模型生成中,它是通过使用Java Native Interface(JNI)访问Native函数来实现的。
因此,需要对该部分进行delete处理。

// 放弃模型数据
userModel.delete();

6. Cubism Framework退出处理

调用CubismFramework.dispose()释放CubismFramework保存的通用资源。
在调用CubismFramework.initialize()之前,请不要调用CubismFramework.dispose()。

// 放弃CubismFramework
CubismFramework.dispose();
Tips

由于使用CubismFramework原始化的数据不依赖于模型数据,因此可以在多个模型之间复用。
因此,如果只是想切换模型,则无需调用CubismFramework.dispose()。

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