前面的篇幅中,我们介绍了PhysX SDK升级过程中需要注意的模拟和碰撞过滤方面的问题,这一篇中,我们介绍物理引擎另一大常用功能--场景查询(Scene Query)--的改进和升级中需要注意的问题。
在2.8和3.2中,PhysX SDK的场景查询都可以分为三大块的功能:raycast,overlap和sweep检测。Raycast检测即射线检测,把一个点沿着一个方向投射出去,看看能够射中哪些物体。Overlap检测是嵌入检测,以一个几何形体为查询单位,查找场景中与其有重叠的物体。Sweep检测与Raycast类似,不同的是,投射出去的不是一个点,而是一个几何形体。虽然提供的功能类似,但是从API和实现来看,2.8和3.2在这一方面还是有一下几点不同:
第一,对于Raycast和Sweep检测,当起始位置在某个物体的几何空间之中时,2.8中是没有定义结果应该是如何的,不同的API可能返回这个物体,也可能不返回;但是在3.2中,这种情况该如何处理,SDK给出了明确的定义:
对于Sweep检测,新增了标志位PxSceneQueryFlag::eINITIAL_OVERLAP 让开发者可以定义如何来处理这样的情形。
对于Raycast检测,对于检测到的不同的几何形体,有着不同的行为定义,具体可以参看SDK专门介绍SceneQuery的文档,里面有表格定义了各种情形下的返回结果。
第二,3.2 的API接口更简洁明了。在2.8中,PhysX SDK对各种几何形体的抽象应用不充分,因此每一种检测,都会有好几个API接口,比如Overlap检测,我们就能看到:overlapAABBTriangles,overlapSphereShapes,overlapAABBShapes,overlapOBBShapes,overlapCapsuleShapes,checkOverlapSphere,checkOverlapAABB,checkOverlapOBB,和checkOverlapCapsule等好些API。但是在3.2中,只有两个:overlapAny和overlapMultiple,这两个API都以对基本几何形体的抽象类PxGeometry作为参数,结合返回值和其他参数,很大程度上减少了 API的数量繁多带来的复杂性。
第三,对于需要多个结果的检测API,返回结果由SDK分配内存改为由用户分配。在2.8中,PhysX SDK对于这种检测API的实现,是自己保留检测结果,然后将这些检测结果通过调用回调函数的方式返回给程序。各种场景检测的API在实际游戏中是非常常用的API,这样的做法,SDK需要频繁的分配和销毁临时内存,难免带来性能上的损耗。
在3.2中,PhysX SDK选择了改成让开发者给定内存的方式,把内存管理的自由,开放给开发者来决定:在调用API时,需要预先分配一个buffer,并且告诉SDK这个buffer的大小,如果实际结果超过了buffer的容纳范围,在返回-1,提示需要更多的空间;如果buffer足够,则返回全部结果。这样,程序中调用这类API的时候,就可以尽量共用这样的buffer,节省性能。只有一点我们需要注意,就是要根据我们程序的实际测试结果,确定一个合适的buffer大小,以及buffer不够用需要增大时的增大方式。
希望能够通过上面的介绍,让大家更了解 PhysX SDK 3.2中的场景查询功能跟2.8相比的改变,更合理的使用新PhysX版本中的场景查询功能。