Added new reconfiguration method WIP

This commit is contained in:
Dawid Pietrykowski 2022-10-05 21:56:02 +02:00
parent 28d61db089
commit 1800ff6f64
3 changed files with 159 additions and 24 deletions

View File

@ -2932,7 +2932,7 @@ MonoBehaviour:
mainPlanContainer: {fileID: 557435656} mainPlanContainer: {fileID: 557435656}
emergencyPlanContainer: {fileID: 632826360} emergencyPlanContainer: {fileID: 632826360}
reconfigurationToggle: {fileID: 441283505} 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 --- !u!1 &1347097428
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -4267,7 +4267,7 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 2357925630791757822, guid: b1d6858046a95bb028d8d68ce050cfa4, type: 3} - target: {fileID: 2357925630791757822, guid: b1d6858046a95bb028d8d68ce050cfa4, type: 3}
propertyPath: m_LocalPosition.z propertyPath: m_LocalPosition.z
value: 0 value: -3.24
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 2357925630791757822, guid: b1d6858046a95bb028d8d68ce050cfa4, type: 3} - target: {fileID: 2357925630791757822, guid: b1d6858046a95bb028d8d68ce050cfa4, type: 3}
propertyPath: m_LocalRotation.w propertyPath: m_LocalRotation.w

View File

@ -45,12 +45,12 @@ namespace Parking
public bool Free = true; public bool Free = true;
public GameObject GameObject; public GameObject GameObject;
public int Lane = 0; public int Lane = 0;
public TimeSpan LastReconfiguration = TimeSpan.Zero;
public ParkingPreference ParkingDirection = ParkingPreference.Any; public ParkingPreference ParkingDirection = ParkingPreference.Any;
public bool Perpendicular = true; public bool Perpendicular = true;
public bool Reserved = false; public bool Reserved = false;
public int ReservedPriority = 0; public int ReservedPriority = 0;
public Size Size; public Size Size;
public TimeSpan LastReconfiguration = TimeSpan.Zero;
public Spot(Size size, bool flipped) 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) public int CompareTo(Spot obj)
{ {
return Size.CompareTo(obj.Size); return Size.CompareTo(obj.Size);

View File

@ -36,7 +36,7 @@ namespace Parking
[SerializeField] public Toggle reconfigurationToggle; [SerializeField] public Toggle reconfigurationToggle;
[SerializeField] public string defaultPath = "Assets/Data/Tablica2.csv"; [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<List<Spot>> _spotMap = new() private readonly List<List<Spot>> _spotMap = new()
{new List<Spot>(), new List<Spot>(), new List<Spot>(), new List<Spot>()}; {new List<Spot>(), new List<Spot>(), new List<Spot>(), new List<Spot>()};
@ -337,6 +337,94 @@ namespace Parking
private bool TryReconfigureSpotForSize(Size newSize) 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<int> 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<Spot> currentLaneSpots in _spotMap) foreach (List<Spot> currentLaneSpots in _spotMap)
for (int i = 0; i < currentLaneSpots.Count; i++) { for (int i = 0; i < currentLaneSpots.Count; i++) {
Spot spot = currentLaneSpots[i]; Spot spot = currentLaneSpots[i];
@ -353,7 +441,7 @@ namespace Parking
Vector3 position = spot.GameObject.transform.position; Vector3 position = spot.GameObject.transform.position;
Quaternion rotation = spot.GameObject.transform.rotation; 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) if (!spot.AlignToTop)
diff *= -1; diff *= -1;
Vector3 offset = spot.Perpendicular ? new Vector3(0, diff, 0) : new Vector3(-diff, 0, 0); Vector3 offset = spot.Perpendicular ? new Vector3(0, diff, 0) : new Vector3(-diff, 0, 0);
@ -363,7 +451,7 @@ namespace Parking
if (!spot.Perpendicular) { if (!spot.Perpendicular) {
float newX = float newX =
GetNextBorderHorizontal(position, spot.Lane, spot.Perpendicular, newSize, true) - 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 = new Vector3(newX,
newPosition.y, newPosition.z); newPosition.y, newPosition.z);
} }
@ -390,7 +478,7 @@ namespace Parking
float spotBorder; float spotBorder;
float thisSizeOffset; float thisSizeOffset;
if (spot.Perpendicular) if (spot.Perpendicular)
thisSizeOffset = _spotHeights[size] / 2.0f; thisSizeOffset = SpotHeights[size] / 2.0f;
else else
thisSizeOffset = 2.25f / 2.0f; thisSizeOffset = 2.25f / 2.0f;
if (!spot.AlignToTop) if (!spot.AlignToTop)
@ -411,15 +499,16 @@ namespace Parking
float nextBorderRight = GetNextBorderHorizontal(position, spot.Lane, spot.Perpendicular, float nextBorderRight = GetNextBorderHorizontal(position, spot.Lane, spot.Perpendicular,
spot.Size, spot.Size,
true); true);
if (nextBorderRight - nextBorderLeft < _spotHeights[(int) newSize] + 1f) { if (nextBorderRight - nextBorderLeft < SpotHeights[(int) newSize] + 1f) {
// Try perpendicular // Try perpendicular
float bottomBorder = newPosition.y - 2.25f / 2.0f; float bottomBorder = newPosition.y - 2.25f / 2.0f;
float topBorder = newPosition.y + 2.25f / 2.0f; float topBorder = newPosition.y + 2.25f / 2.0f;
bool foundByRemoval = false; bool foundByRemoval = false;
if (spot.AlignToTop) { if (spot.AlignToTop) {
float newBottomBorder = topBorder - _spotHeights[size]; float newBottomBorder = topBorder - SpotHeights[size];
float newTopBorder = topBorder; float newTopBorder = topBorder;
float nextBorder = GetNextBorderVectical(newPosition, spot.Lane, spot.Perpendicular, float nextBorder = GetNextBorderVectical(newPosition, spot.Lane,
spot.Perpendicular,
newSize, newSize,
!spot.AlignToTop); !spot.AlignToTop);
if (Math.Abs(nextBorder - newBottomBorder) < 5.5f) { if (Math.Abs(nextBorder - newBottomBorder) < 5.5f) {
@ -429,7 +518,8 @@ namespace Parking
Destroy(nextSpot.GameObject); Destroy(nextSpot.GameObject);
currentLaneSpots.RemoveAt(i + 1); currentLaneSpots.RemoveAt(i + 1);
i--; i--;
newPosition.x = nextBorderRight - _spotHeights[(int) newSize] - 0.5f; newPosition.x = nextBorderRight - SpotHeights[(int) newSize] -
0.5f;
newPosition.y = position.y; newPosition.y = position.y;
foundByRemoval = true; foundByRemoval = true;
} }
@ -440,8 +530,9 @@ namespace Parking
} }
else { else {
float newBottomBorder = bottomBorder; float newBottomBorder = bottomBorder;
float newTopBorder = bottomBorder + _spotHeights[size]; float newTopBorder = bottomBorder + SpotHeights[size];
float nextBorder = GetNextBorderVectical(newPosition, spot.Lane, spot.Perpendicular, float nextBorder = GetNextBorderVectical(newPosition, spot.Lane,
spot.Perpendicular,
newSize, newSize,
!spot.AlignToTop); !spot.AlignToTop);
if (Math.Abs(newTopBorder - nextBorder) < 5.5f) { if (Math.Abs(newTopBorder - nextBorder) < 5.5f) {
@ -451,7 +542,8 @@ namespace Parking
Destroy(nextSpot.GameObject); Destroy(nextSpot.GameObject);
currentLaneSpots.RemoveAt(i + 1); currentLaneSpots.RemoveAt(i + 1);
i--; i--;
newPosition.x = nextBorderRight - _spotHeights[(int) newSize] - 0.5f; newPosition.x = nextBorderRight - SpotHeights[(int) newSize] -
0.5f;
newPosition.y = position.y; newPosition.y = position.y;
foundByRemoval = true; foundByRemoval = true;
} }
@ -464,7 +556,7 @@ namespace Parking
if (!foundByRemoval) { if (!foundByRemoval) {
newPosition.y = bottomBorder + _spotHeights[(int) newSize] / 2.0f; newPosition.y = bottomBorder + SpotHeights[(int) newSize] / 2.0f;
float newX = nextBorderRight; float newX = nextBorderRight;
if (spot.Lane == 0) { if (spot.Lane == 0) {
float xRelativeToRight = -(newX - Width / 2.0f); float xRelativeToRight = -(newX - Width / 2.0f);
@ -486,14 +578,15 @@ namespace Parking
} }
newPosition.x = newX; newPosition.x = newX;
spot.Flipped = currentLaneSpots.FindIndex(spotPredicate => spotPredicate == spot) % spot.Flipped =
currentLaneSpots.FindIndex(spotPredicate => spotPredicate == spot) %
2 == 0; 2 == 0;
rotation *= Quaternion.Euler(0, 0, spot.Flipped ? 90 : -90); rotation *= Quaternion.Euler(0, 0, spot.Flipped ? 90 : -90);
spot.Perpendicular = true; spot.Perpendicular = true;
} }
} }
else { else {
newPosition.x = nextBorderRight - _spotHeights[(int) newSize] / 2.0f - 0.5f; newPosition.x = nextBorderRight - SpotHeights[(int) newSize] / 2.0f - 0.5f;
if (i == 0) if (i == 0)
newPosition.x += 0.5f; newPosition.x += 0.5f;
newPosition.y = position.y; newPosition.y = position.y;
@ -526,11 +619,44 @@ namespace Parking
return false; return false;
} }
private List<int> 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<float> allBorders = new();
List<Spot> targetLane = _spotMap[lane];
List<int> 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) private float GetNextBorderVectical(Vector3 position, int lane, bool perpendicular, Size size, bool up)
{ {
float minX = 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]); float maxX = position.x + (perpendicular ? 2.25f : SpotHeights[(int) size]);
List<float> allBorders = new(); List<float> allBorders = new();
List<Spot> targetLane = up ? _spotMap[lane + 1] : _spotMap[lane - 1]; List<Spot> targetLane = up ? _spotMap[lane + 1] : _spotMap[lane - 1];
@ -541,7 +667,7 @@ namespace Parking
continue; continue;
float sizeOffset; float sizeOffset;
if (spot1.Perpendicular) if (spot1.Perpendicular)
sizeOffset = _spotHeights[(int) spot1.Size] / 2.0f; sizeOffset = SpotHeights[(int) spot1.Size] / 2.0f;
else else
sizeOffset = 2.25f / 2.0f; sizeOffset = 2.25f / 2.0f;
if (up) if (up)
@ -571,7 +697,7 @@ namespace Parking
if (spot1.Perpendicular) if (spot1.Perpendicular)
sizeOffset = 2.25f / 2.0f; sizeOffset = 2.25f / 2.0f;
else else
sizeOffset = _spotHeights[(int) spot1.Size] / 2.0f; sizeOffset = SpotHeights[(int) spot1.Size] / 2.0f;
if (right) if (right)
allBorders.Add(spotPosition.x - sizeOffset); allBorders.Add(spotPosition.x - sizeOffset);
else else
@ -592,7 +718,7 @@ namespace Parking
} }
if (perpendicular) 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) if (right)
return Width / 2.0f; return Width / 2.0f;
return -Width / 2.0f + 5.5f; return -Width / 2.0f + 5.5f;
@ -641,10 +767,10 @@ namespace Parking
float maxP2 = 0; float maxP2 = 0;
foreach (Spot spot in spotMap[2]) foreach (Spot spot in spotMap[2])
if (spot.Size != Size.D) 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]) foreach (Spot spot in spotMap[1])
if (spot.Size != Size.D) 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<GameObject> prefabs = new() {spotPrefabA, spotPrefabB, spotPrefabC, spotPrefabD}; List<GameObject> prefabs = new() {spotPrefabA, spotPrefabB, spotPrefabC, spotPrefabD};