如果角色的骨架拥有未在 HumanIK 内的支持节点列表中直接映射的一个或多个关节,您仍可以使用 HumanIK 来控制角色,只要角色包含 HumanIK 所需的最少节点数。您的角色可能包含任意数量的这些未知其他关节。但是,由于 HumanIK 解算器是基于两足和四足骨架的某些预定义关节如何活动,以及角色不受支持的关节超出了 HumanIK 所了解的关节范围这样的内在知识进行计算的,因此,解算器无法直接平移或旋转不受支持的关节。
结果取决于您使用全局空间还是局部空间在 HumanIK 与游戏引擎之间交换动画数据。
当使用全局空间在 HumanIK 与游戏引擎之间交换动画数据时,可以支持其他未知关节,方法是将 HumanIK 解算器计算的位置和旋转用于其了解的节点(即在 HIKNodeId 枚举中列出的节点),并基于这些值为其他未知关节计算新的位置和旋转。
局部空间表达了每个节点相对于其父节点的平移、方向和缩放数据。尽管 HumanIK 在规格化全局空间中运行,但仍然允许您在使用数据集设置或检索 HIKCharacterState 中节点的平移、旋转和缩放时允许您使用局部空间转换。请参见用于 HIKCharacterState 数据的数据集函数。
如果角色的骨架中包含 HumanIK 所未知的关节,则这些未知关节的平移和旋转将影响骨架中其子关节的局部空间。例如,如果角色是在肩部和肘部之间有附加手臂关节的机器人,则附加关节的旋转将影响肘部节点的位置和旋转(从而将影响腕部节点、手部节点以及所有手指的全局位置和方向)。
如果未知关节位于关节链末端,您可能只需使用局部空间转换将 HumanIK 解算器生成的 HIKCharacterState 应用回游戏角色,便能够透明地支持这些关节。例如,假设角色具有 HumanIK 所未知的一系列尾部关节,其极限父项是 HumanIK 腰部节点。如果 HumanIK 解算器移动或旋转腰部节点,则将腰部节点的局部空间转换应用回游戏角色可能会使尾部随腰部节点移动和旋转,即使尾部不是直接由 HumanIK 控制。
但是,如果未知关节位于两个 HumanIK 关节之间,例如上述有附加肘部的机器人,则您需要为属于未知关节子项的 HumanIK 节点定义父偏移。此父偏移用于定义未知父关节对节点的本地旋转、平移和缩放的影响。例如,要继续上面介绍的情景,机器人的肘部关节将需要定义父偏移,其旋转、平移和缩放与骨架层次中位于肘部上方的附加关节的局部空间相匹配。为该父偏移设置的平移、旋转和缩放值应相对于骨架层次中未知关节的下一个 HumanIK 关节进行定义。
要设置节点的父偏移,必须首先在初始化时在 HIKCharacterDefinition 中指出节点具有未知父项。将与每个所需节点对应的 mUsedNode 元素的值设置为 HIKNodeParentOffset。这将导致 HumanIK 在从 HIKCharacterDefinition 创建的每个 HIKCharacter 中分配用于存储指定节点父偏移的附加内存。有关详细信息,请参见初始化。
请注意,只有未指定自由度的节点需要这样设置。通过将其 mUsedNode 元素的值设置为 HIKNodeLimits 来为节点指定自由度,会自动为父偏移指定内存。请参见自由度。
节点的父偏移将保留在 HIKCharacter 中。如果偏移发生更改(如附加关节伸展或压缩,或相对于自己的父对象移动到不同的平移),则必须更新父偏移。这实际上会导致所有 HumanIK 节点移动到骨架层次中的父偏移之下。
要为具有 HumanIK 所未知的父关节的节点设置父偏移,请调用 HIKSetParentOffsetfv() 函数。有关此函数所预期的参数的详细信息,请参见 API 参考。
HIKSetParentOffsetfv(MyHIKCharacter, RightElbowNodeId, lParentTOffset.mData, lParentQOffset.mData, lParentSOffset.mData);