反向解析PivotPainter2
轴点动画的核心就一个

绕轴旋转。
所以我们要准备好需要的数据。
- 需要绕哪个轴旋转?
- 旋转的角度?
- 轴点在哪个位置?
- 当前顶点位置
最基础的绕轴旋转是这样的:



所以回到PivotPainter,就是得到这几个数据。
需要绕哪个旋转轴?
旋转轴向(RotationAxis)数据主要是通过风向数据来控制主要方向,外加一个噪声做一些角度偏移。
旋转轴向为风向与当前轴点轴向的叉乘。

这里大家可能有点疑问为什么 风向要加上一个 (0,0,-0.2)*pow(dot(XAxis,WindDirectionXAxis),5)
其实这是模拟风与轴向完全水平的状况下,让风向稍微往下吹模拟植物收到重力被风吹的点头的效果。
外加一个扰动的噪声轴向

旋转的角度大小?
旋转的角度由好几个因素影响
- 风力图的影响
- 父物体旋转
- 风向与轴向的角度(可选)
- 当前点在轴向上与轴点的距离,占这个轴向总长度的多少。(相当与离根部越近,偏移越小)

轴点位置?
当前顶点的轴点位置烘焙到贴图(Pos&ID Tex)中,通过UV1直接采用即可获得

数据准备
现在知道旋转所需要的各个参数怎么得到的。刚好说到顶点的轴点位置烘焙在贴图(Pos&ID Tex)中,那么我们需要准备的数据共有哪些呢?分别有什么用处?
需要准备的数据一共有:
- 轴点位置与ID贴图(RGB::Pos & A::ID)Tex
- 轴向方向与轴长度贴图(RGB::XAxis & A::XExtent)Tex
- 树Mesh UV1对应数据贴图采样。
这只是推荐数据格式,实际想怎么编码数据和用UV(N)采样都行。
这里比较重要的是ID数据,这关系到物体的层级结构,UE里面写的很绕。
ID数据主要是为了我们重构层级关系。
层级关系重构
通过贴图解析父级UV
在数据编码阶段,ID或者说Index 代表自身父物体在贴图中的位置。如果没有上一级父物体了那么ID就是自身ID(Current Id = Parent Id)

当前UV转换为当前Id
当前UV采样(Pos&ID)贴图,得到父物体Id,父物体Id转换得到父物体UV,并且通过判断(Current Id = Parent Id)来确定自身还有没有上一级(IsChild=0 or 1)。
因为最多UE最多支持的层级只有4级,重复寻找父物体操作三次即可。

因为输入UV的类型情况总共只有4种:主干、主分支、次分支、叶子
所以我们直接把每种情况对应的结果都展现出来
当输入为主干Mesh:
Level1UVs为主干UV、Level1Index为主干Index,因为主干上面没有父物体了,父物体Index就等于自身,所以
- Level1Index=主干Index,Level1UV=主干UV
- Level2Index=主干Index,Level2UV=主干UV,Level2Child=0;
- Level3Index=主干Index,Level3UV=主干UV,Level3Child=0;
- Level4Index=主干Index,Level4UV=主干UV,Level4Child=0;
当输入为主分支Mesh:
Level1UVs为主分支UV、Level1Index为主分支Index,主分支有一级父物体
- Level1Index=主分支Index,Level1UV=主分支UV
- Level2Index=主干Index,Level2UV=主干UV,Level2Child=1;
- Level3Index=主干Index,Level3UV=主干UV,Level3Child=0;
- Level4Index=主干Index,Level4UV=主干UV,Level4Child=0;
当输入为次分支Mesh:
Level1UVs为次分支UV、Level1Index为次分支Index,主分支有两级父物体
- Level1Index=次分支Index,Level1UV=次分支UV
- Level2Index=主分支Index,Level2UV=主分支UV,Level2Child=1;
- Level3Index=主干Index,Level3UV=主干UV,Level3Child=1;
- Level4Index=主干Index,Level4UV=主干UV,Level4Child=0;
当输入为树叶Mesh:
Level1UVs为次分支UV、Level1Index为次分支Index,主分支有两级父物体
- Level1Index=树叶Index,Level1UV=树叶UV
- Level2Index=次分支Index,Level2UV=次分支UV,Level2Child=1;
- Level3Index=主分支Index,Level3UV=主分支UV,Level3Child=1;
- Level4Index=主干Index,Level4UV=主干UV,Level4Child=1;
确认当前层级以及分配层级数据
通过判断Level2Child、Level3Child、Level4Child的总和(LevelDepth),我们就可以轻松的知道当前顶点处于哪一级层级。

这段逻辑便是通过当前LevelDepth来确定,当前层级需要运算哪些Level(LevelMask为0不运算),以及对应Level对应的UV。
Lerp_Multiple_Float2函数逻辑:

结合上面的通过贴图解析父级UV可得:
当输入为主干Mesh:
因为是主干Mesh,所以可以得知LevelDepth为0,那么
- Level1PivotUVs=Level1UV ;Level1UV=主干UV
- Level2PivotUVs=Level1UV,Level2Mask=0;
- Level3PivotUVs=Level1UV,Level3Mask=0;
- Level4PivotUVs=Level1UV,Level4Mask=0;
当输入为主分支Mesh:
LevelDepth为1
- Level1PivotUVs=Level2UV;Level2UV=主干UV
- Level2PivotUVs=Level1UV,Level2Mask=1;Level1UV=主分支UV
- Level3PivotUVs=Level1UV,Level3Mask=0;
- Level4PivotUVs=Level1UV,Level4Mask=0;
当输入为次分支Mesh:
LevelDepth为2
- Level1PivotUVs=Level3UV;Level3UV=主干UV
- Level2PivotUVs=Level2UV,Level2Mask=1;Level2UV=主分支UV
- Level3PivotUVs=Level1UV,Level3Mask=1;Level1UV=次分支UV
- Level4PivotUVs=Level1UV,Level4Mask=0;
当输入为树叶Mesh:
LevelDepth为3
- Level1PivotUVs=Level4UV;Level4UV=主干UV
- Level2PivotUVs=Level3UV,Level2Mask=1;Level3UV=主分支UV
- Level3PivotUVs=Level2UV,Level3Mask=1;Level2UV=次分支UV
- Level4PivotUVs=Level1UV,Level4Mask=1;Level1UV=树叶UV
这块逻辑挺绕的,前面是反着来,经过这步后就是正的顺序拉。
然后每个Level放入前面的绕轴旋转逻辑代码里面即可




这个MF_Ghis_PivotPainter2_Animation_SingleLevel里面最终要做的就是一开始说的绕轴旋转。

注意法线也需要绕轴旋转,只不过法线的的轴点为000而已,如果对应的LayerMask=0的话就不做任何操作。

