public CompiledNavMesh FindSubgraphUnderPoint(float x, float y, float z, float maxFall = 20f) { CompiledNavMesh bestGraph = null; float bestDistance = maxFall; foreach (var sg in Subgraphs) { if (!sg.BoundsContainsXY(x, y)) { continue; } var node = sg.FindFloorUnderPoint(x, y, z, maxFall); if (node.blockIndex != -1) { float hitZ = NavMeshUtil.DecodeHeight(sg.Z1, sg.Z2, node.encZ); if (hitZ <= z) { float d = z - hitZ; if (d < bestDistance) { bestDistance = d; bestGraph = sg; } } } } return(bestGraph); }
public NodeId GetNeighbor(NodeId start, int direction) { NodeId result = new NodeId(-1, 0, 0xFF); if ((int)(start.directionFlags & direction) == 0) { var offset = NavMeshUtil.OffsetFromDirectionFlag(direction); int neighborIndex = start.blockIndex + (offset.Y * m_blockWidth + offset.X); ForeachHeightAtIndex(neighborIndex, (entry) => { float height = entry.GetRealHeight(m_z1, m_z2); // add .5 because the step isn't always exact. if (Math.Abs(NavMeshUtil.DecodeHeight(m_z1, m_z2, start.encZ) - height) > m_maxZStep + 0.5f) { return(true); // keep looping } result = new NodeId(neighborIndex, entry.encZ, entry.directionFlags); return(false); // stop loop }); if (result.blockIndex == -1) { throw new InvalidOperationException("expected to find neighbor"); } } return(result); }
public void ForeachHeightAtXY(int blockX, int blockY, Action <int, float> action) { if (blockX < 0 || blockY < 0 || blockX >= m_blockWidth || blockY >= m_blockHeight) { throw new ArgumentOutOfRangeException(); } int blockIndex = blockY * m_blockWidth + blockX; ForeachHeightAtIndex(blockIndex, (entry) => { action(entry.directionFlags, NavMeshUtil.DecodeHeight(m_z1, m_z2, entry.encZ)); return(true); // continue looping }); }
public Vector3 WorldPointFromNode(NodeId node) { return(WorldFromBlockIndex(node.blockIndex, NavMeshUtil.DecodeHeight(m_z1, m_z2, node.encZ))); }
public float GetRealHeight(int z1, int z2) { return(NavMeshUtil.DecodeHeight(z1, z2, encZ)); }