角色控制器(CCT)SDK是一个构建在PhysX SDK基础之上的外部组件,拥有和PhysXExtensions类似的机制
CCT可以有多种实现方式:PhysX只实现其中一种。
从本质上讲,CCT通常是基于游戏定制化的,并且它们在每个游戏中具有一些独具的功能。 例如,角色的包围体在一个游戏中是胶囊体,而在另一个游戏中可能是倒金字塔形。 CCT无法提供一种通用的为所有的游戏提供可能的解决方案。 但它提供了对所有CCT来说基本的功能:角色控制和角色互动。 对用户来说这是起点,也是可以以后根据需要进行修改或自定义的基础。
PhysX CCT是一个运动控制器。通常,角色控制器可以是运动学的也可以是动态的。运动控制器直接通过输入位移向量(第一控制序列)来工作。动态控制器通过输入速度(第二控制序列)或力(第三控制序列)来工作。
过去,游戏普遍没有使用像PhysX SDK这样的基于“真实”的物理引擎。但他们仍使用一个角色控制器来移动一个场景中的玩家。例如Quake或Doom,都有专门的定制的代码片段来实现碰撞检测和响应,通常这是整个游戏中唯一的物理相关代码。它实际上几乎没有物理特性,但是有许多经过仔细调整的值来提供操作角色的良好体验。其特殊之处在于实现了通常被称为“碰撞滑动”算法,并且已经“调整了超过一个世代”。 PhysX的CCT模块是这种算法的实现,为角色控制提供了强健且熟知的行为。
运动控制器的主要优点是它们不会受以下问题困扰,这些问题通常适用于动态控制器:
(缺乏)连续碰撞检测:典型的物理引擎使用离散碰撞检查,导致多年来困扰各种商业和非商业物理引擎的臭名昭着的“隧道效应”。隧道效应导致几个主要问题:
总而言之,运动控制器是花费大量精力来调整和禁用物理引擎的功能,来以一个不太复杂模拟方式实现了定制代码。 那么自然地会继续使用这个代替方案。
首先,在应用程序的某个位置创建一个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移动到安全的地方,使其不再与其他物体重叠。这只对重叠的静态对象有效,会忽略动态对象。
使用函数打开或关闭重叠恢复模块
void PxControllerManager::setOverlapRecoveryModule(bool flag);
默认情况下,角色控制器使用精确的扫描测试,其精度通常足以避免所有穿透 - 只要接触偏移不是太小。 因此,在大多数情况下,不需要重叠恢复模块。 使用它时,可以使用以下功能将扫描测试切换为不太准确但可能更快的版本:
void PxControllerManager::setPreciseSweeps(bool flag);