如何直接使用CubismWebFramework

最終更新: 2020年1月30日

Cubism SDK for Web中包含的范例项目使用SDK包的“/Framework”目录下的处理来处理Cubism模型。
在创建处理Cubism模型的项目时,您可以基于范例项目使用它,但在现有应用程序或用户自己的引擎等中实装它时,您可能希望直接处理CubismWebFramework的API。
但是,由于其包含的范例项目功能强大,因此仅参考它很难理解和分割结构。

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

CubismFramework周期

使用CubismFramework的步骤如下:

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

CubismFramework的原始化

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

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 记录等选项设置。
_cubismOption: Csm_Option;
// 信息输出函数。
public static printMessage(message: string): void
// 记录等选项设置。 _cubismOption: Csm_Option; // 信息输出函数。 public static printMessage(message: string): void
    // 记录等选项设置。
    _cubismOption: Csm_Option;

    // 信息输出函数。
    public static printMessage(message: string): void

请参考范例中的同名函数实装printMessage()的内容。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import {Live2DCubismFramework as live2dcubismframework, Option as Csm_Option, LogLevel} from "../../../../Framework/live2dcubismframework";
import Csm_CubismFramework = live2dcubismframework.CubismFramework;
// 设置记录输出级别。在LogLevel_Verbose的情况下,输出详细记录。
this._cubismOption.logFunction = printMessage;
this._cubismOption.loggingLevel = LogLevel.LogLevel_Verbose;
// 设置CubismNativeFramework原始化所需的参数。
Csm_CubismFramework.startUp(this._cubismOption);
// 原始化CubismFramework。
Csm_CubismFramework.initialize();
import {Live2DCubismFramework as live2dcubismframework, Option as Csm_Option, LogLevel} from "../../../../Framework/live2dcubismframework"; import Csm_CubismFramework = live2dcubismframework.CubismFramework; ・ ・ ・ // 设置记录输出级别。在LogLevel_Verbose的情况下,输出详细记录。 this._cubismOption.logFunction = printMessage; this._cubismOption.loggingLevel = LogLevel.LogLevel_Verbose; // 设置CubismNativeFramework原始化所需的参数。 Csm_CubismFramework.startUp(this._cubismOption); // 原始化CubismFramework。 Csm_CubismFramework.initialize();
import {Live2DCubismFramework as live2dcubismframework, Option as Csm_Option, LogLevel} from "../../../../Framework/live2dcubismframework";
import Csm_CubismFramework = live2dcubismframework.CubismFramework;    
・
・
・
    // 设置记录输出级别。在LogLevel_Verbose的情况下,输出详细记录。
    this._cubismOption.logFunction = printMessage;
    this._cubismOption.loggingLevel = LogLevel.LogLevel_Verbose;
    
    // 设置CubismNativeFramework原始化所需的参数。
    Csm_CubismFramework.startUp(this._cubismOption);
    
    // 原始化CubismFramework。
    Csm_CubismFramework.initialize();
Tips

原始化时只调用一次CubismFramework.initialize(),然后跳过连续调用,除非CubismFramework.dispose()放弃了CubismFramework副本。
但是,一旦您放弃了CubismFramework副本,再次对其进行原始化时,则需调用CubismFramework.initialize()。

获取模型文件

对于Cubism的嵌入数据集,各相对路径在.model3.json中都有描述,字节数据参照此进行导入。
推荐解析.model3.json获取模型文件等路径并导入。

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

也可以直接指定.moc3文件和纹理等,并进行导入。
如果直接指定并导入,则需要修改代码。

范例中,在LAppModel.loadAssets()中使用fetch(),并从资源路径中获取文件,导入字节数据,获取Json的内容。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
fetch(path).then(
(response) =>
{
return response.arrayBuffer();
}
).then(
(arrayBuffer) =>
{
let buffer: ArrayBuffer = arrayBuffer;
let size = buffer.byteLength;
// 获取Json中描述的模型数据路径等
let setting: ICubismModelSetting = new CubismModelSettingJson(buffer, size);
// 保存结果
this.setupModel(setting);
}
);
fetch(path).then( (response) => { return response.arrayBuffer(); } ).then( (arrayBuffer) => { let buffer: ArrayBuffer = arrayBuffer; let size = buffer.byteLength; // 获取Json中描述的模型数据路径等 let setting: ICubismModelSetting = new CubismModelSettingJson(buffer, size); // 保存结果 this.setupModel(setting); } );
fetch(path).then(
    (response) =>
    {
        return response.arrayBuffer();
    }
).then(
    (arrayBuffer) =>
    {
        let buffer: ArrayBuffer = arrayBuffer;
        let size = buffer.byteLength;
        // 获取Json中描述的模型数据路径等
        let setting: ICubismModelSetting = new CubismModelSettingJson(buffer, size);

        // 保存结果
        this.setupModel(setting);
    }
);

导入模型

使用CubismModel接口导入模型。

在CubismNativeFramework中,CubismUserModel._model持有CubismModel的副本,使用CubismUserModel.loadModel()获取并保存模型数据。

使用CubismModel时,建议从继承CubismUserModel的类中处理。
在范例中,LAppModel类继承CubismUserModel并进行处理。

还可以在外部管理诸如纹理、动态和表情动态等资源。

范例中,LAppModel.setupModel()中使用fetch()从ICubismModelSetting中保存的文件路径中导入模型数据。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 获取ICubismModelSetting中保存的模型文件路径
let path: string = this._modelSetting.getModelFileName();
path = this._modelHomeDir + path;
fetch(path).then(
(response) =>
{
return response.arrayBuffer();
}
).then(
(arrayBuffer) =>
{
buffer = arrayBuffer;
// 导入模型数据
this.loadModel(buffer);
deleteBuffer(buffer, path);
}
);
this._state = LoadStep.WaitLoadModel;
// 获取ICubismModelSetting中保存的模型文件路径 let path: string = this._modelSetting.getModelFileName(); path = this._modelHomeDir + path; fetch(path).then( (response) => { return response.arrayBuffer(); } ).then( (arrayBuffer) => { buffer = arrayBuffer; // 导入模型数据 this.loadModel(buffer); deleteBuffer(buffer, path); } ); this._state = LoadStep.WaitLoadModel;
// 获取ICubismModelSetting中保存的模型文件路径
let path: string = this._modelSetting.getModelFileName();
path = this._modelHomeDir + path;

fetch(path).then(
    (response) =>
    {
        return response.arrayBuffer();
    }
).then(
    (arrayBuffer) =>
    {
        buffer = arrayBuffer;
        // 导入模型数据
        this.loadModel(buffer);
        deleteBuffer(buffer, path);
    }
);
this._state = LoadStep.WaitLoadModel;

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

Tips

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

更新处理

Cubism模型的更新处理将通过CubismModel接口CubismModel.setParameterValueById()等进行更新的参数和值传递给对象模型来设置,
并调用CubismModel.update()进行更新。
当调用CubismModel.update()时,通过Cubism Core进行更新处理,并根据目前设置的参数和部件的值更新顶点信息等。

通过将更新后的顶点信息等传递给渲染器,可以在画面上绘制Cubism模型。

在下面的代码中,模型的参数操作直接在带有_model(CubismModel)的类中进行,并调用了Cubism Core的更新处理来应用操作。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public update(): void
{
// 参数操作。
// 将ParamAngleX移动到value
this._model.setParameterValueById(CubismFramework.getIdManager().getId("ParamAngleX"), value);
// 部件不透明度操作。
// 将PartArmL不透明度设置为opacity
this._model.setPartOpacityById(CubismFramework.getIdManager().getId("PartArmL"), opacity);
// 更新模型
this._model.update();
}
public update(): void { // 参数操作。 // 将ParamAngleX移动到value this._model.setParameterValueById(CubismFramework.getIdManager().getId("ParamAngleX"), value); // 部件不透明度操作。 // 将PartArmL不透明度设置为opacity this._model.setPartOpacityById(CubismFramework.getIdManager().getId("PartArmL"), opacity); // 更新模型 this._model.update(); }
public update(): void
{
    // 参数操作。
    // 将ParamAngleX移动到value
    this._model.setParameterValueById(CubismFramework.getIdManager().getId("ParamAngleX"), value);

    // 部件不透明度操作。
    // 将PartArmL不透明度设置为opacity
    this._model.setPartOpacityById(CubismFramework.getIdManager().getId("PartArmL"), opacity);

    // 更新模型
    this._model.update();
}

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

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 应用在顶点上
_model.setParameterValue(CubismFramework.getIdManager().getId("ParamAngleX"), value1);
// 更新模型顶点信息
_model.update();
// 不应用在顶点上
_model.setParameterValue(CubismFramework.getIdManager().getId("ParamAngleX"), value);
// 应用在顶点上 _model.setParameterValue(CubismFramework.getIdManager().getId("ParamAngleX"), value1); // 更新模型顶点信息 _model.update(); // 不应用在顶点上 _model.setParameterValue(CubismFramework.getIdManager().getId("ParamAngleX"), value);
    // 应用在顶点上
    _model.setParameterValue(CubismFramework.getIdManager().getId("ParamAngleX"), value1);
    
    // 更新模型顶点信息
    _model.update();
    
    // 不应用在顶点上
    _model.setParameterValue(CubismFramework.getIdManager().getId("ParamAngleX"), value);

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 将正在播放的动态应用到模型中
_motionManager.updateMotion(_model, deltaTimeSeconds);
// 视线跟踪等的值操作和物理模拟处理
// 更新模型顶点信息
_model.update();
// 将正在播放的动态应用到模型中 _motionManager.updateMotion(_model, deltaTimeSeconds); // 视线跟踪等的值操作和物理模拟处理 // 更新模型顶点信息 _model.update();
    // 将正在播放的动态应用到模型中
    _motionManager.updateMotion(_model, deltaTimeSeconds);
    
    // 视线跟踪等的值操作和物理模拟处理
    
    // 更新模型顶点信息
    _model.update();

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 将所有参数的值恢复到保存时的状态
_modelloadParameters();
// 将正在播放的动态应用到模型中
_motionManager.updateMotion(_model, deltaTimeSeconds);
// 保存所有参数的值
_model.saveParameters();
// 相对值操作处理
// 更新模型顶点信息
_model.update();
// 将所有参数的值恢复到保存时的状态 _modelloadParameters(); // 将正在播放的动态应用到模型中 _motionManager.updateMotion(_model, deltaTimeSeconds); // 保存所有参数的值 _model.saveParameters(); // 相对值操作处理 // 更新模型顶点信息 _model.update();
    // 将所有参数的值恢复到保存时的状态
    _modelloadParameters();
    
    // 将正在播放的动态应用到模型中
    _motionManager.updateMotion(_model, deltaTimeSeconds);
    
    // 保存所有参数的值
    _model.saveParameters();
    
    
    // 相对值操作处理
    
    
    // 更新模型顶点信息
    _model.update();

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

通过将更新后的顶点信息等传递给渲染器,可以在画面上绘制Cubism模型。

放弃模型

要放弃模型,请放弃生成的CubismUserModel派生类的副本。
通过该操作,将从CubismUserModel析构函数中放弃该模型保存的动态、表情、物理模拟等信息。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 放弃模型数据
this._model.release();
this._model = null;
// 放弃模型数据 this._model.release(); this._model = null;
    // 放弃模型数据
    this._model.release();
    this._model = null;

Cubism Framework退出处理

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 放弃CubismFramework
CubismFramework.dispose();
// 放弃CubismFramework CubismFramework.dispose();
    // 放弃CubismFramework
    CubismFramework.dispose();
Tips

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

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