private Vector3 getOutgoingVectorForOneWayIntersection(Intersection intersection, Road connectedRoad)
    {
        float roadEndWidth  = connectedRoad.GetRoadWidth();
        float roadEndLength = roadEndWidth / 2;

        return(IntersectionMath.getOutgoingVector(intersection, connectedRoad).normalized *roadEndWidth / 2);
    }
    private Vector3 CoordinateForRoadWithAbstractRoadInfos(Intersection intersection, Road connectedRoad, RightOrLeft rtlt,
                                                           AbstractWayInfo[] infos)
    {
        infos = AbstractWayInfo.sortAbstractWayInfos(infos);

        // convert the road to an abstract way info
        AbstractWayInfo info = new AbstractWayInfo(IntersectionMath.getOutgoingVector(intersection, connectedRoad).normalized,
                                                   connectedRoad.GetRoadWidth());
        // TODO : CHECK FOR nonexistent index
        int index = 0;

        for (int i = 0; i < infos.Length; i++)
        {
            if (infos[i] == info)
            {
                index = i;
            }
        }

        Vector3[] vertices = MeshVerticesForAbstractWayInfos(infos);

        switch (rtlt)
        {
        case RightOrLeft.LEFT:
            return(vertices[index - 1 < 0 ? infos.Length - 1 : index - 1]);

        case RightOrLeft.RIGHT:
            return(vertices[index]);
        }
        Debug.LogError("Semantics Error, please check");

        return(Vector3.zero);
    }
    private GameObject buildTwoWayIntersection(Intersection intersection, Road road1, Road road2)
    {
        // create a four way intersection instead of a two way intersection if the angle is less than 90
        switch (GetTwoWayIntersectionType(intersection))
        {
        case TwoWayIntersectionType.SKEW:
        case TwoWayIntersectionType.TRANSITION:
            AbstractWayInfo[] infos = AbstractWayInfosForTwoWayIntersection(intersection, road1, road2);
            return(buildMultiwayIntersectionWithVectors(intersection, infos));

        case TwoWayIntersectionType.SMOOTH:
            // only when angle > 90
            Vector3 vec1       = IntersectionMath.getOutgoingVector(intersection, road1).normalized;
            Vector3 vec2       = IntersectionMath.getOutgoingVector(intersection, road2).normalized;
            float   roadWidth1 = road1.GetRoadWidth();
            float   roadWidth2 = road2.GetRoadWidth();
            Vector3 vec1Norm   = Quaternion.Euler(new Vector3(0, 90, 0)) * vec1 * roadWidth1 / 2;
            Vector3 vec2Norm   = Quaternion.Euler(new Vector3(0, -90, 0)) * vec2 * roadWidth2 / 2;
            // check the intersection, if there's its inner, if there isn't, its outer
            Vector3    refPoint;
            GameObject inner;
            GameObject outer;
            if (Math3d.LineLineIntersection(out refPoint, vec1Norm, vec1, vec2Norm,
                                            vec2))
            {
                // we intersected, its inner
                inner = buildInner(vec1Norm, vec2Norm, refPoint, intersection.position, intersection.customization);
                outer = buildOuter(-vec1Norm, -vec2Norm, 4, intersection.position, intersection.customization);
            }
            else
            {
                // we are outer
                outer = buildOuter(vec1Norm, vec2Norm, 4, intersection.position, intersection.customization);
                // get the real intersection
                // we need to * a const since the Math scirpt only considers line to be that long


                inner = buildInner(-vec1Norm, -vec2Norm, refPoint, intersection.position, intersection.customization);
            }

            // add rigidbody to enable selection
            return(createParentIntersectionWithChildIntersections("Two way intersection", intersection.customization, inner,
                                                                  outer));
        }

        Debug.LogError("Semantics Error, please check");
        return(null);
    }
    private AbstractWayInfo[] AbstractWayInfosForMultiwayIntersection(Intersection intersection, Road[] connectedRoads)
    {
// convert roads to vectos
        Vector3[] vectors = connectedRoads.Select(rd => IntersectionMath.getOutgoingVector(intersection, rd)).ToArray();
        float[]   widths  = connectedRoads.Select(rd => rd.GetRoadWidth()).ToArray();

        AbstractWayInfo[] infos;
        // handle when connectedRoads.Length == 3  << build a four-way intersection instead
        if (connectedRoads.Length == 3)
        {
            // find the vector whose direction is of greatest difference to other two

            Vector3 maxVector    = vectors[0];
            float   maxRoadWidth = widths[0];
            float   maxAngles    = 0;
            for (int i = 0; i < 3; i++)
            {
                float accum = 0;
                for (int j = 0; j < 3; j++)
                {
                    float zeroTo180Angle = Vector3.Angle(vectors[i], vectors[j]);
                    float distance       = zeroTo180Angle > 90 ? 180 - zeroTo180Angle : zeroTo180Angle;
                    accum += distance;
                }

                if (accum > maxAngles)
                {
                    maxVector    = vectors[i];
                    maxRoadWidth = widths[i];
                    maxAngles    = accum;
                }
            }

            Vector3[] resultingVectors = { vectors[0], vectors[1], vectors[2], -maxVector };
            float[]   resultingWidths  = { widths[0], widths[1], widths[2], maxRoadWidth };

            infos = AbstractWayInfo.InfosWithDirectionsAndWidths(resultingVectors, resultingWidths);
        }
        else
        {
            infos = AbstractWayInfo.InfosWithDirectionsAndWidths(vectors, widths);
        }

        return(infos);
    }
示例#5
0
    // returns the maximum value of AbstractCarPosition.offset so that the car is not rushing into the intersection
    public float stoppingDistanceForCurrentDrive(AbstractCarPosition carPosition)
    {
        /**
         *
         *  toIntersection                                     ref intersection
         *
         *  toLeftEdge
         *  \===================================================|   ^
         *   \|<          STOPPING DISTANCE                   > |  width(refIntersection)
         *    \ ------------------------------------------------|   x
         *     \                                                |  width(toIntersection)
         *      \===============================================|   v
         *     toRightEdge
         *
         *
         *
         */

        Intersection toIntersection = carPosition.referenceRoad.otherIntersection(carPosition.referenceIntersection);
        Vector3      toLeftEdge     = builder.coordinateForRoadAtIntersection(toIntersection, carPosition.referenceRoad,
                                                                              IntersectionBuilder.RightOrLeft.LEFT);
        Vector3 toRightEdge = builder.coordinateForRoadAtIntersection(toIntersection, carPosition.referenceRoad,
                                                                      IntersectionBuilder.RightOrLeft.RIGHT);

        // get the proportion
        int totalNumberOfLanes =
            carPosition.referenceRoad.GetNumberOfLanesInDirectionWithReferenceIntersection(toIntersection)
            + carPosition.referenceRoad.GetNumberOfLanesInDirectionWithReferenceIntersection(carPosition
                                                                                             .referenceIntersection);

        Vector3 stoppingLocation = Vector3.Lerp(toLeftEdge, toRightEdge,
                                                1f / 2 - (1f / 2 + carPosition.laneNumber) / totalNumberOfLanes) * (1f / 2);

        // project the stopping location onto the outgoing vector

        Vector3 stoppingCompensation = Vector3.Project(stoppingLocation,
                                                       IntersectionMath.getOutgoingVector(toIntersection, carPosition.referenceRoad));

        float stoppingDistance = carPosition.referenceRoad.GetRoadLength() - stoppingCompensation.magnitude;

        return(stoppingDistance);
    }
示例#6
0
    public float startingDistanceForCurrentDrive(AbstractCarPosition carPosition)
    {
        /**
         *
         *  refIntersection                                     toIntersection
         *
         *  fromLeftEdge
         *  \===================================================|   ^
         *   \                                                  |  width(toIntersection)
         *    \ ------------------------------------------------|   x
         * <  >\                                                |  width(refIntersection)
         *  |   \===============================================|   v
         *  |  fromRightEdge
         *  |
         *  +--> startingDistance
         *
         */

        Intersection toIntersection = carPosition.referenceRoad.otherIntersection(carPosition.referenceIntersection);
        Vector3      fromLeftEdge   = builder.coordinateForRoadAtIntersection(carPosition.referenceIntersection, carPosition.referenceRoad,
                                                                              IntersectionBuilder.RightOrLeft.LEFT);
        Vector3 fromRightEdge = builder.coordinateForRoadAtIntersection(carPosition.referenceIntersection, carPosition.referenceRoad,
                                                                        IntersectionBuilder.RightOrLeft.RIGHT);

        // get the proportion
        int totalNumberOfLanes =
            carPosition.referenceRoad.GetNumberOfLanesInDirectionWithReferenceIntersection(toIntersection)
            + carPosition.referenceRoad.GetNumberOfLanesInDirectionWithReferenceIntersection(carPosition
                                                                                             .referenceIntersection);

        Vector3 startingLocation = Vector3.Lerp(fromLeftEdge, fromRightEdge,
                                                1f / 2 + (1f / 2 + carPosition.laneNumber) / totalNumberOfLanes) * (1f / 2);

        // project the stopping location onto the outgoing vector

        Vector3 startignCompensation = Vector3.Project(startingLocation,
                                                       IntersectionMath.getOutgoingVector(carPosition.referenceIntersection, carPosition.referenceRoad));

        float startingDistance = startignCompensation.magnitude;

        return(startingDistance);
    }
    private AbstractWayInfo[] AbstractWayInfosForTwoWayIntersection(Intersection intersection, Road road1, Road road2)
    {
        Vector3 vec1 = IntersectionMath.getOutgoingVector(intersection, road1).normalized;
        Vector3 vec2 = IntersectionMath.getOutgoingVector(intersection, road2).normalized;

        // create a four way intersection instead of a two way intersection if the angle is less than 90
        Vector3[] vecs       = null;
        float[]   roadWidths = null;
        switch (GetTwoWayIntersectionType(intersection))
        {
        case TwoWayIntersectionType.SKEW:


            vecs       = new[] { vec1, vec2, -vec1, -vec2 };
            roadWidths = new[] { road1.GetRoadWidth(), road2.GetRoadWidth(), road1.GetRoadWidth(), road2.GetRoadWidth() };
            break;

        case TwoWayIntersectionType.TRANSITION:
            // create a halfway rotation
            Quaternion rotation = Quaternion.Euler(Quaternion.FromToRotation(vec1, vec2).eulerAngles / 2);
            // this is the virtual directional vector
            Vector3 newVec = rotation * vec1;
            // this is the virtual road width, set it to be the average of the two
            float newWidth = road1.GetRoadWidth() + road2.GetRoadWidth() / 2;

            vecs       = new[] { vec1, vec2, newVec, -newVec };
            roadWidths = new[] { road1.GetRoadWidth(), road2.GetRoadWidth(), newWidth, newWidth };
            break;

        case TwoWayIntersectionType.SMOOTH:
            Debug.LogError("Code Error, this method is to be called without smooth transition");

            break;
        }
        // zip vecs and roadWidths into abstract road infos
        AbstractWayInfo[] infos = AbstractWayInfo.InfosWithDirectionsAndWidths(vecs, roadWidths);
        return(infos);
    }
    /**
     * @brief the detailed type for a two-way intersection
     *
     * @param intersection the intersection to inspect type
     *
     */
    public TwoWayIntersectionType GetTwoWayIntersectionType(Intersection intersection)
    {
        Debug.Assert(intersection.getConnectedRoads().Length == 2);
        Road road1 = intersection.getConnectedRoads()[0];
        Road road2 = intersection.getConnectedRoads()[1];

        Vector3 vec1 = IntersectionMath.getOutgoingVector(intersection, road1).normalized;
        Vector3 vec2 = IntersectionMath.getOutgoingVector(intersection, road2).normalized;

        // create a four way intersection instead of a two way intersection if the angle is less than 90
        if (Vector3.Angle(vec1, vec2) < 90)
        {
            return(TwoWayIntersectionType.SKEW);
        }
        else         //force a four way intersection if two roads are of different width
        if (Mathf.Approximately(road1.GetRoadWidth(), road2.GetRoadWidth()) == false)
        {
            return(TwoWayIntersectionType.TRANSITION);
        }
        else
        {
            return(TwoWayIntersectionType.SMOOTH);
        }
    }