public new void Update(GameTime gameTime)
        {
            MouseState    mouseState     = Mouse.GetState();
            RectangleBody mouseCollision = new RectangleBody(mouseState.Position.ToVector2(), new Vector2(0, 0));
            Vector2       coordOffset    = new Vector2((this._grid.Info.TileWidth * this.Data.Size.Width - this._grid.Info.TileWidth) / 2, (this._grid.Info.TileHeight * this.Data.Size.Height - this._grid.Info.TileHeight) / 2);

            if (_grid == null)
            {
                throw new Exception("Grid not initialized in GhostStructure");
            }
            if (mouseCollision.CollidesWith(new RectangleBody(_grid.Info.GridRectangle)))
            {
                _grid.PixelToTile((int)(mouseCollision.Position.X - coordOffset.X), (int)(mouseCollision.Position.Y - coordOffset.Y), out int tileX, out int tileY);
                if (tileX < 0 || tileY < 0)
                {
                    this.Collision.Position = mouseState.Position.ToVector2() - (this.Collision.Region().Size.ToVector2() / 2);
                }
                else
                {
                    Rectangle loc = _grid.TileToPixelRect(tileX, tileY);
                    loc.Size       = new Vector2(loc.Width * Data.Width, loc.Height * Data.Height).ToPoint();
                    this.Collision = new RectangleBody(loc);

                    if (mouseState.LeftButton.HasFlag(ButtonState.Pressed))
                    {
                        this.Data.X1 = tileX;
                        this.Data.Y1 = tileY;
                        _town.FinalizeStructurePlacement(this.ToStructure(), tileX, tileY);
                        if (_town.CanCreateStructure(this))
                        {
                            _town.BeginStructurePlacement(this.Data.Type);
                        }
                    }
                }
            }
            else
            {
                this.Collision.Position = mouseState.Position.ToVector2() - (this.Collision.Region().Size.ToVector2() / 2);
            }

            /*
             * if (mouseState.RightButton == ButtonState.Pressed && !wasPressed)
             * {
             *  wasPressed = true;
             *  this.RotateRight();
             * }
             * else if (mouseState.RightButton == ButtonState.Released && wasPressed)
             * {
             *  wasPressed = false;
             * }
             * //*/
        }
    public bool CalculateCollisionData(RectangleBody bodyA, RectangleBody bodyB, ref Vector2 contactPoint, ref Vector2 contactNormal, ref float penetrationDepth)
    {
        Vector2[] verticesA = new Vector2[4];
        Vector2[] verticesB = new Vector2[4];

        bodyA.GetWorldSpaceVertices(ref verticesA);
        bodyB.GetWorldSpaceVertices(ref verticesB);

        //liste aus collisiondata, da steht drin um welchen punkt es geht -> index vom vertex, penetration depth(die mindest heruasgefundene), und penetration normal
        //List<CollisionData> collisionDatasA = new List<CollisionData>(4);
        //List<CollisionData> collisionDatasB = new List<CollisionData>(4);
        List <CollisionData> collisionDatasA = new List <CollisionData>
        {
            new CollisionData(verticesA[0]),
            new CollisionData(verticesA[1]),
            new CollisionData(verticesA[2]),
            new CollisionData(verticesA[3])
        };
        List <CollisionData> collisionDatasB = new List <CollisionData>
        {
            new CollisionData(verticesB[0]),
            new CollisionData(verticesB[1]),
            new CollisionData(verticesB[2]),
            new CollisionData(verticesB[3])
        };

        //VERTICES VON B IN A
        //alle achsen von a durchgehen(kombination punkt 0 auf 1, 1 auf 2 usw., jede achse wird mit den punkten von b verglichen,
        //man speichert den index für den anfangspunkt
        {
            int p0Index = 3;
            for (int i = 0; i < 4; i++)
            {            //vertex 3 zu 0, 0 zu 1 usw.
                Vector2 axis = (verticesA[i] - verticesA[p0Index]).normalized;
                Vector2 norm = new Vector2(axis.y, -axis.x);
                for (int ii = 0; ii < collisionDatasB.Count; ii++)
                {
                    float depth = -Vector2.Dot(norm, collisionDatasB[ii].vertexPosition - verticesA[p0Index]);
                    if (depth <= 0) //liegt ausserhalb
                    {
                        collisionDatasB.RemoveAt(ii);
                        ii--;
                    }
                    else
                    {
                        if (depth < collisionDatasB[ii].penetrationDepth)
                        {
                            CollisionData collisionData = collisionDatasB[ii];
                            collisionData.penetrationDepth  = depth;
                            collisionData.penetrationNormal = norm;
                            collisionDatasB[ii]             = collisionData;
                        }
                    }
                }
                //int p1Index = i;
                //p0Index = p1Index;
                p0Index = i;
            }
        }

        {
            //VERTICES VON A IN B
            int p0Index = 3;
            for (int i = 0; i < 4; i++)
            {            //vertex 3 zu 0, 0 zu 1 usw.
                Vector2 axis = (verticesB[i] - verticesB[p0Index]).normalized;
                Vector2 norm = new Vector2(axis.y, -axis.x);
                for (int ii = 0; ii < collisionDatasA.Count; ii++)
                {
                    float depth = -Vector2.Dot(norm, collisionDatasA[ii].vertexPosition - verticesB[p0Index]);
                    if (depth <= 0) //liegt ausserhalb
                    {
                        collisionDatasA.RemoveAt(ii);
                        ii--;
                    }
                    else
                    {
                        if (depth < collisionDatasA[ii].penetrationDepth)
                        {
                            CollisionData collisionData = collisionDatasA[ii];
                            collisionData.penetrationDepth  = depth;
                            collisionData.penetrationNormal = norm;
                            collisionDatasA[ii]             = collisionData;
                        }
                    }
                }
                //int p1Index = i;
                //p0Index = p1Index;
                p0Index = i;
            }
        }

        //get most penetration depth
        penetrationDepth = Mathf.NegativeInfinity; //wir wollen die kleinstmögliche penetration kleinster wert

        foreach (CollisionData collisionData in collisionDatasB)
        {
            if (collisionData.penetrationDepth > penetrationDepth)
            {
                penetrationDepth = collisionData.penetrationDepth;
                contactNormal    = collisionData.penetrationNormal;
                contactPoint     = collisionData.vertexPosition;
            }
        }

        foreach (CollisionData collisionData in collisionDatasA)
        {
            if (collisionData.penetrationDepth > penetrationDepth)
            {
                penetrationDepth = collisionData.penetrationDepth;
                contactNormal    = -collisionData.penetrationNormal; //pen normal negieren
                contactPoint     = collisionData.vertexPosition;
            }
        }

        return(penetrationDepth != Mathf.NegativeInfinity);
    }
    public bool CalculateCollisionData(PhysicsBodySphere bodyA, RectangleBody bodyB, ref Vector2 contactPoint, ref Vector2 contactNormal, ref float penetrationDepth)
    {
        //center a in den local space from rectangle bekommen, viel leichter zu berechnen wenn man sichs im lokal space vorstellt, weil das rectangle dann axis aligned ist, un dman spart sich viele vektor berechenungen, skalarprodukte etc.
        //die rotation zurücksetzen und dann wieder zurückdrehen, deswegen mal -bodyB.rotation
        Vector2 centerA = PhysicsBody.RotateVector2(bodyA.GetCenter() - bodyB.GetCenter(), -bodyB.rotation); //wie weit center von sphere vom center vom rectangle entfernt ist

        //vergrößerte bounding box (extents) um zu checken obs innerhalb oder außerhalb liegt, bei den faces workeds, aber bei den ecken dann nichtmehr, da braucht man noch einen check
        Vector2 inflatedExtents = bodyB.extent + Vector2.one * bodyA.radius;

        //jetzt checken ob centerA (den sphere mittelpunkt) innerhalb von diesen inflatedExtents liegt, es kann aber immer noch in den ecken liegen!
        if (centerA.x <= inflatedExtents.x /*zumindest nicht rechts von der box*/ && centerA.x >= -inflatedExtents.x /*nicht links von der box*/ &&
            centerA.y <= inflatedExtents.y && centerA.y >= -inflatedExtents.y)
        {
            //Check ob wir in den ecken liegen
            //absolut wert von x und y
            Vector2 absolutCenterA = new Vector2(Mathf.Abs(centerA.x), Mathf.Abs(centerA.y));

            if (absolutCenterA.x >= bodyB.extent.x && absolutCenterA.y >= bodyB.extent.y)          //wenn wir in dem rechteck (ecke) liegen
            {
                if ((absolutCenterA - bodyB.extent).sqrMagnitude <= bodyA.radius * bodyA.radius)   //ob wir wirklich mit der ecke collidieren
                {
                    Vector2 mirrorDir = new Vector2(Mathf.Sign(centerA.x), Mathf.Sign(centerA.y)); //mathf.Sign liefert +1, -1, oder 0 zurück, kommt drauf an was der input war z.B. 10 = 1, -5 = -1 usw.
                    //nur für ++ space also oberes viertel, deswegen y achse -1 multiplizieren zum spiegeln
                    contactPoint     = bodyB.extent;
                    contactNormal    = (contactPoint - absolutCenterA).normalized * mirrorDir;                                 //* mirrorDir weil es druaf ankommt in welcher ecke es liegt
                    contactPoint    *= mirrorDir;
                    penetrationDepth = bodyA.radius - (absolutCenterA - bodyB.extent) /* hier ist man rechts oben*/.magnitude; //magnitude weil man will die tatsächliche distanz haben

                    //radius - die distanz von center zum point --> da bekommt man die pendepth

                    //jetzt wieder in den World space !!!
                    contactPoint = bodyB.GetCenter() + PhysicsBody.RotateVector2(contactPoint, bodyB.rotation); /*local contactpoint muss rotiert werden */
                    //normalized Vector muss rotiert werden
                    contactNormal = PhysicsBody.RotateVector2(contactNormal, bodyB.rotation);
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            //Berechnung ob es an den flächen links rechts oben unten liegt, und nicht in den ecken
            //RIGHT
            else if (centerA.x > bodyB.extent.x)
            {
                //hier wieder in local space, ContactPoint bie face to face is in der mitte (kann auf der edge sein, oder der punkt der am weitesten drin is
                contactPoint     = new Vector2((bodyB.extent.x + centerA.x - bodyA.radius) * 0.5f /*mittelwert*/, centerA.y);
                contactNormal    = Vector2.left; //weil wir rechts liegen
                penetrationDepth = Mathf.Abs(bodyB.extent.x - (centerA.x - bodyA.radius));

                //weider in world space
                contactPoint  = bodyB.GetCenter() + PhysicsBody.RotateVector2(contactPoint, bodyB.rotation);
                contactNormal = PhysicsBody.RotateVector2(contactNormal, bodyB.rotation);
                return(true);
            }
            //Left
            else if (centerA.x < -bodyB.extent.x)
            {
                contactPoint     = new Vector2((-bodyB.extent.x + centerA.x + bodyA.radius) * 0.5f /*mittelwert*/, centerA.y);
                contactNormal    = Vector2.right;
                penetrationDepth = Mathf.Abs(-bodyB.extent.x - (centerA.x + bodyA.radius));

                contactPoint  = bodyB.GetCenter() + PhysicsBody.RotateVector2(contactPoint, bodyB.rotation);
                contactNormal = PhysicsBody.RotateVector2(contactNormal, bodyB.rotation);
                return(true);
            }
            //UP
            else if (centerA.y > bodyB.extent.y)
            {
                contactPoint     = new Vector2(centerA.x, (bodyB.extent.y + centerA.y - bodyA.radius) * 0.5f);
                contactNormal    = Vector2.down;
                penetrationDepth = Mathf.Abs(bodyB.extent.y - (centerA.y - bodyA.radius));

                contactPoint  = bodyB.GetCenter() + PhysicsBody.RotateVector2(contactPoint, bodyB.rotation);
                contactNormal = PhysicsBody.RotateVector2(contactNormal, bodyB.rotation);
                return(true);
            }
            //Down
            else if (centerA.y < -bodyB.extent.y)
            {
                contactPoint     = new Vector2(centerA.x, (-bodyB.extent.y + centerA.y + bodyA.radius) * 0.5f);
                contactNormal    = Vector2.up;
                penetrationDepth = Mathf.Abs(-bodyB.extent.y - (centerA.y + bodyA.radius));

                contactPoint  = bodyB.GetCenter() + PhysicsBody.RotateVector2(contactPoint, bodyB.rotation);
                contactNormal = PhysicsBody.RotateVector2(contactNormal, bodyB.rotation);
                return(true);
            }
            else
            {
                return(false);
            }
        }
        return(false);
    }