vault backup: 2023-08-08 12:23:03

This commit is contained in:
BlueRose 2023-08-08 12:23:03 +08:00
parent 582360f5f5
commit 5820c5a0af
3 changed files with 164 additions and 21 deletions

View File

@ -143,11 +143,11 @@
}
}
},
"VMC推流": {
"VMC推流": {
"Protocol一种基于OSC的虚拟偶像动作输出传输协议。": {
"Protocol一种基于OSC的虚拟偶像动作输出传输协议。": {
"currentFile": {
"count": 1,
"lastUpdated": 1691401283233
"lastUpdated": 1691462131984
}
}
}

View File

@ -0,0 +1 @@
## 查看UEOSC & VMC4UE实现

View File

@ -12,26 +12,87 @@
- https://www.bilibili.com/video/BV1ub4y1Y74K/?spm_id_from=333.337.search-card.all.click&vd_source=d47c0bb42f9c72fd7d74562185cee290
- https://www.youtube.com/watch?v=ufU9me5pDYE&t=2s
## VMC
# 协议
## OSC
一种远程控制协议
- https://docs.unrealengine.com/5.1/en-US/osc-plugin-overview-for-unreal-engine/
- http://openstagecontrol.ammd.net/docs/getting-started/introduction/
- https://www.youtube.com/watch?v=42eDMmvokMM
- https://www.youtube.com/watch?v=9CkKPCBys44
一种基于UDP的**远程控制协议**传输的数据主要分为Bundle 与 Message。
- OSC:https://opensoundcontrol.stanford.edu/index.html
- Nodejs的OSC实现:https://www.npmjs.com/package/osc
### 反序列化步骤
1. 调用`ReadOSC()`
2. ReadOSCString读取Address。主要分为`#bundle``#message`
3. `#bundle`
1. 读取uint64 Time。
2. 调用`ReadOSC()`,递归序列化之后的数据。
4. `#message`:基础数据反序列化逻辑
1. 读取FString Semantics里面每个字符代表之后基础数据的类型。
2. 根据基础数据类型进行反序列化一个数据生成一个FUEOSCElement。
```c++
UENUM()
enum class EUEOSCElementType : uint8
{
OET_Int32 UMETA(DisplayName = "Int32"),
OET_Float UMETA(DisplayName = "Float"),
OET_String UMETA(DisplayName = "String"),
OET_Blob UMETA(DisplayName = "Blob"),
OET_Bool UMETA(DisplayName = "Bool"),
OET_Nil UMETA(DisplayName = "Nil")
};
```
### UEOSC实现分析
一个数据包的格式为:
```c++
USTRUCT(BlueprintType)
struct UEOSC_API FUEOSCMessage
{
GENERATED_USTRUCT_BODY()
public:
FString Address;
TArray<FUEOSCElement> Elements;
};
```
其中`FUEOSCElement`存储的具体数据,里面是一个结构体存储着基础数据类型数据以及数据类型枚举。
#### 基础数据类型
数据以结构体形式进行序列化/反系列化。可携带的数据类型为:
- int32、int64、uint64
- float32
- String(`FName`)
- blob(`TArray<uint8>`)
- bool
## VMC
全名为Virtual Motion Capture Protocol一种基于OSC的虚拟偶像动作输出传输协议。
**存在问题**
1. 数据没有压缩,不适合互联网传输。
2. 基于OSC这种UDP协议数据没有可靠性。
### 协议分析
一种基于UDP的协议传输的数据主要分为Bundle 与 Message。
- VMC协议可视化工具:https://github.com/gpsnmeajp/VMCProtocolMonitor
- https://protocol.vmc.info/specification
- performer-spec:https://protocol.vmc.info/performer-spec
- marionette-spec:https://protocol.vmc.info/marionette-spec
VMC协议基本上实现了开放声音控制OSC单向UDP通信来进行通信。
具体沟通规定如下:
因此VMC 协议定义了自己的术语:
- **木偶**(**Marionette**)
- 接收动作、绘制等。(必填)
- 它的存在最终是为了在屏幕、视频、通讯上产生结果。
示例EVMC4U、VMC4UE、其他运动接收兼容应用程序
- **表演者**(**performer**)
- 主要处理运动并向 Marionette 发送**全身骨骼信息 (IK)** 和**辅助信息**。(必填)
- 例如虚拟动作捕捉、Waidayo、VSeeFace、MocapForAll、TDPT 等)
- **助理**(**Assistant**)
- 主要不处理动作并向表演者发送辅助信息。(可选)
- 仅负责**发送辅助**信息。(**一些骨骼、跟踪器姿势、面部表情**等)
例如face2vmc 模式下的 Waidayo、Sknuckle、Simple Motion Tracker、Uni-studio 等)
具体沟通规定如下:
- 通信时使用适当类型的 OSC。
- 字符串采用 UTF-8 编码,可以用日语发送。
- 至于端口号Marionette 将监听端口39539而 Performer 将监听端口39540但从 UX 角度来看,我们建议您更改发送地址
@ -44,14 +105,95 @@ VMC协议基本上实现了开放声音控制OSC单向UDP通信来进行
- 未知地址,应忽略太多参数。
- 如果您发现参数太少或类型与扩展规范中定义的参数不同,请将它们视为错误或忽略它们。
![](https://protocol.vmc.info/flow.gif)
![](https://protocol.vmc.info/layer.png)
### 数据类型
数据以结构体形式进行序列化/反系列化。可携带的数据类型为:
- int32、int64、uint64
- float32
- String
- blob
![800](https://protocol.vmc.info/flow.gif)
![500](https://protocol.vmc.info/layer.png)
### performer-spec
这是`Marionette→Performer``Assistent→Performer`流程中的发送数据的规范。
主要有:
- 虚拟设备转换
- 帧周期
- 虚拟 MIDI CC 值输入
- 虚拟摄像机变换和 FOV
- VRM BlendShapeProxyValue
- 眼动追踪目标位置
- [事件发送]信息发送请求(Request Information)
- [事件传输] 响应字符串
- [事件发送] 校准(准备)请求(校准/校准就绪请求)
- [事件发送]请求加载设置文件
- 通过信息
- DirectionalLight 位置/颜色DirectionalLight 变换和颜色)
- [事件传输] 快捷调用Call Shortcut
#### 虚拟设备转换
主要为虚拟头显、控制器Controller和追踪器Track。(HMD被视为跟踪器)
结构为:虚拟序列号 -> Position ->Quaternion
```json
V2.3
/VMC/Ext/Hmd/Pos (string){serial} (float){p.x} (float){p.y} (float){p.z} (float){q.x} (float){q.y} (float){q.z} (float){q.w}
/VMC/Ext/Con/Pos (string){serial} (float){p.x} (float){p.y} (float){p.z} (float){q.x} (float){q.y} (float){q.z} (float){q.w}
/VMC/Ext/Tra/Pos (string){serial} (float){p.x} (float){p.y} (float){p.z} (float){q.x} (float){q.y} (float){q.z} (float){q.w}
```
#### 帧周期
设置虚拟动作捕捉的数据传输间隔。 以 1/x 帧间隔发送。
```json
V2.3
/VMC/Ext/Set/Period (int){Status} (int){Root} (int){Bone} (int){BlendShape} (int){Camera} (int){Devices}
```
### marionette-spec
这是`Performer → Marionette`流程中的发送数据的规范。
- 内容:基础状态描述,校准状态、校准模式、追踪状态
- 发送者相对时间Time
- 根变换
- 骨骼变换
- VRM BlendShapeProxyValue
- 相机位置/FOV相机变换和FOV
- 控制器输入
- [事件传输]键盘输入
- [事件传输] MIDI 音符输入
- [事件传输] MIDI CC 值输入
- [事件传输] MIDI CC 按钮输入
- 设备改造
- [低频] 接收使能
- [低频] DirectionalLight 位置/颜色DirectionalLight 变换和颜色)
- [低频]本地VRM信息
- [低频]远程VRM基本信息
- [低频] 选项字符串
- [低频]背景色
- [低频]窗口属性信息
- [低频]加载设置路径
- 通过信息
### 根骨骼变换
```json
v2.0
/VMC/Ext/Root/Pos (string){name} (float){p.x} (float){p.y} (float){p.z} (float){q.x} (float){q.y} (float){q.z} (float){q.w}
v2.1
/VMC/Ext/Root/Pos (string){name} (float){p.x} (float){p.y} (float){p.z} (float){q.x} (float){q.y} (float){q.z} (float){q.w} (float){s.x} (float){s.y} (float){s.z} (float){o.x} (float){o.y} (float){o.z}
```
p=位置 q=旋转(四元数) s=MR 合成的比例 o=MR 合成的偏移
作为模型根的对象的绝对姿势
名称固定为“root”。 建议将
前半部分视为Position后半部分视为接收侧Loal姿势的四元数以与Bone匹配
从 v2.1 开始,添加了 MR 合成的比例。
通过使用它,可以将虚拟人物的位置和大小调整为实际的身体尺寸。
### 骨骼变换
```json
/VMC/Ext/Bone/Pos (string){name} (float){p.x} (float){p.y} (float){p.z} (float){q.x} (float){q.y} (float){q.z} (float){q.w}
```
作为模型根的对象的局部姿势名称
是UnityEngine沿HumanBodyBones的类型名称
前半部分是Position后半部分是Quaternion
所有 HumanBodyBone 都将被发送。还包括 LastBone。 这还将传输手指运动和眼骨。
## UE Remote Control
https://docs.unrealengine.com/5.1/en-US/remote-control-for-unreal-engine/