PhysX4.0中文用户手册——角色控制器(一)

介绍

角色控制器(CCT)SDK是一个构建在PhysX SDK基础之上的外部组件,拥有和PhysXExtensions类似的机制

CCT可以有多种实现方式:PhysX只实现其中一种。

从本质上讲,CCT通常是基于游戏定制化的,并且它们在每个游戏中具有一些独具的功能。 例如,角色的包围体在一个游戏中是胶囊体,而在另一个游戏中可能是倒金字塔形。 CCT无法提供一种通用的为所有的游戏提供可能的解决方案。 但它提供了对所有CCT来说基本的功能:角色控制和角色互动。 对用户来说这是起点,也是可以以后根据需要进行修改或自定义的基础。

运动角色控制器

PhysX CCT是一个运动控制器。通常,角色控制器可以是运动学的也可以是动态的。运动控制器直接通过输入位移向量(第一控制序列)来工作。动态控制器通过输入速度(第二控制序列)或力(第三控制序列)来工作。

过去,游戏普遍没有使用像PhysX SDK这样的基于“真实”的物理引擎。但他们仍使用一个角色控制器来移动一个场景中的玩家。例如Quake或Doom,都有专门的定制的代码片段来实现碰撞检测和响应,通常这是整个游戏中唯一的物理相关代码。它实际上几乎没有物理特性,但是有许多经过仔细调整的值来提供操作角色的良好体验。其特殊之处在于实现了通常被称为“碰撞滑动”算法,并且已经“调整了超过一个世代”。 PhysX的CCT模块是这种算法的实现,为角色控制提供了强健且熟知的行为。

运动控制器的主要优点是它们不会受以下问题困扰,这些问题通常适用于动态控制器:

(缺乏)连续碰撞检测:典型的物理引擎使用离散碰撞检查,导致多年来困扰各种商业和非商业物理引擎的臭名昭着的“隧道效应”。隧道效应导致几个主要问题:

  1. 隧道效应本身的问题:如果角色走得太快,它可能会穿过墙壁。其后果就是角色的最大速度受到限制(因此也限制了游戏的可能性)。即使没有隧道效应,例如,当角色在角落被向前推动时,角色可能会产生抖动,因为物理引擎会一直来回移动到稍微不同的位置。
  2. 无法直接控制:刚体通常受冲量或力控制。通常无法将其直接移动到最终位置:而是必须将增量的位置向量量转换为脉冲或力,施加它们,然后希望角色处于最终所需的位置。这并不总是起效,特别是当物理引擎使用不完美的线性解算器时。
  3. 摩擦问题:当角色站在斜坡上时,它是不应该滑动的。所以这里需要无限大的摩擦力。当角色在同一个坡道上向前移动时,它不应该减速。这时不需要任何摩擦力。同样的,当角色沿着墙体滑动时,它也不应该减速。因此,对于CCT,摩擦通常要么为0,不么为无限。不幸的是,物理引擎中的摩擦模型并不完美,很容易最终得到很小的摩擦(角色一点点减慢)或非常大但非无限大的摩擦(无论认为施加的摩擦参数多么大,人物仍在斜坡上缓慢滑动)。对斜坡的冲突需求意味着通常根本无法完美地模拟所需的行为。
  4. 复位的问题:通常,CCT应该避免复位。当角色快速运动并与墙壁碰撞时,它不应该在墙上产生反弹。当角色从高处跌落并落地时,应该防止任何反弹。但是,即使复位完全为零,物理引擎依然可以使CCT产生一点反弹。这不仅与线性求解器的不完美性有关,而且还与通常引擎从基于穿透深度的重叠情况中恢复有关,有时会施加过多的力来将对象分开,从而产生复位问题。
  5. 不希望的跳跃:角色经常是必须贴在地上,无论物理行为是什么。例如,动作游戏中的角色往往以不切实际的速度快速移动。当它们到达坡道的顶部时,物理引擎经常会使它们产生一点跳跃,就像一辆飞快的小汽车在旧金山的街道上产生跳跃一样。但这通常不是想要的行为:相反,角色应该粘在地面上,而无论其当前的速度。这有时是使用固定铰链实现的,但如果使用运动控制器,就是一种防止该问题的不必要的复杂解决方案
  6. 不希望的旋转:通常角色总是直立而且从不旋转。 然而,物理引擎通常对这类约束的支持很差,并且经常花费很大力气来防止包围角色的胶囊掉落(胶囊体应该总是使用它的尖端站立)。 这通常使用人工铰链来实现,结果就是系统既不是非常强健也不是非常快。

总而言之,运动控制器是花费大量精力来调整和禁用物理引擎的功能,来以一个不太复杂模拟方式实现了定制代码。 那么自然地会继续使用这个代替方案。

创建角色控制器

首先,在应用程序的某个位置创建一个controller manager。 此对象跟踪所有创建的控制器,并允许来自同一管理器的角色对象可以相互交互。 使用PxCreateControllerManager函数创建manage:

PxScene* scene; // Previously created scene

PxControllerManager* manager = PxCreateControllerManager(*scene);

然后,在游戏中为每个角色创建一个controller,目前只支持boxes类型(PxBoxController)和capsules(PxCapsuleController)

创建一个capule的控制器如下

PxCapsuleControllerDesc desc;

...

<fill the descriptor here>

...

PxController* c = manager->createController(desc);

manager类可以保持对创建的controller的追踪,可以通过以下函数来获取controlle

PxU32 PxControllerManager::getNbControllers() const = 0;

PxController* PxControllerManager::getController(PxU32 index) = 0;

要释放一个角色控制器,可以使用这样的函数

void PxController::release() = 0;

要一次释放所有创建的字符控制器,请释放管理器对象本身,或者如果您打算继续使用管理器,请使用以下函数:

void PxControllerManager::purgeControllers() = 0;

SampleBridges中说明了控制器管理器及其后续控制器的创建。

重叠恢复模块

理想情况下,角色不应创建在初始就有重叠的环境下,即应在不与周围几何图形重叠的位置创建角色。在创建角色之前,可以使用各种PxScene重叠函数来检查所需的空间量是否有重叠。默认情况下,CCT模块本身不会检查重叠。在初始位置有和世界空间中的几何体重叠的地方创建一个角色,可能会产生不能预测行为 - 例如,角色通过地面。

但是,重叠恢复模块可用于自动校正角色的初始位置。只要发生重叠的数量合理,恢复模块就应该能够将角色重新定位到适当的无碰撞位置。

重叠恢复模块在其他几种情况下可能很有用。主要有三种情况:

  • 当CCT直接在另一个对象中被生成或传送到另一个对象时
  • 当CCT算法因FPU精度有限而失败时
  • 当“up向量”被修改时,使CCT发生旋转,造成CCT形状与周围的物体重叠

激活后,CCT模块将自动尝试解决穿透问题,并将CCT移动到安全的地方,使其不再与其他物体重叠。这只对重叠的静态对象有效,会忽略动态对象。

使用函数打开或关闭重叠恢复模块

void PxControllerManager::setOverlapRecoveryModule(bool flag);

默认情况下,角色控制器使用精确的扫描测试,其精度通常足以避免所有穿透 - 只要接触偏移不是太小。 因此,在大多数情况下,不需要重叠恢复模块。 使用它时,可以使用以下功能将扫描测试切换为不太准确但可能更快的版本:

void PxControllerManager::setPreciseSweeps(bool flag);

猜你喜欢

转载自blog.csdn.net/duotemplar/article/details/87891033