예제 #1
0
    private void DebugDrawTestVisibility()
    {
        int             characterID = _gameWorldController.Model.CurrentCharacterID;
        RoomKey         roomKey     = _gameWorldController.Model.CurrentGame.CurrentRoomKey;
        CharacterEntity entity      = _gameWorldController.Model.GetCharacterEntity(characterID);

        if (entity != null)
        {
            Point3d startWorldPos = entity.Position;

            Point2d endPixelPos = GetMousePixelPosition();
            Point3d endWorldPos = GameConstants.ConvertPixelPositionToRoomPosition(endPixelPos);

            // Draw the target nav cell
            AsyncRPGSharedLib.Navigation.NavMesh navMesh = PathfindingSystem.GetNavMesh(roomKey);

            if (navMesh != null)
            {
                NavRef startNavRef = navMesh.ComputeNavRefAtPoint(startWorldPos);
                NavRef endNavRef   = navMesh.ComputeNavRefAtPoint(endWorldPos);

                if (startNavRef.IsValid && endNavRef.IsValid)
                {
                    bool  canSee     = navMesh.NavRefCanSeeOtherNavRef(startNavRef, endNavRef);
                    Color debugColor = canSee ? Color.green : Color.red;

                    // Draw a box around the nav cell
                    {
                        Point3d endCenterWorldPos = navMesh.ComputeNavCellCenter((uint)endNavRef.NavCellIndex);
                        Point2d endCenterPixelPos = GameConstants.ConvertRoomPositionToPixelPosition(endCenterWorldPos);
                        float   halfWidth         = (float)GameConstants.NAV_MESH_PIXEL_SIZE / 2.0f;

                        Vector3 boxUL =
                            ClientGameConstants.ConvertPixelPositionToVertexPosition(
                                endCenterPixelPos.x - halfWidth, endCenterPixelPos.y - halfWidth, 0.0f);
                        Vector3 boxUR =
                            ClientGameConstants.ConvertPixelPositionToVertexPosition(
                                endCenterPixelPos.x + halfWidth, endCenterPixelPos.y - halfWidth, 0.0f);
                        Vector3 boxLR =
                            ClientGameConstants.ConvertPixelPositionToVertexPosition(
                                endCenterPixelPos.x + halfWidth, endCenterPixelPos.y + halfWidth, 0.0f);
                        Vector3 boxLL =
                            ClientGameConstants.ConvertPixelPositionToVertexPosition(
                                endCenterPixelPos.x - halfWidth, endCenterPixelPos.y + halfWidth, 0.0f);

                        Debug.DrawLine(boxUL, boxUR, debugColor);
                        Debug.DrawLine(boxUR, boxLR, debugColor);
                        Debug.DrawLine(boxLR, boxLL, debugColor);
                        Debug.DrawLine(boxLL, boxUL, debugColor);
                    }

                    // Update the visibility status label
                    _visibilityStatusLabel.Text = canSee ? "VISIBLE" : "INVISIBLE";
                    _visibilityStatusLabel.SetLocalPosition(endPixelPos.x, endPixelPos.y);
                    _visibilityStatusLabel.Color   = debugColor;
                    _visibilityStatusLabel.Visible = true;

                    // Render the ray-cast line
                    {
                        Vector3 startVertex = ClientGameConstants.ConvertRoomPositionToVertexPosition(startWorldPos);
                        Vector3 endVertex   = ClientGameConstants.ConvertRoomPositionToVertexPosition(endWorldPos);

                        Debug.DrawLine(startVertex, endVertex, debugColor);
                    }
                }
            }
        }
    }
예제 #2
0
        private void ComputeRawPath()
        {
            int nodesSearchedThisUpdate = 0;

            // Keep searching until we either find the end
            // or we're not allowed to search anymore
            while (!m_nodeHeap.Empty() &&
                   m_totalNodesSearched < MAX_TOTAL_NODES_SEARCHED_ALLOWED &&
                   (m_maxNodesSearchedPerUpdate == 0 || (m_maxNodesSearchedPerUpdate > 0 && nodesSearchedThisUpdate < m_maxNodesSearchedPerUpdate)))
            {
                PathNode currentNode = m_nodeHeap.Top();

                // Keep track of how many nodes total we have visited so far
                m_totalNodesSearched++;

                // Keep track of how many nodes were searched this update
                nodesSearchedThisUpdate++;

                // Make sure we haven't hit the destination
                if (currentNode.NavCellIndex != m_endNavRef.NavCellIndex)
                {
                    // Remove the current node from the heap now that we're investigating it
                    m_nodeHeap.Pop();

                    // Add the current nav-cell to the closed set
                    // (since we just visited it and don't want to visit it again)
                    currentNode.MarkAsInClosedSet();

                    // See which neighbor, if any, looks best at this moment to search from
                    for (NavCellNeighborIterator iterator = new NavCellNeighborIterator(m_navMesh, currentNode.NavCellIndex);
                         iterator.Valid(); iterator.Next())
                    {
                        // See if we already have a search node for the neighbor nav-cell
                        uint     neighborNavCellIndex = iterator.NeighborNavCellIndex;
                        PathNode neighborNode         = null;
                        bool     hasNeighbor          = m_navCellToNodeMap.TryGetValue(neighborNavCellIndex, out neighborNode);

                        // Skip this neighbor if we already put it in the closed set
                        if (!hasNeighbor || !neighborNode.InClosedSet)
                        {
                            // Compute G(x): The path cost from the start to this neighbor
                            float netTraversalCostToNeighbor = currentNode.Cost +
                                                               ComputeTraversalCost(currentNode.NavCellIndex, neighborNavCellIndex);

                            // Add this neighbor into consideration if:
                            // A) We haven't seen it before (i.e. not in the open set)
                            // B) We have seen it before, but the net traversal cost to the neighbor
                            //    from the start through the current node is cheaper than some previous
                            //    traversal to the neighbor.
                            if (neighborNode == null || netTraversalCostToNeighbor < neighborNode.Cost)
                            {
                                // Compute F(x)= G(x) + H(x): The past cost to the neighbor plus the estimated distance to the end
                                Point3d neighborCenter = m_navMesh.ComputeNavCellCenter(neighborNavCellIndex);
                                float   netTraversalPlusHeuristicCost =
                                    netTraversalCostToNeighbor +
                                    ComputeHeuristicCostEstimate(neighborCenter, m_endPosition);

                                // Make sure to add the neighbor to the open set if not already added
                                if (neighborNode == null)
                                {
                                    neighborNode =
                                        new PathNode(
                                            (int)m_nextPathNodeID,
                                            currentNode,
                                            neighborNavCellIndex,
                                            netTraversalCostToNeighbor,
                                            netTraversalPlusHeuristicCost);
                                    m_nextPathNodeID++;

                                    m_navCellToNodeMap[neighborNavCellIndex] = neighborNode;
                                }
                                else
                                {
                                    neighborNode.ParentNode = currentNode;
                                    neighborNode.Cost       = netTraversalCostToNeighbor;
                                    neighborNode.Total      = netTraversalPlusHeuristicCost;
                                }

                                // Add the neighbor into the heap for future consideration
                                m_nodeHeap.Push(neighborNode);
                            }
                        }
                    }
                }
                else
                {
                    // Stop searching and compute the raw path from the search nodes
                    m_state = eState.finalize_raw_path;
                    break;
                }
            }

            // Sanity check to make sure we never get in an infinite loop
            if (m_nodeHeap.Empty())
            {
                m_resultCode = eResult.failed_raw_path_search;
                m_state      = eState.complete;
            }
            else if (m_totalNodesSearched >= MAX_TOTAL_NODES_SEARCHED_ALLOWED)
            {
                //Debug.log("PathComputer: Ran out of search node!", Debug.RED);
                m_resultCode = eResult.failed_raw_path_search;
                m_state      = eState.complete;
            }
        }
예제 #3
0
    private void DebugDrawTestPath()
    {
        int             characterID = _gameWorldController.Model.CurrentCharacterID;
        RoomKey         roomKey     = _gameWorldController.Model.CurrentGame.CurrentRoomKey;
        CharacterEntity entity      = _gameWorldController.Model.GetCharacterEntity(characterID);

        if (entity != null)
        {
            Point2d mousePixelPos = GetMousePixelPosition();
            Point3d mouseWorldPos = GameConstants.ConvertPixelPositionToRoomPosition(mousePixelPos);

            // Draw the target nav cell
            string targetLabel = "";
            AsyncRPGSharedLib.Navigation.NavMesh navMesh = PathfindingSystem.GetNavMesh(roomKey);

            if (navMesh != null)
            {
                NavRef navRef = navMesh.ComputeNavRefAtPoint(mouseWorldPos);

                if (navRef.IsValid)
                {
                    Point3d centerWorldPos = navMesh.ComputeNavCellCenter((uint)navRef.NavCellIndex);
                    Point2d centerPixelPos = GameConstants.ConvertRoomPositionToPixelPosition(centerWorldPos);
                    float   halfWidth      = (float)GameConstants.NAV_MESH_PIXEL_SIZE / 2.0f;

                    Vector3 boxUL =
                        ClientGameConstants.ConvertPixelPositionToVertexPosition(
                            centerPixelPos.x - halfWidth, centerPixelPos.y - halfWidth, 0.0f);
                    Vector3 boxUR =
                        ClientGameConstants.ConvertPixelPositionToVertexPosition(
                            centerPixelPos.x + halfWidth, centerPixelPos.y - halfWidth, 0.0f);
                    Vector3 boxLR =
                        ClientGameConstants.ConvertPixelPositionToVertexPosition(
                            centerPixelPos.x + halfWidth, centerPixelPos.y + halfWidth, 0.0f);
                    Vector3 boxLL =
                        ClientGameConstants.ConvertPixelPositionToVertexPosition(
                            centerPixelPos.x - halfWidth, centerPixelPos.y + halfWidth, 0.0f);

                    Debug.DrawLine(boxUL, boxUR, Color.blue);
                    Debug.DrawLine(boxUR, boxLR, Color.blue);
                    Debug.DrawLine(boxLR, boxLL, Color.blue);
                    Debug.DrawLine(boxLL, boxUL, Color.blue);

                    targetLabel = "\nNavCell=" + navRef.NavCellIndex.ToString();
                }

                // Attempt to compute a path from the active player to the mouse
                _pathComputer.BlockingPathRequest(navMesh, roomKey, entity.Position, mouseWorldPos);

                // Update the path status label
                {
                    if (_pathComputer.ResultCode == PathComputer.eResult.success)
                    {
                        _pathStatusLabel.Text  = "VALID" + targetLabel;
                        _pathStatusLabel.Color = Color.green;
                    }
                    else
                    {
                        _pathStatusLabel.Text  = _pathComputer.ResultCode + targetLabel;
                        _pathStatusLabel.Color = Color.red;
                    }

                    _pathStatusLabel.SetLocalPosition(mousePixelPos.x, mousePixelPos.y);
                    _pathStatusLabel.Visible = true;
                }

                // Render the raw path
                for (int stepIndex = 1; stepIndex < _pathComputer.FinalPath.Count; stepIndex++)
                {
                    Point3d previousPoint      = _pathComputer.FinalPath[stepIndex - 1].StepPoint;
                    Point3d currentPoint       = _pathComputer.FinalPath[stepIndex].StepPoint;
                    Vector3 previousPixelPoint = ClientGameConstants.ConvertRoomPositionToVertexPosition(previousPoint);
                    Vector3 currentPixelPoint  = ClientGameConstants.ConvertRoomPositionToVertexPosition(currentPoint);

                    Debug.DrawLine(previousPixelPoint, currentPixelPoint, Color.green);
                }
            }
        }
    }