public void test4()
    {
        IntersectionChecker i = new IntersectionChecker();
        Edge road             = new Edge(new Node(20, 155), new Node(75, 200), RoadTypes.STREET);

        i.fixRoad(road);
        RoadVisualizer.placeRoad(road, "0");
    }
    //TESTING
    public void test()
    {
        RoadVisualizer.placeRoad(new Edge(new Node(100, 100), new Node(125, 125), RoadTypes.HIGHWAY), "0");
        RoadVisualizer.placeRoad(new Edge(new Node(125, 125), new Node(180, 150), RoadTypes.HIGHWAY), "1");
        RoadVisualizer.placeRoad(PositionLegalizer.legalizeRoad(new Edge(new Node(180, 150), new Node(200, 250), RoadTypes.HIGHWAY)), "2");
        RoadVisualizer.placeRoad(new Edge(new Node(200, 250), new Node(200, 550), RoadTypes.HIGHWAY), "3");
        RoadVisualizer.placeRoad(new Edge(new Node(200, 550), new Node(200, 750), RoadTypes.HIGHWAY), "4");

        RoadVisualizer.placeRoad(new Edge(new Node(125, 125), new Node(125, 175), RoadTypes.STREET), "5");
        RoadVisualizer.placeRoad(new Edge(new Node(125, 175), new Node(80, 225), RoadTypes.STREET), "6");
        RoadVisualizer.placeRoad(new Edge(new Node(125, 175), new Node(180, 150), RoadTypes.STREET), "7");
    }
    public void generateRoadMap()
    {
        resetRoads();

        // Generate the first roads
        foreach (Edge road in globalGoals.generateFirstRoads(Approach.RANDOM))
        {
            q.push(road, road.getTime());
        }

        while (q.size > 0)
        {
            Edge roadToBuild = q.pop();

            //check with localconstraints
            roadToBuild = localConstraints.validateRoad(roadToBuild);
            if (roadToBuild != null)
            {
                if (CityGeneratorUI.DebugMode)
                {
                    Debug.Log("roadToBuild was valid");
                }
                //add it to the roads array
                roads.Add(roadToBuild);
                //visualize it and give it the correct index
                RoadVisualizer.placeRoad(roadToBuild, (roads.Count - 1).ToString());

                foreach (Edge road in globalGoals.generateNewRoads(roadToBuild))
                {
                    q.push(road, road.getTime());
                }
            }
            else
            {
                if (CityGeneratorUI.DebugMode)
                {
                    Debug.Log("roadToBuild was not valid");
                }
            }
        }

        //construct the list of nodes with all their references
        constructNodeGraph();

        CityGenerator.nrOfRoads = roads.Count;

        PreviewRoads.NrRoads = roads.Count; //reset the nr of roads visualized
        roadBuilt            = true;
    }
Exemplo n.º 4
0
    /// <summary>
    /// Checks if the road intersects with other roads within a certain distance from the road (in the direction the road is facing)
    /// </summary>
    /// <returns><c>true</c>, if intersection was found and also changes fixedRoad, <c>false</c> otherwise.</returns>
    /// <param name="road">Road.</param>
    /// <param name="dist">Distance over which the intersection should be checked</param>
    private bool checkIntersection(Edge road, float dist)
    {
        //set up variables needed for boxcastall
        int     layerMask       = 1 << LayerMask.NameToLayer("Edge");
        Vector3 halfExtends     = new Vector3(0.1f, 100, ((posN1 - posN2).magnitude) / 2);
        Vector3 roadCenter      = Vector3.Lerp(posN1, posN2, 0.5f);
        Vector3 direction       = posN2 - posN1;
        Vector2 roadOrientation = new Vector2(direction.x, direction.z);

        //get the intersections with roads
        RaycastHit[] intersections = Physics.BoxCastAll(roadCenter, halfExtends, direction, Quaternion.LookRotation(direction), dist, layerMask);

        //no intersections, good!
        if (intersections.Length == 0)
        {
            //Debug.Log ("Road did not intersect");
            return(false);
        }
        else
        {
            float closestRoadDistance = float.MaxValue;

            //just set it to the first value
            GameObject closestRoad         = null;
            Vector2    closestIntersection = Vector2.zero;

            //first we check which road is closest
            foreach (RaycastHit hit in intersections)
            {
                //Debug.Log (road.getRoadType().ToString() + " intersects with: " + hit.collider.gameObject.name + " which has N1 at: " + hit.transform.GetChild (0).localPosition + " and posN1 is: " + posN1);
                //Debug.Log (road.getRoadType().ToString() + " intersects with: " + hit.collider.gameObject.name + " which has N2 at: " + hit.transform.GetChild (1).localPosition + " and posN1 is: " + posN1);
                //Debug.Log (hit.collider.gameObject.name + " shares N1: " + CoordinateHelper.areEqual (hit.transform.GetChild (0).localPosition, posN1));
                //Debug.Log (hit.collider.gameObject.name + " shares N2: " + CoordinateHelper.areEqual (hit.transform.GetChild (1).localPosition, posN1));

                //consider the case where roads have the same endpoints, i.e., they overlap exactly
                if ((CoordinateHelper.areEqual(hit.transform.GetChild(1).localPosition, posN1) && CoordinateHelper.areEqual(hit.transform.GetChild(0).localPosition, posN2)) ||
                    (CoordinateHelper.areEqual(hit.transform.GetChild(1).localPosition, posN2) && CoordinateHelper.areEqual(hit.transform.GetChild(0).localPosition, posN1)))
                {
                    //in this case the road cannot be placed
                    if (CityGeneratorUI.DebugMode)
                    {
                        Debug.Log("Intersection checker: roads overlapped exactly");
                    }
                    fixedRoad = null;
                    return(true);
                }
                else
                {
                    //only consider road segments that are not a predecessor
                    if (!CoordinateHelper.areEqual(hit.transform.GetChild(1).localPosition, posN1))
                    {
                        //also dont consider roads that branch out from the same point
                        if (!CoordinateHelper.areEqual(hit.transform.GetChild(0).localPosition, posN1))
                        {
                            //these are the roads that have no endpoints in common with the current road.

                            //check if the angle is valid
                            Vector2 otherRoadOrientation = new Vector2(hit.transform.forward.x, hit.transform.forward.z);
                            //check if the two roads have enough "space" between them.

                            if (isValidAngle(roadOrientation.normalized, otherRoadOrientation.normalized))
                            {
                                //find the road that is intersected with first
                                Vector2 intersectionPoint = lineIntersectionPoint(
                                    road.n1.pos,
                                    road.n2.pos,
                                    CoordinateHelper.threeDtoTwoD(hit.transform.GetChild(0).localPosition),
                                    CoordinateHelper.threeDtoTwoD(hit.transform.GetChild(1).localPosition));

                                float distance = (road.n1.pos - intersectionPoint).magnitude;
                                if (distance < closestRoadDistance)
                                {
                                    //Debug.Log ("Road: " + hit.collider.gameObject.name + " has distance: " + (posN1 - hit.collider.transform.position).magnitude + " to n1");
                                    closestRoad         = hit.collider.gameObject;
                                    closestIntersection = intersectionPoint;
                                    closestRoadDistance = distance;
                                }
                            }
                            else
                            {
                                //return that the road is invalid
                                fixedRoad = null;
                                return(true);
                            }
                        }
                        else
                        {
                            if (CityGeneratorUI.DebugMode)
                            {
                                Debug.Log("Roads have same start point");
                            }
                            //there is another road branching out from the same point.. check their angle
                            Vector2 sameBranchRoadOrientation = new Vector2(hit.transform.forward.x, hit.transform.forward.z);

                            if (Vector2.Angle(roadOrientation.normalized, sameBranchRoadOrientation.normalized) > CityGenerator.minRoadAngle)
                            {
                                //this is fine
                            }
                            else
                            {
                                //when this happens we cannot place this road
                                fixedRoad = null;
                                return(true);
                            }
                        }
                    }
                    else
                    {
                        //just to be sure, we dont want to make sharp turns
                        if (CityGeneratorUI.DebugMode)
                        {
                            Debug.Log("Roads have same start point");
                        }
                        //there is another road branching out from the same point.. check their angle
                        Vector2 sameBranchRoadOrientation = new Vector2(hit.transform.forward.x, hit.transform.forward.z);

                        if (Vector2.Angle(roadOrientation.normalized, sameBranchRoadOrientation.normalized) < 180 - CityGenerator.minRoadAngle)
                        {
                            //this is fine
                        }
                        else
                        {
                            //when this happens we cannot place this road
                            fixedRoad = null;
                            return(true);
                        }
                    }
                }
            }

            //no legitimate intersection was found
            if (closestRoad == null)
            {
                //return that no intersection was found
                return(false);
            }
            else
            {
                //Now we want to see if the angle between the roads is large enough.
                Vector2 closestRoadOrientation = new Vector2(closestRoad.transform.forward.x, closestRoad.transform.forward.z);

                //we want to make sure the angle is large enough
                if (isValidAngle(roadOrientation.normalized, closestRoadOrientation.normalized))
                {
                    //now we also need to update the roads list in the roadmapgenerator
                    //set up all involved nodes
                    Node roadToReplaceN1  = new Node(closestRoad.transform.GetChild(0).localPosition.x, closestRoad.transform.GetChild(0).localPosition.z);
                    Node intersectionNode = new Node(closestIntersection);
                    Node roadToReplaceN2  = new Node(closestRoad.transform.GetChild(1).localPosition.x, closestRoad.transform.GetChild(1).localPosition.z);

                    //check if after splitting the new road segments are long enough
                    if ((intersectionNode.pos - roadToReplaceN1.pos).magnitude > CityGenerator.minRoadLengthAfterSplit)
                    {
                        if ((intersectionNode.pos - roadToReplaceN2.pos).magnitude > CityGenerator.minRoadLengthAfterSplit)
                        {
                            fixedRoad.n2 = intersectionNode;

                            //also check if the fixed road is long enough, do this before generating intersections!
                            if (CoordinateHelper.validRoadLength(fixedRoad))
                            {
                                //if the width of the closest road equals the highwaywidth, we create new highways
                                RoadTypes roadType = (closestRoad.transform.localScale.x == CityGenerator.highwayWidth) ? RoadTypes.HIGHWAY : RoadTypes.STREET;

                                //create new road segments for the road that is going to be split
                                Edge splitRoad1 = new Edge(roadToReplaceN1, intersectionNode, roadType);
                                Edge splitRoad2 = new Edge(intersectionNode, roadToReplaceN2, roadType);

                                //get a reference to the road that is going to be split
                                Edge roadToReplace = RoadMapGenerator.getRoad(roadToReplaceN1, roadToReplaceN2);

                                //the road segments which will replace closestRoad
                                List <Edge> replacementRoads = new List <Edge> ();
                                replacementRoads.Add(splitRoad1);
                                replacementRoads.Add(splitRoad2);

                                if (CityGeneratorUI.DebugMode)
                                {
                                    Debug.Log(closestRoad.name + " was split by road starting at" + road.n1 + " and ending at " + road.n2);
                                }

                                //physically change the road
                                RoadVisualizer.replaceRoad(closestRoad, replacementRoads);

                                //now replace the roads in the road list (logically)
                                RoadMapGenerator.replaceRoad(roadToReplace, replacementRoads);
                            }
                        }
                        else
                        {
                            //we cannot fix this intersection
                            fixedRoad = null;
                            return(true);
                        }
                    }
                    else
                    {
                        //we cannot fix this intersection
                        fixedRoad = null;
                        return(true);
                    }

                    return(true);
                }
                else
                {
                    //the road intersects with a road while the angle between them is too small
                    //so we cannot place this road
                    fixedRoad = null;
                    return(true);
                }
            }
        }
    }