예제 #1
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);
        }
    }
예제 #2
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);
        }
    }
예제 #3
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);
    }
예제 #4
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);
            }
        }
    }