Esempio n. 1
0
        /// <summary>
        /// Creates the curve.
        /// </summary>
        /// <param name="positionList">Position list.</param>
        /// <param name="action">メッシュ生成に必要な情報を受け取るコールバック.</param>
        public static void CreateArea(List <Vector3> positionList, Action <CreateRoadMeshScripts.MeshSet> action)
        {
            var positionSetList = new PositionSetList();

            for (int i = 0; i < positionList.Count; i++)
            {
                int prevIndex = i - 1;
                int nextIndex = i + 1;

                if (i == 0)
                {
                    prevIndex = positionList.Count - 1;
                }

                if (i == positionList.Count - 1)
                {
                    nextIndex = 0;
                }

                positionSetList.Add(new PositionSet
                {
                    position  = positionList[i],
                    Index     = i,
                    PrevIndex = prevIndex,
                    NextIndex = nextIndex,
                });
            }

            SeparateAreaSet(positionSetList, action);
        }
Esempio n. 2
0
        public static void SeparateAreaSet(PositionSetList areaSet, Action <CreateRoadMeshScripts.MeshSet> action)
        {
            // どちらも同じ側にあったとき、
            // 今までに見つかっている頂点・辺との交点を探す
            // 探して見つからなければそいつは凸の頂点
            // 探して見つかればそいつは凹の頂点。
            // 交点で2つに分割する。
            // 未知2つを再帰で繰り返していく。
            var sortedList = areaSet.GetSortedList();

            for (int i = 0; i < sortedList.Count; i++)
            {
                var index = sortedList[i].Index;

                if (!areaSet.IsRight(index))
                {
                    continue;
                }

                // 内凸を調べる。
                var sideList = new List <Vector2Int>();

                for (int j = 0; j < i; j++)
                {
                    var nextSide = CreateSet(sortedList[j].Index, sortedList[j].NextIndex);
                    var prevSide = CreateSet(sortedList[j].Index, sortedList[j].PrevIndex);
                    sideList.Add(nextSide);
                    sideList.Add(prevSide);
                }

                sideList = sideList.Distinct().ToList();
                var collisionCount            = 0;
                var collisionNearlyPoint      = Vector3.zero;
                var collisionNearlyPointIndex = Vector2Int.zero;

                foreach (var vector2Int in sideList)
                {
                    Vector3 collisionPoint;
                    var     point1      = areaSet[vector2Int.x].position;
                    var     vec1        = areaSet[vector2Int.y].position - point1;
                    var     point2      = areaSet[index].position;
                    var     vec2        = point2 - areaSet[areaSet[index].NextIndex].position;
                    bool    isCollision = LineInnerIntersection(out collisionPoint, point1, vec1, point2, vec2);

                    if (isCollision)
                    {
                        collisionCount++;

                        if (Vector3.Distance(collisionPoint, point2) < Vector3.Distance(collisionNearlyPoint, point2))
                        {
                            collisionNearlyPoint      = collisionPoint;
                            collisionNearlyPointIndex = vector2Int;
                        }
                    }
                }

                if (collisionCount % 2 == 1)
                {
                    // 分割する.
                    var newList1 = new List <Vector3>();
                    var newList2 = new List <Vector3>();

                    if (areaSet[collisionNearlyPointIndex.x].NextIndex != collisionNearlyPointIndex.y)
                    {
                        var t = collisionNearlyPointIndex.x;
                        collisionNearlyPointIndex.x = collisionNearlyPointIndex.y;
                        collisionNearlyPointIndex.y = t;
                    }

                    {
                        {
                            newList1.Add(areaSet[collisionNearlyPointIndex.x].position);
                            newList1.Add(collisionNearlyPoint);
                            newList1.Add(areaSet[index].position);
                            var nextIndex = areaSet[index].NextIndex;

                            while (nextIndex != collisionNearlyPointIndex.x)
                            {
                                newList1.Add(areaSet[nextIndex].position);
                                nextIndex = areaSet[nextIndex].NextIndex;
                            }
                        }
                        {
                            newList2.Add(areaSet[collisionNearlyPointIndex.y].position);
                            newList2.Add(collisionNearlyPoint);
                            newList2.Add(areaSet[index].position);
                            var prevIndex = areaSet[index].PrevIndex;

                            while (prevIndex != collisionNearlyPointIndex.y)
                            {
                                newList2.Add(areaSet[prevIndex].position);
                                prevIndex = areaSet[prevIndex].NextIndex;
                            }
                        }
                    }

                    CreateArea(newList1, action);
                    CreateArea(newList2, action);
                    return;
                }
            }

            CreateAreaMesh(areaSet, action);
        }