/// <summary> /// Add a new CollisionUnit to the CollisionChief. /// </summary> /// <param name="unit">The CollisionUnit to add to the CollisionChief.</param> public void AddCollisionUnit(CollisionUnit unit) { Vector2 circleCenter; int circleRadius; Vector2 lineStart; Vector2 lineEnd; Point topLeftCell; Point bottomRightCell; if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE) { circleCenter = unit.GetCircleCenter(); circleRadius = unit.GetCircleRadius(); // put in appropriate cells topLeftCell = CalculateCircleTopLeftCell(circleCenter, circleRadius); bottomRightCell = CalculateCircleBottomRightCell(circleCenter, circleRadius); for (int i = topLeftCell.X; i <= bottomRightCell.X; i++) { for (int j = topLeftCell.Y; j <= bottomRightCell.Y; j++) { mCollisionGrid.Cells[i,j].AddCollisionUnit(unit); } } } else if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_LINE) { lineStart = unit.GetLineStart(); lineEnd = unit.GetLineEnd(); // TODO: put in appropriate cells } else if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_BOX) { topLeftCell = CalculateCellPosition(unit.GetUpperLeft()); bottomRightCell = CalculateCellPosition(unit.GetLowerRight()); for (int i = topLeftCell.X; i <= bottomRightCell.X; i++) { for (int j = topLeftCell.Y; j <= bottomRightCell.Y; j++) { mCollisionGrid.Cells[i, j].AddCollisionUnit(unit); } } } }
/// <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 } }
/// <summary> /// Scale a CollisionUnit by the given amount. /// </summary> /// <param name="unit">The CollisionUnit to scale.</param> /// <param name="scale">The delta scale to perform on the CollisionUnit.</param> public void ScaleCollisionUnit(CollisionUnit unit, Vector2 scale) { int oldCircleRadius; int newCircleRadius; Vector2 circleCenter; Vector2 oldLineStart; Vector2 oldLineEnd; Point oldTopLeftCell; Point oldBottomRightCell; Point newTopLeftCell; Point newBottomRightCell; bool scaleFromCenter = false; if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE || unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_BOX) { if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_CIRCLE) { oldCircleRadius = unit.GetCircleRadius(); //newCircleRadius = (int)(unit.GetCircleRadius() * ((scale.X + scale.Y) / 2)); //newCircleRadius = (int)(unit.GetCircleRadius() + unit.GetCircleRadius() * ((scale.X + scale.Y) / 2)); newCircleRadius = (int)(unit.GetCircleRadius() + ((scale.X + scale.Y) / 2)); circleCenter = unit.GetCircleCenter(); // calculate containing cells oldTopLeftCell = CalculateCircleTopLeftCell(circleCenter, oldCircleRadius); oldBottomRightCell = CalculateCircleBottomRightCell(circleCenter, oldCircleRadius); newTopLeftCell = CalculateCircleTopLeftCell(circleCenter, newCircleRadius); newBottomRightCell = CalculateCircleBottomRightCell(circleCenter, newCircleRadius); } else { Vector2 point1 = unit.GetUpperLeft(); Vector2 point2 = unit.GetLowerRight(); int oldWidth = unit.GetWidth(); int oldHeight = unit.GetHeight(); //int xChange = (int)(((oldWidth * scale.X) - oldWidth) / 2); //int yChange = (int)(((oldHeight * scale.Y) - oldHeight) / 2); //int xChange = (int)(oldWidth * scale.X / 2); //int yChange = (int)(oldHeight * scale.Y / 2); int xChange = (int)scale.X; int yChange = (int)scale.Y; // scale from center if (scaleFromCenter) { point1.X -= xChange; point1.Y -= yChange; point2.X += xChange; point2.Y += yChange; } else { // scale with top left stationary point2.X += xChange * 2; point2.Y += yChange * 2; } oldTopLeftCell = CalculateCellPosition(unit.GetUpperLeft()); oldBottomRightCell = CalculateCellPosition(unit.GetLowerRight()); newTopLeftCell = CalculateCellPosition(point1); newBottomRightCell = CalculateCellPosition(point2); } //if (scale.X < 1) if (scale.X < 0) { for (int j = oldTopLeftCell.Y; j <= oldBottomRightCell.Y; j++) { // remove left for (int i = oldTopLeftCell.X; i < newTopLeftCell.X; i++) { mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit); } // remove right for (int i = newBottomRightCell.X + 1; i <= oldBottomRightCell.X; i++) { mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit); } } //if (scale.Y < 1) if (scale.Y < 0) { for (int i = newTopLeftCell.X; i <= newBottomRightCell.X; i++) { // remove top for (int j = oldTopLeftCell.Y; j < newTopLeftCell.Y; j++) { mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit); } // remove bottom for (int j = newBottomRightCell.Y + 1; j <= oldBottomRightCell.Y; j++) { mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit); } } } //else if (scale.Y > 1) else if (scale.Y > 0) { for (int i = newTopLeftCell.X; i <= newBottomRightCell.X; i++) { // add top for (int j = newTopLeftCell.Y; j < oldTopLeftCell.Y; j++) { mCollisionGrid.Cells[i, j].AddCollisionUnit(unit); } // add bottom for (int j = oldBottomRightCell.Y + 1; j <= newBottomRightCell.Y; j++) { mCollisionGrid.Cells[i, j].AddCollisionUnit(unit); } } } } //else if (scale.X > 1) else if (scale.X > 0) { for (int j = newTopLeftCell.Y; j <= newBottomRightCell.Y; j++) { // add left for (int i = newTopLeftCell.X; i < oldTopLeftCell.X; i++) { mCollisionGrid.Cells[i, j].AddCollisionUnit(unit); } // add right for (int i = oldBottomRightCell.X + 1; i <= newBottomRightCell.X; i++) { mCollisionGrid.Cells[i, j].AddCollisionUnit(unit); } } //if (scale.Y < 1) if (scale.Y < 0) { for (int i = oldTopLeftCell.X; i <= oldBottomRightCell.X; i++) { // remove top for (int j = oldTopLeftCell.Y; j < newTopLeftCell.Y; j++) { mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit); } // remove bottom for (int j = newBottomRightCell.Y + 1; j <= oldBottomRightCell.Y; j++) { mCollisionGrid.Cells[i, j].RemoveCollisionUnit(unit); } } } //else if (scale.Y > 1) else if (scale.Y > 0) { for (int i = oldTopLeftCell.X; i <= oldBottomRightCell.X; i++) { // add top for (int j = newTopLeftCell.Y; j < oldTopLeftCell.Y; j++) { mCollisionGrid.Cells[i, j].AddCollisionUnit(unit); } // add bottom for (int j = oldBottomRightCell.Y + 1; j <= newBottomRightCell.Y; j++) { mCollisionGrid.Cells[i, j].AddCollisionUnit(unit); } } } } } else if (unit.GetCollisionType() == CollisionUnit.CollisionType.COLLISION_LINE) { oldLineStart = unit.GetLineStart(); oldLineEnd = unit.GetLineEnd(); // TODO: put in appropriate cells } }