PhysX3.4文档(16) -- Character Controllers

Character Controllers


Introduction


角色控制器 (CCT) SDK 是构建在 PhysX SDK 之上的外部组件,其方式类似于 PhysXExtensions

CCT 可以通过多种方式实现:CCT module 中的 PhysX 实现只是其中之一。

从本质上讲, CCT 通常是针对特定游戏的,并且它们可以在每个游戏中具有许多独特的功能。 例如,角色的边界体积在一个游戏中可能是一个胶囊,而在另一个游戏中可能是一个倒金字塔。 CCT SDK 并不试图提供一种适用于所有可能游戏的开箱即用的解决方案。 但它提供了所有 CCT 共有的基本功能:角色控制(character control)和角色交互(character interactions)。 它是用户的默认起点,是一个可以构建的强大基础,可以在以后根据需要进行修改或自定义。

Kinematic Character Controller


PhysX CCT 是一个 kinematic controller。传统上,角色控制器(character controllers)可以是 kinematic 的或 dynamic 的。运动控制器直接处理输入位移向量(displacement vectors)(1st order control)。dynamic controller 与输入速度(2nd order control)或力(3rd order control)一起工作。

过去,游戏并没有使用像 PhysX SDK 这样的“真实”物理引擎。但他们仍然使用角色控制器在关卡中移动玩家。这些游戏,比如 Quake 甚至 Doom,都有专门的、定制的代码来实现碰撞检测和响应,这通常是整个游戏中唯一的物理部分。它实际上几乎没有物理特性,但有很多精心调整的值,以在控制玩家的同时提供良好的感觉。它实现的特定行为通常被称为“collide and slide”算法,并且已经“tweaked for more than a decade”。 PhysX CCT 模块是此类算法的实现,为角色控制提供了稳健且众所周知的行为。

kinematic controllers的主要优点是它们不会遇到以下问题,这些问题对于dynamic controllers来说是典型的:

  • (缺乏)连续碰撞检测:典型的物理引擎使用离散碰撞检查,导致臭名昭著的“tunneling effect”,多年来一直困扰着各种商业和非商业物理包。 这导致三个主要问题:

    • tunneling effect:如果角色走得太快,它可能会穿过墙壁
    • 因此,角色的最大速度受到限制(因此也限制了游戏的可能性)
    • 即使它没有tunneling,例如在角落里向前推时,角色可能会抖动,因为物理引擎不断将其前后移动到略有不同的位置。
  • 没有直接控制:刚体通常由脉冲或力控制。 通常不可能将其直接移动到其最终位置:相反,必须将位置变化向量转换为脉冲力/力来应用它们,并希望角色最终到达所需位置。 这并不总是有效,特别是当物理引擎使用不完美的线性求解器时。

  • 摩擦问题:当角色站在斜坡上时,它不应该滑动。所以这里需要无限摩擦。可是当角色在同一个斜坡上向前移动时,它不应减速,这时又不需要任何摩擦。同样,当角色靠墙滑动时,它也不应该放慢速度。因此,对于 CCT,摩擦通常为 0 或无穷大。不幸的是,物理引擎中的摩擦模型可能并不完美,很容易以少量摩擦(角色减速一点)或非常大但不是无限大的摩擦(无论人为的摩擦参数有多大,角色在该斜坡上的滑动速度都非常缓慢)。斜坡的相互矛盾的要求也意味着通常根本无法完美地模拟所需的行为。

  • restitution 的问题:通常,对于 CCT 应避免 restitution 。当角色快速移动并与墙壁碰撞时,它不应弹开。当角色从高处坠落并着地时,弯曲双腿,应防止任何弹跳。但是再一次,即使 restitution 完全为零,物理引擎仍然可以造成 CCT 轻微反弹。这不仅与线性求解器的不完美本质有关,还与典型的基于穿透深度的引擎如何从overlap情况中restitution有关,有时会施加过多的力将对象分开太多。

  • 不希望的跳跃:无论 physical behavior 应该是什么,角色必须经常粘在地上。例如,动作游戏中的角色往往以不切实际的速度快速移动。当他们到达坡道顶部时,物理引擎通常会让他们跳跃一点,就像一辆快速的汽车在旧金山的街道上跳跃一样。但这通常不是想要的行为:相反,角色应该经常粘在地面上,而不管其当前的速度如何。这有时是使用固定关节来实现的,但对于使用运动控制器可以轻松避免的问题,这是一种不必要的复杂解决方案。

  • 不希望的旋转:一个典型的角色总是站着,从不旋转。然而,物理引擎通常对这种约束的支持很差,并且通常会付出很大的努力来防止角色周围的胶囊掉落(它应该始终在其尖端站立)。这通常是使用人工关节(artificial joints)来实现的,由此产生的系统既不是很健壮也不是很快。

总而言之,可以花费大量精力来调整和禁用物理引擎的功能,只是为了模拟不太复杂的自定义代码。 继续使用那段简单的自定义代码是很自然的。

Creating a character controller


首先,在应用程序中的某处创建一个 controller manager。 该对象跟踪所有创建的 controller ,并允许来自同一manager的角色交互。 使用 PxCreateControllerManager 函数创建管理器:

PxScene* scene;    // Previously created scene
PxControllerManager* manager = PxCreateControllerManager(*scene);

然后,为游戏中的每个角色创建一个 controller 。 在撰写本文时,仅支持盒 (PxBoxController) 和胶囊 (PxCapsuleController)。 例如, capsule controller 是这样创建的:

PxCapsuleControllerDesc desc;
...
<fill the descriptor here>
...
PxController* c = manager->createController(desc);

manager 类将跟踪所有创建的 controller 。 可以使用以下功能随时检索它们:

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

要释放 character controller ,只需调用它的释放函数:

void    PxController::release() = 0;

要一次释放所有创建的 character controller ,请释放 manager 对象本身,或者如果您打算继续使用 manager ,则使用以下函数:

void    PxControllerManager::purgeControllers() = 0;

SampleBridges 中说明了 controller manager 及其后续 controllers 的创建。

Overlap Recovery Module


理想情况下,不应在初始 overlap 状态下创建角色,即它们应创建在不与周围几何体重叠的位置。 在创建角色之前,可以使用各种 PxScene overlap functions 来检查所需的空间体积是否为空。 默认情况下, CCT 模块不检查重叠本身,并且创建最初与world's static geometry重叠的角色可能会产生不希望的和未定义的行为 - 例如角色穿过地面。

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

overlap rec

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值