public void CreateRandomPolygon()
        {
            Vector2 mp = UserInterface.WorldMousePos;
            List<Vector2> randVerts = new List<Vector2>();
            int count = Utils.random.Next(7) + 3;
            for (int i = 0; i < count; i++)
            {
                Vector2 v = new Vector2(Utils.random.Next(200) - 100, Utils.random.Next(200) - 100);
                randVerts.Add(v);
            }

            Vector2[] vertices = randVerts.ToArray();
            //Node newNode = new Node(ShapeType.ePolygon);
            Node newNode = OrbIt.ui.sidebar.ActiveDefaultNode.CreateClone();
            //Node.cloneNode(OrbIt.ui.sidebar.ActiveDefaultNode, newNode);
            Polygon poly = new Polygon();
            poly.body = newNode.body;
            poly.SetCenterOfMass(vertices);
            //poly.Set(vertices, vertices.Length);
            newNode.body.shape = poly;
            newNode.body.pos = mp;
            room.spawnNode(newNode);

            verts = new List<Vector2>();
        }
        public void CreateBox()
        {
            Vector2 mp = UserInterface.WorldMousePos;

            //if (verts.Count < 3) return;
            //Vector2[] vertices = verts.ToArray();
            //Node newNode = new Node(ShapeType.ePolygon);
            Node newNode = OrbIt.ui.sidebar.ActiveDefaultNode.CreateClone();
            //Node.cloneNode(OrbIt.ui.sidebar.ActiveDefaultNode, newNode);
            Polygon poly = new Polygon();
            poly.body = newNode.body;
            poly.SetBox(Utils.random.Next(100),Utils.random.Next(100));
            newNode.body.shape = poly;
            newNode.body.pos = mp;
            room.spawnNode(newNode);

            //verts = new List<Vector2>();
        }
        public override void OnSpawn()
        {
            collisionAction = (s, t) =>
            {
                if (t.IsPlayer)
                {
                    if (damageMode == DamanageMode.Players || damageMode == DamanageMode.Both)
                    {
                        t.meta.CalculateDamage(s, damageMultiplier);
                    }
                    if (pushBack.enabled)
                    {
                        Vector2 f = (t.body.pos - s.body.pos);
                        VMath.NormalizeSafe(ref f);
                        f *= pushBack.value;
                        t.body.velocity += f;
                    }
                    if (stunSeconds.enabled)
                    {
                        if (t.movement.active)
                        {
                            t.movement.active = false;
                            Action<Node> ad = (n) =>
                                {
                                    t.movement.active = true;
                                };
                            room.scheduler.AddAppointment(new Appointment(ad, (int)(stunSeconds.value * 1000)));
                        }
                    }
                }
                else
                {
                    if (damageMode == DamanageMode.Nodes || damageMode == DamanageMode.Both)
                    {
                        t.meta.CalculateDamage(s, damageMultiplier);
                    }
                    if (pushBack.enabled)
                    {
                        Vector2 f = (t.body.pos - s.body.pos);
                        VMath.NormalizeSafe(ref f);
                        f *= pushBack.value;
                        t.body.velocity += f;
                    }
                    if (stunSeconds.enabled)
                    {
                        if (t.movement.active)
                        {
                            t.movement.active = false;
                            Action<Node> ad = (n) => t.movement.active = true;
                            t.scheduler.AddAppointment(new Appointment(ad, (int)(stunSeconds.value * 1000)));
                        }
                    }
                }
            };

            Polygon poly = new Polygon();
            poly.body = parent.body;
            float dist = parent.body.radius * 1.3f;
            Vector2[] verts = new Vector2[3];
            for (int i = 0; i < 3; i++)
            {
                verts[i] = VMath.AngleToVector(GMath.TwoPI / 3f * i) * dist;
            }
            parent.body.shape = poly;
            poly.Set(verts, 3);
            parent.body.DrawPolygonCenter = true;
            parent.body.orient = parent.body.orient; //todo:set this every init of polys
            parent.body.OnCollisionEnter += collisionAction;

            parent.body.ExclusionCheck += (s, t) =>
            {
                return Vector2.Distance(s.pos, t.pos) > dist;
            };
        }
        public override void OnSpawn()
        {
            //Node.cloneNode(parent.Game1.ui.sidebar.ActiveDefaultNode, sword);
            //parent.body.texture = textures.orientedcircle;
            swordNode.dataStore["swordnodeparent"] = parent;
            Polygon poly = new Polygon();
            poly.body = swordNode.body;
            poly.SetBox(swordWidth, swordLength);

            swordNode.body.shape = poly;
            swordNode.body.pos = parent.body.pos;
            swordNode.body.DrawPolygonCenter = false;
            swordNode.basicdraw.active = false;
            ///room.spawnNode(sword);

            room.groups.items.IncludeEntity(swordNode);
            swordNode.OnSpawn();
            swordNode.body.AddExclusionCheck(parent.body);
            swordNode.body.ExclusionCheck += delegate(Collider p, Collider o) { return !movingStick; };
            swordNode.body.OnCollisionEnter += (p, o) =>
            {
                if (o.dataStore.ContainsKey("swordnodeparent"))
                {
                    Node otherparent = o.dataStore["swordnodeparent"];
                    Vector2 f = otherparent.body.pos - parent.body.pos;
                    VMath.NormalizeSafe(ref f);
                    f *= parryKnockback;
                    otherparent.body.ApplyForce(f);
                }
                else if (o.IsPlayer)
                {
                    o.player.node.meta.CalculateDamage(parent, damageMultiplier);
                }
            };
            //sword.body.exclusionList.Add(parent.body);
            //
            //parent.body.exclusionList.Add(sword.body);
        }
        public override Shape Clone()
        {
            Polygon poly = new Polygon();
            poly.u = u;
            poly.RecurseCount = RecurseCount;
            poly.RecurseDrawEnabled = RecurseDrawEnabled;
            poly.RecurseScaleReduction = RecurseScaleReduction;
            poly.LineThickness = LineThickness;
            poly.FillEnabled = FillEnabled;

            for (int i = 0; i < vertexCount; i++)
            {
                poly.vertices[i] = vertices[i];
                poly.normals[i] = normals[i];
            }
            poly.vertexCount = vertexCount;
            poly.polyReach = polyReach;
            return poly;
        }
        public Node ConstructWallPoly(Dictionary<dynamic, dynamic> props, int hw, int hh, Vector2 pos)
        {
            Node n = new Node(this, props);
            n.Comp<BasicDraw>().active = false;
            Polygon poly = new Polygon();
            poly.body = n.body;
            poly.body.pos = pos;
            poly.SetBox(hw, hh);
            //poly.SetOrient(0f);

            n.body.shape = poly;
            n.body.SetStatic();
            n.body.orient =(0);
            //n.body.restitution = 1f;

            //n.movement.pushable = false;

            masterGroup.childGroups["Wall Group"].entities.Add(n);
            return n;
        }
        public static void FindIncidentFace(ref Vector2[] v, Polygon RefPoly, Polygon IncPoly, int referenceIndex)
        {
            Vector2 referenceNormal = RefPoly.normals[referenceIndex];

            // Calculate normal in incident's frame of reference
            referenceNormal = RefPoly.u * referenceNormal; // To world space
            referenceNormal = IncPoly.u.Transpose() * referenceNormal; // To incident's model space

            // Find most anti-normal face on incident polygon
            int incidentFace = 0;
            double minDot = float.MaxValue;
            for (int i = 0; i < IncPoly.vertexCount; ++i)
            {
                double dot = Vector2.Dot(referenceNormal, IncPoly.normals[i]);
                if (dot < minDot)
                {
                    minDot = dot;
                    incidentFace = i;
                }
            }

            // Assign face vertices for incidentFace
            v[0] = IncPoly.u * IncPoly.vertices[incidentFace] + IncPoly.body.pos;
            incidentFace = incidentFace + 1 >= IncPoly.vertexCount ? 0 : incidentFace + 1;
            v[1] = IncPoly.u * IncPoly.vertices[incidentFace] + IncPoly.body.pos;
        }
        public static double FindAxisLeastPenetration(ref int faceIndex, Polygon A, Polygon B)
        {
            double bestDistance = -float.MaxValue;
            int bestIndex = 0;

            for (int i = 0; i < A.vertexCount; ++i)
            {
                // Retrieve a face normal from A
                Vector2 n = A.normals[i];
                Vector2 nw = A.u * n;

                // Transform face normal into B's model space
                Mat22 buT = B.u.Transpose();
                n = buT * nw;

                // Retrieve support point from B along -n
                Vector2 s = B.GetSupport(-n);

                // Retrieve vertex on face from A, transform into
                // B's model space
                Vector2 v = A.vertices[i];
                v = A.u * v + A.body.pos;
                v -= B.body.pos;
                v = buT * v;

                // Compute penetration distance (in B's model space)
                double d = Vector2.Dot(n, s - v);

                // Store greatest distance
                if (d > bestDistance)
                {
                    bestDistance = d;
                    bestIndex = i;
                }
            }

            faceIndex = bestIndex;
            return bestDistance;
        }