从零开始手敲次世代游戏引擎(三十八)

从零开始手敲次世代游戏引擎(三十七),本篇我们来进行物理引擎的一些基本探讨。
最后执行的效果如下:
视频封面

上传视频封面

场景的创建
首先我们使用Blender来创建一个测试用的场景。这个场景很简单,由一个平面和两个球体组成。布置好之后,可以切换到摄像机视角看一下位置:
视频封面

上传视频封面

接下来我们用GIMP创建地板的贴图。创建一个空白的512×512的图像,然后用滤镜加入彩色的噪点,再用一个马赛克滤镜将其转化成为彩色蜂窝状的马赛克拼接就可以了。将其保存为TGA图片,放到贴图目录当中。
视频封面

上传视频封面

然后我们再回到Blender当中,为平面指定这个图片作为贴图。注意如果贴图出现错位现象,需要修一下UV。
视频封面

上传视频封面

好了,将场景导出为OGEX文件,然后用文本编辑器修改一下OGEX当中的贴图路径。(因为导出的路径为绝对路径,而我们的引擎需要相对路径)
导入物理仿真库
在游戏当中有两类常用的物理计算:
  1. 碰撞
  2. 运动学(力学)
在详细讨论这些之前,我们先导入一个在业界比较有名的,也是比较成熟的库来建立一些感性认识。
参考引用*1是一个名为Bullet的物理仿真库,是由原SIEA(索尼互动娱乐美国)的员工写的并作为开放源码项目在GitHub上面提供。因为它也是采用了CMake的编译系统,所以我们可以很容易地将其导入到我们项目当中。具体细节这里就不赘述了,感兴趣的可以直接看本章对应的源码当中build_bullet脚本。
编写PhysicsManager
为了管理物理仿真,我们在我们的引擎代码的Framework/Common下面新建PhysicsManager的源代码,将Bullet的初始化/销毁以及创建物理仿真用场景的代码进行包装。
在PhysicsManager的Tick事件处理代码当中,我们从之前写的SceneManager那里获取需要渲染的场景结构,对于其中的每个SceneNode进行检测,看看是否需要进行物理仿真:如果需要,我们使用Bullet创建一个刚体模型(含碰撞盒),将其绑定到对应的SceneNode上面,并将其加入到物理仿真场景(DynamicsWorld)当中去。然后我们通过调用DynamicsWorld的stepSimulation,计算下一个1/60秒的仿真结果。
仿真结果的反映
在渲染时,我们同样从SceneManager获取所需要渲染的场景结构,遍历所需要渲染的SceneNode并检测其是否绑定了刚体模型。如果绑定了刚体模型,则我们使用存储在刚体模型当中的最新仿真结果更新SceneNode的Transform(也就是空间位置与姿态)。这样我们仿真的结果就会在渲染的结果当中反映出来了。
其它
因为Blender当中也集成有Bullet,本来我是想直接在Blender当中绑定物理模型并直接导出的,但是目前最新的OGEX(2.0)似乎还不支持物理模型的导出。所以我就自己利用OGEX的Extension自定义结构对OGEX进行了一点儿简单的扩展,使其可以支持物理模型。
不过我目前还没有对Blender的OGEX导出脚本进行修改,因为我还不了解Blender的Python接口。所以写这篇文章的时候我是通过文本编辑器直接编辑OGEX文件(Asset/Scene/physics_1.ogex)加入了这些扩展属性。
如之前文章下面有读者评论的,业界其实用得比较多的场景导出格式是COLLADA。之后等我们支持了COLLADA之后,这些问题也自然解决了。所以目前我不准备在这方面花太多精力。
另外,因为这个场景很简单,整个仿真很快就结束了,不太容易观察,所以我修改了前一篇所写的InputManager,加入了“按下R键重置场景”的功能。也就是说,按下键盘上的R键就可以重新载入场景进行仿真。
最后完成的代码在:
图标
参考引用
图标
图标
图标
图标
图标
图标

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

您正在使用您的 WordPress.com 账号评论。 注销 /  更改 )

Facebook photo

您正在使用您的 Facebook 账号评论。 注销 /  更改 )

Connecting to %s

%d 博主赞过: