예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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
            });
        }
예제 #4
0
 public Vector3 WorldPointFromNode(NodeId node)
 {
     return(WorldFromBlockIndex(node.blockIndex, NavMeshUtil.DecodeHeight(m_z1, m_z2, node.encZ)));
 }
예제 #5
0
 public float GetRealHeight(int z1, int z2)
 {
     return(NavMeshUtil.DecodeHeight(z1, z2, encZ));
 }