/// <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); }
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); }