在内部,Gameware Navigation 创建其所有数据,并使用具有下列特性的坐标系进行内部计算:
该坐标系的轴使用以下约定定义。请注意,Y 轴(或者“前方向轴”)的正方向朝向屏幕“里面”(远离读者)。
如果在游戏引擎中使用不同的坐标系,您将需要来回转换值。请参见以下部分。
CoordSystem 类是可选辅助对象,可用于转换坐标、向量、距离以及在游戏中使用的坐标系和 Gameware Navigation 使用的坐标系之间的包围盒。
以下代码显示了如何设置 CoordSystem 以在游戏中使用 Y 轴作为上方轴并使用厘米表示距离:
Kaim::CoordSystem coordSystem = Kaim::CoordSystem(); KyFloat32 oneMeterInClientUnits = 100.f; Kaim::CoordSystem::ClientAxis clientRightAxis = Kaim::CLIENT_X; Kaim::CoordSystem::ClientAxis clientFrontAxis = Kaim::CLIENT_MINUS_Z; Kaim::CoordSystem::ClientAxis clientUpAxis = Kaim::CLIENT_Y; coordSystem.Setup( oneMeterInClientUnits, clientRightAxis, clientFrontAxis, clientUpAxis );
例如,以下调用会将指定位置从游戏引擎中使用的坐标系变换为 Gameware Navigation 坐标系。
Kaim::Vec3f navPos = coordSystem.ClientToNavigation_Pos(position);
同样,以下调用会将指定的方向向量从 Gameware Navigation 坐标系变换为游戏引擎中使用的坐标系。
Kaim::Vec3f navDir = coordSystem.NavigationToClient_Normal(dir);
CoordSystem 类提供的转换方法使用浮点数表示距离测量值,以浮点数数组表示坐标。如果使用双精度数,那么数据转换可能还需要额外的处理工作。
当然,您也可以自由编写自己的函数来封装数据转换。这样可以最大程度地减少代码复制,还使您能够通过使函数接收和返回在游戏中使用的相同数据类型来确保类型安全。
有时您可能需要在 Gameware Navigation 坐标系与游戏引擎中使用的坐标系之间转换包围盒。这种情况下,特别建议您使用 CoordSystem 或它的宏来执行变换,因为在坐标系之间转换包围盒会比较复杂。
如果将最低点和最高点的坐标从一个坐标系独立转换到另一个坐标系,则在目标坐标系会得到两个不同的框角。
例如,如果您在游戏世界使用左手 Z 轴向上坐标系,将坐标映射到 Gameware Navigation 使用的右手 Z 轴向上坐标系可能涉及以下变换:(-X, Y, Z)。如果最低点和最高点的坐标分别是 (minX, minY, minZ) 和 (maxX, maxY, maxZ),独立变换这些坐标会得到 (-minX, minY, minZ) 和 (-maxX, maxY, maxZ)。由于 maxX 最初一定大于 minX,因此在变换后 -maxX 一定小于 -minX。这两组坐标尽管仍然表示包围盒的对角,但却不再表示极值。
让我们举个直观的例子,假设立方体轴对齐包围盒的最低点在原点 (0, 0, 0),最高点在角 (100, 100, 100)。独立变换这两组坐标会得到坐标 (-0, 0, 0) 和 (-100, 100, 100)。这些角不再表示最低点,即 X、Y 和 Z 值最小的角;以及最高点,即 X、Y 和 Z 值最大的角。变换后包围盒的最低点应该是 (-100, 0, 0),最高点应该是 (-0, 100, 100)。
CoordSystem 类在变换包围盒时会考虑到这一点,并确保用于定义框的各角在目标坐标系中始终是最低点和最高点。
例如,以下调用会将包围盒从游戏引擎中使用的坐标系变换为 Gameware Navigation 坐标系。
Kaim::Box3f navAABB; coordSystem.ClientToNavigation_Box(gameMinima, gameMaxima, navAABB);