public void findShadowHull(Texture2D texture) { //Create an array to hold the data from the texture uint[] data = new uint[texture.Width * texture.Height]; //Transfer the texture data to the array texture.GetData(data); //Find the vertices that makes up the outline of the shape in the texture textureVertices = PolygonTools.CreatePolygon(data, texture.Width, false); //We simplify the vertices found in the texture. textureVertices = SimplifyTools.DouglasPeuckerSimplify(textureVertices, 0.5f); //Since it is a concave polygon, we need to partition it into several smaller convex polygons vertices = BayazitDecomposer.ConvexPartition(textureVertices); _scale = 1f; //scale the vertices from graphics space to sim space foreach (Vertices vertex in vertices) { Vector2[] verticesArray = vertex.ToArray(); var hull = ShadowHull.CreateConvex(ref verticesArray); hulls.Add(hull); krypton.Hulls.Add(hull); } }
public void ShapeFromTexture(string shape, float scale, Color color, out Texture2D outputTexture, out Vertices vertices) { Texture2D shapeTexture = _shapes[shape]; uint[] data = new uint[shapeTexture.Width * shapeTexture.Height]; shapeTexture.GetData(data); Vertices textureVertices = PolygonTools.CreatePolygon(data, shapeTexture.Width, false); AABB vertsBounds = textureVertices.GetCollisionBox(); Vector2 origin = vertsBounds.Center; textureVertices.Translate(-origin); int width = (int)((vertsBounds.UpperBound.X - vertsBounds.LowerBound.X) * scale); int height = (int)((vertsBounds.UpperBound.Y - vertsBounds.LowerBound.Y) * scale); textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 4f); Vector2 vertScale = ConvertUnits.ToSimUnits(Vector2.One) * scale; textureVertices.Scale(ref vertScale); vertices = new Vertices(textureVertices); RenderTarget2D renderTarget = new RenderTarget2D(_device, width + 2, height + 2, false, SurfaceFormat.Color, DepthFormat.None, 8, RenderTargetUsage.DiscardContents); SpriteBatch batch = new SpriteBatch(_device); _device.SetRenderTarget(renderTarget); _device.Clear(Color.Transparent); batch.Begin(SpriteSortMode.Immediate, null, SamplerState.LinearClamp, null, RasterizerState.CullNone); batch.Draw(shapeTexture, new Vector2(renderTarget.Width / 2, renderTarget.Height / 2), null, color, 0, origin, scale, SpriteEffects.None, 0f); batch.End(); _device.SetRenderTarget(null); outputTexture = renderTarget as Texture2D; }
static private void CreateShape(SFML.Graphics.Texture texture, World world) { // Make collision Geo from bitmap // Get pixel data in array byte[] bytes = texture.CopyToImage().Pixels; uint[] data = new uint[texture.Size.X * texture.Size.Y]; for (int i = 0; i < bytes.Length; i += 4) { data[i / 4] = BitConverter.ToUInt32(bytes, i); } Byte myByte = 1; List <Vertices> _list = PolygonTools.CreatePolygon(data, (int)texture.Size.X, 0.05f, myByte, true, true); Vertices verts = new Vertices(); Vector2 scale = ConvertUnits.ToSimUnits(new Vector2(1, 1)); foreach (Vertices v in _list) { v.Scale(scale); // v.Translate(ConvertUnits.ToSimUnits(new Vector2(-16, -16))); Body body = new Body(world); body.SleepingAllowed = false; body.UserData = "wall"; List <Fixture> fixtures = FixtureFactory.AttachCompoundPolygon( FarseerPhysics.Common.Decomposition.Triangulate.ConvexPartition(SimplifyTools.DouglasPeuckerSimplify(v, 0.05f), TriangulationAlgorithm.Bayazit, false, 0.05f), 1, body); } }
public CaveWall(GameWorld gameWorld, string textureName) : base(gameWorld, textureName) { // Read the texture data var textureData = new uint[Texture.Width * Texture.Height]; Texture.GetData(textureData); // Detect an outline of the texture var outline = PolygonTools.CreatePolygon(textureData, Texture.Width); // Scale the outline so that it fits the size of my game world var scaleVector = ConvertUnits.ToSimUnits(2, 2); outline.Scale(scaleVector); // Simplify the outline to remove redundant points outline = SimplifyTools.CollinearSimplify(outline); // Decompose the outline into polygons var decomposed = BayazitDecomposer.ConvexPartition(outline); // Create the body for the game world Body = BodyFactory.CreateCompoundPolygon(World, decomposed, 1f); }
private void Simplify() { var vertices = SimplifyTools.CollinearSimplify(this); Clear(); AddRange(vertices); }
public static Body ConvertToBody(this Texture2D me, Scene scene) { var polygonTexture = me; var data = new uint[polygonTexture.Width * polygonTexture.Height]; polygonTexture.GetData(data); var verts = PolygonTools.CreatePolygon(data, polygonTexture.Width, true); //These 2 seem to work the best with tile maps verts = SimplifyTools.CollinearSimplify(verts); verts = SimplifyTools.DouglasPeuckerSimplify(verts, 0f); var list = BayazitDecomposer.ConvexPartition(verts); var vertScale = new Vector2(1f / ConvertUnits._displayUnitsToSimUnitsRatio); foreach (var vertices in list) { vertices.Scale(ref vertScale); } var body = BodyFactory.CreateCompoundPolygon(scene.World, list, 1); Debugging.Debug.WriteLine( "WARNING: In Texture2D.ConvertToBody, Body functions have not been implemented!"); body.Friction = 0f; body.IsStatic = true; return(body); }
} // PhysicTexture(setPos, setDensity, setDiffuseTexture, setCollisionTexture) #endregion #region CreateBody /// <summary> Creates the physics Body </summary> private void CreateBody() { uint[] data = new uint[collisionTexture.Width * collisionTexture.Height]; collisionTexture.GetData(data); Vertices textureVertices = PolygonTools.CreatePolygon(data, collisionTexture.Width, true); Vector2 centroid = -textureVertices.GetCentroid(); textureVertices.Translate(ref centroid); origin = -centroid; textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 4f); Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(1)); List <Vertices> list = BayazitDecomposer.ConvexPartition(textureVertices); list.ForEach(v => v.Scale(ref vertScale)); size = list.SelectMany(v => v).CalculateSize(); body = BodyFactory.CreateCompoundPolygon(PhysicsGameScreen.World, list, density, BodyType.Static);//BodyType.Dynamic); body.Position = position; body.UserData = "physictexture"; body.Friction = 10f; } // CreateBody(setPos, setDensity)
public override void Initialize() { base.Initialize(); var data = new uint[_subtexture.SourceRect.Width * _subtexture.SourceRect.Height]; _subtexture.Texture2D.GetData(0, _subtexture.SourceRect, data, 0, data.Length); var verts = PolygonTools.CreatePolygonFromTextureData(data, _subtexture.SourceRect.Width); verts = SimplifyTools.DouglasPeuckerSimplify(verts, 2); var decomposedVerts = Triangulate.ConvexPartition(verts, TriangulationAlgorithm.Bayazit); for (var i = 0; i < decomposedVerts.Count; i++) { var polygon = decomposedVerts[i]; polygon.Translate(-_subtexture.Center); } // add the fixtures var fixtures = Body.AttachCompoundPolygon(decomposedVerts, 1); // fetch all the Vertices and save a copy in case we need to scale them later foreach (var fixture in fixtures) { _verts.Add(new Vertices((fixture.Shape as PolygonShape).Vertices)); } }
public override void Initialize() { base.Initialize(); uint[] data = new uint[Sprite.SourceRect.Width * Sprite.SourceRect.Height]; Sprite.Texture2D.GetData(0, Sprite.SourceRect, data, 0, data.Length); Vertices verts = PolygonTools.CreatePolygonFromTextureData(data, Sprite.SourceRect.Width); verts = SimplifyTools.DouglasPeuckerSimplify(verts, 2); List <Vertices> decomposedVerts = Triangulate.ConvexPartition(verts, TriangulationAlgorithm.Bayazit); for (int i = 0; i < decomposedVerts.Count; i++) { Vertices polygon = decomposedVerts[i]; polygon.Translate(-Sprite.Center); } // add the fixtures List <FarseerPhysics.Dynamics.Fixture> fixtures = Body.AttachCompoundPolygon(decomposedVerts, 1); // fetch all the Vertices and save a copy in case we need to scale them later foreach (FarseerPhysics.Dynamics.Fixture fixture in fixtures) { _verts.Add(new Vertices((fixture.Shape as PolygonShape).Vertices)); } }
private void LoadPolygonFromSprite() { #if UNITY_EDITOR Rect r = spriteRenderer.sprite.rect; Texture2D tex = spriteRenderer.sprite.texture; IBitmap bmp = ArrayBitmap.CreateFromTexture(tex, new Rect(r.x, r.y, r.width, r.height)); var polygon = BitmapHelper.CreateFromBitmap(bmp); polygon = SimplifyTools.DouglasPeuckerSimplify(new Vertices(polygon), simplify).ToArray(); Rect bounds = GetBounds(polygon); float scalex = spriteRenderer.sprite.bounds.size.x / bounds.width; float scaley = spriteRenderer.sprite.bounds.size.y / bounds.height; polygon = polygon.Select(v => new Vector2(v.x * scalex, v.y * scaley) - (bounds.center * scalex) + (Vector2)spriteRenderer.sprite.bounds.center).ToArray(); verts = polygon.Select(v => new Vertex(spriteRenderer.transform.TransformPoint(v))).ToList(); segments = new List <Segment>(); AddSegment(verts[verts.Count - 1], verts[0]); for (int i = 1; i < verts.Count; i++) { AddSegment(verts[i - 1], verts[i]); } #endif }
public FSCompoundPolygonBody(World world, Subtexture subtexture, float density, Vector2 position = default(Vector2), BodyType bodyType = BodyType.Static) : base(world, subtexture, position, bodyType) { var data = new uint[subtexture.sourceRect.Width * subtexture.sourceRect.Height]; subtexture.texture2D.GetData(0, subtexture.sourceRect, data, 0, data.Length); var verts = PolygonTools.CreatePolygon(data, subtexture.sourceRect.Width); verts = SimplifyTools.DouglasPeuckerSimplify(verts, 2); var decomposedVerts = Triangulate.ConvexPartition(verts, TriangulationAlgorithm.Bayazit); for (var i = 0; i < decomposedVerts.Count; i++) { var polygon = decomposedVerts[i]; polygon.Translate(-subtexture.center); } // add the fixtures var fixtures = Farseer.FixtureFactory.attachCompoundPolygon(decomposedVerts, density, body); // fetch all the Vertices and save a copy in case we need to scale them later foreach (var fixture in fixtures) { _verts.Add(new Vertices((fixture.Shape as PolygonShape).Vertices)); } }
public static List <Vertices> GetCompoundPolygonVertices(Texture2D _polygonTexture, float _scale, ref Vector2 origin) { uint[] data = new uint[_polygonTexture.Width * _polygonTexture.Height]; _polygonTexture.GetData(data); Vertices textureVertices = PolygonTools.CreatePolygon(data, _polygonTexture.Width, false); Vector2 centroid = -textureVertices.GetCentroid(); textureVertices.Translate(ref centroid); origin = -centroid; textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 4f); List <Vertices> list = BayazitDecomposer.ConvexPartition(textureVertices); Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(1)) * _scale; foreach (Vertices vertices in list) { vertices.Scale(ref vertScale); } return(list); }
void generateTerrain(int gx, int gy) { float ax = gx * cellSize; float ay = gy * cellSize; var polys = MarchingSquares.detectSquares(new AABB(new Vector2(ax, ay), new Vector2(ax + cellSize, ay + cellSize)), subCellSize, subCellSize, _terrainMap, iterations, true); if (polys.Count == 0) { return; } _bodyMap[gx, gy] = new List <Body>(); // create the scale vector var scale = new Vector2(1f / pointsPerUnit, 1f / -pointsPerUnit); // create physics object for this grid cell foreach (Vertices item in polys) { // does this need to be negative? item.scale(ref scale); item.translate(ref _topLeft); var simplified = SimplifyTools.collinearSimplify(item); var decompPolys = Triangulate.convexPartition(simplified, decomposer); foreach (Vertices poly in decompPolys) { if (poly.Count > 2) { _bodyMap[gx, gy].Add(BodyFactory.createPolygon(world, poly, 1)); } } } }
public override void LoadContent() { base.LoadContent(); DebugView.AppendFlags(DebugViewFlags.Shape); World.Gravity = Vector2.Zero; _border = new Border(World, ScreenManager, Camera); Texture2D alphabet = ScreenManager.Content.Load <Texture2D>("Samples/alphabet"); uint[] data = new uint[alphabet.Width * alphabet.Height]; alphabet.GetData(data); List <Vertices> list = PolygonTools.CreatePolygon(data, alphabet.Width, 3.5f, 20, true, true); float yOffset = -5f; float xOffset = -14f; for (int i = 0; i < list.Count; i++) { if (i == 9) { yOffset = 0f; xOffset = -14f; } if (i == 18) { yOffset = 5f; xOffset = -12.25f; } Vertices polygon = list[i]; Vector2 centroid = -polygon.GetCentroid(); polygon.Translate(ref centroid); polygon = SimplifyTools.CollinearSimplify(polygon); polygon = SimplifyTools.ReduceByDistance(polygon, 4); List <Vertices> triangulated = Triangulate.ConvexPartition(polygon, TriangulationAlgorithm.Bayazit); #if WINDOWS_PHONE const float scale = 0.6f; #else const float scale = 1f; #endif Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(1)) * scale; foreach (Vertices vertices in triangulated) { vertices.Scale(ref vertScale); } BreakableBody breakableBody = new BreakableBody(triangulated, World, 1); breakableBody.MainBody.Position = new Vector2(xOffset, yOffset); breakableBody.Strength = 100; World.AddBreakableBody(breakableBody); xOffset += 3.5f; } }
public override void LoadContent() { base.LoadContent(); DebugView.AppendFlags(DebugViewFlags.Shape); World.Gravity = Vector2.Zero; _border = new Border(World, ScreenManager, Camera); _breakableBodies = new List <BreakableBody>(); Texture2D alphabet = ScreenManager.Content.Load <Texture2D>("Samples/alphabet"); uint[] data = new uint[alphabet.Width * alphabet.Height]; alphabet.GetData(data); List <Vertices> list = PolygonTools.CreatePolygon(data, alphabet.Width, 3.5f, 20, true, true); for (int i = 0; i < list.Count; i++) { list[i].Scale(new Vector2(1f, -1f)); // flip Vert } float yOffset = -5f; float xOffset = -14f; for (int i = 0; i < list.Count; i++) { if (i == 9) { yOffset = 0f; xOffset = -14f; } if (i == 18) { yOffset = 5f; xOffset = -12.25f; } Vertices polygon = list[i]; Vector2 centroid = -polygon.GetCentroid(); polygon.Translate(ref centroid); polygon = SimplifyTools.CollinearSimplify(polygon); polygon = SimplifyTools.ReduceByDistance(polygon, 4); List <Vertices> triangulated = Triangulate.ConvexPartition(polygon, TriangulationAlgorithm.Bayazit); Vector2 vertScale = new Vector2(13.916667f, 23.25f) / new Vector2(alphabet.Width, alphabet.Height); foreach (Vertices vertices in triangulated) { vertices.Scale(ref vertScale); } var breakableBody = new BreakableBody(World, triangulated, 1); breakableBody.MainBody.Position = new Vector2(xOffset, yOffset); breakableBody.Strength = 100; _breakableBodies.Add(breakableBody); xOffset += 3.5f; } }
private static Vector2[] CreatePolygon(Sprite sprite) { Rect r = sprite.rect; Texture2D tex = sprite.texture; IBitmap bmp = ArrayBitmap.CreateFromTexture(tex, new Rect(r.x, r.y, r.width, r.height)); Vector2[] polygon = BitmapHelper.CreateFromBitmap(bmp); polygon = SimplifyTools.DouglasPeuckerSimplify(new Vertices(polygon), 1.0f).ToArray(); return(polygon); }
public override void LoadContent() { base.LoadContent(); World.Gravity = Vector2.Zero; _border = new Border(World, this, ScreenManager.GraphicsDevice.Viewport); //load texture that will represent the physics body _polygonTexture = ScreenManager.Content.Load <Texture2D>("Samples/object"); //Create an array to hold the data from the texture uint[] data = new uint[_polygonTexture.Width * _polygonTexture.Height]; //Transfer the texture data to the array _polygonTexture.GetData(data); //Find the vertices that makes up the outline of the shape in the texture Vertices textureVertices = PolygonTools.CreatePolygon(data, _polygonTexture.Width, false); //The tool return vertices as they were found in the texture. //We need to find the real center (centroid) of the vertices for 2 reasons: //1. To translate the vertices so the polygon is centered around the centroid. Vector2 centroid = -textureVertices.GetCentroid(); textureVertices.Translate(ref centroid); //2. To draw the texture the correct place. _origin = -centroid; //We simplify the vertices found in the texture. textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 4f); //Since it is a concave polygon, we need to partition it into several smaller convex polygons List <Vertices> list = BayazitDecomposer.ConvexPartition(textureVertices); //Adjust the scale of the object for WP7's lower resolution #if WINDOWS_PHONE _scale = 0.6f; #else _scale = 1f; #endif //scale the vertices from graphics space to sim space Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(1)) * _scale; foreach (Vertices vertices in list) { vertices.Scale(ref vertScale); } //Create a single body with multiple fixtures _compound = BodyFactory.CreateCompoundPolygon(World, list, 1f, BodyType.Dynamic); _compound.BodyType = BodyType.Dynamic; }
public override void LoadContent() { base.LoadContent(); World.Gravity = Vector2.Zero; _border = new Border(World, ScreenManager, Camera); //load texture that will represent the physics body _polygonTexture = ScreenManager.Content.Load <Texture2D>("Samples/object"); //Create an array to hold the data from the texture uint[] data = new uint[_polygonTexture.Width * _polygonTexture.Height]; //Transfer the texture data to the array _polygonTexture.GetData(data); //Find the vertices that makes up the outline of the shape in the texture Vertices textureVertices = PolygonTools.CreatePolygon(data, _polygonTexture.Width, false); //The tool return vertices as they were found in the texture. //We need to find the real center (centroid) of the vertices for 2 reasons: //1. To translate the vertices so the polygon is centered around the centroid. Vector2 centroid = -textureVertices.GetCentroid(); textureVertices.Translate(ref centroid); //2. To draw the texture the correct place. _origin = -centroid; var aabb = textureVertices.GetAABB(); _polygonSize = new Vector2(aabb.Width, aabb.Height); //We simplify the vertices found in the texture. textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 4f); //Since it is a concave polygon, we need to partition it into several smaller convex polygons List <Vertices> list = Triangulate.ConvexPartition(textureVertices, TriangulationAlgorithm.Bayazit); //scale the vertices from graphics space to sim space Vector2 vertScale = new Vector2(1f / 24f); _polygonSize *= vertScale; foreach (Vertices vertices in list) { vertices.Scale(new Vector2(1f, -1f)); vertices.Translate(new Vector2(0f, 30f)); vertices.Scale(vertScale); } //Create a single body with multiple fixtures _compound = World.CreateCompoundPolygon(list, 1f, Vector2.Zero, 0, BodyType.Dynamic); _compound.BodyType = BodyType.Dynamic; }
/// <summary> /// Implements "A new algorithm for Boolean operations on general polygons" available here: /// http://liama.ia.ac.cn/wiki/_media/user:dong:dong_cg_05.pdf Merges two polygons, a subject and a clip with the /// specified /// operation. Polygons may not be self-intersecting. Warning: May yield incorrect results or even crash if polygons /// contain collinear points. /// </summary> /// <param name="subject">The subject polygon.</param> /// <param name="clip">The clip polygon, which is added, substracted or intersected with the subject</param> /// <param name="clipType">The operation to be performed. Either Union, Difference or Intersection.</param> /// <param name="error">The error generated (if any)</param> /// <returns> /// A list of closed polygons, which make up the result of the clipping operation. Outer contours are ordered /// counter clockwise, holes are ordered clockwise. /// </returns> private static List <Vertices> Execute(Vertices subject, Vertices clip, PolyClipType clipType, out PolyClipError error) { Debug.Assert(subject.IsSimple() && clip.IsSimple(), "Non simple input!", "Input polygons must be simple (cannot intersect themselves)."); // Copy polygons // Calculate the intersection and touch points between // subject and clip and add them to both CalculateIntersections(subject, clip, out Vertices slicedSubject, out Vertices slicedClip); // Translate polygons into upper right quadrant // as the algorithm depends on it Vector2 lbSubject = subject.GetAabb().LowerBound; Vector2 lbClip = clip.GetAabb().LowerBound; Vector2 translate = Vector2.Min(lbSubject, lbClip); translate = Vector2.One - translate; if (translate != Vector2.Zero) { slicedSubject.Translate(ref translate); slicedClip.Translate(ref translate); } // Enforce counterclockwise contours slicedSubject.ForceCounterClockWise(); slicedClip.ForceCounterClockWise(); // Build simplical chains from the polygons and calculate the // the corresponding coefficients CalculateSimplicalChain(slicedSubject, out List <float> subjectCoeff, out List <Edge> subjectSimplices); CalculateSimplicalChain(slicedClip, out List <float> clipCoeff, out List <Edge> clipSimplices); // Determine the characteristics function for all non-original edges // in subject and clip simplical chain and combine the edges contributing // to the result, depending on the clipType CalculateResultChain(subjectCoeff, subjectSimplices, clipCoeff, clipSimplices, clipType, out List <Edge> resultSimplices); // Convert result chain back to polygon(s) error = BuildPolygonsFromChain(resultSimplices, out List <Vertices> result); // Reverse the polygon translation from the beginning // and remove collinear points from output translate *= -1f; for (int i = 0; i < result.Count; ++i) { result[i].Translate(ref translate); SimplifyTools.CollinearSimplify(result[i]); } return(result); }
public static PhysicsFrame GetVerticesForTextureData(uint[] textureData, int textureWidth) { Vertices textureVertices = PolygonTools.CreatePolygon(textureData, textureWidth, false); Vector2 offset = -textureVertices.GetCentroid(); textureVertices.Translate(ref offset); SimplifyTools.MergeParallelEdges(textureVertices, 0); List <Vertices> convexVertices = BayazitDecomposer.ConvexPartition(textureVertices); ConvertUnits.ScaleToSimUnits(ref convexVertices); return(new PhysicsFrame(convexVertices, -offset)); }
static List <Vertices> ToVertices(Texture2D texture, out Vector2 origin) { //Create an array to hold the data from the texture uint[] data = new uint[texture.Width * texture.Height]; //Transfer the texture data to the array texture.GetData(data); Vertices textureVertices = PolygonTools.CreatePolygon(data, texture.Width, false); //The tool return vertices as they were found in the texture. //We need to find the real center (centroid) of the vertices for 2 reasons: //1. To translate the vertices so the polygon is centered around the centroid. var centroid = -textureVertices.GetCentroid(); textureVertices.Translate(ref centroid); //2. To draw the texture the correct place. origin = -centroid; //We simplify the vertices found in the texture. textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 5f); //Since it is a concave polygon, we need to partition it into several smaller convex polygons //List<Vertices> list = BayazitDecomposer.ConvexPartition(textureVertices); try { List <Vertices> list = BayazitDecomposer.ConvexPartition(textureVertices); //Now we need to scale the vertices (result is in pixels, we use meters) //At the same time we flip the y-axis. var scale = new Vector2(0.015f, 0.015f); foreach (Vertices vertices in list) { vertices.Scale(ref scale); //When we flip the y-axis, the orientation can change. //We need to remember that FPE works with CCW polygons only. vertices.ForceCounterClockWise(); } return(list); } catch { return(new List <Vertices>()); } }
public static TexVertOutput TexToVert(World world, Texture2D texture, float mass, bool useCentroid, float scale) { Vertices verts; TexVertOutput output = new TexVertOutput(); // Creates an array for every pixel in the texture uint[] data = new uint[texture.Width * texture.Height]; texture.GetData(data); verts = PolygonTools.CreatePolygon(data, texture.Width, false); Vector2 centroid = Vector2.Zero; // Origin needs to be altered so it uses the origin of the verts // rather than the texture's centre. if (useCentroid) { centroid = -verts.GetCentroid(); verts.Translate(ref centroid); } else { centroid = ConvertUnits.ToSimUnits(new Vector2(texture.Width, texture.Height) * 0.5f); } float simScale = ConvertUnits.ToSimUnits(scale); Vector2 Scale = new Vector2(simScale, simScale); verts.Scale(ref Scale); verts = SimplifyTools.ReduceByDistance(verts, ConvertUnits.ToSimUnits(4f)); Body body = BodyFactory.CreateCompoundPolygon(world, EarclipDecomposer.ConvexPartition(verts), mass); body.BodyType = BodyType.Dynamic; if (!useCentroid) { body.LocalCenter = centroid; } output.Body = body; output.Origin = ConvertUnits.ToDisplayUnits(centroid); return(output); }
public void findShadowHull(Texture2D texture) { //Create an array to hold the data from the texture uint[] data = new uint[texture.Width * texture.Height]; //Transfer the texture data to the array texture.GetData(data); //Find the vertices that makes up the outline of the shape in the texture textureVertices = PolygonTools.CreatePolygon(data, texture.Width, false); //The tool return vertices as they were found in the texture. //We need to find the real center (centroid) of the vertices for 2 reasons: //1. To translate the vertices so the polygon is centered around the centroid. Vector2 centroid = -textureVertices.GetCentroid(); textureVertices.Translate(ref centroid); //2. To draw the texture the correct place. _origin = -centroid; //We simplify the vertices found in the texture. textureVertices = SimplifyTools.CollinearSimplify(textureVertices, 0f); //Since it is a concave polygon, we need to partition it into several smaller convex polygons list = BayazitDecomposer.ConvexPartition(textureVertices); //Adjust the scale of the object for WP7's lower resolution //Adjust the scale of the object for WP7's lower resolution #if WINDOWS_PHONE _scale = 0.6f; #else _scale = 1f; #endif //scale the vertices from graphics space to sim space Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(1)) * _scale; foreach (Vertices vertices in list) { vertices.Scale(ref vertScale); Vector2[] verticesArray = vertices.ToArray(); var hull = ShadowHull.CreateConvex(ref verticesArray); hulls.Add(hull); krypton.Hulls.Add(hull); } }
private List <Vector2[]> ProcessVertices(PolygonCollider2D collider, Vertices v, List <Vector2[]> list, ref PolygonParameters p, ref int pathIndex) { Vector2 offset = p.Offset; float flipXMultiplier = (spriteRenderer.flipX ? -1.0f : 1.0f); float flipYMultiplier = (spriteRenderer.flipY ? -1.0f : 1.0f); if (p.DistanceThreshold > 1) { v = SimplifyTools.DouglasPeuckerSimplify(v, p.DistanceThreshold); } if (p.Decompose) { List <List <Vector2> > points = BayazitDecomposer.ConvexPartition(v); for (int j = 0; j < points.Count; j++) { List <Vector2> v2 = points[j]; for (int i = 0; i < v2.Count; i++) { float xValue = (2.0f * (((v2[i].x - offset.x) + 0.5f) / p.Rect.width)); float yValue = (2.0f * (((v2[i].y - offset.y) + 0.5f) / p.Rect.height)); v2[i] = new Vector2(xValue * p.XMultiplier * Scale * flipXMultiplier, yValue * p.YMultiplier * Scale * flipYMultiplier); } Vector2[] arr = v2.ToArray(); collider.pathCount = pathIndex + 1; collider.SetPath(pathIndex++, arr); list.Add(arr); } } else { collider.pathCount = pathIndex + 1; for (int i = 0; i < v.Count; i++) { float xValue = (2.0f * (((v[i].x - offset.x) + 0.5f) / p.Rect.width)); float yValue = (2.0f * (((v[i].y - offset.y) + 0.5f) / p.Rect.height)); v[i] = new Vector2(xValue * p.XMultiplier * Scale * flipXMultiplier, yValue * p.YMultiplier * Scale * flipYMultiplier); } Vector2[] arr = v.ToArray(); collider.SetPath(pathIndex++, arr); list.Add(arr); } return(list); }
public PhysicObj(World world, Texture2D texture, Vector2 scale, float density) : base(texture, 0, scale, Vector2.Zero) { this.texture = texture; this.scale = scale; scale /= MULTIPLER; uint[] data = new uint[texture.Width * texture.Height]; texture.GetData(data); Vertices textureVertices = PolygonTools.CreatePolygon(data, texture.Width, false); Vector2 centroid = -textureVertices.GetCentroid(); textureVertices.Translate(ref centroid); origin = -centroid; textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 4f); List <Vertices> list = BayazitDecomposer.ConvexPartition(textureVertices); float minX = float.PositiveInfinity; float maxX = float.NegativeInfinity; foreach (Vertices vertices in list) { vertices.Scale(ref scale); foreach (Vector2 vec in vertices) { if (vec.X < minX) { minX = vec.X; } if (maxX < vec.X) { maxX = vec.X; } } } body = BodyFactory.CreateCompoundPolygon(world, list, density, BodyType.Dynamic); body.BodyType = BodyType.Dynamic; }
public Wall(Vertices vertices, WallType type, PlayWindow playWindow) { _playWindow = playWindow; _thickness = 100.0f; Vertices wallVertices = SimplifyTools.CollinearSimplify(vertices); _body = BodyFactory.CreateLoopShape(_playWindow.World, VerticesToSimUnits(wallVertices)); _body.CollisionCategories = Category.All; _body.CollidesWith = Category.All; _basicEffect = new BasicEffect(_playWindow.GraphicsDevice); _basicEffect.TextureEnabled = true; _basicEffect.Texture = _wallTexture; InitDrawVertices(wallVertices, type); }
private void CreatePolygon(Texture2D a_texture, World a_world) { //Create an array to hold the data from the texture uint[] data = new uint[a_texture.Width * a_texture.Height]; //Transfer the texture data to the array a_texture.GetData(data); //Find the vertices that makes up the outline of the shape in the texture Vertices textureVertices = PolygonTools.CreatePolygon(data, a_texture.Width, false); //The tool return vertices as they were found in the texture. //We need to find the real center (centroid) of the vertices for 2 reasons: //1. To translate the vertices so the polygon is centered around the centroid. Vector2 centroid = -textureVertices.GetCentroid(); textureVertices.Translate(ref centroid); //2. To draw the texture the correct place. _origin = -centroid; //We simplify the vertices found in the texture. textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 4f); //Since it is a concave polygon, we need to partition it into several smaller convex polygons List <Vertices> list = Triangulate.ConvexPartition(textureVertices, TriangulationAlgorithm.Bayazit); //Adjust the scale of the object for WP7's lower resolution _scale = new Vector2(1f, 1f); //scale the vertices from graphics space to sim space Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(1)) * _scale; foreach (Vertices vertices in list) { vertices.Scale(ref vertScale); } //Create a single body with multiple fixtures _body = BodyFactory.CreateCompoundPolygon(a_world, list, 1f, BodyType.Dynamic); _body.BodyType = BodyType.Dynamic; }
public FarseerObject(FarseerWorld world, Texture2D texture, float density = 1, BodyType BodyType = BodyType.Dynamic, float colapseDistance = 4) { //Create an array to hold the data from the texture uint[] data = new uint[texture.Width * texture.Height]; //Transfer the texture data to the array texture.GetData(data); //Find the vertices that makes up the outline of the shape in the texture Vertices textureVertices = PolygonTools.CreatePolygon(data, texture.Width); //The tool return vertices as they were found in the texture. //We need to find the real center (centroid) of the vertices for 2 reasons: //1. To translate the vertices so the polygon is centered around the centroid. Vector2 centroid = -textureVertices.GetCentroid(); textureVertices.Translate(ref centroid); //2. To draw the texture the correct place. Origin = -centroid - new Vector2(texture.Width / 2, texture.Height / 2);; //We simplify the vertices found in the texture. textureVertices = SimplifyTools.ReduceByDistance(textureVertices, colapseDistance); //Since it is a concave polygon, we need to partition it into several smaller convex polygons List <Vertices> list = BayazitDecomposer.ConvexPartition(textureVertices); //scale the vertices from graphics space to sim space Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(1)); foreach (Vertices vertices in list) { vertices.Scale(ref vertScale); } //Create a single body with multiple fixtures body = BodyFactory.CreateCompoundPolygon(world.World, list, density, BodyType); body.BodyType = BodyType; body.CollisionCategories = Category.All; body.CollidesWith = Category.All; body.Enabled = false; }
public void loadConvexHulls() { //World.Gravity = Vector2.Zero; //load texture that will represent the physics body _polygonTexture = Content.Load <Texture2D>("Tiles/Exit"); //Create an array to hold the data from the texture uint[] data = new uint[_polygonTexture.Width * _polygonTexture.Height]; //Transfer the texture data to the array _polygonTexture.GetData(data); //Find the vertices that makes up the outline of the shape in the texture textureVertices = PolygonTools.CreatePolygon(data, _polygonTexture.Width, false); //The tool return vertices as they were found in the texture. //We need to find the real center (centroid) of the vertices for 2 reasons: //1. To translate the vertices so the polygon is centered around the centroid. //Vector2 centroid = -textureVertices.GetCentroid(); //textureVertices.Translate(ref centroid); //2. To draw the texture the correct place. //_origin = -centroid; //We simplify the vertices found in the texture. textureVertices = SimplifyTools.CollinearSimplify(textureVertices, 1f); //Since it is a concave polygon, we need to partition it into several smaller convex polygons list = BayazitDecomposer.ConvexPartition(textureVertices); //scale the vertices from graphics space to sim space // Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(1)) * _scale; //foreach (Vertices vertices in list) //{ // vertices.Scale(ref vertScale); // } //Create a single body with multiple fixtures // _compound = BodyFactory.CreateCompoundPolygon(World, list, 1f, BodyType.Dynamic); // _compound.BodyType = BodyType.Dynamic; }
/* * private void world_OnBroadPhaseCollision(ref FixtureProxy proxyA, ref FixtureProxy proxyB) * { * // Get the collided entities * Entity entityA = proxyA.Fixture.Body.UserData as Entity; * Entity entityB = proxyB.Fixture.Body.UserData as Entity; * if (entityA == null || entityB == null) * { * // fail in debug builds * Debug.Assert(entityA != null && entityB != null); * return; * } * entityA.CollideWith(entityB); * } */ private Body BodyFromTexture(Texture2D texture, float density) { //Create an array to hold the data from the texture uint[] data = new uint[texture.Width * texture.Height]; //Transfer the texture data to the array texture.GetData(data); //Find the vertices that makes up the outline of the shape in the texture Vertices textureVertices = PolygonTools.CreatePolygon(data, texture.Width, false); //The tool return vertices as they were found in the texture. //We need to find the real center (centroid) of the vertices for 2 reasons: //1. To translate the vertices so the polygon is centered around the centroid. Vector2 centroid = -textureVertices.GetCentroid(); textureVertices.Translate(ref centroid); //2. To draw the texture the correct place. Vector2 _origin = -centroid; //We simplify the vertices found in the texture. textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 4f); //Since it is a concave polygon, we need to partition it into several smaller convex polygons List <Vertices> list = BayazitDecomposer.ConvexPartition(textureVertices); //scale the vertices from graphics space to sim space Vector2 vertScale = new Vector2(WorldConversions.ConvertFromPixels(1)); foreach (Vertices vertices in list) { vertices.Scale(ref vertScale); } //Create a single body with multiple fixtures Body body = BodyFactory.CreateCompoundPolygon( CurrentLevel.PhysicsWorld, list, density, BodyType.Dynamic); return(body); }