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}
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

View File

@ -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);

View File

@ -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<List<Spot>> _spotMap = new()
{new List<Spot>(), new List<Spot>(), new List<Spot>(), new List<Spot>()};
@ -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<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)
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;
@ -526,11 +619,44 @@ namespace Parking
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)
{
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<float> allBorders = new();
List<Spot> 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<GameObject> prefabs = new() {spotPrefabA, spotPrefabB, spotPrefabC, spotPrefabD};