private void Init() { //id振る List <LinkedListNode <AABBPoint> > xTmpList = new List <LinkedListNode <AABBPoint> >(); List <LinkedListNode <AABBPoint> > yTmpList = new List <LinkedListNode <AABBPoint> >(); for (int i = 0; i < collisions.Count; i++) { CollisionAABB c = collisions[i]; c.ID = i; AABBList.Add(new AABB(i, c.Min, c.Max)); xTmpList.Add(AABBList[i].xMin); xTmpList.Add(AABBList[i].xMax); yTmpList.Add(AABBList[i].yMin); yTmpList.Add(AABBList[i].yMax); } //ソートする xTmpList.Sort((a, b) => a.Value.pos.CompareTo(b.Value.pos)); yTmpList.Sort((a, b) => a.Value.pos.CompareTo(b.Value.pos)); //連結リストに入れる for (int i = 0; i < collisions.Count * 2; i++) { xAxisAABB.AddLast(xTmpList[i]); yAxisAABB.AddLast(yTmpList[i]); } idHead = collisions.Count; }
// Start is called before the first frame update void Start() { //Debug.Display(() => "CollisionCount:" + cnt, this); //Debug.Display(() => "axisCount:" + string.Join(", ", axisCount), this); for (int i = 0; i < initNum; i++) { CollisionAABB col = Instantiate(original, new Vector3(Random.Range(-9f, 9f), Random.Range(-5f, 5f)), Quaternion.identity); col.size = new Vector2(Random.Range(0.5f, 1), Random.Range(0.5f, 1)); col.transform.localScale = col.size; col.UpdateAABB(); collisions.Add(col); } original.gameObject.SetActive(false); Init(); }
//AABBが重なっていたらtrue public bool IsOverlap(CollisionAABB other) { if (other.Min.x < this.Max.x && this.Min.x < other.Max.x && other.Min.y < this.Max.y && this.Min.y < other.Max.y) { this.color = Color.red; other.color = Color.red; return(true); } else { this.color = Color.white; other.color = Color.white; return(false); } }
private void Update() { //追加 if (Input.GetKeyDown(KeyCode.A)) { CollisionAABB col = Instantiate(original, new Vector3(Random.Range(-9f, 9f), Random.Range(-5f, 5f)), Quaternion.identity); col.gameObject.SetActive(true); col.size = new Vector2(Random.Range(0.5f, 1), Random.Range(0.5f, 1)); col.transform.localScale = col.size; col.UpdateAABB(); collisions.Add(col); AddAABB(new AABB(idHead, col.Min, col.Max)); idHead++; } //最適化なし cnt = 0; /* * for (int i = 0; i < list.Count - 1; i++) * { * for (int j = i + 1; j < list.Count; j++) * { * bool result = list[i].IsOverlap(list[j]); * if (result) * { * //Debug.DrawLine2D(list[i].Center(), list[j].Center(), 0.1f, Color.red); * UnityEngine.Debug.DrawLine(list[i].Center(), list[j].Center()); * } * cnt++; * } * } */ //移動 for (int i = 0; i < collisions.Count; i++) { CollisionAABB c = collisions[i]; AABBList[i].ChangePos(c.Center()); } //スイーププルーン //初期化 int max = AABBList.Count * (AABBList.Count - 1) / 2; for (int i = 0; i < max; i++) { axisCount[i] = 0; } //x軸 for (LinkedListNode <AABBPoint> node = xAxisAABB.First; node != null; node = node.Next) { AABBPoint point = node.Value; //終点 if (point.isEnd) { //始点リストから自分を削除する、AABBがポインタを持ってるのでO(1) sIdList.Remove(AABBList[point.rootId].xId); //デバッグ用 if (sIdList.Count == 0) { Debug.DrawLine2D(new Vector3(point.pos, -10), new Vector3(point.pos, 10), 0.05f, new Color(0, 0, 1, 0.5f)); } } //始点 else { //始点リストとの衝突回数を増やす for (LinkedListNode <int> tmpNode = sIdList.First; tmpNode != null; tmpNode = tmpNode.Next) { int tmpId = tmpNode.Value; axisCount[ListIndex(point.rootId, tmpId)]++; } //最後に自身を追加する sIdList.AddLast(AABBList[point.rootId].xId); } } //y軸 for (LinkedListNode <AABBPoint> node = yAxisAABB.First; node != null; node = node.Next) { AABBPoint point = node.Value; //終点 if (point.isEnd) { //始点リストから自分を削除する、AABBがポインタを持ってるのでO(1) sIdList.Remove(AABBList[point.rootId].yId); //デバッグ用 if (sIdList.Count == 0) { Debug.DrawLine2D(new Vector3(-10, point.pos), new Vector3(10, point.pos), 0.05f, new Color(0, 0, 1, 0.5f)); } } //始点 else { //始点リストとの衝突回数を増やす for (LinkedListNode <int> tmpNode = sIdList.First; tmpNode != null; tmpNode = tmpNode.Next) { int tmpId = tmpNode.Value; axisCount[ListIndex(point.rootId, tmpId)]++; if (axisCount[ListIndex(point.rootId, tmpId)] >= 2) { //UnityEngine.Debug.DrawLine(AABBList[point.rootId].Center(), AABBList[tmpId].Center(), Color.white); //Debug.DrawLine2D(AABBList[point.rootId].Center(), AABBList[tmpId].Center(), 0.1f, Color.red); Debug.DrawArrow2D(AABBList[point.rootId].Center(), AABBList[tmpId].Center(), 0.05f, new Color(1, 0, 0, 0.5f)); //Debug.Log("衝突ペア(" + point.rootId + ", " + tmpId + ")"); } } //最後に自身を追加する sIdList.AddLast(AABBList[point.rootId].yId); } } }