这里尝试非常多次还是没有办法对于里面的demo信息完整打开且没有报错,可以跑的demo。
因此我们在AIAnimation的基础上首先来看看这个工程怎么使用起来。
首先来看重点在角色,我们来看其角色的构造:
上面是两个demo的使用结构,可以看到就一个重要的csharp文件,我们来对比分析。
Original对应的是Siggraph17的内容,Adam对应的是Siggraph18的内容,我们先来看17。
首先看大的结构:
第二个类继承Editor对象,作用是在editor里面形成层级菜单Animation,其余的三个则是分别由另外的三个类来完成。
这三个对象也分别形成了三个子标签菜单项,如上面所示的图。
-
NeuralNetwork 这个类,里面只做了一件事情,就是让用户选择NN模型,也就是说这个类处理的是交互UI表现和逻辑,没有其他。NN里面应该包含的信息都在Model这个类里面。下图就是model里面存储的数据结构:
然后我们来看接口函数:
这边是为了兼容和扩展多种的NN方法设置的接口。
剩下的就是一些Tensor相关的函数,Tensor是对Eigen数据的封装,其真实的计算实现都是由Eigen实现的,这边同时提供了一堆的数据结构关联操作的方法。
最后model里面涉及的比较重要的内容就是Parameters,这边unity里面主要做的就是加载读取和存储方法。
- Controller 这个类,处理的是Input,主要就是WSADQE. 还有一个很重要的变量是Styles数组,记录的应该是状态权重。
- Character 这里做的就是驱动骨架运动。
而作为核心的中介数据 Trajectory 这个类,其就是一组数据点数组,并且包含对这个数组,单个点的操作方法。单个点的数据内容很丰富,包括各种变换和状态等:
所有的核心使用方法就是在Update函数里面,这边的做法应该是和AIAnimation里面是一模一样的,我们可以对比一下:
- 只有存在NN模型的情况下,才会执行下面的所有内容。
-
Update Target Direction / Velocity
这里做的就是:
TargetDirection = TargetDirection 与 Trajectory定义的当前位置 跟据 TargetBlending 权重混合。
TargetVelocity = TargetVelocity 与 Controller输入速度 跟据 TargetBlending 权重混合。
-
Update Gait
Trajectory.Points[RootPointIndex] 的每一个Style的值 = 当前值 和 用户是否点选了要成为该Style 跟据 GaitTransition 权重混合。
-
Predict Future Trajectory
预测的位置 = 当前位置和前一个位置的差值的延续 和 TargetPosition 差值获得
预测的style = 延续当前的style
预测的方向 = 当前的方向 和 TargetDirection 差值获得
-
Avoid Collisions
保证新的位置可靠,也就是考虑了碰撞。
-
Input Trajectory Positions / Directions
给NN.Model喂数据,Trajectory的每一个Point的位置和方向(都是xz轴值)
-
Input Trajectory Gaits
给NN.Model喂数据,Trajectory的每一个Point的Style数组
-
Input Previous Bone Positions / Velocities
给NN.Model喂数据,Joints的每一个关节的位置和速度
-
Input Trajectory Heights
给NN.Model喂数据,Trajectory的每一个Point的高度信息(y轴值)
-
Predict【利用模型运算】
-
Update Past Trajectory (轨迹上 i < RootPointIndex 的点)
更新Trajectory.Points[i] 的每一个点的信息:i位置=i+1位置的值(意思就是向前取一个点)
-
Update Current Trajectory(轨迹上 RootPointIndex 所在的点)
跟据NN的输出结果来构建一个新的点Trajectory.Points[RootPointIndex]的信息,设置其位置方向
-
Update Future Trajectory(轨迹上 RootPointIndex+1 < i < Trajectory.Points.Length的点)
每个点新的位置 = 每个点原来位置 + 当前方向 与 跟据模型输出值混合得到的距离和方向 差值(这边做了多重的影响差值考虑)
-
Avoid Collisions
同 5 做法一致
-
Compute Posture
positions、rotations两个数组存每一个joint的变换;
每个 positions[i] = NN返回结果 * 0.5 + 上一个位置按照上一个方向到达的这一个应该在的位置 * 0.5;
每个 Velocities[i] = NN返回的结果
-
Update Posture
每个joint的position,rotation直接取上一步数组中对应的值
-
Map to Character
transform应用在角色上面