LineLineIntersection() public static method

public static LineLineIntersection ( Vector3 &intersection, Vector3 linePoint1, Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2 ) : bool
intersection Vector3
linePoint1 Vector3
lineVec1 Vector3
linePoint2 Vector3
lineVec2 Vector3
return bool
Ejemplo n.º 1
0
    /// <summary>
    /// Method used to calculate destination position when player jumps.
    /// </summary>
    /// <returns>The player's jump destination position.</returns>
    /// <param name="jumpStartPosition">Jump start position (typically, player's current position).</param>
    /// <param name="currentVertexFollowed">Current vertex that is being followed.</param>
    public Vector2 GetJumpDestinationPosition(Vector2 jumpStartPosition, VertexController currentVertexFollowed)
    {
        int currentVertexIndex  = currentVertexFollowed.transform.GetSiblingIndex();
        int previousVertexIndex = currentVertexIndex - 1;

        previousVertexIndex = previousVertexIndex < 0 ? previousVertexIndex + this.transform.childCount : previousVertexIndex;
        VertexController previousVertex = this.transform.GetChild(previousVertexIndex).GetComponent <VertexController>();
        int nextVertexIndex             = (currentVertexIndex + 1) % this.transform.childCount;
        VertexController nextVertex     = this.transform.GetChild(nextVertexIndex).GetComponent <VertexController>();

        Vector2 line = (nextVertex.transform.position - previousVertex.transform.position).normalized;

        line = line.y < 0 ? -line : line;
        float lineA = Mathf.Tan(Vector2.Angle(line, Vector2.right) * Mathf.Deg2Rad);
        float lineB = jumpStartPosition.y - (lineA * jumpStartPosition.x);

        Vector2 linePoint1 = new Vector2(0, lineB);
        Vector2 linePoint2 = new Vector2(1, lineA + lineB);

        // Debug lines drawing, uncomment to debug this method
        //Debug.DrawLine(previousVertex.transform.position, nextVertex.transform.position, Color.green, 3f);
        //Debug.DrawLine(linePoint1, linePoint2, Color.red, 3f);
        //Debug.DrawLine(jumpStartPosition + Vector2.left, jumpStartPosition + Vector2.right, Color.white, 3f);
        //Debug.DrawLine(jumpStartPosition + Vector2.down, jumpStartPosition + Vector2.up, Color.white, 3f);

        Vector3 intersectionPoint = Vector3.zero;

        Math3d.LineLineIntersection(out intersectionPoint, currentVertexFollowed.transform.position, (nextVertex.transform.position - currentVertexFollowed.transform.position).normalized, linePoint1, (linePoint2 - linePoint1).normalized);

        return(intersectionPoint);
    }
Ejemplo n.º 2
0
    private static bool IsTopAndBottomCrossing(Vector3 wayFirstMiddleLineTopPos, Vector3 waySecondMiddleLineTopPos, Vector3 wayFirstMiddleLineBottomPos, Vector3 waySecondMiddleLineBottomPos)
    {
        Vector3 topVector         = waySecondMiddleLineTopPos - wayFirstMiddleLineTopPos;
        Vector3 bottomVector      = waySecondMiddleLineBottomPos - wayFirstMiddleLineBottomPos;
        Vector3 intersectionPoint = Vector3.zero;

        return(Math3d.LineLineIntersection(out intersectionPoint, wayFirstMiddleLineTopPos, topVector, wayFirstMiddleLineBottomPos, bottomVector));
    }
Ejemplo n.º 3
0
    public void tick()
    {
        // check if there are cars waiting to go through the intersection
        if (currentlyOperatingCar == null)
        {
            if (carsAtThisIntersection.Count != 0)
            {
                currentlyOperatingCar = carsAtThisIntersection [0];
                carsAtThisIntersection.RemoveAt(0);
                // remove the car from the road // TODO: Redesign the communication between road control and intersection control
                trafficManager.roadControlForRoad(currentlyOperatingCar.position.referenceRoad).RemoveCarFromRoad(currentlyOperatingCar);


                // calculate the final form after going through the intersection
                Road targetRoad = navigationManager.targetWayForAbstractCarAtIntersection(currentlyOperatingCar, referenceIntersection);

                // get target abstract position
                AbstractCarPosition targetAbstractPosition = new AbstractCarPosition(targetRoad, referenceIntersection,
                                                                                     0, currentlyOperatingCar.position.laneNumber);
                float startingDistance = trafficMath.startingDistanceForCurrentDrive(targetAbstractPosition);
                targetAbstractPosition.offset = startingDistance;
                // get current and target real location
                currentPosition = currentlyOperatingCar.carGameObject.transform.position;
                currentRotation = currentlyOperatingCar.carGameObject.transform.rotation;
                currentlyOperatingCar.position = targetAbstractPosition;
                currentlyOperatingCar.CalculatePositionAndOrientation(out targetPosition, out targetRotation);
                // calculate the pivot
                Math3d.LineLineIntersection(out pivot, currentPosition,
                                            Quaternion.Euler(0, 90, 0) * currentRotation * Vector3.right,
                                            targetPosition, Quaternion.Euler(0, 90, 0) * targetRotation * Vector3.right);
                startTime = Time.time;
            }
        }
        else
        {
            // animate
            // very little animation if it is just a curve
            float turningDuration = referenceIntersection.GetGraphicsType() == Intersection.IntersectionGraphicsType.TWO_WAY_SMOOTH ?
                                    0.1f : 1f;
            // end if necessary
            if (Time.time - startTime > turningDuration)
            {
                // we end turning and proceed to the following route
                RoadTrafficControl roadControl = trafficManager.roadControlForRoad(currentlyOperatingCar.position.referenceRoad);
                roadControl.AddCar(currentlyOperatingCar);
                // remember intersections is updated after roads
                currentlyOperatingCar.updateCarPosition();
                currentlyOperatingCar = null;
                return;
            }
            // Slerp between positions around pivot and lerp the Quaternion rotation
            currentlyOperatingCar.carGameObject.transform.position
                = pivot + Vector3.Slerp(currentPosition - pivot, targetPosition - pivot, (Time.time - startTime) / turningDuration);
            currentlyOperatingCar.carGameObject.transform.rotation
                = Quaternion.Slerp(currentRotation, targetRotation, (Time.time - startTime) / turningDuration);
        }
    }
Ejemplo n.º 4
0
    public void PopulateNodeMap()
    {
        roads = GetComponentsInChildren <Road>();
        Vector3 road1start, road1end, road2start, road2end, road1vec, road2vec;

        nodeSegments = new List <Segment>();

        for (int i = 0; i < roads.Length; i++)
        {
            if (roads.Length > 1)
            {
                for (int j = 0; j < roads[i].segments.Count; j++)
                {
                    for (int k = 0; k < roads.Length; k++)
                    {
                        if (roads[k] != roads[i])
                        {
                            for (int t = 0; t < roads[k].segments.Count; t++)
                            {
                                road1start = roads[i].segments[j].start();
                                road1end   = roads[i].segments[j].end();
                                road1vec   = roads[i].segments[j].vector();
                                if (!nodeSegments.Contains(roads[i].segments[j]))
                                {
                                    nodeSegments.Add(roads[i].segments[j]);
                                }
                                road2start = roads[k].segments[t].start();
                                road2end   = roads[k].segments[t].end();
                                road2vec   = roads[k].segments[t].vector();

                                if (Math3d.AreLineSegmentsCrossing(road1start, road1end, road2start, road2end))
                                {
                                    Vector3 intersection;
                                    Math3d.LineLineIntersection(out intersection, road1start, road1vec, road2start, road2vec);
                                    if (CheckForIntersection(intersection) == false)
                                    {
                                        Node node = NewNode(intersection);
                                        node.transform.parent = roads[i].transform;
                                        Segment seg1 = roads[i].segments[j];
                                        Segment seg2 = roads[k].segments[t];
                                        AddIntersection(node, roads[i], roads[k], seg1, seg2, type: Node.Type.intersection);
                                        roads[i].SplitSegment(seg1, node);
                                        roads[k].SplitSegment(seg2, node);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        //Debug.Log(nodeSegments.Count + " road nodes in NodeMap");
        CleanUpIntersections();
        SetNodeSegments();
        roads.ToList().ForEach(x => x.nodes = x.OrderNodes());
    }
Ejemplo n.º 5
0
        // Get updated ac bd
        private static Vector3[] GetVerticesToStickWalls(Wall cur, Wall linked)
        {
            var common = GetCommonPosition(cur, linked);

            var perp = cur.Perpendicular;

            var decal = perp * cur.Thickness / 2;

            var a = cur.P1 - decal;
            var c = cur.P1 + decal;

            var b = cur.P2 - decal;
            var d = cur.P2 + decal;

            var perp2 = linked.Perpendicular;

            var decal2 = perp2 * linked.Thickness / 2;

            var a2 = linked.P1 - decal2;
            var c2 = linked.P1 + decal2;

            var b2 = linked.P2 - decal2;
            var d2 = linked.P2 + decal2;

            Vector3 f, g;

            // p1 side
            if (cur.P1 == common)
            {
                if (linked.P1 == common)
                {
                    var okf = Math3d.LineLineIntersection(out f, a, cur.Direction, c2, linked.Direction);
                    var okg = Math3d.LineLineIntersection(out g, c, cur.Direction, a2, linked.Direction);
                    return(new[] { f, g, b, d });
                }
                else
                {
                    var okf = Math3d.LineLineIntersection(out f, a, cur.Direction, b2, linked.Direction);
                    var okg = Math3d.LineLineIntersection(out g, c, cur.Direction, d2, linked.Direction);
                    return(new[] { f, g, b, d });
                }
            }

            if (linked.P1 == common)
            {
                var okf = Math3d.LineLineIntersection(out f, b, cur.Direction, b2, linked.Direction);
                var okg = Math3d.LineLineIntersection(out g, d, cur.Direction, d2, linked.Direction);
                return(new[] { a, c, f, g });
            }
            else
            {
                var okf = Math3d.LineLineIntersection(out f, b, cur.Direction, d2, linked.Direction);
                var okg = Math3d.LineLineIntersection(out g, d, cur.Direction, b2, linked.Direction);
                return(new[] { a, c, f, g });
            }
        }
Ejemplo n.º 6
0
    // get intersection of rd1's right edge with rd2's left edge
    private Vector3 CoordinateOfIntersectionBetweenTwoWays(AbstractWayInfo rd1, AbstractWayInfo rd2)
    {
        Vector3 coordinateRes;

        Vector3 vec1     = rd1.direction.normalized;
        Vector3 vec2     = rd2.direction.normalized;
        Vector3 vec1Norm = Quaternion.Euler(new Vector3(0, 90, 0)) * vec1 * rd1.roadWidth / 2;
        Vector3 vec2Norm = Quaternion.Euler(new Vector3(0, -90, 0)) * vec2 * rd2.roadWidth / 2;

        bool res = Math3d.LineLineIntersection(out coordinateRes, vec1Norm, vec1, vec2Norm, vec2);

        return(coordinateRes);
    }
Ejemplo n.º 7
0
    public static Vector3 Circumcentre2(Vector3 a, Vector3 b, Vector3 c, Vector3 d)
    {
        // Calculate plane for edge AB
        Vector3 planeABNormal = b - a;
        Vector3 planeABPoint  = Vector3.Lerp(a, b, 0.5f);

        // Calculate plane for edge AC
        Vector3 planeACNormal = c - a;
        Vector3 planeACPoint  = Vector3.Lerp(a, c, 0.5f);

        // Calculate plane for edge BD
        Vector3 planeBDNormal = d - b;
        Vector3 planeBDPoint  = Vector3.Lerp(b, d, 0.5f);

        // Calculate plane for edge CD
        Vector3 planeCDNormal = d - c;
        Vector3 planeCDPoint  = Vector3.Lerp(c, d, 0.5f);

        // Calculate line that is the plane-plane intersection between AB and AC
        Vector3 linePoint1;
        Vector3 lineDirection1;

        // Taken from: http://wiki.unity3d.com/index.php/3d_Math_functions
        Math3d.PlanePlaneIntersection(out linePoint1, out lineDirection1, planeABNormal, planeABPoint, planeACNormal, planeACPoint);

        Vector3 linePoint2;
        Vector3 lineDirection2;

        Math3d.PlanePlaneIntersection(out linePoint2, out lineDirection2, planeBDNormal, planeBDPoint, planeCDNormal, planeCDPoint);

        // Calculate the point that is the plane-line intersection between the above line and CD
        Vector3 intersection;

        // Floating point inaccuracy often causes these two lines to not intersect, in that case get the two closest points on each line
        // and average them
        // Taken from: http://wiki.unity3d.com/index.php/3d_Math_functions
        if (!Math3d.LineLineIntersection(out intersection, linePoint1, lineDirection1, linePoint2, lineDirection2))
        {
            Vector3 closestLine1;
            Vector3 closestLine2;

            // Taken from: http://wiki.unity3d.com/index.php/3d_Math_functions
            Math3d.ClosestPointsOnTwoLines(out closestLine1, out closestLine2, linePoint1, lineDirection1, linePoint2, lineDirection2);

            // Intersection is halfway between the closest two points on lines
            intersection = Vector3.Lerp(closestLine2, closestLine2, 0.5f);
        }

        return(intersection);
    }
Ejemplo n.º 8
0
    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);
    }
Ejemplo n.º 9
0
    private static void MakeBezier(List <DrivePath> drivePaths, Vector3 start, Vector3 startDirection, Vector3 end, Vector3 endDirection, long posId, float breakFactor, float wayWidthFactor, float bezierResolution, string blinkDirection)
    {
        bezierResolution = Mathf.Min(bezierResolution, BEZIER_MAX_RESOLUTION);
        Vector3 intersection = Vector3.zero;
        bool    intersects   = Math3d.LineLineIntersection(out intersection, start, startDirection, end, endDirection);

        if (intersects)
        {
            Vector3 prev = Vector3.zero;
            for (float t = 0.0f; t <= 1.0f; t += 1f / bezierResolution)
            {
                Vector3 curr = Math3d.GetVectorInBezierAtTime(t, start, intersection, end);
                if (prev != Vector3.zero)
                {
                    DrivePath bezierDrivePath = new DrivePath();
                    bezierDrivePath.startVector         = prev;
                    bezierDrivePath.endVector           = curr;
                    bezierDrivePath.startId             = posId;
                    bezierDrivePath.endId               = posId;
                    bezierDrivePath.fullLength          = (curr - prev).magnitude;
                    bezierDrivePath.breakFactor         = breakFactor;
                    bezierDrivePath.originalBreakFactor = breakFactor;
                    bezierDrivePath.wayWidthFactor      = wayWidthFactor;
                    bezierDrivePath.blinkDirection      = blinkDirection;
                    bezierDrivePath.blinkStart          = 0f;
                    drivePaths.Add(bezierDrivePath);
                }
                prev = curr;
            }
        }
        else
        {
            // Something is weird, just drive straight...
            DrivePath straightDrivePath = new DrivePath();
            straightDrivePath.startVector         = start;
            straightDrivePath.endVector           = end;
            straightDrivePath.startId             = posId;
            straightDrivePath.endId               = posId;
            straightDrivePath.fullLength          = (end - start).magnitude;
            straightDrivePath.breakFactor         = 1.0f;
            straightDrivePath.originalBreakFactor = straightDrivePath.breakFactor;
            straightDrivePath.wayWidthFactor      = wayWidthFactor;
            straightDrivePath.blinkDirection      = blinkDirection;
            straightDrivePath.blinkStart          = 0f;
            drivePaths.Add(straightDrivePath);
        }
    }
Ejemplo n.º 10
0
    Segment ReturnBoundingSegment(Vector3 origin, Vector3 hitPoint, Road hitRoad)
    {
        Segment hitSegment = hitRoad.segments[0];
        float   distance   = 0;

        foreach (Segment segment in hitRoad.segments)
        {
            Vector3 intersection;
            if (Math3d.LineLineIntersection(out intersection, origin, hitPoint, segment.start(), segment.end()))
            {
                if (Vector3.Distance(intersection, origin) > distance)
                {
                    hitSegment = segment;
                    distance   = Vector3.Distance(intersection, origin);
                }
            }
        }
        return(hitSegment);
    }
Ejemplo n.º 11
0
    public LotInfo(Block block, List <Vector3> lotVerts, Vector3 direction, Vector3 left, Vector3 right, bool parentBlock = false, LotInfo parentLot = null)
    {
        ParentBlock = block;
        ParentLot   = parentLot;
        LotVerts    = lotVerts;
        Direction   = direction;
        Left        = left;
        Right       = right;
        Center      = (Left + Right) / 2;
        Frontage    = (right.x - left.x);

        List <Segment> segments = block.boundingSegments;

        RoadFacingVerts = new List <Vector3>();
        LotCenter       = Utils.AverageVectors(lotVerts);
        Vector3 _dir = new Vector3(0, 0, (LotCenter - ParentBlock.BlockCenter).z).normalized * 3f;

        Direction = _dir;
        if (_dir == Vector3.zero)
        {
            //Debug.Log("center " + LotCenter + " parent " + ParentBlock.BlockCenter);
        }


        for (int i = 0; i < lotVerts.Count; i++)
        {
            for (int j = 0; j < segments.Count; j++)
            {
                Vector3 A2 = lotVerts[i] + _dir;
                if (Math3d.AreLineSegmentsCrossing(lotVerts[i], A2, segments[j].start(), segments[j].end()))
                {
                    RoadFacingVerts.Add(lotVerts[i]);
                    RoadSegment = segments[j];
                    Math3d.LineLineIntersection(out RoadPoint,
                                                lotVerts[i], A2, segments[j].start(), segments         [j].end());
                }
            }
        }
        //Debug.Log(RoadFacingVerts.Count);
        //Frontage = Vector3.Distance(RoadFacingVerts[0],RoadFacingVerts[1]);
    }
Ejemplo n.º 12
0
    public List <Vector3> BlockRay(Vector3 origin, Vector3 dir, bool vertical = false, bool reciprocal = true, bool baseLine = false)
    {
        Vector3 point1 = origin;
        var     points = new List <Vector3>();

        points.Add(origin);
        Ray ray = new Ray(origin, dir * 1000f);

        ray.origin = ray.GetPoint(20f);


        foreach (var pair in shiftedPairs)
        {
            Vector3 intersection;

            //i'm so so so so so sorry for this
            if (Math3d.AreLineSegmentsCrossing(ray.origin, origin, pair[0], pair[1]))
            {
                Math3d.LineLineIntersection(out intersection, ray.origin, ray.origin - origin, pair[0], pair[0] - pair[1]);

                if ((Mathf.Sign(dir.x) == -1 && intersection.x <= point1.x) ||
                    (Mathf.Sign(dir.x) == 1 && intersection.x >= point1.x) ||
                    (Mathf.Sign(dir.z) == 1 && vertical == true && intersection.z >= point1.z) ||
                    (Mathf.Sign(dir.z) == -1 && vertical == true && intersection.z <= point1.z))
                {
                    point1 = intersection;
                    //Debug.Log(point1);
                    if (baseLine)
                    {
                        //shiftedVerts.Add(intersection);
                    }
                    points.Add(point1);
                    //Instantiate(marker, point1, Quaternion.identity, this.transform);
                }
            }
        }

        return(points);
    }
Ejemplo n.º 13
0
    private static void GetBezierPoints(List <Vector3> meshPoints, WayReference way1, WayReference way2, Vector3 right, Vector3 leftWay2)
    {
        // Add bezier points between this ways "right" and next ways "left" point
        Vector3 intersectionPoint;
        bool    intersectionFound = Math3d.LineLineIntersection(out intersectionPoint, right, way1.transform.rotation * Vector3.right, leftWay2, way2.transform.rotation * Vector3.right);

        if (!intersectionFound)
        {
            intersectionFound = Math3d.LineLineIntersection(out intersectionPoint, right, Quaternion.Euler(new Vector3(0, 0, 180f) + way1.transform.rotation.eulerAngles) * Vector3.right, leftWay2, Quaternion.Euler(new Vector3(0, 0, 180f) + way2.transform.rotation.eulerAngles) * Vector3.right);
        }
        if (intersectionFound)
        {
            // Intersection found, draw the bezier curve
            float bezierLength   = Math3d.GetBezierLength(right, intersectionPoint, leftWay2);
            float numberOfPoints = bezierLength * WayHelper.BEZIER_RESOLUTION;
            float step           = 1.0f / numberOfPoints;
            bool  doBreak        = false;
            for (float time = step; time < 1.0f + step; time += step)
            {
                if (time > 1f)
                {
                    time    = 1f;
                    doBreak = true;
                }
                Vector3 bezierPoint = Math3d.GetVectorInBezierAtTime(time, right, intersectionPoint, leftWay2);
                meshPoints.Add(bezierPoint);
                if (doBreak)
                {
                    break;
                }
            }
        }
        else
        {
            // No intersection found for way points, just draw a straight line
            meshPoints.Add(leftWay2);
        }
    }
Ejemplo n.º 14
0
    private static void AddBezierPoints(List <Vector3> meshPoints, Vector3 start, Quaternion startRotation, Vector3 end, Quaternion endRotation)
    {
        // Add bezier points between "start" and "end"
        Vector3 intersectionPoint;
        bool    intersectionFound = Math3d.LineLineIntersection(out intersectionPoint, start, startRotation * Vector3.right, end, endRotation * Vector3.right);

        if (!intersectionFound)
        {
            intersectionFound = Math3d.LineLineIntersection(out intersectionPoint, start, Quaternion.Euler(new Vector3(0, 0, 180f) + startRotation.eulerAngles) * Vector3.right, end, Quaternion.Euler(new Vector3(0, 0, 180f) + endRotation.eulerAngles) * Vector3.right);
        }
        if (intersectionFound)
        {
            // Intersection found, draw the bezier curve
            float bezierLength   = Math3d.GetBezierLength(start, intersectionPoint, end);
            float numberOfPoints = bezierLength * WayHelper.BEZIER_RESOLUTION;
            float step           = 1.0f / numberOfPoints;
            bool  doBreak        = false;
            for (float time = step; time < 1.0f + step; time += step)
            {
                if (time > 1f)
                {
                    time    = 1f;
                    doBreak = true;
                }
                Vector3 bezierPoint = Math3d.GetVectorInBezierAtTime(time, start, intersectionPoint, end);
                meshPoints.Add(bezierPoint);
                if (doBreak)
                {
                    break;
                }
            }
        }
        else
        {
            // No intersection found for way points, just draw a straight line
            meshPoints.Add(end);
        }
    }
Ejemplo n.º 15
0
    void Compute()
    {
        Awake();
        float delta     = 1.0f / size;
        int   lastCount = count;

        count = (size) * (size);
        if (rays == null || rays.Length != lastCount)
        {
            uv   = new Vector2[count];
            xyz  = new Vector3[count];
            rays = new BouncyRay[count];
        }

        int     current = 0;
        Vector3 origin  = this.transform.position;

        for (int x = 0; x < size; ++x)
        {
            for (int y = 0; y < size; ++y)
            {
                Vector2 uv  = new Vector2(x, y) / (size - 1);
                Ray     ray = _camera.ViewportPointToRay(new Vector3(uv.x, uv.y, 1));

                rays[current] = new BouncyRay(ray)
                {
                    uv = uv
                };
                bool hit = CastRay(ray, ref rays[current]);

                ++current;
            }
        }

        // Sîmple stats
        idxRayOpticalCenter = (size - 1) / 2 + size * (size - 1) / 2;
        int hits = 0;

        lengthAvg = 0;
        foreach (BouncyRay r in rays)
        {
            if (r.Hit)
            {
                ++hits;
                lengthAvg += r.Length;
            }
        }

        coverture = ((float)hits) / count;
        lengthAvg = lengthAvg / hits;
        lengthDev = 0;
        foreach (BouncyRay r in rays)
        {
            lengthDev += Mathf.Abs(r.Length - lengthAvg);
        }

        // find the intersections
        intersectionCount = 0;
        Vector3 centroidIntersection = Vector3.zero;
        Vector3 avgCentroid          = Vector3.zero;

        for (int r1 = 0; r1 < rays.Length; ++r1)
        {
            BouncyRay raycast1 = rays[r1];
            if (raycast1.Hit)
            {
                Ray ray1 = raycast1.Unfolded;
                for (int r2 = r1 + 1; r2 < rays.Length; ++r2)
                {
                    BouncyRay raycast2 = rays[r2];
                    if (raycast2.Hit)
                    {
                        Ray     ray2 = raycast2.Unfolded;
                        Vector3 intersection;
                        if (Math3d.LineLineIntersection(out intersection, ray1.origin, ray1.direction, ray2.origin, ray2.direction))
                        {
                            centroidIntersection += intersection;
                            ++intersectionCount;
                        }
                    }
                }
                avgCentroid += ray1.origin;
            }
        }

        if (compute && intersectionCount > 0)
        {
            centroidIntersection /= intersectionCount;
            if (otherCamera != null)
            {
                Ray physicalCenterRay = new Ray(this.transform.position, this.transform.forward);
                physicalCenterBounce = new BouncyRay(physicalCenterRay);
                bool hit = CastRay(physicalCenterRay, ref physicalCenterBounce);

                Ray TheCenterRay = physicalCenterBounce.Unfolded;// rays[idxRayOpticalCenter].Unfolded;
                otherCamera.CopyFrom(_camera);
                otherCamera.transform.position = centroidIntersection;
                Debug.Log("" + idxRayOpticalCenter + ": " + TheCenterRay.origin);
                otherCamera.transform.rotation = Quaternion.LookRotation(TheCenterRay.origin - centroidIntersection, Vector3.down);
                Gizmos.DrawLine(TheCenterRay.origin, centroidIntersection);
            }
        }
        lengthDev /= hits;
    }
Ejemplo n.º 16
0
    static List <Vector3> getMeshPointsForComplexTwoWay(List <WayReference> wayReferences, List <Bounds> wayBounds, Pos pos)
    {
        // if (pos.Id == 945711788L) {
        //     Debug.Break();
        // }
        List <Vector3> meshPoints = new List <Vector3> ();

        // middle of intersection "pos"
        Vector3 intersectionPos = Game.getCameraPosition(pos);

        WayReference way1         = wayReferences [0];
        Bounds       way1Bounds   = wayBounds [0];
        bool         way1IsNode1  = way1.isNode1(pos);
        Quaternion   way1Rotation = way1IsNode1 ? way1.transform.rotation : Quaternion.Euler(way1.transform.rotation.eulerAngles + new Vector3(0f, 0f, 180f));

        bool    way1Small      = way1.way.CarWay && way1.SmallWay;
        Vector3 way1Left       = intersectionPos + way1Rotation * new Vector3(way1Small ? way1.transform.localScale.x / 2f : way1.transform.localScale.y / 2f, -way1.transform.localScale.y / 2f, 0f);
        Bounds  leftCheckPoint = new Bounds(way1Left + (way1Rotation * new Vector3(way1Small ? way1.transform.localScale.x / 20f : way1.transform.localScale.y / 20f, way1.transform.localScale.y / 20f, 0f)) - new Vector3(0f, 0f, 0.1f), new Vector3(way1Small ? way1.transform.localScale.x / 10f : way1.transform.localScale.y / 10f, way1.transform.localScale.y / 10f, way1.transform.localScale.y / 10f));

        // DebugFn.DrawBounds (leftCheckPoint);

        WayReference way2;
        Bounds       way2Bounds = wayBounds [1];
        bool         way2IsNode1;
        Quaternion   way2Rotation;

        if (way2Bounds.Intersects(leftCheckPoint))
        {
            way1         = wayReferences [1];
            way1Bounds   = wayBounds [1];
            way1IsNode1  = way1.isNode1(pos);
            way1Rotation = way1IsNode1 ? way1.transform.rotation : Quaternion.Euler(way1.transform.rotation.eulerAngles + new Vector3(0f, 0f, 180f));
            way1Left     = intersectionPos + way1Rotation * new Vector3(way1Small ? way1.transform.localScale.x / 2f : way1.transform.localScale.y / 2f, -way1.transform.localScale.y / 2f, 0f);

            way2         = wayReferences [0];
            way2Bounds   = wayBounds [0];
            way2IsNode1  = way2.isNode1(pos);
            way2Rotation = way2IsNode1 ? way2.transform.rotation : Quaternion.Euler(way2.transform.rotation.eulerAngles + new Vector3(0f, 0f, 180f));
        }
        else
        {
            way2         = wayReferences [1];
            way2Bounds   = wayBounds [1];
            way2IsNode1  = way2.isNode1(pos);
            way2Rotation = way2IsNode1 ? way2.transform.rotation : Quaternion.Euler(way2.transform.rotation.eulerAngles + new Vector3(0f, 0f, 180f));
        }

        bool    way2IsSmallWay = way2.way.CarWay && way2.SmallWay;
        Vector3 way2Right      = intersectionPos + way2Rotation * new Vector3(way2IsSmallWay ? way2.transform.localScale.x / 2f : way2.transform.localScale.y / 2f, way2.transform.localScale.y / 2f, 0f);

        // Angles looking towards intersection of ways
        Vector3 way1IntersectionAngle = (way1IsNode1 ? WayHelper.DEGREES_90_VECTOR : WayHelper.DEGREES_270_VECTOR) + way1.transform.rotation.eulerAngles;
        Vector3 way2IntersectionAngle = (way2IsNode1 ? WayHelper.DEGREES_270_VECTOR : WayHelper.DEGREES_90_VECTOR) + way2.transform.rotation.eulerAngles;

        // Get intersection point
        Vector3 intersectionPoint;
        bool    intersectionFound = Math3d.LineLineIntersection(out intersectionPoint, way1Left, Quaternion.Euler(way1IntersectionAngle) * Vector3.right, way2Right, Quaternion.Euler(way2IntersectionAngle) * Vector3.right);

//		DebugFn.square (intersectionPoint);

        if (!intersectionFound)
        {
            // TODO DEBUG ONLY
            // DebugFn.arrow (way1Left, way1IntersectionAngle, new Vector3(0.1f, 0f, 0f));
            // DebugFn.arrow (way2Right, way2IntersectionAngle, new Vector3(0.1f, 0f, 0f));
            // Debug.Log ("Complex Intersection point not found");
            // Debug.Break ();
            // TODO - Keep this, though
            return(getMeshPointsForNonComplex(wayReferences, wayBounds, pos, noIntersectSpecialCase: true));
        }

        meshPoints.Add(intersectionPoint);
        meshPoints.Add(way2Right);

        // TODO - Can this use GetBezeirPoints below?
        // Add bezier points between the ways, from "right" point in way2 to "left" point in way1
        Vector3 intersectionPointBezier;
        bool    intersectionFoundBezier = Math3d.LineLineIntersection(out intersectionPointBezier, way2Right, way2.transform.rotation * Vector3.right, way1Left, way1.transform.rotation * Vector3.right);

        if (!intersectionFoundBezier)
        {
            intersectionFoundBezier = Math3d.LineLineIntersection(out intersectionPointBezier, way2Right, Quaternion.Euler(new Vector3(0, 0, 180f) + way2.transform.rotation.eulerAngles) * Vector3.right, way1Left, Quaternion.Euler(new Vector3(0, 0, 180f) + way1.transform.rotation.eulerAngles) * Vector3.right);
        }

//		DebugFn.arrow (way1Left, way1.transform.rotation.eulerAngles, new Vector3(0.1f, 0f, 0f));
//		DebugFn.arrow (way2Right, way2.transform.rotation.eulerAngles, new Vector3(0.1f, 0f, 0f));
//
//		DebugFn.square (intersectionPointBezier);

        // Intersection found, draw the bezier curve
        float bezierLength   = Math3d.GetBezierLength(way2Right, intersectionPointBezier, way1Left);
        float numberOfPoints = bezierLength * WayHelper.BEZIER_RESOLUTION;

        float step    = 1.0f / numberOfPoints;
        bool  doBreak = false;

        for (float time = step; time < 1.0f + step; time += step)
        {
            if (time > 1f)
            {
                time    = 1f;
                doBreak = true;
            }
            Vector3 bezierPoint = Math3d.GetVectorInBezierAtTime(time, way2Right, intersectionPointBezier, way1Left);
            meshPoints.Add(bezierPoint);
            if (doBreak)
            {
                break;
            }
        }

        return(meshPoints);
    }
Ejemplo n.º 17
0
	public List<MeshPack> getBuildingMeshes(float outputchance) {

		List<MeshPack> meshes = new List<MeshPack> ();

		// slight offset to move buildings away from road
		Vector3[] temppoints = new Vector3[4];
		temppoints [0] = points [0] + new Vector3 (streetwidth / 2, 0, -streetwidth / 2);
		temppoints [1] = points [1] + new Vector3 (-streetwidth / 2, 0, -streetwidth / 2);
		temppoints [2] = points [2] + new Vector3 (streetwidth / 2, 0, streetwidth / 2);
		temppoints [3] = points [3] + new Vector3 (-streetwidth / 2, 0, streetwidth / 2);

		// Get minimum bounding box
		float minx = Mathf.Min (temppoints [0].x, temppoints [2].x);
		float maxx = Mathf.Max (temppoints [1].x, temppoints [3].x);

		float miny = Mathf.Min (temppoints [2].z, temppoints [3].z);
		float maxy = Mathf.Max (temppoints [0].z, temppoints [1].z);

		float currentx = minx;
		float currenty = maxy;

		// iterate in building sizes (random) over the bounding box
		while (currenty >= miny) {
			float randy = Random.Range (0.6f, 1f);
			float nexty = currenty - randy;
			if (nexty < miny) {
				nexty = miny - 0.01f;
			}
			currentx = minx;
			while (currentx <= maxx) {
				float randx = Random.Range (0.6f, 1f);
				float nextx = currentx + randx;
				if (nextx > maxx) {
					nextx = maxx + 0.01f;
				}

				Vector2 midpoint = new Vector2 ((currentx + nextx) / 2, (currenty + nexty) / 2);

				float lengthx = nextx - currentx;
				float lengthy = currenty - nexty;

				// midpoint of building is on road, don't render the building
				if (containsPointInMesh (midpoint) && lengthx > randx / 2 && lengthy > randy / 2) {

					Vector2 tl = new Vector2 (currentx, currenty);
					Vector2 tr = new Vector2 (nextx, currenty);
					Vector2 bl = new Vector2 (currentx, nexty);
					Vector2 br = new Vector2 (nextx, nexty);

					Vector2 newtl = tl;
					Vector2 newtr = tr;
					Vector2 newbl = bl;
					Vector2 newbr = br;

					// tower, food, shop etc...
					Statistics.BuildingType btype = stats.getRandomBuilding ();

					// Check if each corner sticks out from subdivision and crop appropriately
					if (!containsPointInMesh (tl)) {

						Vector3 intersectionpoint = new Vector3 ();
						Vector2 line1dir = new Vector3 (tr.x, 0, tr.y) - new Vector3 (tl.x, 0, tl.y);
						Math3d.LineLineIntersection (out intersectionpoint, new Vector3 (tl.x, 0, tl.y), line1dir, temppoints [0], temppoints [2] - temppoints [0]);
						Vector2 point = new Vector2 (intersectionpoint.x + 0.001f, intersectionpoint.z);
						if (containsPointInMesh (point) && tl.x <= point.x) {
							newtl = point;
						} else {
							Vector2 point2 = Math3d.LineIntersectionPoint (new Vector2(temppoints [0].x, temppoints[0].z), new Vector2(temppoints [1].x, temppoints[1].z), tl, bl);
							point2 = point2 + new Vector2(0, -0.001f);
							if (containsPointInMesh (point2) && tl.y >= point2.y) {
								newtl = point2;
							}
						}

					}
					if (!containsPointInMesh (tr)) {
						Vector3 intersectionpoint = new Vector3 ();
						Vector2 line1dir = new Vector3 (tl.x, 0, tl.y) - new Vector3 (tr.x, 0, tr.y);
						Math3d.LineLineIntersection (out intersectionpoint, new Vector3 (tr.x, 0, tr.y), line1dir, temppoints [1], temppoints [3] - temppoints [1]);
						Vector2 point = new Vector2 (intersectionpoint.x - 0.001f, intersectionpoint.z);
						if (containsPointInMesh (point) && tr.x >= point.x) {
							newtr = point;
						} else {
							Vector2 point2 = Math3d.LineIntersectionPoint (new Vector2(temppoints [1].x, temppoints[1].z), new Vector2(temppoints [0].x, temppoints[0].z), tr, br);
							point2 = point2 + new Vector2(0, -0.001f);
							if (containsPointInMesh (point2) && tr.y >= point2.y) {
								newtr = point2;
							}
						} 

					}
					if (!containsPointInMesh (bl)) {
						Vector3 intersectionpoint = new Vector3 ();
						Vector2 line1dir = new Vector3 (br.x, 0, br.y) - new Vector3 (bl.x, 0, bl.y);
						Math3d.LineLineIntersection (out intersectionpoint, new Vector3 (bl.x, 0, bl.y), line1dir, temppoints [2], temppoints [0] - temppoints [2]);
						Vector2 point = new Vector2 (intersectionpoint.x + 0.001f, intersectionpoint.z);
						if (containsPointInMesh (point) && bl.x <= point.x) {
							newbl = point;
						} else {
							Vector2 point2 = Math3d.LineIntersectionPoint (new Vector2(temppoints [2].x, temppoints[2].z), new Vector2(temppoints [3].x, temppoints[3].z), bl, tl);
							point2 = point2 + new Vector2(0, +0.001f);
							if (containsPointInMesh (point2) && bl.y <= point2.y) {
								newbl = point2;
							}
						} 

					}
					if (!containsPointInMesh (br)) {
						Vector3 intersectionpoint = new Vector3 ();
						Vector2 line1dir = new Vector3 (bl.x, 0, bl.y) - new Vector3 (br.x, 0, br.y);
						Math3d.LineLineIntersection (out intersectionpoint, new Vector3 (br.x, 0, br.y), line1dir, temppoints [3], temppoints [1] - temppoints [3]);
						Vector2 point = new Vector2 (intersectionpoint.x - 0.001f, intersectionpoint.z);
						if (containsPointInMesh (point) && br.x >= point.x) {
							newbr = point;
						} else {
							Vector2 point2 = Math3d.LineIntersectionPoint (new Vector2(temppoints [3].x, temppoints[3].z), new Vector2(temppoints [2].x, temppoints[2].z), br, tr);
							point2 = point2 + new Vector2(0, +0.001f);
							if (containsPointInMesh (point2) && br.y <= point2.y) {
								newbr = point2;
							}
						} 

					}
					// Special cropping case where the corner sticks out on the x and y
					if (pointInTriangle (new Vector2 (temppoints [0].x, temppoints [0].z), tl, tr, bl) || pointInTriangle (new Vector2 (temppoints [0].x, temppoints [0].z), bl, tr, br)) {
						newtl = new Vector2 (temppoints [0].x, temppoints [0].z);
					}
					if (pointInTriangle (new Vector2 (temppoints [1].x, temppoints [1].z), tl, tr, bl) || pointInTriangle (new Vector2 (temppoints [1].x, temppoints [1].z), bl, tr, br)) {
						newtr = new Vector2 (temppoints [1].x, temppoints [1].z);
					}
					if (pointInTriangle (new Vector2 (temppoints [2].x, temppoints [2].z), tl, tr, bl) || pointInTriangle (new Vector2 (temppoints [2].x, temppoints [2].z), bl, tr, br)) {
						newbl = new Vector2 (temppoints [2].x, temppoints [2].z);
					}	
					if (pointInTriangle (new Vector2 (temppoints [3].x, temppoints [3].z), tl, tr, bl) || pointInTriangle (new Vector2 (temppoints [3].x, temppoints [3].z), bl, tr, br)) {
						newbr = new Vector2 (temppoints [3].x, temppoints [3].z);
					}

					tl = newtl;
					tr = newtr;
					bl = newbl;
					br = newbr;

					// Set small spaces between buildings
					Vector2 reducedtl = tl + new Vector2 (streetwidth / 4, -streetwidth / 4);
					Vector2 reducedtr = tr + new Vector2 (-streetwidth / 4, -streetwidth / 4);
					Vector2 reducedbl = bl + new Vector2 (streetwidth / 4, streetwidth / 4);
					Vector2 reducedbr = br + new Vector2 (-streetwidth / 4, streetwidth / 4);

					float maxwidth = Mathf.Max (reducedtr.x - reducedtl.x, reducedbr.x - reducedbl.x);
					float maxheight = Mathf.Max (reducedtl.y - reducedbl.y, reducedtr.y - reducedbr.y);

					// Don't render if building is too skinny
					if (maxwidth < streetwidth || maxheight < streetwidth) {
						currentx = nextx;
						continue;
					}

					if (btype == Statistics.BuildingType.TOWER) {
						float rand = Random.Range (0f, 1f);
						if (rand <= outputchance) {
							// Get random tower height based on avg height and variance
							float h = (float)stats.getRandomTowerHeight ();
							MeshPack mp = new MeshPack (createBuildingMesh (reducedtl, reducedtr, reducedbl, reducedbr, h / 10 + 0.2f));
							mp.btype = btype;
							meshes.Add(mp);
						}

					} else {
						float rand = Random.Range (0f, 1f);
						if (rand <= outputchance) {
							float randheight = Random.Range (0.4f, 1f);
							MeshPack mp = new MeshPack (createBuildingMesh (reducedtl, reducedtr, reducedbl, reducedbr, randheight));
							mp.btype = btype;
							meshes.Add (mp);
						}
					}		
				}
				currentx = nextx;
			}
			currenty = nexty;
		}

		return meshes;
	}
Ejemplo n.º 18
0
    private static void CreateCurvedDashedLines(GameObject parent, long key, List <WayReference> wayReferences)
    {
        GameObject curveDashedLines = new GameObject();

        curveDashedLines.name = "Curved dashed lines";
        curveDashedLines.transform.SetParent(parent.transform);
        curveDashedLines.transform.localPosition = Vector3.zero;

        Pos     centerPos   = NodeIndex.getPosById(key);
        Vector3 posPosition = Game.getCameraPosition(centerPos);

        WayReference firstReference  = wayReferences [0];
        WayReference secondReference = wayReferences [1];

        bool firstIsNode1  = firstReference.isNode1(centerPos);
        bool secondIsNode1 = secondReference.isNode1(centerPos);

        GameObject wayFirst  = firstReference.gameObject;
        GameObject waySecond = secondReference.gameObject;

        // Number of fields in opposite direction
        float fieldsFromPos2 = firstReference.getNumberOfFieldsInDirection(false);

        // Number of fields in own direction
        float fieldsFromPos1 = firstReference.getNumberOfFieldsInDirection(true);

        // Number of fields in total
        float numberOfFields = firstReference.getNumberOfFields();

        List <float> dashedLineFields = new List <float> ();

        for (float field = 1; field < fieldsFromPos2; field++)
        {
            dashedLineFields.Add(field);
        }

        for (float field = 1; field < fieldsFromPos1; field++)
        {
            dashedLineFields.Add(fieldsFromPos2 + field);
        }

        // If ways have same "isNode1", invert y-axis for second way
        bool isSameNode1 = firstIsNode1 == secondIsNode1;

        // Way width
        float wayHeight            = wayFirst.transform.localScale.y;
        float wayHeightCompensated = wayHeight - GetLineHeight() * 2f;

        foreach (float field in dashedLineFields)
        {
            GameObject curveDashes = new GameObject();
            curveDashes.name = "Curved dashes";
            curveDashes.transform.SetParent(curveDashedLines.transform);
            curveDashes.transform.localPosition = Vector3.zero;

            // Percentual position of way width, where to put middle line
            float percentualPositionY = field / numberOfFields;

            // Get our points (center in y-axis)
            float yPositionInWay       = percentualPositionY * wayHeightCompensated;
            float dashYMiddle          = -wayHeightCompensated / 2f + GetLineHeight() + yPositionInWay - GetDashedLineHeight() / 2f;
            float dashYMiddleSameNode1 = wayHeightCompensated / 2f - yPositionInWay + GetDashedLineHeight() / 2f;

            Vector3 firstPosMiddle  = posPosition + wayFirst.transform.rotation * new Vector3((firstIsNode1 ? 1 : -1) * wayHeight / 2f, dashYMiddle, 0);
            Vector3 secondPosMiddle = posPosition + waySecond.transform.rotation * new Vector3((secondIsNode1 ? 1 : -1) * wayHeight / 2f, isSameNode1 ? dashYMiddleSameNode1 : dashYMiddle, 0);

            Vector3 halfDashedLineHeight = new Vector3(0, GetDashedLineHeight() / 2f, 0);

            // Get our points (top in y-axis)
            Vector3 wayFirstHalfDashedHeight  = wayFirst.transform.rotation * halfDashedLineHeight;
            Vector3 waySecondHalfDashedHeight = waySecond.transform.rotation * halfDashedLineHeight;
            Vector3 firstPosTop  = firstPosMiddle - wayFirstHalfDashedHeight;
            Vector3 secondPosTop = secondPosMiddle + (isSameNode1 ? 1 : -1) * waySecondHalfDashedHeight;

            // Get our points (bottom in y-axis)
            Vector3 firstPosBottom  = firstPosMiddle + wayFirstHalfDashedHeight;
            Vector3 secondPosBottom = secondPosMiddle + (isSameNode1 ? -1 : 1) * waySecondHalfDashedHeight;

            Quaternion firstRotation   = firstIsNode1 ? WayHelper.ONEEIGHTY_DEGREES * wayFirst.transform.rotation : wayFirst.transform.rotation;
            Quaternion secondRotation  = secondIsNode1 ? WayHelper.ONEEIGHTY_DEGREES * waySecond.transform.rotation : waySecond.transform.rotation;
            Vector3    firstDirection  = firstRotation * Vector3.right;
            Vector3    secondDirection = secondRotation * Vector3.right;

            Vector3 intersectionPoint;
            Vector3 intersectionPointTop;
            Vector3 intersectionPointBottom;
            bool    intersectionFound = Math3d.LineLineIntersection(out intersectionPoint, firstPosMiddle, firstDirection, secondPosMiddle, secondDirection);
            if (!intersectionFound && firstRotation.eulerAngles.z == secondRotation.eulerAngles.z)
            {
                intersectionFound       = true;
                intersectionPoint       = firstPosMiddle + ((secondPosMiddle - firstPosMiddle) / 2);
                intersectionPointTop    = firstPosTop + ((secondPosTop - firstPosTop) / 2);
                intersectionPointBottom = firstPosBottom + ((secondPosBottom - firstPosBottom) / 2);
            }
            else
            {
                Math3d.LineLineIntersection(out intersectionPointTop, firstPosTop, firstDirection, secondPosTop, secondDirection);
                Math3d.LineLineIntersection(out intersectionPointBottom, firstPosBottom, firstDirection, secondPosBottom, secondDirection);
            }

            // TODO - Shouldn't be needed - debug only
            if (!intersectionFound)
            {
                Debug.Log("ERR: " + key);
                return;
            }

            // 1. Get bezier length for curve
            float bezierLength = Math3d.GetBezierLength(firstPosMiddle, intersectionPoint, secondPosMiddle);

            // 2. Decide how many dashes to fit, with gaps (also calculate each dash and gap length)
            // If only one line
            float numberOfLines   = 1f;
            float dashedLineWidth = bezierLength;
            float dashedLineGap   = 0f;
            // If more lines
            if (bezierLength > DASHED_LINE_WIDTH + CITY_DASHED_LINE_GAP)
            {
                float totalWidth = 0f;
                for (numberOfLines = 2f;  ; numberOfLines++)
                {
                    totalWidth = DASHED_LINE_WIDTH + (DASHED_LINE_WIDTH + CITY_DASHED_LINE_GAP) * (numberOfLines - 1);
                    if (totalWidth >= bezierLength)
                    {
                        break;
                    }
                }
                dashedLineWidth = DASHED_LINE_WIDTH * bezierLength / totalWidth;
                dashedLineGap   = CITY_DASHED_LINE_GAP * bezierLength / totalWidth;
            }


            // 3. Calculate each dash along the line t (time) on bezier curve
            List <KeyValuePair <float, float> > dashTimes = new List <KeyValuePair <float, float> > ();
            if (numberOfLines == 1f)
            {
                dashTimes.Add(new KeyValuePair <float, float>(0f, 1f));
            }
            else
            {
                dashTimes.Add(new KeyValuePair <float, float>(0f, dashedLineWidth / bezierLength));
                for (float lineStart = dashedLineWidth + dashedLineGap; lineStart < bezierLength; lineStart += dashedLineWidth + dashedLineGap)
                {
                    float lineStartTime = lineStart / bezierLength;
                    dashTimes.Add(new KeyValuePair <float, float>(lineStartTime, lineStartTime + dashedLineWidth / bezierLength));
                }
            }

            foreach (KeyValuePair <float, float> dashTime in dashTimes)
            {
                float startTime         = dashTime.Key;
                float endTime           = dashTime.Value;
                float dashLengthPercent = endTime - startTime;
                float numberOfPoints    = Mathf.Max(bezierLength / dashLengthPercent * WayHelper.BEZIER_RESOLUTION, 4f);
                float eachPointTime     = dashLengthPercent / numberOfPoints;

                List <Vector3> dashPoints = new List <Vector3>();

                // Top line
                for (float t = startTime; t <= endTime; t += eachPointTime)
                {
                    dashPoints.Add(Math3d.GetVectorInBezierAtTime(t, firstPosTop, intersectionPointTop, secondPosTop));
                }

                // Bottom line
                for (float t = endTime; t >= startTime; t -= eachPointTime)
                {
                    dashPoints.Add(Math3d.GetVectorInBezierAtTime(t, firstPosBottom, intersectionPointBottom, secondPosBottom));
                }

                GameObject lineMiddle = MapSurface.createPlaneMeshForPoints(dashPoints);
                lineMiddle.name = "Curved dash";
                WayLine.SetWhiteMaterial(lineMiddle);
                lineMiddle.transform.SetParent(curveDashes.transform);
                lineMiddle.transform.localPosition = new Vector3(0, 0, -0.01f);
            }
        }
    }
Ejemplo n.º 19
0
    // Create random lines through area and subdivide based on these lines
    public void setRandomSubdivisions()
    {
        Vector2 topleft     = new Vector2(minx, maxy);
        Vector2 topright    = new Vector2(maxx, maxy);
        Vector2 bottomleft  = new Vector2(minx, miny);
        Vector2 bottomright = new Vector2(maxx, miny);

        // Area is divide by 2 to 3 on each side
        int xdivisions = Random.Range(2, 4);
        int ydivisions = Random.Range(2, 4);

        Vector2[,] intersections          = new Vector2[xdivisions + 2, ydivisions + 2];
        intersections [0, 0]              = topleft;
        intersections [xdivisions + 1, 0] = topright;
        intersections [0, ydivisions + 1] = bottomleft;
        intersections [xdivisions + 1, ydivisions + 1] = bottomright;

        // top and bottom random points
        for (int i = 1; i <= xdivisions; i++)
        {
            float minxpointtop = minx + ((float)(i - 1) / xdivisions) * width;
            float maxxpointtop = minx + ((float)i / xdivisions) * width;


            float randxtop = Random.Range(minxpointtop + streetwidth, maxxpointtop - streetwidth);
            float randxbot = Random.Range(minxpointtop + streetwidth, maxxpointtop - streetwidth);

            intersections [i, 0] = new Vector2(randxtop, maxy);
            intersections [i, ydivisions + 1] = new Vector2(randxbot, miny);
        }

        // left and right random points
        for (int i = 1; i <= ydivisions; i++)
        {
            float minypointleft = maxy - ((float)(i - 1) / ydivisions) * height;
            float maxypointleft = maxy - ((float)i / ydivisions) * height;


            float randxleft  = Random.Range(minypointleft + streetwidth, maxypointleft - streetwidth);
            float randxright = Random.Range(minypointleft + streetwidth, maxypointleft - streetwidth);

            intersections [0, i] = new Vector2(minx, randxleft);
            intersections [xdivisions + 1, i] = new Vector2(maxx, randxright);
        }

        // get intersection points between lines
        for (int i = 1; i <= xdivisions; i++)
        {
            for (int j = 1; j <= ydivisions; j++)
            {
                Vector2 vertlinepoint1 = intersections [i, 0];
                Vector2 vertlinepoint2 = intersections [i, ydivisions + 1];
                Vector2 vertdirection  = (vertlinepoint2 - vertlinepoint1);

                Vector2 horlinepoint1 = intersections [0, j];
                Vector2 horlinepoint2 = intersections [xdivisions + 1, j];
                Vector2 hordirection  = (horlinepoint2 - horlinepoint1);

                Vector3 vertorigin = new Vector3(vertlinepoint1.x, vertlinepoint1.y, 0);
                Vector3 hororigin  = new Vector3(horlinepoint1.x, horlinepoint1.y, 0);
                Vector3 vertline   = new Vector3(vertdirection.x, vertdirection.y, 0);
                Vector3 horline    = new Vector3(hordirection.x, hordirection.y, 0);

                Vector3 resultpoint = new Vector3();

                Math3d.LineLineIntersection(out resultpoint, vertorigin, vertline, hororigin, horline);

                Vector2 result2d = new Vector2(resultpoint.x, resultpoint.y);

                intersections [i, j] = result2d;
            }
        }

        // Create subdivisions from each of the subareas formed
        for (int j = 0; j <= ydivisions; j++)
        {
            for (int i = 0; i <= xdivisions; i++)
            {
                Vector2 tl = intersections [i, j];
                Vector2 tr = intersections [i + 1, j];
                Vector2 bl = intersections [i, j + 1];
                Vector2 br = intersections [i + 1, j + 1];

                Subdivision sub = new Subdivision(tl, tr, bl, br, streetwidth);
                sub.stats = statistics;

                subdivisions.Add(sub);
            }
        }
    }
Ejemplo n.º 20
0
    public bool createSplitMeshes(List <Vector3> outer, List <Vector3> inner)
    {
        Rect rectOfOuter = Misc.GetRectOfVectorList(outer);
        // Vector3 centerOuter = Misc.GetCenterOfVectorList(outer);
        Vector3 centerInner = Misc.GetCenterOfVectorList(inner);

        if (Misc.IsPointInsideRect(centerInner, rectOfOuter))
        {
            // Now try to split this with a line going from this point straight left and right (x axis)
            Vector3 intersectionCheckPoint = centerInner - new Vector3(rectOfOuter.width, 0f, 0f);
            Vector3 intersectionCheckLine  = new Vector3(rectOfOuter.width * 2, 0f, 0f);

            // Loop through outers in pairs and keep them in separate lists
            List <Vector3> beforeSplitOuter        = new List <Vector3>();
            List <Vector3> afterSplitOuter         = new List <Vector3>();
            List <Vector3> outerIntersectionPoints = new List <Vector3>();
            bool           beforeSplit             = true;
            for (int i = 0; i < outer.Count - 1; i++)
            {
                Vector3 vec1 = outer[i];
                Vector3 vec2 = outer[i + 1];
                // Add current vector
                if (beforeSplit)
                {
                    beforeSplitOuter.Add(vec1);
                }
                else
                {
                    afterSplitOuter.Add(vec1);
                }

                Vector3 intersectionPoint;
                bool    intersected = Math3d.LineLineIntersection(out intersectionPoint, vec1, vec2 - vec1, intersectionCheckPoint, intersectionCheckLine);
                if (intersected)
                {
                    // We have crossed the intersection point, add this to both and shift the boolean value, to push coming values to the other list
                    beforeSplitOuter.Add(intersectionPoint);
                    afterSplitOuter.Add(intersectionPoint);
                    // Also keep track of the actual intersection points
                    outerIntersectionPoints.Add(intersectionPoint);
                    beforeSplit = !beforeSplit;
                }
            }

            // Loop through inners in pairs and keep them in separate lists
            List <Vector3> beforeSplitInner        = new List <Vector3>();
            List <Vector3> afterSplitInner         = new List <Vector3>();
            List <Vector3> innerIntersectionPoints = new List <Vector3>();
            beforeSplit = true;
            for (int i = 0; i < inner.Count - 1; i++)
            {
                Vector3 vec1 = inner[i];
                Vector3 vec2 = inner[i + 1];
                // Add current vector
                if (beforeSplit)
                {
                    beforeSplitInner.Add(vec1);
                }
                else
                {
                    afterSplitInner.Add(vec1);
                }

                Vector3 intersectionPoint;
                bool    intersected = Math3d.LineLineIntersection(out intersectionPoint, vec1, vec2 - vec1, intersectionCheckPoint, intersectionCheckLine);
                if (intersected)
                {
                    // We have crossed the intersection point, add this to both and shift the boolean value, to push coming values to the other list
                    beforeSplitInner.Add(intersectionPoint);
                    afterSplitInner.Add(intersectionPoint);
                    // Also keep track of the actual intersection points
                    innerIntersectionPoints.Add(intersectionPoint);
                    beforeSplit = !beforeSplit;
                }
            }

            // TODO - If we have more than two intersection points for either inner or outer, we should try and rotate the intersectionCheckLine and redo above
            // - If eg. outer would happen to be irregular, a third intersection could occur, probably failing everything

            // We now have two lists for outer and two lists for inner, and one list for each to know where the intersections are at
            List <Vector3> topMostOuters    = Misc.GetTopMost(beforeSplitOuter, afterSplitOuter);
            List <Vector3> topMostInners    = Misc.GetTopMost(beforeSplitInner, afterSplitInner);
            List <Vector3> bottomMostOuters = topMostOuters == beforeSplitOuter ? afterSplitOuter : beforeSplitOuter;
            List <Vector3> bottomMostInners = topMostInners == beforeSplitInner ? afterSplitInner : beforeSplitInner;

            // Tie together topmost outer and inner, so they make one solid block
            List <Vector3> topPart = Misc.TieTogetherOuterAndInner(topMostOuters, topMostInners, outerIntersectionPoints, innerIntersectionPoints);
            // Tie together bottommost outer and inner, so they make one solid block
            List <Vector3> bottomPart = Misc.TieTogetherOuterAndInner(bottomMostOuters, bottomMostInners, outerIntersectionPoints, innerIntersectionPoints);

            if (topPart != null && bottomPart != null)
            {
                // Create the mesh
                // DebugFn.print(intersectionCheckPoint);
                // DebugFn.print(intersectionCheckLine);
                // Debug.Log(outerIntersectionPoints.Count);
                // Debug.Log(innerIntersectionPoints.Count);
                // DebugFn.square(topPart[0]);
                // DebugFn.square(bottomPart[0]);
                // DebugFn.print(topPart);
                // DebugFn.print(bottomPart);
                // DebugFn.DebugPath(topPart);
                // DebugFn.DebugPath(bottomPart);

                GameObject   top   = createMesh(topPart, "top", this.transform);
                BuildingRoof topBR = top.AddComponent <BuildingRoof>();
                topBR.createMeshCollider(false);
                topBR.slave  = true;
                topBR.parent = this;
                slaves.Add(topBR);

                GameObject   bottom   = createMesh(bottomPart, "bottom", this.transform);
                BuildingRoof bottomBR = bottom.AddComponent <BuildingRoof>();
                bottomBR.createMeshCollider(false);
                bottomBR.slave  = true;
                bottomBR.parent = this;
                slaves.Add(bottomBR);

                return(true);
            }
        }

        return(false);
    }
Ejemplo n.º 21
0
    public void AngleCheck()
    {
        Ray ray  = new Ray(BlockCenter, Vector3.forward * 1000f);
        Ray ray2 = new Ray(BlockCenter, Vector3.back * 1000f);
        Ray RayL = new Ray(BlockCenter, Vector3.left * 1000f);
        Ray RayR = new Ray(BlockCenter, Vector3.right * 1000f);

        Debug.DrawLine(ray.origin, ray.GetPoint(10));
        AngleDown  = 0;
        AngleUp    = 0;
        AngleRight = 0;
        AngleRight = 0;
        float   top_distance   = 0;
        float   bot_distance   = 0;
        float   left_distance  = 0;
        float   right_distance = 0;
        Vector3 top_intersect;
        Vector3 bot_intersect;

        foreach (var segment in boundingSegments)    //FIND TOP AND BOTTOM INTERSECTION POINTS, CALCULATE CENTER
        {
            if (Math3d.AreLineSegmentsCrossing(ray.origin, ray.GetPoint(20f), segment.start(), segment.end()))
            {
                AngleUp = segment.Angle();
                //X_angle_top = Math3d.SignedVectorAngle(segment.end() - segment.start(), Vector3.right, Vector3.forward);
                Math3d.LineLineIntersection(out top_intersect, ray.origin, ray.direction, segment.start(), segment.vector());
                top_distance = Vector3.Distance(ray.origin, top_intersect);
            }
            if (Math3d.AreLineSegmentsCrossing(ray2.origin, ray2.GetPoint(20f), segment.start(), segment.end()))
            {
                AngleDown = segment.Angle();
                //X_angle_top = (Mathf.Sign(X_angle_top) == 1) ? X_angle_top - 90f : X_angle_top +90f;
                Math3d.LineLineIntersection(out bot_intersect, ray.origin, ray2.direction, segment.start(), segment.vector());
                bot_distance = Vector3.Distance(ray.origin, bot_intersect);
            }
            if (Math3d.AreLineSegmentsCrossing(RayL.origin, RayL.GetPoint(20f), segment.start(), segment.end()))
            {
                AngleLeft = segment.angleV();
                Math3d.LineLineIntersection(out bot_intersect, ray.origin, ray2.direction, segment.start(), segment.vector());
                left_distance = Vector3.Distance(ray.origin, bot_intersect);
            }
            if (Math3d.AreLineSegmentsCrossing(RayR.origin, RayR.GetPoint(20f), segment.start(), segment.end()))
            {
                AngleRight = segment.angleV();
                Math3d.LineLineIntersection(out bot_intersect, ray.origin, ray2.direction, segment.start(), segment.vector());
                right_distance = Vector3.Distance(ray.origin, bot_intersect);
            }
        }
        float distance = bot_distance - top_distance;

        //float topAdj = BlockCenter.z + top_distance;
        //float botAdj = BlockCenter.z - bot_distance;
        BlockCenter     = BlockCenter - new Vector3(0, 0, distance / 2);
        RayVectorAngleH = (AngleDown + AngleUp) / 2;

        if (Mathf.Abs(RayVectorAngleH) > 10)
        {
            RayVectorAngleV = (AngleLeft + AngleRight) / 2;
        }
        else
        {
            RayVectorAngleV = 90;
        }

        //if (Mathf.Abs(RayVectorAngleH) > 10) RayVectorAngleH = RayVectorAngleV - 90;


        if (RayVectorAngleV < 0)
        {
            RayVectorV = Quaternion.Euler(0, RayVectorAngleV, 0) * Vector3.right;
        }
        else
        {
            RayVectorV = Quaternion.Euler(0, RayVectorAngleV, 0) * Vector3.left;
        }

        RayVectorH = Quaternion.Euler(0, RayVectorAngleH, 0) * Vector3.right;
        if (Mathf.Abs(RayVectorAngleH) >= 20f)
        {
            //RayVectorV = Quaternion.Euler(0,-90f,0) * RayVectorH;
        }
    }
Ejemplo n.º 22
0
    static List <Vector3> getMeshPointsForNonComplex(List <WayReference> wayReferences, List <Bounds> wayBounds, Pos pos, bool noIntersectSpecialCase = false)
    {
        List <Vector3> meshPoints = new List <Vector3> ();

        // Add first one last as well, so we can iterate them as pairs
        wayReferences.Add(wayReferences [0]);
        wayBounds.Add(wayBounds [0]);

        // middle of intersection "pos"
        Vector3 intersectionPos = Game.getCameraPosition(pos);

        // Iterate over our wayReferences in pairs
        bool lastWaysIntersected = false;

        for (int i = 0; i < wayReferences.Count - 1; i++)
        {
            WayReference way1 = wayReferences[i];
            WayReference way2 = wayReferences[i + 1];

            Bounds way1Bounds = wayBounds[i];
            Bounds way2Bounds = wayBounds[i + 1];

            bool way1IsNode1 = way1.isNode1(pos);
            bool way2IsNode1 = way2.isNode1(pos);

            bool way1Small = way1.way.CarWay && way1.SmallWay;
            bool way2Small = way2.way.CarWay && way2.SmallWay;

            Quaternion way1Rotation = way1IsNode1 ? way1.transform.rotation : Quaternion.Euler(way1.transform.rotation.eulerAngles + new Vector3(0f, 0f, 180f));
            Quaternion way2Rotation = way2IsNode1 ? way2.transform.rotation : Quaternion.Euler(way2.transform.rotation.eulerAngles + new Vector3(0f, 0f, 180f));

            if (!lastWaysIntersected && i == 0)
            {
                // Add "left" point of first way only
                Vector3 left = intersectionPos + way1Rotation * new Vector3(way1Small ? way1.transform.localScale.x / 2f : way1.transform.localScale.y / 2f, -way1.transform.localScale.y / 2f, 0f);
                meshPoints.Add(left);
            }
            lastWaysIntersected = false;

            if (!noIntersectSpecialCase && way1Bounds.Intersects(way2Bounds))
            {
                // Ways intersects, no bezier, instead take the intersection point along the border
                lastWaysIntersected = true;

                // Left pos of way1 and right pos of way2
                Vector3 way1Left  = intersectionPos + way1Rotation * new Vector3(way1Small ? way1.transform.localScale.x / 2f : way1.transform.localScale.y / 2f, -way1.transform.localScale.y / 2f, 0f);
                Vector3 way2Right = intersectionPos + way2Rotation * new Vector3(way2Small ? way2.transform.localScale.x / 2f : way2.transform.localScale.y / 2f, way2.transform.localScale.y / 2f, 0f);

                // Angles looking towards intersection of ways
                Vector3 way1IntersectionAngle = (way1IsNode1 ? WayHelper.DEGREES_90_VECTOR : WayHelper.DEGREES_270_VECTOR) + way1.transform.rotation.eulerAngles;
                Vector3 way2IntersectionAngle = (way2IsNode1 ? WayHelper.DEGREES_270_VECTOR : WayHelper.DEGREES_90_VECTOR) + way2.transform.rotation.eulerAngles;

//				// TODO DEBUG ONLY
//				DebugFn.arrow (way1Left, way1IntersectionAngle, new Vector3(0.1f, 0f, 0f));
//				DebugFn.arrow (way2Right, way2IntersectionAngle, new Vector3(0.1f, 0f, 0f));

                // Get intersection point
                Vector3 intersectionPoint;
                bool    intersectionFound = Math3d.LineLineIntersection(out intersectionPoint, way1Left, Quaternion.Euler(way1IntersectionAngle) * Vector3.right, way2Right, Quaternion.Euler(way2IntersectionAngle) * Vector3.right);

//				DebugFn.square (intersectionPoint);

//				// TODO DEBUG ONLY
//				if (!intersectionFound) {
//					Debug.Log ("Intersection point not found");
//				}

                meshPoints.Add(intersectionPoint);

                if (i == wayReferences.Count - 2)
                {
                    meshPoints.RemoveAt(0);
                    meshPoints.Insert(0, meshPoints[meshPoints.Count - 1]);
                }
            }
            else
            {
                // Add "right" point
                Vector3 right = intersectionPos + way1Rotation * new Vector3(way1Small ? way1.transform.localScale.x / 2f : way1.transform.localScale.y / 2f, way1.transform.localScale.y / 2f, 0f);
                meshPoints.Add(right);

                // "Left" point in next way
                Vector3 leftWay2 = intersectionPos + way2Rotation * new Vector3(way2Small ? way2.transform.localScale.x / 2f : way2.transform.localScale.y / 2f, -way2.transform.localScale.y / 2f, 0f);

                GetBezierPoints(meshPoints, way1, way2, right, leftWay2);
            }
        }

        meshPoints.RemoveAt(meshPoints.Count - 1);


        return(meshPoints);
    }