Beispiel #1
0
    public bool IsOnOffMeshLink()
    {
        //Debug.Log ("is off mesh link " + CentralizedManager.IsOffMeshLink(currentState.getPosition()));
        //return offMeshLinkWayPoint[currentPlanExecutionIndex];

        if (currentPlanExecutionIndex >= gridNavigationTasks.Count)
        {
            return(false);
        }

        Vector3 meshLinkStartPos = gridNavigationTasks[currentPlanExecutionIndex].goalState.getPosition();

        if (CentralizedManager.IsOffMeshLink(meshLinkStartPos) == true)
        {
            Debug.LogError("on off mesh link " + currentPlanExecutionIndex + " " + meshLinkStartPos);
        }

        return(CentralizedManager.IsOffMeshLink(meshLinkStartPos));
    }
Beispiel #2
0
    public void notifyEvent(Event ev, System.Object data)
    {
        switch (ev)
        {
        case Event.GLOBAL_PATH_CHANGED:

            Debug.Log("the global path has changed, we must update the path");

            // removing the agent from the polygons associated with the old path in the centralized manager
            if (GlobalNavigator.usingDynamicNavigationMesh)
            {
                for (int i = 0; i < numGlobalPathWaypoints; i++)
                {
                    CentralizedManager.polygonDictionary[globalPathPolygonIndices[i]].agents.Remove(this);
                }
            }

            // probably make this an event handler
            if (GlobalNavigator.pathStatus != NavMeshPathStatus.PathInvalid)
            {
                // TODO :: do some checking how much plan has changed
                // ALSO, we could do some filtering here maybe --- sometimes it gives points which are very close to each otehr

                Debug.Log("number of points in nav mesh path " + GlobalNavigator.numberOfNodes);

                // we dont want to put in the start state, so starting from 1
                int currentGlobalPathWaypoint = 0;


                for (int i = 1; i < GlobalNavigator.numberOfNodes; i++)
                {
                    // should we round off here ...  we prob want to round of when we give it to the discrete planner
                    // TODO this rounding off might sometimes place it on an obstacle
                    // either we make hte nav mesh more conservative (give it 0.5 boundary around obstracles) or do some check here

                    Vector3 p = GlobalNavigator.path[i];

                    // check for off mesh link before rounding off  -- only using x-z values
                    // using previous point to determin because the dictionary keys in using the start point -- NOT ANY MORE
                    bool offMeshLinkState = CentralizedManager.IsOffMeshLink(GlobalNavigator.path[i]);

                    p.x = Mathf.Round(p.x);
                    p.y = Mathf.Round(p.y);
                    p.z = Mathf.Round(p.z);

                    // TODO : maybe off mesh link has its own time computation
                    float time = (GlobalNavigator.pathCost[i] / GlobalNavigator.totalPathCost) * (goalState._time - currentState._time);

                    // we ignore points that are the same as the previos point in the nav mesh path
                    if (currentGlobalPathWaypoint != 0 && globalPath[currentGlobalPathWaypoint - 1].positionEquals(p))
                    {
                        continue;
                    }


                    // todo check for automatic offmesh link as well ... maybe we will just create all of them manually


                    if (currentGlobalPathWaypoint < globalPath.Count)
                    {
                        // some global path nodes have been statically allocated
                        if (currentGlobalPathWaypoint >= numGlobalPathWaypoints && offMeshLinkState == false)
                        {
                            // we are now introducing more waypoints than before -- we need to make these valid
                            globalPath[currentGlobalPathWaypoint].notifyObservers(Event.GOAL_VALID);
                        }
                    }
                    else
                    {
                        _addNewEmptyGlobalPathWayPointAtIndex(currentGlobalPathWaypoint);

                        if (offMeshLinkState == false)
                        {
                            globalPath[currentGlobalPathWaypoint].notifyObservers(Event.GOAL_VALID);
                        }
                    }

                    // TODO: here check if the position actually changed -- else no need to call setPosition -- which triggers goal change event
                    globalPath[currentGlobalPathWaypoint].setPosition(p);

                    // adding time computation
                    // TODO : REMOVE TIME.TIME
                    if (currentGlobalPathWaypoint == 0)
                    {
                        globalPath[currentGlobalPathWaypoint]._time = currentState._time + time;
                    }
                    else
                    {
                        globalPath[currentGlobalPathWaypoint]._time = globalPath[currentGlobalPathWaypoint - 1]._time + time;
                    }

                    // TODO COMPUTE SPEED


                    // storing offmesh link state
                    if (offMeshLinkState == true)                     // this is an offlink
                    {
                        globalPath[currentGlobalPathWaypoint].notifyObservers(Event.GOAL_INVALID);
                    }

                    // setting off mesh link
                    offMeshLinkWayPoint[currentGlobalPathWaypoint] = offMeshLinkState;

                    if (GlobalNavigator.usingDynamicNavigationMesh)
                    {
                        globalPathPolygonIndices[currentGlobalPathWaypoint] = GlobalNavigator.recastSteeringManager.GetClosestPolygon(p);

                        // adding agent to the respective polygon in the centralized manager
                        if (CentralizedManager.polygonDictionary.ContainsKey(globalPathPolygonIndices[currentGlobalPathWaypoint]) == false)
                        {
                            CentralizedManager.polygonDictionary.Add(globalPathPolygonIndices[currentGlobalPathWaypoint], new PolygonData());
                        }

                        CentralizedManager.polygonDictionary[globalPathPolygonIndices[currentGlobalPathWaypoint]].agents.Add(this);
                    }

                    currentGlobalPathWaypoint++;
                }

                Debug.LogWarning("current " + currentGlobalPathWaypoint + " prev " + numGlobalPathWaypoints);

                for (int i = currentGlobalPathWaypoint; i < numGlobalPathWaypoints; i++)
                {
                    // this loop is iterating through all states in globalPath which are currently inactive
                    globalPath[i].notifyObservers(Event.GOAL_INVALID);
                }

                numGlobalPathWaypoints = currentGlobalPathWaypoint;
            }
            else
            {
                Debug.LogError("Path is invalid for agent");                 // this does happen when the goal is on an obstacle
            }

            break;
        }
    }
Beispiel #3
0
    public static void CalculateNavigationMeshPath(Vector3 startPosition, Vector3 goalPosition, int passableMask)
    {
        ClearNavigationMeshPath();

        switch (navigationMeshChoice)
        {
        default:
        case NavigationMeshChoice.USE_UNITY:

            NavMeshPath unityPath = new NavMeshPath();
            NavMesh.CalculatePath(startPosition, goalPosition, passableMask, unityPath);

            pathStatus = unityPath.status;


            if (pathStatus == NavMeshPathStatus.PathInvalid)
            {
                numberOfNodes = 0;
            }
            else
            {
                if (unityPath.corners.Length >= maxNumberOfNodes)
                {
                    Debug.LogWarning("Navigation mesh path greater than maximum number of nodes");
                    numberOfNodes = maxNumberOfNodes;
                    pathStatus    = NavMeshPathStatus.PathPartial;
                }
                else
                {
                    numberOfNodes = unityPath.corners.Length;
                }

                for (int i = 0; i < numberOfNodes; i++)
                {
                    // MAKING SURE LAST WAYPOINT IS THE GOAL
                    if (i == numberOfNodes - 1)
                    {
                        path[i] = goalPosition;
                    }
                    else
                    {
                        path[i] = unityPath.corners[i];
                    }

                    // computing path cost
                    if (i == 0)
                    {
                        pathCost[i] = 0.0f;
                    }
                    else
                    {
                        // assuming that all off mesh links will override cost
                        if (CentralizedManager.IsOffMeshLink(path[i]))
                        {
                            pathCost[i] = CentralizedManager.GetOffMeshLinkInformation(path[i]).offMeshLink.costOverride;
                        }
                        else
                        {
                            pathCost[i] = Vector3.Distance(path[i], path[i - 1]);
                        }
                    }

                    totalPathCost += pathCost[i];
                }
            }

            break;

        case NavigationMeshChoice.USE_RECAST:

            if (recastSteeringManager == null)
            {
                recastSteeringManager = GameObject.Find("ADAPTPrefab").GetComponentInChildren <SteeringManager>();
            }

            numberOfNodes = recastSteeringManager.FindPath(startPosition, goalPosition, path, maxNumberOfNodes);

            if (numberOfNodes > 0)
            {
                path[numberOfNodes - 1] = goalPosition;
            }

            // computing path cost
            for (int i = 1; i < numberOfNodes; i++)
            {
                // TODO : incorporate number of obstacles from centralized manager here
                pathCost[i]    = Vector3.Distance(path[i], path[i - 1]);
                totalPathCost += pathCost[i];
            }

            if (numberOfNodes == 0)
            {
                pathStatus = NavMeshPathStatus.PathInvalid;
            }
            else if (numberOfNodes == maxNumberOfNodes)
            {
                pathStatus = NavMeshPathStatus.PathPartial;
            }
            else
            {
                pathStatus = NavMeshPathStatus.PathComplete;
            }

            break;
        }
    }