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); } } }
public void ChangePosX(float newX) { //左に移動 if (newX < xPos) { xPos = newX; min.x = newX - width / 2; max.x = newX + width / 2; xMin.Value.pos = min.x; xMax.Value.pos = max.x; //もう少し最適化できる for (LinkedListNode <AABBPoint> node = xMin.Previous; node != null; node = node.Previous) { AABBPoint point = node.Value; if (point.pos < min.x) { xAxisAABB.Remove(xMin); xAxisAABB.AddAfter(node, xMin); break; } else if (node.Previous == null) { xAxisAABB.Remove(xMin); xAxisAABB.AddBefore(node, xMin); break; } } for (LinkedListNode <AABBPoint> node = xMax.Previous; node != null; node = node.Previous) { AABBPoint point = node.Value; if (point.pos < max.x) { xAxisAABB.Remove(xMax); xAxisAABB.AddAfter(node, xMax); break; } else if (node.Previous == null) { xAxisAABB.Remove(xMax); xAxisAABB.AddBefore(node, xMax); break; } } } //右に移動 else if (newX > xPos) { xPos = newX; min.x = newX - width / 2; max.x = newX + width / 2; xMin.Value.pos = min.x; xMax.Value.pos = max.x; for (LinkedListNode <AABBPoint> node = xMax.Next; node != null; node = node.Next) { AABBPoint point = node.Value; if (point.pos > max.x) { xAxisAABB.Remove(xMax); xAxisAABB.AddBefore(node, xMax); break; } else if (node.Next == null) { xAxisAABB.Remove(xMax); xAxisAABB.AddAfter(node, xMax); break; } } for (LinkedListNode <AABBPoint> node = xMin.Next; node != null; node = node.Next) { AABBPoint point = node.Value; if (point.pos > min.x) { xAxisAABB.Remove(xMin); xAxisAABB.AddBefore(node, xMin); break; } else if (node.Next == null) { xAxisAABB.Remove(xMin); xAxisAABB.AddAfter(node, xMin); break; } } } }
public void ChangePosY(float newY) { //下に移動 if (newY < yPos) { yPos = newY; min.y = newY - width / 2; max.y = newY + width / 2; yMin.Value.pos = min.y; yMax.Value.pos = max.y; //もう少し最適化できる for (LinkedListNode <AABBPoint> node = yMin.Previous; node != null; node = node.Previous) { AABBPoint point = node.Value; if (point.pos < min.y) { yAxisAABB.Remove(yMin); yAxisAABB.AddAfter(node, yMin); break; } else if (node.Previous == null) { yAxisAABB.Remove(yMin); yAxisAABB.AddBefore(node, yMin); break; } } for (LinkedListNode <AABBPoint> node = yMax.Previous; node != null; node = node.Previous) { AABBPoint point = node.Value; if (point.pos < max.y) { yAxisAABB.Remove(yMax); yAxisAABB.AddAfter(node, yMax); break; } else if (node.Previous == null) { yAxisAABB.Remove(yMax); yAxisAABB.AddBefore(node, yMax); break; } } } //上に移動 else if (newY > yPos) { yPos = newY; min.y = newY - width / 2; max.y = newY + width / 2; yMin.Value.pos = min.y; yMax.Value.pos = max.y; for (LinkedListNode <AABBPoint> node = yMax.Next; node != null; node = node.Next) { AABBPoint point = node.Value; if (point.pos > max.y) { yAxisAABB.Remove(yMax); yAxisAABB.AddBefore(node, yMax); break; } else if (node.Next == null) { yAxisAABB.Remove(yMax); yAxisAABB.AddAfter(node, yMax); break; } } for (LinkedListNode <AABBPoint> node = yMin.Next; node != null; node = node.Next) { AABBPoint point = node.Value; if (point.pos > min.y) { yAxisAABB.Remove(yMin); yAxisAABB.AddBefore(node, yMin); break; } else if (node.Next == null) { yAxisAABB.Remove(yMin); yAxisAABB.AddAfter(node, yMin); break; } } } }
public void AddAABB(AABB aabb) { AABBList.Add(aabb); AABBPoint xMin = aabb.xMin.Value; AABBPoint xMax = aabb.xMax.Value; //x軸 for (LinkedListNode <AABBPoint> node = xAxisAABB.First; node != null; node = node.Next) { AABBPoint point = node.Value; if (xMin.pos < point.pos) { xAxisAABB.AddBefore(node, aabb.xMin); for (LinkedListNode <AABBPoint> node2 = node; node2 != null; node2 = node2.Next) { AABBPoint point2 = node2.Value; if (xMax.pos < point2.pos) { xAxisAABB.AddBefore(node2, aabb.xMax); break; } else if (node2.Next == null) { xAxisAABB.AddLast(aabb.xMax); break; } } break; } else if (node.Next == null) { xAxisAABB.AddLast(aabb.xMin); xAxisAABB.AddLast(aabb.xMax); break; } } AABBPoint yMin = aabb.yMin.Value; AABBPoint yMax = aabb.yMax.Value; //y軸 for (LinkedListNode <AABBPoint> node = yAxisAABB.First; node != null; node = node.Next) { AABBPoint point = node.Value; if (yMin.pos < point.pos) { yAxisAABB.AddBefore(node, aabb.yMin); for (LinkedListNode <AABBPoint> node2 = node; node2 != null; node2 = node2.Next) { AABBPoint point2 = node2.Value; if (yMax.pos < point2.pos) { yAxisAABB.AddBefore(node2, aabb.yMax); break; } else if (node2.Next == null) { yAxisAABB.AddLast(aabb.yMax); break; } } break; } else if (node.Next == null) { yAxisAABB.AddLast(aabb.yMin); yAxisAABB.AddLast(aabb.yMax); break; } } }