历尽艰难跑起来了,问题是没有办法操作,猜测Ubuntu和windows的操作代码不兼容,代码分析部分的主要目标之一就是把操作改掉:
代码结构分析
一切从main函数开始:
-
首先是SDL初始化,Simple DirectMedia Layer(SDL) is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D. 可以说是一个常用的跨平台opengl支持库。
这边就是想到应该不会是操作兼容性的问题导致不能动,一看代码原来是只支持手柄。
可惜的是,windows平台上面跑起来好卡,感觉帧率小于10帧!
-
GLEW初始化
-
资源加载
-
Options 里面定义的是一些我们可以修改的设置选项:
-
CameraOrbit 则是相机初始化设置
-
LightDirectional 场景光照初始化设置
这里就是一堆GL设置
-
Character 角色初始化设置
这部分是这里的角色的定义信息和加载,这部分很重要!
首先我们来看一下存储的角色数据的文件包涵下面四个,坑爹的采用了二进制存储:
顶点,三角形,父子关系,xforms信息分别四个文件。
读文件的函数这边也很简单,将数据直接存进对应的容器,角色数据结构信息如下:
这部分最后就是一个前向动力学的实现,这个很简单,就是子类跟着父类运动。
-
Trajectory 路径初始化设置
这里就是定义了运动路径的数据结构,如下所示:
-
IK 初始化设置
Ik数据结构如下所示:
这里还提供了一个two_joint函数,这个后面用到再讲,因为暂时也看不出来其功能。
-
Shader 相关
这部分就是加载shader的函数,并将其运用到opengl
-
Heightmap 高度图初始化设置
这边主要来看一下高度数据的读取和存储
高度文件数据示例,包括两个文件:
Load()函数就是一个一个读取float存储在 vector<vector<float>> data 里面:
xxx.txt 信息就是用来生出 data,xxx_ao.txt 信息则是用来生出 vbo/tbo(坐标,颜色等信息);vbo_data/tbo_data(索引坐标信息)。
-
Areas 区域初始化设置
这部分的数据结构如下:
-
PFNN模型
模型的加载和初始化,首先来看其数据结构:
ArrayXf 这个数据结构是Eigen下面存储 float array的结构。Load函数底下就是加载的文件,很多很多文件啊!
我们来看上图所示的文件结构就可以发现,pfnn这个网格模型相关的数据内容,主要包含的就是网络模型和角色。
-
加载游戏世界
load_world 这些函数,目前来看这些函数里面主要是在做地形标记,所以来说这程序跑起来需要做的地形标记?
-
-
Game Loop 部分
-
Input处理
目前只支持手柄,SDL包含跨平台的输入交互模块,细节不解释,见下图
但事实上不是所有的交互都在这里,在渲染那边很多的主要操作都是直接写在渲染的部分的,但都是用了SDL接口。
-
渲染
一共包含前处理,渲染处理,后处理三部分,我们分别来看。
-
前处理
-
更新相机(直接按键确定)
右手柄摇杆控制相机旋转,LR控制zoomin/zoomout,然后直接作用于相机参数。
-
更新目标方向和速度(直接按键确定)
这部分也是直接响应按键输入,按键就确定了用户期望的目标方向和速度。
-
更新步态(算法数据前处理第一步)
通过上一时刻的 trajectory 参数 和 options 参数来确定当前时刻 trajectory 的参数。
-
预测未来的 Trajectory(算法数据前处理第二步)
通过上一步获得的 trajectory 参数 和 character 参数,来混合获得 trajectory_positions_blend 这个对象
-
碰撞处理(算法数据前处理第三步)
根据 areas 的 walls 的信息,来调整 trajectory_positions_blend 的值。
在这里,又做了一步将 trajectory_positions_blend 的值写回 trajectory。
-
跳跃(算法数据前处理第四步)
根据 areas 的 jump 的信息,来调整 trajectory 的值。
-
Crouch 区域(算法数据前处理第五步)
根据 areas 的 crouch_pos 的信息,来调整 trajectory 的值。
-
墙(算法数据前处理第六步)
根据 areas 的 walls 的信息,来直接调整 trajectory 的值。
-
Trajectory 旋转(算法数据前处理第七步)
trajectory->rotations 的值调整
-
Trajectory 高(算法数据前处理第八步)
根据 heightmap 的值来调整 trajectory 的值
-
输入的 Trajectory 位置方向(pfnn输入内容第一步)
由 Trajectory 信息来获得 pfnn->Xp
-
输入的 Trajectory 步态(pfnn输入内容第二步)
由 Trajectory 信息来获得 pfnn->Xp
-
输入的 当前的 Joint 位置速度和旋转角度(pfnn输入内容第三步)
由 Trajectory 信息来获得 pfnn->Xp
-
输入的 Trajectory 高度(pfnn输入内容第四步)
由 Trajectory 信息来获得 pfnn->Xp
-
Perform Regression 【核心步骤:模型predict】
上面在设置的是pfnn的参数,而这里还需要设置的是predict函数的传入参数,是character->phase
- 时间处理,这一步就是计算一下predict时间,debug用。
-
Build Local Transform(pfnn输出)
这一步就是运用pfnn的输出结果,来获得角色每个关节的position/velocity/rotation
这里还需要的一步就是上面得到的关节数据是世界坐标,要转换到局部坐标。
-
IK 处理
这一步就是对上面获得的关节数据,一个一个的应用到角色的IK关节!
渲染处理
- Render Shadow
- Render Terrain
- Render Character
- Render the Rest
- Render Crouch Area
- Render Jump Areas
- Render Walls
- Render Trajectory
- Render Joints
- UI Elements
- PFNN Visual
- Display UI
这里都是opengl使用,和AI数据的使用无关,就不在赘述。
后处理
-
Update Past Trajectory
Trajectory 数据传递更新
-
Update Current Trajectory
Trajectory数值计算更新
-
Collide with walls
Trajectory 碰撞更新
-
Update Future Trajectory
Trajectory 依据 pfnn结果来做更新
-
Update Phase
-
Update Camera