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])); } } }
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)); }
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 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; }
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; }
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); }
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; } } }
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; } }
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); } }