From 1800ff6f64d4f76f271bd83d2aadb63799080102 Mon Sep 17 00:00:00 2001 From: Dawid Pietrykowski Date: Wed, 5 Oct 2022 21:56:02 +0200 Subject: [PATCH] Added new reconfiguration method WIP --- Assets/Scenes/SampleScene.unity | 4 +- Assets/Scripts/Driver.cs | 11 +- Assets/Scripts/ParkingManager.cs | 168 +++++++++++++++++++++++++++---- 3 files changed, 159 insertions(+), 24 deletions(-) diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 50ff73f..76da5bf 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -2932,7 +2932,7 @@ MonoBehaviour: mainPlanContainer: {fileID: 557435656} emergencyPlanContainer: {fileID: 632826360} reconfigurationToggle: {fileID: 441283505} - defaultPath: Assets/Data/Tablica5_2022-09-09.csv + defaultPath: /home/davp/Projects/Customers/Parking/Assets/Data/Tablica5_2022-09-09.csv --- !u!1 &1347097428 GameObject: m_ObjectHideFlags: 0 @@ -4267,7 +4267,7 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 2357925630791757822, guid: b1d6858046a95bb028d8d68ce050cfa4, type: 3} propertyPath: m_LocalPosition.z - value: 0 + value: -3.24 objectReference: {fileID: 0} - target: {fileID: 2357925630791757822, guid: b1d6858046a95bb028d8d68ce050cfa4, type: 3} propertyPath: m_LocalRotation.w diff --git a/Assets/Scripts/Driver.cs b/Assets/Scripts/Driver.cs index 4b8446b..509c26a 100644 --- a/Assets/Scripts/Driver.cs +++ b/Assets/Scripts/Driver.cs @@ -45,12 +45,12 @@ namespace Parking public bool Free = true; public GameObject GameObject; public int Lane = 0; + public TimeSpan LastReconfiguration = TimeSpan.Zero; public ParkingPreference ParkingDirection = ParkingPreference.Any; public bool Perpendicular = true; public bool Reserved = false; public int ReservedPriority = 0; public Size Size; - public TimeSpan LastReconfiguration = TimeSpan.Zero; public Spot(Size size, bool flipped) { @@ -63,6 +63,15 @@ namespace Parking } + public float LowerBorder => GameObject.transform.position.y - + (Perpendicular ? 2.25f / 2.0f : ParkingManager.SpotHeights[(int) Size] / 2.0f); + + public Vector3 Position + { + get => GameObject.transform.position; + set => GameObject.transform.position = value; + } + public int CompareTo(Spot obj) { return Size.CompareTo(obj.Size); diff --git a/Assets/Scripts/ParkingManager.cs b/Assets/Scripts/ParkingManager.cs index 22295f6..302cb1e 100644 --- a/Assets/Scripts/ParkingManager.cs +++ b/Assets/Scripts/ParkingManager.cs @@ -36,7 +36,7 @@ namespace Parking [SerializeField] public Toggle reconfigurationToggle; [SerializeField] public string defaultPath = "Assets/Data/Tablica2.csv"; - private readonly float[] _spotHeights = {4f, 4.5f, 5f, 7.5f}; + public static readonly float[] SpotHeights = {4f, 4.5f, 5f, 7.5f}; private readonly List> _spotMap = new() {new List(), new List(), new List(), new List()}; @@ -337,6 +337,94 @@ namespace Parking private bool TryReconfigureSpotForSize(Size newSize) { + if (newSize == Size.C) { + Debug.Log("Reconfiguring using new method"); + int lane1 = 2; + int lane2 = 1; + for (int i = _spotMap[lane2].Count - 1; i >= 0; i--) + // Check if both spots free + if (_spotMap[lane1][i].Free && _spotMap[lane2][i].Free) { + // Check if we can make space on lane 1 + Spot lowerSpot = _spotMap[lane2][i]; + Spot higherSpot = _spotMap[lane1][i]; + float lowerBorder = GetNextBorderVectical(lowerSpot.GameObject.transform.position, 1, false, + lowerSpot.Size, false); + float lowerReconfiguredBorder = Height / 2.0f - 5.0f - 5.5f - 5.0f - 5.0f; + if (lowerReconfiguredBorder - lowerBorder >= 5.5f) { + // We have space + higherSpot.Size = Size.C; + lowerSpot.Size = Size.C; + Vector3 higherPosition = higherSpot.Position; + higherPosition.y = Height / 2.0f - 5.0f - 5.5f - 5.0f / 2.0f; + Vector3 lowerPosition = lowerSpot.Position; + lowerPosition.y = Height / 2.0f - 5.0f - 5.5f - 5.0f - 5.0f / 2.0f; + higherSpot.Position = higherPosition; + lowerSpot.Position = lowerPosition; + lowerSpot.Reserved = false; + higherSpot.Reserved = false; + Destroy(lowerSpot.GameObject); + Destroy(higherSpot.GameObject); + lowerSpot.GameObject = Instantiate(_spotPrefabs[(int)Size.C], + lowerPosition, lowerSpot.GameObject.transform.rotation, mainPlanContainer); + higherSpot.GameObject = Instantiate(_spotPrefabs[(int)Size.C], + higherPosition, higherSpot.GameObject.transform.rotation, mainPlanContainer); + lowerSpot.LastReconfiguration = _currentTime; + higherSpot.LastReconfiguration = _currentTime; + + + return true; + } + else { + List conflictingSpots = GetConflictingSpotsLower(lowerSpot.GameObject.transform.position, 0, false, + lowerSpot.Size, 0.0f); + + // verify we can delete them + foreach (int conflictingSpotId in conflictingSpots) { + if (!_spotMap[0][conflictingSpotId].Free) + continue; + } + + // delete them + int removed = 0; + conflictingSpots.Sort(); + foreach (int conflictingSpotId in conflictingSpots) { + Destroy(_spotMap[0][conflictingSpotId - removed].GameObject); + _spotMap[0].RemoveAt(conflictingSpotId - removed); + removed++; + } + + //Adjust new spots + higherSpot.Size = Size.C; + lowerSpot.Size = Size.C; + Vector3 higherPosition = higherSpot.Position; + higherPosition.y = Height / 2.0f - 5.0f - 5.5f - 5.0f / 2.0f; + Vector3 lowerPosition = lowerSpot.Position; + lowerPosition.y = Height / 2.0f - 5.0f - 5.5f - 5.0f - 5.0f / 2.0f; + higherSpot.Position = higherPosition; + lowerSpot.Position = lowerPosition; + lowerSpot.Reserved = false; + higherSpot.Reserved = false; + Destroy(lowerSpot.GameObject); + Destroy(higherSpot.GameObject); + lowerSpot.GameObject = Instantiate(_spotPrefabs[(int)Size.C], + lowerPosition, lowerSpot.GameObject.transform.rotation, mainPlanContainer); + higherSpot.GameObject = Instantiate(_spotPrefabs[(int)Size.C], + higherPosition, higherSpot.GameObject.transform.rotation, mainPlanContainer); + lowerSpot.LastReconfiguration = _currentTime; + higherSpot.LastReconfiguration = _currentTime; + + return true; + } + + } + else { + continue; + } + + return false; + } + // TODO: Add new spot generation (lower lane) + foreach (List currentLaneSpots in _spotMap) for (int i = 0; i < currentLaneSpots.Count; i++) { Spot spot = currentLaneSpots[i]; @@ -353,7 +441,7 @@ namespace Parking Vector3 position = spot.GameObject.transform.position; Quaternion rotation = spot.GameObject.transform.rotation; - float diff = (_spotHeights[(int) spot.Size] - _spotHeights[size]) / 2.0f; + float diff = (SpotHeights[(int) spot.Size] - SpotHeights[size]) / 2.0f; if (!spot.AlignToTop) diff *= -1; Vector3 offset = spot.Perpendicular ? new Vector3(0, diff, 0) : new Vector3(-diff, 0, 0); @@ -363,7 +451,7 @@ namespace Parking if (!spot.Perpendicular) { float newX = GetNextBorderHorizontal(position, spot.Lane, spot.Perpendicular, newSize, true) - - _spotHeights[(int) spot.Size] / 2.0f - 0.5f; + SpotHeights[(int) spot.Size] / 2.0f - 0.5f; newPosition = new Vector3(newX, newPosition.y, newPosition.z); } @@ -390,7 +478,7 @@ namespace Parking float spotBorder; float thisSizeOffset; if (spot.Perpendicular) - thisSizeOffset = _spotHeights[size] / 2.0f; + thisSizeOffset = SpotHeights[size] / 2.0f; else thisSizeOffset = 2.25f / 2.0f; if (!spot.AlignToTop) @@ -411,15 +499,16 @@ namespace Parking float nextBorderRight = GetNextBorderHorizontal(position, spot.Lane, spot.Perpendicular, spot.Size, true); - if (nextBorderRight - nextBorderLeft < _spotHeights[(int) newSize] + 1f) { + if (nextBorderRight - nextBorderLeft < SpotHeights[(int) newSize] + 1f) { // Try perpendicular float bottomBorder = newPosition.y - 2.25f / 2.0f; float topBorder = newPosition.y + 2.25f / 2.0f; bool foundByRemoval = false; if (spot.AlignToTop) { - float newBottomBorder = topBorder - _spotHeights[size]; + float newBottomBorder = topBorder - SpotHeights[size]; float newTopBorder = topBorder; - float nextBorder = GetNextBorderVectical(newPosition, spot.Lane, spot.Perpendicular, + float nextBorder = GetNextBorderVectical(newPosition, spot.Lane, + spot.Perpendicular, newSize, !spot.AlignToTop); if (Math.Abs(nextBorder - newBottomBorder) < 5.5f) { @@ -429,7 +518,8 @@ namespace Parking Destroy(nextSpot.GameObject); currentLaneSpots.RemoveAt(i + 1); i--; - newPosition.x = nextBorderRight - _spotHeights[(int) newSize] - 0.5f; + newPosition.x = nextBorderRight - SpotHeights[(int) newSize] - + 0.5f; newPosition.y = position.y; foundByRemoval = true; } @@ -440,8 +530,9 @@ namespace Parking } else { float newBottomBorder = bottomBorder; - float newTopBorder = bottomBorder + _spotHeights[size]; - float nextBorder = GetNextBorderVectical(newPosition, spot.Lane, spot.Perpendicular, + float newTopBorder = bottomBorder + SpotHeights[size]; + float nextBorder = GetNextBorderVectical(newPosition, spot.Lane, + spot.Perpendicular, newSize, !spot.AlignToTop); if (Math.Abs(newTopBorder - nextBorder) < 5.5f) { @@ -451,7 +542,8 @@ namespace Parking Destroy(nextSpot.GameObject); currentLaneSpots.RemoveAt(i + 1); i--; - newPosition.x = nextBorderRight - _spotHeights[(int) newSize] - 0.5f; + newPosition.x = nextBorderRight - SpotHeights[(int) newSize] - + 0.5f; newPosition.y = position.y; foundByRemoval = true; } @@ -464,7 +556,7 @@ namespace Parking if (!foundByRemoval) { - newPosition.y = bottomBorder + _spotHeights[(int) newSize] / 2.0f; + newPosition.y = bottomBorder + SpotHeights[(int) newSize] / 2.0f; float newX = nextBorderRight; if (spot.Lane == 0) { float xRelativeToRight = -(newX - Width / 2.0f); @@ -486,14 +578,15 @@ namespace Parking } newPosition.x = newX; - spot.Flipped = currentLaneSpots.FindIndex(spotPredicate => spotPredicate == spot) % + spot.Flipped = + currentLaneSpots.FindIndex(spotPredicate => spotPredicate == spot) % 2 == 0; rotation *= Quaternion.Euler(0, 0, spot.Flipped ? 90 : -90); spot.Perpendicular = true; } } else { - newPosition.x = nextBorderRight - _spotHeights[(int) newSize] / 2.0f - 0.5f; + newPosition.x = nextBorderRight - SpotHeights[(int) newSize] / 2.0f - 0.5f; if (i == 0) newPosition.x += 0.5f; newPosition.y = position.y; @@ -525,12 +618,45 @@ namespace Parking return false; } + + private List GetConflictingSpotsLower(Vector3 position, int lane, bool perpendicular, Size size, float margin = 0) + { + + float minX = position.x - (perpendicular ? 2.25f : SpotHeights[(int) size]) - margin; + float maxX = position.x + (perpendicular ? 2.25f : SpotHeights[(int) size]) + margin; + + List allBorders = new(); + List targetLane = _spotMap[lane]; + List conflictingSpotsIds = new(); + + for (int i = 0; i < targetLane.Count; i++) { + Spot spot1 = targetLane[i]; + Vector3 targetSpotPosition = spot1.GameObject.transform.position; + if (targetSpotPosition.x < minX || targetSpotPosition.x > maxX) + continue; + float sizeOffset; + if (spot1.Perpendicular) + sizeOffset = SpotHeights[(int) spot1.Size] / 2.0f; + else + sizeOffset = 2.25f / 2.0f; + // allBorders.Add(targetSpotPosition.y + sizeOffset); + conflictingSpotsIds.Add(i); + } + + // if (12.85 - 2.5 / 2.0f <= maxX && lane == 2 && up) + // allBorders.Add(Height / 2.0f - 5); + + // if (allBorders.Count == 0) + // return -Height / 2.0f; + // float nextBorder = up ? allBorders.Min() : allBorders.Max(); + return conflictingSpotsIds; + } private float GetNextBorderVectical(Vector3 position, int lane, bool perpendicular, Size size, bool up) { - float minX = position.x - (perpendicular ? 2.25f : _spotHeights[(int) size]); - float maxX = position.x + (perpendicular ? 2.25f : _spotHeights[(int) size]); + float minX = position.x - (perpendicular ? 2.25f : SpotHeights[(int) size]); + float maxX = position.x + (perpendicular ? 2.25f : SpotHeights[(int) size]); List allBorders = new(); List targetLane = up ? _spotMap[lane + 1] : _spotMap[lane - 1]; @@ -541,7 +667,7 @@ namespace Parking continue; float sizeOffset; if (spot1.Perpendicular) - sizeOffset = _spotHeights[(int) spot1.Size] / 2.0f; + sizeOffset = SpotHeights[(int) spot1.Size] / 2.0f; else sizeOffset = 2.25f / 2.0f; if (up) @@ -571,7 +697,7 @@ namespace Parking if (spot1.Perpendicular) sizeOffset = 2.25f / 2.0f; else - sizeOffset = _spotHeights[(int) spot1.Size] / 2.0f; + sizeOffset = SpotHeights[(int) spot1.Size] / 2.0f; if (right) allBorders.Add(spotPosition.x - sizeOffset); else @@ -592,7 +718,7 @@ namespace Parking } if (perpendicular) - return position.x + (right ? 1 : -1) * _spotHeights[(int) size] / 2.0f; + return position.x + (right ? 1 : -1) * SpotHeights[(int) size] / 2.0f; if (right) return Width / 2.0f; return -Width / 2.0f + 5.5f; @@ -641,10 +767,10 @@ namespace Parking float maxP2 = 0; foreach (Spot spot in spotMap[2]) if (spot.Size != Size.D) - maxP3 = Math.Max(maxP3, spot.Perpendicular ? _spotHeights[(int) spot.Size] : 2.25f); + maxP3 = Math.Max(maxP3, spot.Perpendicular ? SpotHeights[(int) spot.Size] : 2.25f); foreach (Spot spot in spotMap[1]) if (spot.Size != Size.D) - maxP2 = Math.Max(maxP2, spot.Perpendicular ? _spotHeights[(int) spot.Size] : 2.25f); + maxP2 = Math.Max(maxP2, spot.Perpendicular ? SpotHeights[(int) spot.Size] : 2.25f); List prefabs = new() {spotPrefabA, spotPrefabB, spotPrefabC, spotPrefabD};