« 会抽到自己的那张吗? | 返回首页 | 推荐一下 bbLean »

3d 引擎中对场景数据的接口设计

目前是我第一次设计 3d engine ,虽然主要贡献 3d 方面代码的同事不是第一次做了。我们做了两年多,大方向上是我在把握设计。但是毕竟是没有什么经验,也就老在修改。

这个周末再审以前做的东西,觉得接口上还需要调整一下。比如精灵的控制接口、摄象机的控制接口、场景描述的接口等等。以一个游戏开发人员的角度来看,我需要接口是什么样子的?

我希望是最方便的描述虚拟世界中各样东西的相互关系,引擎当隐藏住不必要的细节,比如 3d 方面的数学知识,专业化的术语,复杂的坐标转换等等。今天写下这些,不是定论,而是做些思考的记录。

我想知道,对于 3d 引擎的使用人员,如何描述虚拟场景,暴露出怎样的接口是比较合适的。

对于我们的游戏,和大多数游戏,角色在场景中的坐标是二维而不是三维的。就好象描述你在地球上的位置,大体上经纬度就够了,只有在需要更在很复杂的场景中(比如一栋高楼中),再加上一个离地面的高度。

这里,我们取的都是离地面的高度,而不是相对地心的。所以你站在南极比站在赤道上离地面更近,或是站在拉萨的街道上比站在上海的商场里离地心更远,都是不需要考虑的事情。

高度这个维度,远不需要经纬度的精度高。在一些需要得到高度信息的位置,比如我们在高层建筑里,只需要说自己在第几层。而在小河边,则只需要了解在桥上还是桥下。因为大多数情况下, 人必须脚踏实地。

最终,我需要 3d engine 加载完场景数据后,使用它时,只需要设置经纬度,就可以把一个物件放置在那里了。默认情况下,物体总是紧贴地面的。如果需要让物体悬浮在空中,我们只需要外加一个高度属性,这个属性的值描述了物体相当当前经纬坐标上的地表的高度值。

当同一个经纬坐标上,有多层地表怎么办?解决方法是分层表示。地面可分成多个层面。举个例子,有一条河,两岸之间架了一座桥。这样一个场景当被分成三个层面。

两岸及河床是第一层,水面是第二层,桥面是第三层。

当河水干涸的时候,水面一层消失,退化成两层。(通常在建模的时,岸边和河床就是一体的,水是额外做上去的)

人从岸边上桥,就从一个层跨越到了更高的层,这个跨越线,可以额外标注出来。

同样,从岸边下水,也是一个跨层的过程,同时触发游泳的事件。从水面下潜,也有类似的过程。

根据逻辑需要,引擎还应该提供层与层之间的高度换算。比如桥面的高度相当于从水面计算的高度值。

那么空中的物体如何计算?方法是,提供一个零层,这个层面一定是在欧式几何空间中保持水平的。(当然如果想做一个球面的游戏,这个层面也可以是球形的)浮在空中的物体可以依据这个来换算坐标。

我们还需要引擎提供同一层面上每个经纬坐标点上的法向量值,或是两个不同点之间相对零层面的高度差(这个值可以通过上面的方法换算得到)。这个用途之一是为了处理四足动物的摆放。

不是每个层面的任意坐标点上都有有效的法向量的,比如一座桥,桥面以外的空间在它那个层面上都是无效的。如果命令物体移动到无效的位置上,我们可以知道该物体会发生坠落,掉到下个层面上。或是简单的阻止这样干。所以这个信息还可以用于描述阻挡物。


大多数情况下,我们并不需要精确的描述物体的坐标。正如我们在现实生活中,除非手持 GPS 设备,否则很少用经纬度来汇报自己的方位。我们只需要知道什么在什么的附近就够了。所以确定位置通常是编辑器做的事情,而游戏逻辑只用知道物体在哪个地点。

坐标值通常只用在描述和计算物体运动的过程里面。存在于比较低阶层次的接口上。

尽量脱离坐标值本身,我们也不必太在意坐标是二维量,还是一个三维量;物体在空间中的状态,是用一个向量表示、还是一个矩阵,或是四元数等等。我们也就隐藏了引擎是 3d 还是 2d 或是所谓 2.5D 这些细节了。

最后的目标就是,用图象引擎提供的接口来描述物体和物体之间的关系,而不是单个物体在空间中的绝对位置。应该抽象出哪些接口供开发者使用,还需要再斟酌一下。

Comments

如果我在飞怎么办?

文中讨论过了。

如果我在飞怎么办。以水平面做参考可能更恰当点

最近看云风的书,里面写的你比较倾向用C++做游戏项目的,什么时候又转C了呢?什么原因?

云风也作 3D 了.

虽然简化的接口会带来很大的方便,但个人认为也不能太过于个性化。也许你觉得符合生活规律的描述(不适用坐标等)不错,但别忘了你的用户的思维方式可能还是坐标的,他习惯用他的方式来进行设计、构思。除非你能100%保证这套接口满足所有的需求,否则这样的设计肯定会带来很大的非议,也会给使用者带来不必要的麻烦。
实际上,我现在正是在饱受底层模块设计则过于强调简化,从而脱离模块本性的接口设计,带来的上层变化限制的痛苦。就好像我经常说的,他们这简直是在强奸需求!
当然了,也许云风有能力设计出这么一套更完善的抽象,或者说这个抽象并不是云风设计的,而是人类多年以来生活总结的抽象。不过考虑到程序员的思维,这个过程显然会困难重重。

如果你特定所以物体不会飞行,那么用2维坐标已经够了,但是这样设计,就需要额外记录其他的信息,例如你在一座建筑物里,只提供了XY,那么你必须再记录你在第几层。OK,你没有室内场景,你在室外,那么当你在一条河里,头上又有一座桥,那么你要记录你是不是在桥上……

虽然简化了高度,但是带来其他不必要的开销,当然特定的世界,用特定的方法简化是最好的,不过泛三维世界还是用三维坐标来的更方便。

当然,只是一点看法,无谓正确与否。

比如:你在为一个对像设计它的成员接口时,这个函数的所有位置信息都是以对像空间来衡量的,当然不能是以绝对世界坐标来衡量的.

这个其实没有必要花太多的心思,用面像对像的方法就可以去解决了.每个对像都有一个在世界空间的绝对位置,而被这个对像的包裹框圈住的小对象,只要以父对像的相对位置表示就行了.世界完全可以用大对像包含小对象,对象又包含更小对像来且示就OK了.在游戏里面,人物具体进入哪个物体,都是很容易知道的,只要是进入了这个物本,那么人物的位置就是相对于这个物体来计算的.

当某个层的高度变化较大时,这个层就不是很典型了,这时还是用一个高度值描述更直接。

windows编程里面的hwnd要用x、y指定绝对位置,而在wxWidgets、IUP、GTK等GUI框架里,可以用类似hbox、vbox、zbox的方式来描述布局

本文正是探讨如何在更 3d 的游戏中,更好的表达。

就跟相对论需要依托黎曼几何去解释一样,虽然黎曼几何空间可以和欧式几何空间做数学上完全等价的转换,但离开了黎曼几何,相对论就变的很难理解和运用。

在一个更 3d 的游戏里,我们也需要一个更贴切的描述方法。

现在的3D要上能飞天,下能游海。越来越往3~~~~~~~D的方向发展了。所以角色在场景中的坐标会越来越三维。

Post a comment

非这个主题相关的留言请到:留言本