コード例 #1
0
        private Vector3 FindBestSegmentMatch(Vector3 position, Vector2 nVector, SegmentedLine3D previousMatchedSegment, out SegmentedLine3D matchedSegment)
        {
            const float angleThreshold = 30f;

            var pos2D = new Vector2(position.x, position.z);
            var nVec0 = pos2D - nVector;
            var nVec1 = pos2D + nVector;
            var nVec  = nVec1 - nVec0;

            var bestSqrMag = float.MaxValue;
            var bestPos    = Vector3.zero;
            var matchFound = false;

            SegmentedLine3D currentMatchedSegment = null;

            void CheckSegment(SegmentedLine3D segment)
            {
                // foreach (var line in segment.lines)
                for (var i = 0; i < segment.lines.Count; ++i)
                {
                    var lnStart = segment.lines[i].Start;
                    var lnEnd   = segment.lines[i].End;

                    if (i == 0)
                    {
                        lnStart -= segment.lines[i].Vector.normalized;
                    }
                    if (i == segment.lines.Count - 1)
                    {
                        lnEnd += segment.lines[i].Vector.normalized;
                    }

                    var lnStart2D = new Vector2(lnStart.x, lnStart.z);
                    var lnEnd2D   = new Vector2(lnEnd.x, lnEnd.z);

                    if (Angle(lnEnd2D - lnStart2D, nVec) < 90 - angleThreshold)
                    {
                        continue;
                    }

                    LineUtils.LineLineIntersection(nVec0, nVec1, lnStart2D, lnEnd2D, out var _, out var segmentsIntersect, out var intersection);
                    if (!segmentsIntersect)
                    {
                        continue;
                    }

                    var sqrMag = (intersection - pos2D).sqrMagnitude;
                    if (sqrMag < bestSqrMag)
                    {
                        matchFound            = true;
                        bestSqrMag            = sqrMag;
                        currentMatchedSegment = segment;
                        bestPos = Vector3.Lerp(lnStart, lnEnd, (intersection.x - lnStart.x) / (lnEnd.x - lnStart.x));
                    }
                }
            }

            if (previousMatchedSegment != null)
            {
                CheckSegment(previousMatchedSegment);
            }

            if (!matchFound)
            {
                foreach (var segment in connectedSegments)
                {
                    CheckSegment(segment);
                }
            }

            matchedSegment = currentMatchedSegment;

            return(!matchFound ? position : bestPos);
        }
コード例 #2
0
        private static TriangleSearchResult TryGetNextTriangle(Vector2 uvStart, Vector2 uvDir, int triangleStart, int[] tris, Vector2[] uv, List <int> triangleEndMatches, List <Vector2> uvEndMatches, int pointCount, out Vector2 intersection, out int nextTriangleStart)
        {
            var inTriangleMatch = -1;

            for (var i = 0; i < triangleEndMatches.Count; ++i)
            {
                if (triangleStart == triangleEndMatches[i])
                {
                    inTriangleMatch = i;
                    break;
                }
            }

            if (inTriangleMatch != -1 && (triangleEndMatches[inTriangleMatch] == triangleStart || TryMatchInTriangleEnd(uvStart, uvDir, uvEndMatches[inTriangleMatch], pointCount)))
            {
                intersection      = uvEndMatches[inTriangleMatch];
                nextTriangleStart = triangleStart;
                return(TriangleSearchResult.WithinTriangle);
            }

            nextTriangleStart = -1;
            intersection      = uvStart;

            var uv1 = uv[tris[triangleStart]];
            var uv2 = uv[tris[triangleStart + 1]];
            var uv3 = uv[tris[triangleStart + 2]];

            var uvEnd = uvStart + uvDir * 50f;

            uvStart = uvStart - uvDir * 50f;

            LineUtils.LineLineIntersection(uv1, uv2, uvStart, uvEnd, out _, out var ints12, out var pos12, out _, out _);
            LineUtils.LineLineIntersection(uv2, uv3, uvStart, uvEnd, out _, out var ints23, out var pos23, out _, out _);
            LineUtils.LineLineIntersection(uv3, uv1, uvStart, uvEnd, out _, out var ints31, out var pos31, out _, out _);

            var indexA     = -1;
            var indexB     = -1;
            var bestSqrMag = -1f;

            if (ints12 && Vector3.SqrMagnitude(pos12 - uvStart) > bestSqrMag)
            {
                indexA       = tris[triangleStart];
                indexB       = tris[triangleStart + 1];
                bestSqrMag   = Vector3.SqrMagnitude(pos12 - uvStart);
                intersection = pos12;
            }

            if (ints23 && Vector3.SqrMagnitude(pos23 - uvStart) > bestSqrMag)
            {
                indexA       = tris[triangleStart + 1];
                indexB       = tris[triangleStart + 2];
                bestSqrMag   = Vector3.SqrMagnitude(pos23 - uvStart);
                intersection = pos23;
            }

            if (ints31 && Vector3.SqrMagnitude(pos31 - uvStart) > bestSqrMag)
            {
                indexA       = tris[triangleStart + 2];
                indexB       = tris[triangleStart];
                intersection = pos31;
            }

            bool TriangleMatches(int a1, int a2, int t1, int t2, int t3)
            {
                var a1Match = a1 == t1 || a1 == t2 || a1 == t3;
                var a2Match = a2 == t1 || a2 == t2 || a2 == t3;

                return(a1Match && a2Match);
            }

            for (var i = 0; i < tris.Length; i += 3)
            {
                if (i == triangleStart)
                {
                    continue;
                }

                var t1 = tris[i];
                var t2 = tris[i + 1];
                var t3 = tris[i + 2];
                if (TriangleMatches(indexA, indexB, t1, t2, t3))
                {
                    nextTriangleStart = i;
                    break;
                }
            }

            return(nextTriangleStart == -1 ? TriangleSearchResult.EdgeTermination : TriangleSearchResult.Continues);
        }