public void ConvertToConvex()
    {
        FSShapeComponent[] childFsShapes = GetComponentsInChildren<FSShapeComponent>();

        foreach (FSShapeComponent shapeComponent in childFsShapes) {
            if (shapeComponent.gameObject == null) continue;
            DestroyImmediate(shapeComponent.gameObject);
        }
        // convert vertices
        var concaveVertices = new FarseerPhysics.Common.Vertices();

        if (PointInput == FSShapePointInput.Transform)
            for (int i = 0; i < PointsTransforms.Length; i++)
                concaveVertices.Add(FSHelper.Vector3ToFVector2(PointsTransforms[i].localPosition));

        if (PointInput == FSShapePointInput.Vector2List)
            foreach (var coordinate in PointsCoordinates)
                concaveVertices.Add(FSHelper.Vector2ToFVector2(transform.TransformPoint(coordinate)));

        List<FarseerPhysics.Common.Vertices> convexShapeVs =
            FarseerPhysics.Common.Decomposition.BayazitDecomposer.ConvexPartition(concaveVertices);

        for (int i = 0; i < convexShapeVs.Count; i++) {
            var newConvShape = new GameObject("convexShape" + i.ToString());
            newConvShape.transform.parent = transform;
            newConvShape.transform.localPosition = Vector3.zero;
            newConvShape.transform.localRotation = Quaternion.Euler(Vector3.zero);
            newConvShape.transform.localScale = Vector3.one;

            var shapeComponent = newConvShape.AddComponent<FSShapeComponent>();
            shapeComponent.CollidesWith = CollidesWith;
            shapeComponent.CollisionFilter = CollisionFilter;
            shapeComponent.BelongsTo = BelongsTo;
            shapeComponent.CollisionGroup = CollisionGroup;
            shapeComponent.Friction = Friction;
            shapeComponent.Restitution = Restitution;
            shapeComponent.Density = Density;
            shapeComponent.UseUnityCollider = false;
            shapeComponent.UseTransforms = (PointInput == FSShapePointInput.Transform);

            if (PointInput == FSShapePointInput.Transform) {
                shapeComponent.PolygonTransforms = new Transform[convexShapeVs[i].Count];
                for (int j = 0; j < convexShapeVs[i].Count; j++) {
                    var pnew = new GameObject("p" + j.ToString(CultureInfo.InvariantCulture));
                    pnew.transform.parent = shapeComponent.transform;
                    pnew.transform.localPosition = FSHelper.FVector2ToVector3(convexShapeVs[i][j]);
                    shapeComponent.PolygonTransforms[j] = pnew.transform;
                }
            } else {
                shapeComponent.PolygonCoordinates = new Vector2[convexShapeVs[i].Count];
                for (int j = 0; j < convexShapeVs[i].Count; j++)
                    shapeComponent.PolygonCoordinates[j] = newConvShape.transform.InverseTransformPoint(FSHelper.FVector2ToVector3(convexShapeVs[i][j]));
            }
        }
    }
Beispiel #2
0
        public static Col.Shapes.PolygonShape RectShape(float x0, float y0, float x1, float y1)
        {
            var verts = new FarseerPhysics.Common.Vertices {
                new Microsoft.Xna.Framework.Vector2(x0, y0),
                new Microsoft.Xna.Framework.Vector2(x0, y1),
                new Microsoft.Xna.Framework.Vector2(x1, y1),
                new Microsoft.Xna.Framework.Vector2(x1, y0),
            };

            return(new Col.Shapes.PolygonShape(verts, 1f));
        }
Beispiel #3
0
        private FarseerPhysics.Common.Vertices CreateVertices(float scale)
        {
            if (this.vertices == null || this.vertices.Length < 3)
            {
                return(null);
            }
            Vector2[] vertices = this.vertices.ToArray();

            FarseerPhysics.Common.Vertices farseerVert = new FarseerPhysics.Common.Vertices(vertices.Length);
            for (int i = 0; i < vertices.Length; i++)
            {
                farseerVert.Add(PhysicsUnit.LengthToPhysical * vertices[i] * scale);
            }
            return(farseerVert);
        }
Beispiel #4
0
        public void CreateBoxCollider(int width, int height)
        {
            var w = FarseerPhysics.ConvertUnits.ToSimUnits(width);
            var h = FarseerPhysics.ConvertUnits.ToSimUnits(height);

            FarseerPhysics.Common.Vertices rectangleVertices            = FarseerPhysics.Common.PolygonTools.CreateRectangle(w / 2, h / 2);
            FarseerPhysics.Collision.Shapes.PolygonShape rectangleShape = new FarseerPhysics.Collision.Shapes.PolygonShape(rectangleVertices, 1.0f);
            var fixture = _body.CreateFixture(rectangleShape);

            //fixture.IsSensor = true;
            fixture.OnCollision       += HandleCollision;
            fixture.Friction           = 0f;
            fixture.Body.Mass          = 10f;
            fixture.Body.FixedRotation = true;
        }
Beispiel #5
0
		private FarseerPhysics.Common.Vertices CreateVertices(float scale)
		{
			if (this.vertices == null || this.vertices.Length < 3) return null;
			if (!MathF.IsPolygonConvex(this.vertices)) return null;
			
			// Be sure to not exceed the maximum vertex count
			Vector2[] sortedVertices = this.vertices.ToArray();
			if (sortedVertices.Length > MaxVertices)
			{
				Array.Resize(ref sortedVertices, MaxVertices);
				Log.Core.WriteWarning("Maximum Polygon Shape vertex count exceeded: {0} > {1}", this.vertices.Length, MaxVertices);
			}

			// Don't let all vertices be aligned on one axis (zero-area polygons)
			if (sortedVertices.Length > 0)
			{
				Vector2 firstVertex = sortedVertices[0];
				bool alignX = true;
				bool alignY = true;
				for (int i = 0; i < sortedVertices.Length; i++)
				{
					if (sortedVertices[i].X != firstVertex.X)
						alignX = false;
					if (sortedVertices[i].Y != firstVertex.Y)
						alignY = false;
					if (!alignX && !alignY)
						break;
				}
				if (alignX) sortedVertices[0].X += 0.01f;
				if (alignY) sortedVertices[0].Y += 0.01f;
			}

			// Sort vertices clockwise before submitting them to Farseer
			Vector2 centroid = Vector2.Zero;
			for (int i = 0; i < sortedVertices.Length; i++)
				centroid += sortedVertices[i];
			centroid /= sortedVertices.Length;
			sortedVertices.StableSort(delegate(Vector2 first, Vector2 second)
			{
				return MathF.RoundToInt(
					1000000.0f * MathF.Angle(centroid.X, centroid.Y, first.X, first.Y) - 
					1000000.0f * MathF.Angle(centroid.X, centroid.Y, second.X, second.Y));
			});

			// Shrink a little bit
			//for (int i = 0; i < sortedVertices.Length; i++)
			//{
			//    Vector2 rel = (sortedVertices[i] - centroid);
			//    float len = rel.Length;
			//    sortedVertices[i] = centroid + rel.Normalized * MathF.Max(0.0f, len - 1.5f);
			//}

			// Submit vertices
			FarseerPhysics.Common.Vertices v = new FarseerPhysics.Common.Vertices(sortedVertices.Length);
			for (int i = 0; i < sortedVertices.Length; i++)
			{
				v.Add(new Vector2(
					PhysicsConvert.ToPhysicalUnit(sortedVertices[i].X * scale), 
					PhysicsConvert.ToPhysicalUnit(sortedVertices[i].Y * scale)));
			}
			return v;
		}
Beispiel #6
0
        private FarseerPhysics.Common.Vertices CreateVertices(float scale)
        {
            if (this.vertices == null || this.vertices.Length < 3)
            {
                return(null);
            }
            if (!MathF.IsPolygonConvex(this.vertices))
            {
                return(null);
            }

            // Be sure to not exceed the maximum vertex count
            Vector2[] sortedVertices = this.vertices.ToArray();
            if (sortedVertices.Length > MaxVertices)
            {
                Array.Resize(ref sortedVertices, MaxVertices);
                Log.Core.WriteWarning("Maximum Polygon Shape vertex count exceeded: {0} > {1}", this.vertices.Length, MaxVertices);
            }

            // Don't let all vertices be aligned on one axis (zero-area polygons)
            if (sortedVertices.Length > 0)
            {
                Vector2 firstVertex = sortedVertices[0];
                bool    alignX      = true;
                bool    alignY      = true;
                for (int i = 0; i < sortedVertices.Length; i++)
                {
                    if (sortedVertices[i].X != firstVertex.X)
                    {
                        alignX = false;
                    }
                    if (sortedVertices[i].Y != firstVertex.Y)
                    {
                        alignY = false;
                    }
                    if (!alignX && !alignY)
                    {
                        break;
                    }
                }
                if (alignX)
                {
                    sortedVertices[0].X += 0.01f;
                }
                if (alignY)
                {
                    sortedVertices[0].Y += 0.01f;
                }
            }

            // Sort vertices clockwise before submitting them to Farseer
            Vector2 centroid = Vector2.Zero;

            for (int i = 0; i < sortedVertices.Length; i++)
            {
                centroid += sortedVertices[i];
            }
            centroid /= sortedVertices.Length;
            sortedVertices.StableSort(delegate(Vector2 first, Vector2 second)
            {
                return(MathF.RoundToInt(
                           1000000.0f * MathF.Angle(centroid.X, centroid.Y, first.X, first.Y) -
                           1000000.0f * MathF.Angle(centroid.X, centroid.Y, second.X, second.Y)));
            });

            // Shrink a little bit
            //for (int i = 0; i < sortedVertices.Length; i++)
            //{
            //    Vector2 rel = (sortedVertices[i] - centroid);
            //    float len = rel.Length;
            //    sortedVertices[i] = centroid + rel.Normalized * MathF.Max(0.0f, len - 1.5f);
            //}

            // Submit vertices
            FarseerPhysics.Common.Vertices v = new FarseerPhysics.Common.Vertices(sortedVertices.Length);
            for (int i = 0; i < sortedVertices.Length; i++)
            {
                v.Add(PhysicsUnit.LengthToPhysical * sortedVertices[i] * scale);
            }
            return(v);
        }
Beispiel #7
0
		private FarseerPhysics.Common.Vertices CreateVertices(float scale)
		{
			if (this.vertices == null || this.vertices.Length < 3) return null;
			Vector2[] vertices = this.vertices.ToArray();

			FarseerPhysics.Common.Vertices farseerVert = new FarseerPhysics.Common.Vertices(vertices.Length);
			for (int i = 0; i < vertices.Length; i++)
			{
				farseerVert.Add(PhysicsUnit.LengthToPhysical * vertices[i] * scale);
			}
			return farseerVert;
		}
		public override void OnInit()
		{
			var desc = ResourcesList.Instance[this.Id];			
			ClashEngine.NET.PhysicsManager.Instance.World.RayCast((fixture, point, n, f) =>
				{
					if (fixture.Body.UserData is IMap)
					{
						this.Position = new OpenTK.Vector2(this.Position.X, point.Y - desc.Size.Y);
						return 0;
					}
					return -1;
				}, new Microsoft.Xna.Framework.Vector2(this.Position.X + desc.Size.X / 2f, 0),
				new Microsoft.Xna.Framework.Vector2(this.Position.X + desc.Size.X / 2f, float.MaxValue));
			
			//Fizyka
			var pObj = new ClashEngine.NET.Components.PhysicalObject();
			this.Components.Add(pObj);
			this.Body = pObj.Body;

			//Tworzymy figurę dla zasobu
			FarseerPhysics.Common.Vertices verts = new FarseerPhysics.Common.Vertices();
			foreach (var point in desc.Polygon)
			{
				verts.Add(point.ToXNA());
			}
			FarseerPhysics.Factories.FixtureFactory.CreatePolygon(verts, 1, this.Body);

			this.Body.Position = this.Position.ToXNA();
			this.Body.SetCollidesWith(Category.Cat11 | Category.Cat12);
			this.Body.SetCollisionCategories(Category.Cat10);
			this.Body.UserData = this;
			this.Body.FixedRotation = true;


			this.Body.BodyType = BodyType.Dynamic;
			this.Body.FixtureList[0].AfterCollision = (a, b, c) =>
				{
					if (b.Body.UserData is IMap)
					{
						this.Body.IsStatic = true;
#if !SERVER
						this.Components.Add(new ClashEngine.NET.Graphics.Components.Sprite(this.Id, this.GameInfo.Content.Load<Texture>(desc.Image)));
#endif
					}
				};
#if !SERVER
			//Wygląd
			this.Attributes.GetOrCreate<OpenTK.Vector2>("Size").Value = desc.Size;
#endif
		}
	protected virtual void ConvertToConvex(FSConcaveShapeComponent targetCSC)
	{
		FSShapeComponent[] childcomps = targetCSC.GetComponentsInChildren<FSShapeComponent>();
		if(childcomps != null)
		{
			if(childcomps.Length > 0)
			{
				for(int i = 0; i < childcomps.Length; i++)
				{
					if(childcomps[i] == null)
						continue;
					if(childcomps[i].gameObject == null)
						continue;
					DestroyImmediate(childcomps[i].gameObject);
				}
			}
		}
		// convert vertices
		FarseerPhysics.Common.Vertices concaveVertices = new FarseerPhysics.Common.Vertices();
		
		if(targetCSC.PointInput == FSShapePointInput.Transform)
		{
			for(int i = 0; i < targetCSC.TransformPoints.Length; i++)
			{
				concaveVertices.Add(FSHelper.Vector3ToFVector2(targetCSC.TransformPoints[i].localPosition));
			}
		}
		List<FarseerPhysics.Common.Vertices> convexShapeVs = FarseerPhysics.Common.Decomposition.BayazitDecomposer.ConvexPartition(concaveVertices);
		
		for(int i = 0; i < convexShapeVs.Count; i++)
		{
			GameObject newConvShape = new GameObject("convexShape"+i.ToString());
			newConvShape.transform.parent = targetCSC.transform;
			newConvShape.transform.localPosition = Vector3.zero;
			newConvShape.transform.localRotation = Quaternion.Euler(Vector3.zero);
			newConvShape.transform.localScale = Vector3.one;
			FSShapeComponent shape0 = newConvShape.AddComponent<FSShapeComponent>();
			shape0.CollidesWith = targetCSC.CollidesWith;
			shape0.CollisionFilter = targetCSC.CollisionFilter;
			shape0.BelongsTo = targetCSC.BelongsTo;
			shape0.CollisionGroup = targetCSC.CollisionGroup;
			shape0.Friction = targetCSC.Friction;
			shape0.Restitution = targetCSC.Restitution;
			shape0.Density = targetCSC.Density;
			shape0.UseUnityCollider = false;
			shape0.PolygonPoints = new Transform[convexShapeVs[i].Count];
			for(int j = 0; j < convexShapeVs[i].Count; j++)
			{
				GameObject pnew = new GameObject("p"+j.ToString());
				pnew.transform.parent = shape0.transform;
				pnew.transform.localPosition = FSHelper.FVector2ToVector3(convexShapeVs[i][j]);
				shape0.PolygonPoints[j] = pnew.transform;
			}
		}
	}
Beispiel #10
0
        public static void ScaleFixtures(Body body, Vector2 scale)
        {
            foreach (Fixture f in body.FixtureList)
            {
                FixtureData data = FixtureExt.GetData(f);
                PolygonShape shape = (PolygonShape)f.Shape;
                Debug.Assert(data.DefaultShape.Length == shape.Vertices.Count);

                FarseerPhysics.Common.Vertices vertices = new FarseerPhysics.Common.Vertices();
                for (int i = 0; i < shape.Vertices.Count; i++)
                {
                    vertices.Add((Xna.Vector2)(data.DefaultShape[i] * scale));
                }
                //FPE will ensure the polygon is c. clockwise so we don't need to check that here.
                shape.Vertices = vertices;
            }
        }
Beispiel #11
0
        public static void CreatePolygon(Body body, Transform2 transform, IList<Vector2> vertices)
        {
            Debug.Assert(body != null);
            Debug.Assert(transform != null);
            Debug.Assert(vertices != null && vertices.Count >= 3);
            List<Vector2> fixtureContour = Actor.GetFixtureContour(vertices, transform.Scale);
            fixtureContour = MathExt.SetWinding(fixtureContour, false);

            var convexList = PolygonExt.DecomposeConcave(fixtureContour);

            List<FarseerPhysics.Common.Vertices> vList = new List<FarseerPhysics.Common.Vertices>();

            BodyExt.SetTransform(body, transform);

            for (int i = convexList.Count - 1; i >= 0; i--)
            {
                int vertMax = FarseerPhysics.Settings.MaxPolygonVertices;
                int divs = 1 + convexList[i].Count / vertMax;
                if (divs < 2)
                {
                    continue;
                }
                int j = 1;
                while (j < convexList[i].Count)
                {
                    List<Vector2> list = new List<Vector2>();
                    list.Add(convexList[i][0]);

                    list.AddRange(convexList[i].GetRange(j, Math.Min(convexList[i].Count - j, vertMax - 1)));
                    j += vertMax - 2;
                    convexList.Add(list);
                }
                convexList.RemoveAt(i);
            }

            for (int i = 0; i < convexList.Count; i++)
            {
                var v1 = new FarseerPhysics.Common.Vertices();
                v1.AddRange(convexList[i].Select(v => (Xna.Vector2)v));

                vList.Add(v1);
                PolygonShape shape = new PolygonShape(v1, 1);
                Fixture fixture = body.CreateFixture(shape);
                FixtureData userData = FixtureExt.SetData(fixture);
            }
        }