/// <summary>
/// Translate a CollisionUnit by the given amount.
/// </summary>
/// <param name="unit">The CollisionUnit to translate.</param>
/// <param name="translation">The delta translation to perform on the CollisionUnit.</param>
public void TranslateCollisionUnit(CollisionUnit unit, Vector2 translation)
{
int circleRadius;
Vector2 oldCircleCenter;
Vector2 oldLineStart;
Vector2 oldLineEnd;
Point oldTopLeftCell;
Point oldBottomRightCell;
Vector2 newCircleCenter;
Point newTopLeftCell;
Point newBottomRightCell;
if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE || unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_BOX)
{
if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE)
{
circleRadius = unit.GetCircleRadius();
oldCircleCenter = unit.GetCircleCenter();
newCircleCenter = oldCircleCenter + translation;
// calculate containing cells
oldTopLeftCell = CalculateCircleTopLeftCell(oldCircleCenter, circleRadius);
oldBottomRightCell = CalculateCircleBottomRightCell(oldCircleCenter, circleRadius);
newTopLeftCell = CalculateCircleTopLeftCell(newCircleCenter, circleRadius);
newBottomRightCell = CalculateCircleBottomRightCell(newCircleCenter, circleRadius);
}
else
{
oldTopLeftCell = CalculateCellPosition(unit.GetUpperLeft());
oldBottomRightCell = CalculateCellPosition(unit.GetLowerRight());
newTopLeftCell = CalculateCellPosition(unit.GetUpperLeft() + translation);
newBottomRightCell = CalculateCellPosition(unit.GetLowerRight() + translation);
}
// remove from cells no longer within and add to new cells that unit is within
if (translation.X > 0)
{
// remove
for (int i = oldTopLeftCell.X; i < newTopLeftCell.X && i <= oldBottomRightCell.X; i++)
{
for (int j = oldTopLeftCell.Y; j <= oldBottomRightCell.Y; j++)
{
mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit);
}
}
// add
int minStart = oldBottomRightCell.X + 1;
if (minStart < newTopLeftCell.X)
{
minStart = newTopLeftCell.X;
}
for (int i = minStart; i <= newBottomRightCell.X; i++)
{
for (int j = newTopLeftCell.Y; j <= newBottomRightCell.Y; j++)
{
mCollisionGrid.Cells[i, j].AddCollisionUnit(unit);
}
}
}
else if (translation.X < 0)
{
// remove
int minStart = newBottomRightCell.X + 1;
if (minStart < oldTopLeftCell.X)
{
minStart = oldTopLeftCell.X;
}
for (int i = minStart; i <= oldBottomRightCell.X; i++)
{
for (int j = oldTopLeftCell.Y; j <= oldBottomRightCell.Y; j++)
{
mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit);
}
}
// add
for (int i = newTopLeftCell.X; i < oldTopLeftCell.X && i <= newBottomRightCell.X; i++)
{
for (int j = newTopLeftCell.Y; j <= newBottomRightCell.Y; j++)
{
mCollisionGrid.Cells[i, j].AddCollisionUnit(unit);
}
}
}
if (translation.Y > 0)
{
// remove
for (int i = oldTopLeftCell.Y; i < newTopLeftCell.Y && i <= oldBottomRightCell.Y; i++)
{
for (int j = oldTopLeftCell.X; j <= oldBottomRightCell.X; j++)
{
mCollisionGrid.Cells[j, i].RemoveCollisionUnit(unit);
}
}
// add
int minStart = oldBottomRightCell.Y + 1;
if (minStart < newTopLeftCell.Y)
{
minStart = newTopLeftCell.Y;
}
for (int i = minStart; i <= newBottomRightCell.Y; i++)
{
// avoid double adds
if (translation.X > 0)
{
for (int j = newTopLeftCell.X; j <= oldBottomRightCell.X; j++)
{
mCollisionGrid.Cells[j, i].AddCollisionUnit(unit);
}
}
else
{
for (int j = oldTopLeftCell.X; j <= newBottomRightCell.X; j++)
{
mCollisionGrid.Cells[j, i].AddCollisionUnit(unit);
}
}
}
}
else if (translation.Y < 0)
{
// remove
int minStart = newBottomRightCell.Y + 1;
if (minStart < oldTopLeftCell.Y)
{
minStart = oldTopLeftCell.Y;
}
for (int i = minStart; i <= oldBottomRightCell.Y; i++)
{
for (int j = oldTopLeftCell.X; j <= oldBottomRightCell.X; j++)
{
mCollisionGrid.Cells[j, i].RemoveCollisionUnit(unit);
}
}
// add
for (int i = newTopLeftCell.Y; i < oldTopLeftCell.Y && i <= newBottomRightCell.Y; i++)
{
// avoid double adds
if (translation.X > 0)
{
for (int j = newTopLeftCell.X; j <= oldBottomRightCell.X; j++)
{
mCollisionGrid.Cells[j, i].AddCollisionUnit(unit);
}
}
else
{
for (int j = oldTopLeftCell.X; j <= newBottomRightCell.X; j++)
{
mCollisionGrid.Cells[j, i].AddCollisionUnit(unit);
}
}
}
}
}
else if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_LINE)
{
oldLineStart = unit.GetLineStart();
oldLineEnd = unit.GetLineEnd();
// TODO: put in appropriate cells
}
}