예제 #1
0
        public bool Raycast(Point3d start, Point3d end, out float t)
        {
            NavRef startNavRef = ComputeNavRefAtPoint(start);
            NavRef endNavRef   = ComputeNavRefAtPoint(end);

            return(Raycast(start, startNavRef, end, endNavRef, out t));
        }
예제 #2
0
        public NavRef ComputeNavRefAtPoint(Point2d point)
        {
            NavRef navRef = null;

            if (m_boundingBox.ContainsPoint2d(point))
            {
                if (m_navCells.Length > 0)
                {
                    float cellSize    = GameConstants.NAV_MESH_WORLD_UNITS_SIZE;
                    uint  colomnIndex = (uint)((point.x - m_boundingBox.Min.x) / cellSize);
                    uint  rowIndex    = (uint)((m_boundingBox.Max.y - point.y) / cellSize);
                    uint  cellIndex   = GetNavCellIndex(rowIndex, colomnIndex);

                    if (m_navCells[cellIndex].connectivityId != EMPTY_NAV_CELL)
                    {
                        navRef = new NavRef((int)cellIndex, m_roomKey);
                    }
                    else
                    {
                        navRef = new NavRef();
                    }
                }
                else
                {
                    // The whole nav mesh is one big nav cell
                    navRef = new NavRef(0, m_roomKey);
                }
            }
            else
            {
                navRef = new NavRef();
            }

            return(navRef);
        }
예제 #3
0
        private void ComputeSmoothedPath()
        {
            // Convert the raw path steps into a proper path step sequence

            // Always add the first step
            m_finalPath.Add(new PathStep(m_startNavRef, m_startPosition));

            // Add a step at the midpoint between each neighboring nav-cell in the path
            for (uint rawStepIndex = 1; rawStepIndex < m_rawPath.Count; rawStepIndex++)
            {
                NavRef  previousNavRef = m_rawPath[(int)rawStepIndex - 1];
                NavRef  currentNavRef = m_rawPath[(int)rawStepIndex];
                Point3d portalLeft, portalRight;

                if (m_navMesh.ComputePortalPoints(
                        previousNavRef,
                        currentNavRef,
                        out portalLeft,
                        out portalRight))
                {
                    Point3d portalMidpoint = Point3d.Interpolate(portalLeft, portalRight, 0.5F);

                    m_finalPath.Add(new PathStep(currentNavRef, portalMidpoint));
                }
            }

            // Always add the lest step
            m_finalPath.Add(new PathStep(m_endNavRef, m_endPosition));

            // TODO: Remove the extraneous path steps using funnel algorithm + ray casting
            m_state = eState.complete;
        }
예제 #4
0
        public bool PointCanSeeOtherPoint(Point3d a, Point3d b)
        {
            NavRef navRefA = ComputeNavRefAtPoint(a);
            NavRef navRefB = ComputeNavRefAtPoint(b);

            return(NavRefCanSeeOtherNavRef(navRefA, navRefB));
        }
예제 #5
0
 public ContextOverlayView(ContextOverlayController contextOverlayController)
 {
     m_contextOverlayController = contextOverlayController;
     m_hotspotWidgets = new List<HotspotWidget>();
     m_currentNavRef = new NavRef(-1, null);
     CurrentHotspot = null;
     m_style= contextOverlayController.ParentController.contextOverlayStyle;
 }
예제 #6
0
 // Helper Functions
 private void ResetRequest()
 {
     m_navMesh       = null;
     m_roomKey       = null;
     m_startPosition = new Point3d();
     m_endPosition   = new Point3d();
     m_startNavRef   = null;
     m_endNavRef     = null;
 }
예제 #7
0
        public int GetNavRefConnectivityID(NavRef navRef)
        {
            int connectivityID = EMPTY_NAV_CELL;

            if (navRef.IsValid)
            {
                connectivityID = GetNavCellConnectivityID((uint)navRef.NavCellIndex);
            }

            return(connectivityID);
        }
예제 #8
0
        public bool AreNavRefsConnected(NavRef navRefA, NavRef navRefB)
        {
            bool areConnected = false;

            if (navRefA.IsValid && navRefB.IsValid)
            {
                areConnected = navRefA.NavRoomKey.Equals(navRefB.NavRoomKey) &&
                               ((navRefA.NavCellIndex == navRefB.NavCellIndex) ||
                                (m_navCells[navRefA.NavCellIndex].connectivityId == m_navCells[navRefB.NavCellIndex].connectivityId));
            }

            return(areConnected);
        }
예제 #9
0
        private void BuildNavCellPotentiallyVisibleSet()
        {
            if (m_nonEmptyNavCellCount > 0)
            {
                // Only need PVS information on non-empty nav cells
                m_pvs = new PotentiallyVisibleSet(m_nonEmptyNavCellCount);

                // Raycast from each non-empty nav cell...
                for (int startNavCellIndex = 0; startNavCellIndex < m_navCells.Length; ++startNavCellIndex)
                {
                    NavRef  startNavRef  = new NavRef(startNavCellIndex, m_roomKey);
                    NavCell startNavCell = m_navCells[startNavCellIndex];

                    if (startNavCell.connectivityId != EMPTY_NAV_CELL)
                    {
                        // ... to every other non-empty nav cell
                        for (int endNavCellIndex = 0; endNavCellIndex < m_navCells.Length; ++endNavCellIndex)
                        {
                            NavCell endNavCell = m_navCells[endNavCellIndex];

                            if (startNavCellIndex != endNavCellIndex &&
                                endNavCell.connectivityId != EMPTY_NAV_CELL)
                            {
                                NavRef endNavRef = new NavRef(endNavCellIndex, m_roomKey);

                                Point3d start = ComputeNavCellCenter((uint)startNavCellIndex);
                                Point3d end   = ComputeNavCellCenter((uint)endNavCellIndex);

                                float t;
                                bool  hit = Raycast(start, startNavRef, end, endNavRef, out t);

                                // Mark visibility in the PVS where the raycast succeeds
                                if (!hit)
                                {
                                    m_pvs.SetCellCanSeeOtherCell((uint)startNavCell.pvsCellIndex, (uint)endNavCell.pvsCellIndex);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #10
0
        private void ComputeEndpoints()
        {
            m_startNavRef = m_navMesh.ComputeNavRefAtPoint(m_startPosition);
            m_endNavRef   = m_navMesh.ComputeNavRefAtPoint(m_endPosition);

            if (m_startNavRef.IsValid)
            {
                if (m_endNavRef.IsValid)
                {
                    if (m_navMesh.AreNavRefsConnected(m_startNavRef, m_endNavRef))
                    {
                        if (m_startNavRef.Equals(m_endNavRef))
                        {
                            // We can head directly to the destination
                            m_finalPath.Add(new PathStep(m_startNavRef, m_startPosition));
                            m_finalPath.Add(new PathStep(m_endNavRef, m_endPosition));
                            m_state = eState.complete;
                        }
                        else
                        {
                            // We have to do the expensive query
                            m_state = eState.setup_raw_path;
                        }
                    }
                    else
                    {
                        m_state      = eState.complete;
                        m_resultCode = eResult.failed_start_off_nav_mesh;
                    }
                }
                else
                {
                    m_state      = eState.complete;
                    m_resultCode = eResult.failed_end_off_nav_mesh;
                }
            }
            else
            {
                m_state      = eState.complete;
                m_resultCode = eResult.failed_start_off_nav_mesh;
            }
        }
예제 #11
0
        public uint[] ComputeNavCellsInRadius(Point3d center, float radius, bool include_center)
        {
            List <uint> navCells       = new List <uint>();
            NavRef      centerRef      = ComputeNavRefAtPoint(center);
            float       radius_squared = radius * radius;

            if (centerRef.NavCellIndex != EMPTY_NAV_CELL)
            {
                uint centerCellIndex = (uint)centerRef.NavCellIndex;
                uint centerColomn    = GetNavCellColomn(centerCellIndex);
                uint centerRow       = GetNavCellRow(centerCellIndex);

                uint radiusInCells  = (uint)Math.Ceiling(radius / GameConstants.NAV_MESH_WORLD_UNITS_SIZE);
                uint minColomnIndex = (centerColomn >= radiusInCells) ? centerColomn - radiusInCells : 0;
                uint maxColomnIndex = Math.Min(centerColomn + radiusInCells, m_colomnCount - 1);
                uint minRowIndex    = (centerRow >= radiusInCells) ? centerRow - radiusInCells : 0;
                uint maxRowIndex    = Math.Min(centerRow + radiusInCells, m_rowCount - 1);

                for (uint row = minRowIndex; row <= maxRowIndex; ++row)
                {
                    for (uint colomn = minColomnIndex; colomn <= maxColomnIndex; ++colomn)
                    {
                        uint cellIndex = GetNavCellIndex(row, colomn);

                        if ((cellIndex != centerCellIndex || include_center) &&
                            m_navCells[cellIndex].connectivityId == m_navCells[centerCellIndex].connectivityId)
                        {
                            Point3d cellCenter = ComputeNavCellCenter(cellIndex);

                            if (Point3d.DistanceSquared(cellCenter, center) <= radius_squared)
                            {
                                navCells.Add(cellIndex);
                            }
                        }
                    }
                }
            }

            return(navCells.ToArray());
        }
예제 #12
0
        public bool NavRefCanSeeOtherNavRef(NavRef navRefA, NavRef navRefB)
        {
            bool canSee = false;

            if (navRefA.IsValid && navRefB.IsValid)
            {
                canSee = true;

                if (m_pvs != null)
                {
                    NavCell navCellA = m_navCells[navRefA.NavCellIndex];
                    NavCell navCellB = m_navCells[navRefB.NavCellIndex];

                    canSee =
                        m_pvs.CanCellSeeOtherCell(
                            (uint)navCellA.pvsCellIndex,
                            (uint)navCellB.pvsCellIndex);
                }
            }

            return(canSee);
        }
예제 #13
0
        public bool NavRefCanSeeOtherNavRef(NavRef navRefA, NavRef navRefB)
        {
            bool canSee = false;

            if (navRefA.IsValid && navRefB.IsValid)
            {
                canSee = true;

                if (m_pvs != null)
                {
                    NavCell navCellA = m_navCells[navRefA.NavCellIndex];
                    NavCell navCellB = m_navCells[navRefB.NavCellIndex];

                    canSee =
                        m_pvs.CanCellSeeOtherCell(
                            (uint)navCellA.pvsCellIndex,
                            (uint)navCellB.pvsCellIndex);
                }
            }

            return canSee;
        }
예제 #14
0
 // Helper Functions
 private void ResetRequest()
 {
     m_navMesh = null;
     m_roomKey = null;
     m_startPosition = new Point3d();
     m_endPosition = new Point3d();
     m_startNavRef = null;
     m_endNavRef = null;
 }
예제 #15
0
        private void ComputeEndpoints()
        {
            m_startNavRef = m_navMesh.ComputeNavRefAtPoint(m_startPosition);
            m_endNavRef = m_navMesh.ComputeNavRefAtPoint(m_endPosition);

            if (m_startNavRef.IsValid)
            {
                if (m_endNavRef.IsValid)
                {
                    if (m_navMesh.AreNavRefsConnected(m_startNavRef, m_endNavRef))
                    {
                        if (m_startNavRef.Equals(m_endNavRef))
                        {
                            // We can head directly to the destination
                            m_finalPath.Add(new PathStep(m_startNavRef, m_startPosition));
                            m_finalPath.Add(new PathStep(m_endNavRef, m_endPosition));
                            m_state = eState.complete;
                        }
                        else
                        {
                            // We have to do the expensive query
                            m_state = eState.setup_raw_path;
                        }
                    }
                    else
                    {
                        m_state = eState.complete;
                        m_resultCode = eResult.failed_start_off_nav_mesh;
                    }
                }
                else
                {
                    m_state = eState.complete;
                    m_resultCode = eResult.failed_end_off_nav_mesh;
                }
            }
            else
            {
                m_state = eState.complete;
                m_resultCode = eResult.failed_start_off_nav_mesh;
            }
        }
예제 #16
0
        public int GetNavRefConnectivityID(NavRef navRef)
        {
            int connectivityID = EMPTY_NAV_CELL;

            if (navRef.IsValid)
            {
                connectivityID = GetNavCellConnectivityID((uint)navRef.NavCellIndex);
            }

            return connectivityID;
        }
예제 #17
0
    private void UpdateCurrentNavRef()
    {
        SessionData sessionData = SessionData.GetInstance();
        GameData gameData = sessionData.CurrentGameData;
        RoomData roomData = gameData.GetCachedRoomData(gameData.CurrentRoomKey);

        if (roomData != null)
        {
            AsyncRPGSharedLib.Navigation.NavMesh navMesh = roomData.StaticRoomData.NavMesh;

            Point2d pixelPoint = WidgetEventDispatcher.GetMousePosition();
            Point3d roomPoint = GameConstants.ConvertPixelPositionToRoomPosition(pixelPoint);

            m_currentNavRef = navMesh.ComputeNavRefAtPoint(roomPoint);
        }
    }
예제 #18
0
 public PathStep(NavRef navRef, Point3d point)
 {
     m_navRef = new NavRef(navRef.NavCellIndex, navRef.NavRoomKey);
     m_point  = new Point3d(point);
 }
예제 #19
0
        public bool Raycast(
            Point3d start,
            NavRef startNavRef,
            Point3d end,
            NavRef endNavRef,
            out float t)
        {
            bool hit = false;

            if (!startNavRef.IsValid || !endNavRef.IsValid)
            {
                hit = true;
                t   = 0.0f;
            }
            else if (startNavRef.Equals(endNavRef))
            {
                hit = false;
                t   = 1.0f;
            }
            else
            {
                uint maxRaycastIteration = m_rowCount + m_colomnCount;
                uint iterationCount      = 0;

                NavRef   currentNavRef        = startNavRef;
                AABB2d   currentNavCellBounds = ComputeNavCellBounds2d((uint)currentNavRef.NavCellIndex);
                Point2d  start2d      = start.ToPoint2d();
                Vector2d rayDirection = (end - start).ToVector2d();
                float    tEpsilon     = MathConstants.POSITIONAL_EPSILON / rayDirection.Magnitude();

                t = 0.0f;

                while (t < 1.0f && !hit)
                {
                    float clipMinT = 0.0f;
                    float clipMaxT = 0.0f;

                    // Compute where the ray exists the bounding box of the cell
                    if (!currentNavCellBounds.ClipRay(
                            start2d,
                            rayDirection,
                            out clipMinT,
                            out clipMaxT))
                    {
                        // If we failed to clip against the bounds that we were suppose to be inside of,
                        // just use the current t and rely on the positional epsilon advancement to get
                        // us back on track
                        Debug.Assert(false, "Raycast didn't clip against box it was suppose to intersect");
                        clipMinT = t;
                        clipMaxT = t;
                    }

                    if (clipMaxT < 1.0f)
                    {
                        // If we haven't gotten to the end of the ray yet, try to advance to the next nav cell
                        Point2d newTestPoint = start2d + rayDirection * (clipMaxT + tEpsilon);

                        // Find the adjacent neighboring cell, if any
                        currentNavRef = ComputeNavRefAtPoint(newTestPoint);

                        if (currentNavRef.IsValid)
                        {
                            currentNavCellBounds = ComputeNavCellBounds2d((uint)currentNavRef.NavCellIndex);

                            if (currentNavRef.Equals(endNavRef))
                            {
                                t   = 1.0f;
                                hit = false;
                            }
                            else
                            {
                                t   = Math.Min(clipMaxT + tEpsilon, 1.0f);
                                hit = false;
                            }
                        }
                        else
                        {
                            t   = clipMaxT;
                            hit = true;
                        }
                    }
                    else
                    {
                        // Made it all the way to the end without hitting anything
                        t   = 1.0f;
                        hit = false;
                    }

                    // Safety iteration max to prevent infinite loops
                    iterationCount++;
                    if (iterationCount > maxRaycastIteration)
                    {
                        // Something funky happened. Just assume we can see to the end
                        Debug.Assert(false, "Raycast hit iteration limit");
                        t   = 1.0f;
                        hit = false;
                        break;
                    }
                }
            }

            return(hit);
        }
예제 #20
0
        public bool Raycast(
            Point3d start,
            NavRef startNavRef,
            Point3d end,
            NavRef endNavRef,
            out float t)
        {
            bool hit = false;

            if (!startNavRef.IsValid || !endNavRef.IsValid)
            {
                hit = true;
                t = 0.0f;
            }
            else if (startNavRef.Equals(endNavRef))
            {
                hit = false;
                t = 1.0f;
            }
            else
            {
                uint maxRaycastIteration = m_rowCount + m_colomnCount;
                uint iterationCount = 0;

                NavRef currentNavRef = startNavRef;
                AABB2d currentNavCellBounds = ComputeNavCellBounds2d((uint)currentNavRef.NavCellIndex);
                Point2d start2d = start.ToPoint2d();
                Vector2d rayDirection = (end - start).ToVector2d();
                float tEpsilon = MathConstants.POSITIONAL_EPSILON / rayDirection.Magnitude();

                t = 0.0f;

                while (t < 1.0f && !hit)
                {
                    float clipMinT = 0.0f;
                    float clipMaxT = 0.0f;

                    // Compute where the ray exists the bounding box of the cell
                    if (!currentNavCellBounds.ClipRay(
                            start2d,
                            rayDirection,
                            out clipMinT,
                            out clipMaxT))
                    {
                        // If we failed to clip against the bounds that we were suppose to be inside of,
                        // just use the current t and rely on the positional epsilon advancement to get
                        // us back on track
                        Debug.Assert(false, "Raycast didn't clip against box it was suppose to intersect");
                        clipMinT = t;
                        clipMaxT = t;
                    }

                    if (clipMaxT < 1.0f)
                    {
                        // If we haven't gotten to the end of the ray yet, try to advance to the next nav cell
                        Point2d newTestPoint = start2d + rayDirection * (clipMaxT + tEpsilon);

                        // Find the adjacent neighboring cell, if any
                        currentNavRef = ComputeNavRefAtPoint(newTestPoint);

                        if (currentNavRef.IsValid)
                        {
                            currentNavCellBounds = ComputeNavCellBounds2d((uint)currentNavRef.NavCellIndex);

                            if (currentNavRef.Equals(endNavRef))
                            {
                                t = 1.0f;
                                hit = false;
                            }
                            else
                            {
                                t = Math.Min(clipMaxT + tEpsilon, 1.0f);
                                hit = false;
                            }
                        }
                        else
                        {
                            t = clipMaxT;
                            hit = true;
                        }
                    }
                    else
                    {
                        // Made it all the way to the end without hitting anything
                        t = 1.0f;
                        hit = false;
                    }

                    // Safety iteration max to prevent infinite loops
                    iterationCount++;
                    if (iterationCount > maxRaycastIteration)
                    {
                        // Something funky happened. Just assume we can see to the end
                        Debug.Assert(false, "Raycast hit iteration limit");
                        t = 1.0f;
                        hit = false;
                        break;
                    }
                }
            }

            return hit;
        }
예제 #21
0
        public bool ComputePortalPoints(NavRef fromNavRef, NavRef toNavRef, out Point3d portalLeft, out Point3d portalRight)
        {
            bool validPortal = false;

            if (fromNavRef.IsValid && toNavRef.IsValid &&
                fromNavRef.NavRoomKey.Equals(toNavRef.NavRoomKey))
            {
                uint fromColomn = GetNavCellColomn((uint)fromNavRef.NavCellIndex);
                uint fromRow = GetNavCellRow((uint)fromNavRef.NavCellIndex);
                uint toColomn = GetNavCellColomn((uint)toNavRef.NavCellIndex);
                uint toRow = GetNavCellRow((uint)toNavRef.NavCellIndex);

                // toNavRef is to the right of the fromNavRef (+X)
                if (toColomn == fromColomn + 1 && toRow == fromRow)
                {
                    validPortal =
                        ComputePointsOnNavCellSide(
                            (uint)fromNavRef.NavCellIndex,
                            MathConstants.eDirection.right,
                            out portalLeft,
                            out portalRight);
                }
                // toNavRef is to the left of the fromNavRef (-X)
                else if (toColomn == fromColomn - 1 && toRow == fromRow)
                {
                    validPortal =
                        ComputePointsOnNavCellSide(
                            (uint)fromNavRef.NavCellIndex,
                            MathConstants.eDirection.left,
                            out portalLeft,
                            out portalRight);
                }
                // toNavRef is below fromNavRef (-Y)
                else if (toRow == fromRow + 1 && toColomn == fromColomn)
                {
                    validPortal =
                        ComputePointsOnNavCellSide(
                            (uint)fromNavRef.NavCellIndex,
                            MathConstants.eDirection.down,
                            out portalLeft,
                            out portalRight);
                }
                // toNavRef is above fromNavRef (+Y)
                else if (toRow == fromRow - 1 && toColomn == fromColomn)
                {
                    validPortal =
                        ComputePointsOnNavCellSide(
                            (uint)fromNavRef.NavCellIndex,
                            MathConstants.eDirection.up,
                            out portalLeft,
                            out portalRight);
                }
                else
                {
                    portalLeft = new Point3d();
                    portalRight = new Point3d();
                }
            }
            else
            {
                portalLeft = new Point3d();
                portalRight = new Point3d();
            }

            return validPortal;
        }
예제 #22
0
        public NavRef ComputeNavRefAtPoint(Point2d point)
        {
            NavRef navRef = null;

            if (m_boundingBox.ContainsPoint2d(point))
            {
                if (m_navCells.Length > 0)
                {
                    float cellSize = GameConstants.NAV_MESH_WORLD_UNITS_SIZE;
                    uint colomnIndex = (uint)((point.x - m_boundingBox.Min.x) / cellSize);
                    uint rowIndex = (uint)((m_boundingBox.Max.y - point.y) / cellSize);
                    uint cellIndex = GetNavCellIndex(rowIndex, colomnIndex);

                    if (m_navCells[cellIndex].connectivityId != EMPTY_NAV_CELL)
                    {
                        navRef = new NavRef((int)cellIndex, m_roomKey);
                    }
                    else
                    {
                        navRef = new NavRef();
                    }
                }
                else
                {
                    // The whole nav mesh is one big nav cell
                    navRef = new NavRef(0, m_roomKey);
                }
            }
            else
            {
                navRef = new NavRef();
            }

            return navRef;
        }
예제 #23
0
        public bool ComputePortalPoints(NavRef fromNavRef, NavRef toNavRef, out Point3d portalLeft, out Point3d portalRight)
        {
            bool validPortal = false;

            if (fromNavRef.IsValid && toNavRef.IsValid &&
                fromNavRef.NavRoomKey.Equals(toNavRef.NavRoomKey))
            {
                uint fromColomn = GetNavCellColomn((uint)fromNavRef.NavCellIndex);
                uint fromRow    = GetNavCellRow((uint)fromNavRef.NavCellIndex);
                uint toColomn   = GetNavCellColomn((uint)toNavRef.NavCellIndex);
                uint toRow      = GetNavCellRow((uint)toNavRef.NavCellIndex);

                // toNavRef is to the right of the fromNavRef (+X)
                if (toColomn == fromColomn + 1 && toRow == fromRow)
                {
                    validPortal =
                        ComputePointsOnNavCellSide(
                            (uint)fromNavRef.NavCellIndex,
                            MathConstants.eDirection.right,
                            out portalLeft,
                            out portalRight);
                }
                // toNavRef is to the left of the fromNavRef (-X)
                else if (toColomn == fromColomn - 1 && toRow == fromRow)
                {
                    validPortal =
                        ComputePointsOnNavCellSide(
                            (uint)fromNavRef.NavCellIndex,
                            MathConstants.eDirection.left,
                            out portalLeft,
                            out portalRight);
                }
                // toNavRef is below fromNavRef (-Y)
                else if (toRow == fromRow + 1 && toColomn == fromColomn)
                {
                    validPortal =
                        ComputePointsOnNavCellSide(
                            (uint)fromNavRef.NavCellIndex,
                            MathConstants.eDirection.down,
                            out portalLeft,
                            out portalRight);
                }
                // toNavRef is above fromNavRef (+Y)
                else if (toRow == fromRow - 1 && toColomn == fromColomn)
                {
                    validPortal =
                        ComputePointsOnNavCellSide(
                            (uint)fromNavRef.NavCellIndex,
                            MathConstants.eDirection.up,
                            out portalLeft,
                            out portalRight);
                }
                else
                {
                    portalLeft  = new Point3d();
                    portalRight = new Point3d();
                }
            }
            else
            {
                portalLeft  = new Point3d();
                portalRight = new Point3d();
            }

            return(validPortal);
        }
예제 #24
0
        public bool AreNavRefsConnected(NavRef navRefA, NavRef navRefB)
        {
            bool areConnected = false;

            if (navRefA.IsValid && navRefB.IsValid)
            {
                areConnected = navRefA.NavRoomKey.Equals(navRefB.NavRoomKey) &&
                    ((navRefA.NavCellIndex == navRefB.NavCellIndex) ||
                     (m_navCells[navRefA.NavCellIndex].connectivityId == m_navCells[navRefB.NavCellIndex].connectivityId));
            }

            return areConnected;
        }
예제 #25
0
        private void BuildNavCellPotentiallyVisibleSet()
        {
            if (m_nonEmptyNavCellCount > 0)
            {
                // Only need PVS information on non-empty nav cells
                m_pvs = new PotentiallyVisibleSet(m_nonEmptyNavCellCount);

                // Raycast from each non-empty nav cell...
                for (int startNavCellIndex = 0; startNavCellIndex < m_navCells.Length; ++startNavCellIndex)
                {
                    NavRef startNavRef = new NavRef(startNavCellIndex, m_roomKey);
                    NavCell startNavCell = m_navCells[startNavCellIndex];

                    if (startNavCell.connectivityId != EMPTY_NAV_CELL)
                    {
                        // ... to every other non-empty nav cell
                        for (int endNavCellIndex = 0; endNavCellIndex < m_navCells.Length; ++endNavCellIndex)
                        {
                            NavCell endNavCell = m_navCells[endNavCellIndex];

                            if (startNavCellIndex != endNavCellIndex &&
                                endNavCell.connectivityId != EMPTY_NAV_CELL)
                            {
                                NavRef endNavRef = new NavRef(endNavCellIndex, m_roomKey);

                                Point3d start = ComputeNavCellCenter((uint)startNavCellIndex);
                                Point3d end = ComputeNavCellCenter((uint)endNavCellIndex);

                                float t;
                                bool hit = Raycast(start, startNavRef, end, endNavRef, out t);

                                // Mark visibility in the PVS where the raycast succeeds
                                if (!hit)
                                {
                                    m_pvs.SetCellCanSeeOtherCell((uint)startNavCell.pvsCellIndex, (uint)endNavCell.pvsCellIndex);
                                }
                            }
                        }
                    }
                }
            }
        }