关于表情动态
最終更新: 2023年1月26日
什么是表情动态?
表情动态与通常的动态不同,是一项SDK的功能,设置相对于当前状态的表情值。
您可以利用动态管理器的渐变功能,使当前的表情随着时间的推移变化为播放的新表情设置。
动态不具备的一个功能是可以指定计算方法。
由于它继承自ACubismMotion类,因此可以像通常的动态一样由CubismMotionManager类管理。
要创建表情数据(.exp3.json文件),需要将.motion3.json文件作为表情动态导入到Cubism Viewer(for OW)中,进行转变并输出。
导入.motion3.json文件时,将动态的初始值设置为表情的目标值。
“在动画视图中创建表情”
“设置和输出表情”
与动态相比,表情具有以下差异。
- 随着时间的推移,值不发生变化。
- 它不能影响部件。
- 可以指定计算方法(加算、正片叠底、覆盖)。
创建副本(导入.exp3.json)
表情使用派生自ACubismMotion类的CubismExpressionMotion类播放。
要生成CubismExpressionMotion副本,请使用Native(C++)的CubismExpressionMotion::Create函数、Web(TypeScript)、Java的CubismExpressionMotion.create函数。
// C++ csmInt32 len = _modelSetting->GetExpressionCount(); for (csmInt32 i = 0; i < len; ++i) { csmString name = _modelSetting->GetExpressionName(i); csmString path = _modelSetting->GetExpressionFileName(i); path = _modelHomeDir + path; buffer = CreateBuffer(path.GetRawString(), &size); ACubismMotion* motion = CubismExpressionMotion::Create(buffer, size); if (_expressions[name] != NULL) { ACubismMotion::Delete(_expressions[name]); _expressions[name] = NULL; } _expressions[name] = motion; DeleteBuffer(buffer, path.GetRawString()); }
// TypeScript let len: number = _modelSetting.getExpressionCount(); for(let i: number = 0; i < len; ++i) { let name: string = this._modelSetting.getExpressionName(i); let path: string = this._modelSetting.getExpressionFileName(i); path = this._modelHomeDir + path; fetch(path).then( (response) => { return response.arrayBuffer(); } ).then( (arrayBuffer) => { let buffer: ArrayBuffer = arrayBuffer; let size: number = buffer.byteLength; let motion: ACubismMotion = CubismExpressionMotion.create(buffer, size); if(this._expressions.getValue(name) != null) { ACubismMotion.delete(this._expressions.getValue(name)); this._expressions.setValue(name, null); } this._expressions.setValue(name, motion); deleteBuffer(buffer, path); } ); }
// Java final int count = modelSetting.getExpressionCount(); for (int i = 0; i < count; i++) { String name = modelSetting.getExpressionName(i); String path = modelSetting.getExpressionFileName(i); path = modelHomeDirectory + path; byte[] buffer = createBuffer(path); CubismExpressionMotion motion = loadExpression(buffer); if (expression.get(name) != null) { expressions.remove(name); } expressions.put(name, motion); }
创建表情管理副本
使用CubismMotionManager类来应用表情。
但是,为了结合通常的动态和效果,需要将其创建为单独的副本。
// C++ CubismMotionManager* motionManager = CSM_NEW CubismMotionManager(); CubismMotionManager* expressionManager = CSM_NEW CubismMotionManager();
// TypeScript let motionManager: CubismMotionmanager = new CubismMotionManager(); let expressionManager: CubismMotionManager = new CubismMotionManager();
// Java CubismMotionManager motionManager = new CubismMotionManager(); CubismMotionManager expressionManager = new CubismMotionManager();
表情播放及其机制
与动态播放相同,表情播放时向管理类发出播放命令。
// C++ ACubismMotion* motion = _expressions[expressionID];//loaded CubismExpression if (motion != NULL) { expressionManager->StartMotionPriority(motion, false, PriorityForce); }
// TypeScript let motion: ACubismMotion = _expressions[expressionID];//loaded CubismExpressionMotion if(motion != null) { expressionManager.startMotionPriority(motion, false, PriorityForce); }
// Java ACubismMotion motion = expressions.get(expressionID); // loaded CubismExpression if (motion != null){ expressionManager.startMotionPriority(motion, LAppDefine.Priority.FORCE.getPriority()); }
可以为表情的各参数指定计算方法。
共有三种计算方法:加算、正片叠底和覆盖。
加算
当计算方法指定为“Add”或未指定计算方法时,选择此方法。
.exp3.json文件中显示的值会直接加算到应用时的参数值中。
对于动态中不经常操作的参数、
以及想要直接滑动影响时使用。
使用Cubism Viewer(for OW)输出值时,设置参数初始值与设置值的差值。
正片叠底
当计算方法显示为“Multiply”时选择。
应用时的参数值直接乘以.exp3.json文件中显示的值。
请注意,此正片叠底不影响应用后的加算和覆盖。
当您想按原样放大或缩小动态的动作时,十分方便。
使用Cubism Viewer(for OW)输出值时,设置值按原样设置。
如果将−30~30的动态乘以30,则动态将为−900~900,
设置动态和表情值的组合时敬请注意。
覆盖
无法在Cubism Viewer(for OW)中设置,但可以通过将计算方法指定为“Overwrite”来使用。
应用时的参数值被忽略,该值被原样覆盖。
当您想忽略动态等的动作时,十分有效。
计算方法不同导致的表达差异
这是将双眼的开合设置为0.4,并分别应用Add、Multiply和Overwrite表情的示例。
由于Add中每次绘制为−0.6,立即达到开合下限并覆盖下限值,所以暂时保持闭眼状态。
在Multiply中,该值乘以全体波形,因此眨眼效果很好。
Overwrite中忽略眨眼或不眨眼。
组合动态等时,您只需一次表情计算即可改变细微差别。
应用表情
应用到模型时使用的是管理类Native(C++)的CubismMotionManager::UpdateMotion函数、Web(TypeScript)、Java的CubismMotionManager.updateMotion函数及Native(C++)的MotionQueueManager::DoUpdateMotion函数、Web(TypeScript)、Java的CubismMotionQueueManager.doUpdateMotion函数。
// C++ expressionManager->UpdateMotion(_model, deltaTimeSeconds);
// TypeScript expressionManager.updateMotion(_model, deltaTimeSeconds);
// Java expressionManager.updateMotion(model, deltaTimeSeconds);
动态、表情和其他参数操作元素的计算顺序极大地影响表达。
请充分注意应用顺序。