/// <summary> /// Konvertiert den aktuellen Type in den dazugehörigen ShapeType. /// </summary> /// <param name="shape">ein Shape, dessen Type genommen werden soll</param> /// <returns></returns> public static ShapeType GetShapeType(Shape shape) { if(shape.GetType().Equals(typeof(AABBShape))) return ShapeType.AABB; else if(shape.GetType().Equals(typeof(CircleShape))) return ShapeType.Circle; else //if(shape.GetType().Equals(typeof(OBBShape))) return ShapeType.OBB; //TODO Andere implementieren }
/// <summary> /// Berechnet einen Vektor um eine Kollision zwischen diesen und einer anderen Shape aufzulösen. /// </summary> /// <param name="shape">eine andere Shape</param> /// <returns></returns> public Vector2 GetCollisionSolvingVector(Shape shape) { // Die Shapes werden dynamisch mit ihren jeweiligen Typ erzeugt. // Das erspart einen, das jede abgeleitete Klasse zu jeder anderen Klasse eine extra Methode hat. // Diese wurden dann in die "ShapeCollisionManager" Klasse ausgelagert. dynamic thisDerived = Convert.ChangeType(this, Type.GetTypeType()); dynamic shapeDerived = Convert.ChangeType(shape, shape.Type.GetTypeType()); return ShapeCollisionManager.GetCollisionSolvingVector(thisDerived, shapeDerived); }
/// <summary> /// Gibt alle Kinder an, in denen sich das Kollisionsobjekt befindet. /// </summary> /// <param name="objectShape">die Form eines Objektes</param> /// <returns>Liste aller Kinder, in die das übergeben Objekt fällt</returns> private List<int> getIndexList(Shape objectShape) { List<int> childIndices = new List<int>(); int midX = boundingRectangle.X + (boundingRectangle.Width / 2); int midY = boundingRectangle.Y + (boundingRectangle.Height / 2); bool topQuadrant = objectShape.UppermostSide < midY; bool bottomQuadrant = objectShape.LowermostSide > midY; bool rightQuadrant = objectShape.RightmostSide > midX; bool leftQuadrant = objectShape.LeftmostSide < midX; // Rechtsoben if(rightQuadrant && topQuadrant) childIndices.Add(0); // Linksoben if(leftQuadrant && topQuadrant) childIndices.Add(1); // Linksunten if(leftQuadrant && bottomQuadrant) childIndices.Add(2); // Rechtsunten if(rightQuadrant && bottomQuadrant) childIndices.Add(3); return childIndices; }
/// <summary> /// Gibt alle Objekte zurück, welche mit dem Objekt, dessen ID übergeben wurde, kollidieren könnten. /// </summary> /// <param name="objectID"></param> /// <returns></returns> public List<Tuple<Body, Shape>> GetObjectCollisionList(Shape shape) { // Füge alle Objekte dieser Ebene hinzu. List<Tuple<Body, Shape>> outputList = new List<Tuple<Body, Shape>>(); outputList.AddRange(objectList); int childIndex = getIndex(shape); // Falls das Objekt auf einer unteren Ebene liegt, füge auch diese Objekte zur Liste hinzu. if(childIndex != -1 && quadtreeChildren != null) outputList.AddRange(quadtreeChildren[childIndex].GetObjectCollisionList(shape)); else if(childIndex == -1) { // Hinzufügen aller Kinder, in welchen die Form auch ragt. List<int> childList = getIndexList(shape); foreach(int child in childList) outputList.AddRange(quadtreeChildren[child].GetObjectCollisionList(shape)); } return objectList; }
/// <summary> /// Entscheidet zu welchem der Kinder ein Kollisionobjekt gehört. /// </summary> /// <param name="objectShape">die Form eines Objektes</param> /// <returns>gibt das Kind zurück, in dem das Objekt vollends hineinpasst. Andernfalls -1</returns> private int getIndex(Shape objectShape) { int childIndex = -1; int midX = boundingRectangle.X + (boundingRectangle.Width / 2); int midY = boundingRectangle.Y + (boundingRectangle.Height / 2); bool topQuadrant = objectShape.LowermostSide < midY; bool bottomQuadrant = objectShape.UppermostSide > midY; if(objectShape.LeftmostSide > midX) { // Rechtsoben if(topQuadrant) childIndex = 0; // Rechtsunten else if(bottomQuadrant) childIndex = 3; } else if(objectShape.RightmostSide < midX) { // Linksoben if(topQuadrant) childIndex = 1; // Linksunten else if(bottomQuadrant) childIndex = 2; } return childIndex; }