public Texture2D TextureFromVertices(Vertices vertices, MaterialType type, Color color, float materialScale, float pixelsPerMeter) { // copy vertices Vertices verts = new Vertices(vertices); // scale to display units (i.e. pixels) for rendering to texture Vector2 scale = Vector2.One * pixelsPerMeter; verts.Scale(ref scale); // translate the boundingbox center to the texture center // because we use an orthographic projection for rendering later AABB vertsBounds = verts.GetAABB(); verts.Translate(-vertsBounds.Center); List <Vertices> decomposedVerts; if (!verts.IsConvex()) { decomposedVerts = Triangulate.ConvexPartition(verts, TriangulationAlgorithm.Earclip); } else { decomposedVerts = new List <Vertices>(); decomposedVerts.Add(verts); } List <VertexPositionColorTexture[]> verticesFill = new List <VertexPositionColorTexture[]>(decomposedVerts.Count); materialScale /= _materials[type].Width; for (int i = 0; i < decomposedVerts.Count; ++i) { verticesFill.Add(new VertexPositionColorTexture[3 * (decomposedVerts[i].Count - 2)]); for (int j = 0; j < decomposedVerts[i].Count - 2; ++j) { // fill vertices verticesFill[i][3 * j].Position = new Vector3(decomposedVerts[i][0], 0f); verticesFill[i][3 * j + 1].Position = new Vector3(decomposedVerts[i].NextVertex(j), 0f); verticesFill[i][3 * j + 2].Position = new Vector3(decomposedVerts[i].NextVertex(j + 1), 0f); verticesFill[i][3 * j].TextureCoordinate = decomposedVerts[i][0] * materialScale; verticesFill[i][3 * j + 1].TextureCoordinate = decomposedVerts[i].NextVertex(j) * materialScale; verticesFill[i][3 * j + 2].TextureCoordinate = decomposedVerts[i].NextVertex(j + 1) * materialScale; verticesFill[i][3 * j].Color = verticesFill[i][3 * j + 1].Color = verticesFill[i][3 * j + 2].Color = color; } } // calculate outline VertexPositionColor[] verticesOutline = new VertexPositionColor[2 * verts.Count]; for (int i = 0; i < verts.Count; ++i) { verticesOutline[2 * i].Position = new Vector3(verts[i], 0f); verticesOutline[2 * i + 1].Position = new Vector3(verts.NextVertex(i), 0f); verticesOutline[2 * i].Color = verticesOutline[2 * i + 1].Color = Color.Black; } Vector2 vertsSize = new Vector2(vertsBounds.UpperBound.X - vertsBounds.LowerBound.X, vertsBounds.UpperBound.Y - vertsBounds.LowerBound.Y); return(RenderTexture((int)vertsSize.X, (int)vertsSize.Y, _materials[type], verticesFill, verticesOutline)); }
public override void Initialize() { Bitmap polygonTexture = Bitmap.FromFile("AltData/FarseerPhysics/Testbed/Content/Texture.png"); uint[] data = new uint[polygonTexture.PixelWidth * polygonTexture.PixelHeight]; BitmapData bitmapData = polygonTexture.LockBits(ImageLockMode.ReadOnly); byte[] src_buffer = bitmapData.Scan0; System.Buffer.BlockCopy(src_buffer, 0, data, 0, src_buffer.Length); polygonTexture.UnlockBits(bitmapData); Vertices verts = PolygonTools.CreatePolygon(data, polygonTexture.PixelWidth); Vector2 scale = new Vector2(0.07f, -0.07f); verts.Scale(ref scale); Vector2 centroid = -verts.GetCentroid(); verts.Translate(ref centroid); Body compund = BodyFactory.CreateCompoundPolygon(World, Triangulate.ConvexPartition(verts, TriangulationAlgorithm.Bayazit), 1); compund.Position = new Vector2(-25, 30); Body b = compund.DeepClone(); b.Position = new Vector2(20, 30); b.BodyType = BodyType.Dynamic; base.Initialize(); }
private void CreateFixtures() { //Partition shape into convex pieces List <Vertices> verts; if (!Vertices.IsConvex()) { verts = Triangulate.ConvexPartition(Vertices, TriangulationAlgorithm.Bayazit); } else { verts = new List <Vertices>(); verts.Add(Vertices); } //Create fixtures for each piece foreach (Vertices v in verts) { PolygonShape shape = new PolygonShape(v, _density); Body.CreateFixture(shape); } //wake body up Body.Awake = true; }
private void EnsureDecomposedPolygons() { if (this.convexPolygons != null && this.convexPolygons.Count > 0) { return; } if (this.convexPolygons == null) { this.convexPolygons = new List <Vector2[]>(); } // No valid polygon defined at all: Nothing to generate. if (this.vertices == null || this.vertices.Length < 3) { return; } Vertices fullPolygon = VerticesToFarseer(this.vertices, 1.0f); // Do not allow neighbor vertices that are too close to each other. for (int i = 1; i < fullPolygon.Count; i++) { float distance = (fullPolygon[i - 1] - fullPolygon[i]).Length; if (distance < 0.01f) { return; } } // Discard non-simple and micro area polygons early, as there // is nothing that decomposition can do in this case. if (!fullPolygon.IsSimple()) { return; } if (fullPolygon.GetArea() < 0.0001f) { return; } // If the polygon is small enough and convex, use it as-is. if (this.vertices.Length <= FarseerPhysics.Settings.MaxPolygonVertices) { fullPolygon.ForceCounterClockWise(); if (fullPolygon.IsConvex()) { this.convexPolygons.Add(VerticesToDuality(fullPolygon)); return; } } // Decompose non-convex polygons and save them persistently, // so we don't need to decompose them again unless modified. List <Vertices> decomposed = Triangulate.ConvexPartition(fullPolygon, TriangulationAlgorithm.Delauny); foreach (Vertices polygon in decomposed) { this.convexPolygons.Add(VerticesToDuality(polygon)); } }
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)); } } } }
private static void test02(string prefix) //****************************************************************************80 // // Purpose: // // TEST02 triangulates a polygon described in a file. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 06 May 2014 // // Author: // // John Burkardt. // { int i; // // Create filenames. // string node_filename = prefix + "_nodes.txt"; string element_filename = prefix + "_elements.txt"; Console.WriteLine(""); Console.WriteLine("TEST02"); Console.WriteLine(" Read polygon coordinates in \"" + node_filename + "\""); // // Read the node coordinates. // TableHeader h = typeMethods.r8mat_header_read(node_filename); int n = h.n; double[] xy = typeMethods.r8mat_data_read(node_filename, 2, n); // // Get the triangulation. // double[] x = new double[n]; double[] y = new double[n]; for (i = 0; i < n; i++) { x[i] = xy[0 + i * 2]; y[i] = xy[1 + i * 2]; } int[] triangles = Triangulate.polygon_triangulate(n, x, y); // // Write the triangulation to a file. // int triangle_num = n - 2; typeMethods.i4mat_write(element_filename, 3, triangle_num, triangles); Console.WriteLine(" Write triangulation to \"" + element_filename + "\""); }
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)); } }
void CreateMesh(List <Vector2> stroke) { var go = new GameObject(); go.name = "Polygon"; go.transform.parent = this.transform; go.transform.localRotation = Quaternion.Euler(Vector3.zero); var mesh = new Mesh(); mesh.vertices = PurifyStroke(stroke).Select(v2 => new Vector3(v2.x, v2.y, -(polygonCount + 1) / 100.0f)).ToArray(); var indices = new List <int>(); Triangulate.EarCut(mesh.vertices, indices); mesh.SetIndices(indices.ToArray(), MeshTopology.Triangles, 0); var renderer = go.AddComponent <MeshRenderer>(); renderer.material = BrushMaterial; renderer.material.color = palette[currentBrush.PaletteIndex]; var filter = go.AddComponent <MeshFilter>(); filter.mesh = mesh; this.mesh = mesh; polygonCount++; }
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 void OnSceneGUI() { if (!acceptInput) { return; } DrawHandleGUI(MeshPath); #region 创建藤节点坐标显示轴 for (int i = 0; i < MeshPath.Count; i++) { MeshPath[i] = Handles.PositionHandle(MeshPath[i], Quaternion.identity); tp = MeshPath[i]; if (tp != MeshPath[i]) { Vector3 p = MeshPath[i]; p.z = MeshPath[i].z; MeshPath[i] = p; } } #endregion MeshVertices = GetMeshVertices(MeshPath); MeshTriangles = Triangulate.Points(MeshVertices); Mesh meshS = new Mesh(); meshS.name = "Mesh2"; meshS.vertices = MeshVertices; meshS.uv = GetMeshUV(MeshPath); meshS.triangles = MeshTriangles; mesh.mesh = meshS; }
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)); } }
/** * makeFaceText: Given an input texture and points, transfer texture to outoutTexture */ public void makeFaceText(Texture2D tex, List <Vector2> facePoints) { // Set input texture inputTexture = tex; // Set user points this.points = facePoints; // If debug, draw red dots on the original image points if (debug) { foreach (var p in points) { tex.SetPixel((int)p.x, (int)p.y, Color.red); Debug.Log("(" + (int)p[0] + ", " + (int)p[1] + ") "); } tex.Apply(); } // Triangulate inpute texture triangulation = new Triangulate(points, tex.width, tex.height); // Create output texture //outputTexture = new Texture2D (standardFaceWidth, standardFaceHeight); // Make the transfer transferTexture(inputTexture, triangulation, outputTexture, standardFaceTriangulation); // Set as texture GetComponent <Renderer> ().material.mainTexture = outputTexture; }
private void CreateFixture(TmxObject tmxObj) { float density = 1f; string densityStr; tmxObj.Properties.TryGetValue("Density", out densityStr); if (densityStr != null) { density = float.Parse(densityStr); } // A Farseer Body's Position variable defines the CENTER of the Body, so we add half the width and height to get it to the desired location. switch (tmxObj.ObjectType) { case TmxObjectType.Basic: case TmxObjectType.Tile: { Vector2 size = ConvertUnits.ToSimUnits(new Vector2((float)tmxObj.Width, (float)tmxObj.Height)); fixture = FixtureFactory.AttachRectangle(size.X, size.Y, density, Vector2.Zero, body); break; } case TmxObjectType.Ellipse: { Vector2 size = ConvertUnits.ToSimUnits(new Vector2((float)tmxObj.Width, (float)tmxObj.Height)); if (size.X == size.Y) { fixture = FixtureFactory.AttachCircle(size.X / 2, density, body); } else { fixture = FixtureFactory.AttachEllipse(size.X / 2, size.Y / 2, Settings.MaxPolygonVertices, density, body); } break; } case TmxObjectType.Polygon: { Vertices vertices = new Vertices(); foreach (var v in tmxObj.Points) { vertices.Add(ConvertUnits.ToSimUnits(new Vector2((float)v.X, (float)v.Y))); } List<Vertices> decomposedVertices = Triangulate.ConvexPartition(vertices, TriangulationAlgorithm.Bayazit); fixtures = FixtureFactory.AttachCompoundPolygon(decomposedVertices, density, body); break; } case TmxObjectType.Polyline: { Vertices vertices = new Vertices(); foreach (var v in tmxObj.Points) { vertices.Add(ConvertUnits.ToSimUnits(new Vector2((float)v.X, (float)v.Y))); } fixture = FixtureFactory.AttachChainShape(vertices, body); break; } default: { throw new InvalidOperationException("TmxObjectType not recognized: " + tmxObj.ObjectType.ToString()); } } }
public override void Initialize() { Texture2D polygonTexture = GameInstance.Content.Load <Texture2D>("Texture"); uint[] data = new uint[polygonTexture.Width * polygonTexture.Height]; polygonTexture.GetData(data); Vertices verts = PolygonTools.CreatePolygon(data, polygonTexture.Width); Vector2 scale = new Vector2(0.07f, -0.07f); verts.Scale(ref scale); Vector2 centroid = -verts.GetCentroid(); verts.Translate(ref centroid); Body compund = World.CreateCompoundPolygon(Triangulate.ConvexPartition(verts, TriangulationAlgorithm.Bayazit), 1); compund.Position = new Vector2(-25, 30); Body b = compund.DeepClone(); b.Position = new Vector2(20, 30); b.BodyType = BodyType.Dynamic; base.Initialize(); }
void UpdateMesh(List <Vector2> stroke) { mesh.vertices = PurifyStroke(stroke).Select(v2 => new Vector3(v2.x, v2.y, -(polygonCount + 1) / 100.0f)).ToArray(); var indices = new List <int>(); Triangulate.EarCut(mesh.vertices, indices); mesh.SetIndices(indices.ToArray(), MeshTopology.Triangles, 0); }
/// <summary> /// Generates the bodies for each of the pieces of the sheet. /// </summary> /// <param name="levelWorld">The world to create bodies in</param> /// <param name="collisionCategory">The FULL category of what these bodies should collide with</param> public void GenerateBodies(World levelWorld, Category collisionCategory) //TODO get scale { BodiesGenerated = true; int SpriteSheetSize = SpriteSheet.Width * SpriteSheet.Height; int IndividualSize = ImageSize.X * ImageSize.Y; uint[] TextureData = new uint[SpriteSheetSize]; //Array to copy texture info into SpriteSheet.GetData <uint>(TextureData); //Gets which pixels of the texture are actually filled List <uint[]> IndividualData = new List <uint[]>(); for (int Processed = 0; Processed < SpriteSheetSize && IndividualData.Count < Bodies.Length; Processed += IndividualSize) { //TODO CHECK IF THIS WORKS TESTING TO CUT OFF ARRAY ARGUMENT EXCEPTION uint[] TempArray = new uint[IndividualSize]; try { Array.Copy(TextureData, Processed, TempArray, 0, IndividualSize); } catch (ArgumentException) { //At the end of textures the amount of data left might be to small Array.Copy(TextureData, Processed, TempArray, 0, TextureData.Length - Processed); } IndividualData.Add(TempArray); } int BodyIndex = 0; for (int count = 0; count < IndividualData.Count; ++count) { uint[] I = IndividualData[count]; Vertices vertices = TextureConverter.DetectVertices(I, ImageSize.X); List <Vertices> VertexList = Triangulate.ConvexPartition(vertices, TriangulationAlgorithm.Earclip); //error with bayazit and deluny //Siedle doesnt wortk //Earclip & flipcode results in glitches //Earclip works very well Vector2 VertScale = new Vector2(ConvertUnits.ToSimUnits(Scale)); foreach (Vertices vert in VertexList) { vert.Scale(ref VertScale); //Scales the vertices to match the size we specified } Vector2 Centroid = -vertices.GetCentroid(); vertices.Translate(ref Centroid); //basketOrigin = -centroid; //This actually creates the body Bodies[BodyIndex] = BodyFactory.CreateCompoundPolygon(levelWorld, VertexList, 1, Vector2.Zero); Bodies[BodyIndex].BodyType = BodyType.Dynamic; Bodies[BodyIndex].Enabled = false; //Bodies[BodyIndex].CollisionCategories = collisionCategory; ++BodyIndex; } }
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; } }
public IList <Texture2D> BreakableTextureFragments(BreakableBody body, string textureName) { List <Texture2D> result = new List <Texture2D>(); Vector2 scale = ConvertUnits.ToDisplayUnits(Vector2.One); foreach (Fixture f in body.Parts) { Vertices v = null; if (f.Shape is PolygonShape polygonShape) { v = new Vertices(polygonShape.Vertices); v.Scale(ref scale); } if (v != null) { AABB polygonBounds = v.GetAABB(); List <Vertices> decomposedVertices; if (!v.IsConvex()) { decomposedVertices = Triangulate.ConvexPartition(v, TriangulationAlgorithm.Bayazit); } else { decomposedVertices = new List <Vertices>(); decomposedVertices.Add(v); } List <VertexPositionColorTexture[]> verticesFill = new List <VertexPositionColorTexture[]>(decomposedVertices.Count); for (int i = 0; i < decomposedVertices.Count; i++) { verticesFill.Add(new VertexPositionColorTexture[3 * (decomposedVertices[i].Count - 2)]); for (int j = 0; j < decomposedVertices[i].Count - 2; j++) { // fill vertices verticesFill[i][3 * j].Position = new Vector3(decomposedVertices[i][0] - polygonBounds.Center, 0f); verticesFill[i][3 * j + 1].Position = new Vector3(decomposedVertices[i].NextVertex(j) - polygonBounds.Center, 0f); verticesFill[i][3 * j + 2].Position = new Vector3(decomposedVertices[i].NextVertex(j + 1) - polygonBounds.Center, 0f); verticesFill[i][3 * j].TextureCoordinate = new Vector2(decomposedVertices[i][0].X / _textureList[textureName].Width, decomposedVertices[i][0].Y / _textureList[textureName].Height - 1f); verticesFill[i][3 * j + 1].TextureCoordinate = new Vector2(decomposedVertices[i].NextVertex(j).X / _textureList[textureName].Width, decomposedVertices[i].NextVertex(j).Y / _textureList[textureName].Height - 1f); verticesFill[i][3 * j + 2].TextureCoordinate = new Vector2(decomposedVertices[i].NextVertex(j + 1).X / _textureList[textureName].Width, decomposedVertices[i].NextVertex(j + 1).Y / _textureList[textureName].Height - 1f); verticesFill[i][3 * j].Color = verticesFill[i][3 * j + 1].Color = verticesFill[i][3 * j + 2].Color = Color.Transparent; } } Vector2 vertsSize = new Vector2(polygonBounds.UpperBound.X - polygonBounds.LowerBound.X, polygonBounds.UpperBound.Y - polygonBounds.LowerBound.Y); result.Add(RenderTexture((int)vertsSize.X, (int)vertsSize.Y, _textureList.ContainsKey(textureName) ? _textureList[textureName] : null, Color.White, verticesFill, Array.Empty <VertexPositionColor>())); } else { result.Add(_textureList["Blank"]); } } return(result); }
public static MPTanks.Engine.Serialization.GameObjectBodySpecifierJSON BuildBody(uint[] imageData, int width, Vector2 objSize) { var vertices = PolygonTools.CreatePolygon(imageData, width, true); var imgHeight = imageData.Length / width; var scale = new Vector2(objSize.X / width, objSize.Y / imgHeight); vertices.Scale(scale); var decomposed = Triangulate.ConvexPartition(vertices, TriangulationAlgorithm.Seidel); var result = new Engine.Serialization.GameObjectBodySpecifierJSON(); var fixtures = new List <Engine.Serialization.GameObjectBodySpecifierJSON.FixtureSpecifierJSON>(); foreach (var fixture in decomposed) { var fx = new Engine.Serialization.GameObjectBodySpecifierJSON.FixtureSpecifierJSON(); var vertList = new List <Engine.Serialization.JSONVector>(); var holeList = new List <Engine.Serialization.GameObjectBodySpecifierJSON.FixtureSpecifierJSON.HolesSpecifierJSON>(); foreach (var vert in fixture) { vertList.Add(new Engine.Serialization.JSONVector { X = vert.X - (objSize.X / 2), Y = vert.Y - (objSize.Y / 2) }); } if (fixture.Holes != null) { foreach (var h in fixture.Holes) { var hole = new Engine.Serialization.GameObjectBodySpecifierJSON.FixtureSpecifierJSON.HolesSpecifierJSON(); var vList = new List <Engine.Serialization.JSONVector>(); foreach (var v in h) { vList.Add(new Engine.Serialization.JSONVector { X = v.X - (objSize.X / 2), Y = v.Y - (objSize.Y / 2) }); } hole.Vertices = vList.ToArray(); holeList.Add(hole); } } fx.Vertices = vertList.ToArray(); fx.Holes = holeList.ToArray(); fixtures.Add(fx); } result.Fixtures = fixtures.ToArray(); result.Size = new Engine.Serialization.JSONVector { X = objSize.X, Y = objSize.Y }; return(result); }
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; }
public void BuildMesh() { var points = GetEdgePoints(); var vertices = points.ToArray(); //Build the index array var indices = new List <int>(); //Build the color array var colors = new List <Color32>(); // Convert color once to Color32 for performance Color32 color32 = (Color32)vertexColor; while (indices.Count < points.Count) { indices.Add(indices.Count); colors.Add(color32); } //Build the triangle array var triangles = Triangulate.Points(points); //Build the uv array var scale = uvScale != 0 ? (1 / uvScale) : 0; var matrix = Matrix4x4.TRS(-uvPosition, Quaternion.Euler(0, 0, uvRotation), new Vector3(scale, scale, 1)); var uv = new Vector2[points.Count]; for (int i = 0; i < uv.Length; i++) { var p = matrix.MultiplyPoint(points[i]); uv[i] = new Vector2(p.x, p.y); } //Find the mesh (create it if it doesn't exist) var meshFilter = GetComponent <MeshFilter>(); var mesh = meshFilter.sharedMesh; if (mesh == null) { mesh = new Mesh(); mesh.name = "PolySprite_Mesh"; meshFilter.mesh = mesh; } //Update the mesh mesh.Clear(); mesh.vertices = vertices; mesh.colors32 = colors.ToArray(); mesh.uv = uv; mesh.triangles = triangles; mesh.RecalculateNormals(); mesh.Optimize(); //Update collider after the mesh is updated UpdateCollider(points, triangles); }
/** * transferTexture: Transfer texture src with 'src' and triangulation 'srcTriangulation' to * texture 'dst' with triangulation 'dstTriangulation' */ public static void transferTexture(Texture2D src, Triangulate srcTriangulation, Texture2D dst, Triangulate dstTriangulation) { int inCount = 0; int outCount = 0; // First, try to make triangulations compatible fixTriangulationIncompability(srcTriangulation, dstTriangulation); // For every pixel in destination texture for (int i = 0; i < dst.width; i++) { for (int j = 0; j < dst.height; j++) { // For each triangle in dest. triangulation foreach (var t in dstTriangulation.triangles) { // If the pixel is inside the triangle if (t.isPointInside(new Vector2((float)i, (float)j))) { // Get the barycentric coordinates var barycentric = t.getBarycentricCoords(new Vector2((float)i, (float)j)); // Get the equivalent triangle in the source triangulation var src_triangle = srcTriangulation.findCompatible(t); if (src_triangle == null) { //Debug.Log("src triangle null"); dst.SetPixel(i, j, Color.red); continue; } // Get the equivalent pixel coordinates in the src triangle Vector2 src_pixel = src_triangle.getCartesianCoords(barycentric); // Get the pixel value at source texture Color src_val = src.GetPixel((int)src_pixel.x, (int)src_pixel.y); // Set the same value at dest. texture dst.SetPixel(i, j, src_val); //dst.SetPixel(i, j, Color.red); inCount++; break; } else { //dst.SetPixel(i, j, Color.blue); outCount++; } } } } dst.Apply(); Debug.Log("In = " + inCount + ", Out = " + outCount + ", triangles = " + dstTriangulation.triangles.Count); }
public static BreakableBody CreateBreakableBody(World world, Vertices vertices, float density, Vector2 position = new Vector2(), float rotation = 0) { //TODO: Implement a Voronoi diagram algorithm to split up the vertices var triangles = Triangulate.ConvexPartition(vertices, TriangulationAlgorithm.Earclip); var breakableBody = new BreakableBody(world, triangles, density, position, rotation); breakableBody.MainBody.Position = position; world.AddBreakableBody(breakableBody); return(breakableBody); }
/// <summary> /// Creates a breakable body. You would want to remove collinear points before using this. /// </summary> /// <param name="world">The world.</param> /// <param name="vertices">The vertices.</param> /// <param name="density">The density.</param> /// <param name="position">The position.</param> /// <returns></returns> public static BreakableBody CreateBreakableBody(World world, Vertices vertices, float density, Vector2 position) { List <Vertices> triangles = Triangulate.ConvexPartition(vertices, TriangulationAlgorithm.Earclip); BreakableBody breakableBody = new BreakableBody(triangles, world, density); breakableBody.MainBody.Position = position; world.AddBreakableBody(breakableBody); return(breakableBody); }
public static BreakableBody CreateBreakableBody(World world, Vertices vertices, GGame.Math.Fix64 density, Vector2 position = new Vector2(), GGame.Math.Fix64 rotation = new Fix64()) { //TODO: Implement a Voronoi diagram algorithm to split up the vertices List <Vertices> triangles = Triangulate.ConvexPartition(vertices, TriangulationAlgorithm.Earclip, true, 0.001f); BreakableBody breakableBody = new BreakableBody(world, triangles, density, position, rotation); breakableBody.MainBody.Position = position; world.AddBreakableBody(breakableBody); return(breakableBody); }
void Start() { // Create standard triangulation outputTexture = GetComponent <Renderer> ().material.mainTexture as Texture2D; standardFaceWidth = outputTexture.width; standardFaceHeight = outputTexture.height; standardFaceTriangulation = new Triangulate(standardFacePoints, standardFaceWidth, standardFaceHeight); }
public static Body CreateRoundedRectangle(World world, float width, float height, float xRadius, float yRadius, int segments, float density, Vector2 position = new Vector2(), float rotation = 0, BodyType bodyType = BodyType.Static, object userData = null) { var verts = PolygonTools.CreateRoundedRectangle(width, height, xRadius, yRadius, segments); //There are too many vertices in the rect. We decompose it. if (verts.Count >= Settings.MaxPolygonVertices) { var vertList = Triangulate.ConvexPartition(verts, TriangulationAlgorithm.Earclip); return(CreateCompoundPolygon(world, vertList, density, position, rotation, bodyType, userData)); } return(CreatePolygon(world, verts, density, position, rotation, bodyType, userData)); }
public static Body CreateCapsule(World world, float height, float topRadius, int topEdges, float bottomRadius, int bottomEdges, float density, Vector2 position = new Vector2(), float rotation = 0, BodyType bodyType = BodyType.Static, object userData = null) { var verts = PolygonTools.CreateCapsule(height, topRadius, topEdges, bottomRadius, bottomEdges); //There are too many vertices in the capsule. We decompose it. if (verts.Count >= Settings.MaxPolygonVertices) { var vertList = Triangulate.ConvexPartition(verts, TriangulationAlgorithm.Earclip); return(CreateCompoundPolygon(world, vertList, density, position, rotation, bodyType, userData)); } return(CreatePolygon(world, verts, density, position, rotation, bodyType, userData)); }
public List <Fixture> CreateSolidArc(float density, float radians, int sides, float radius) { Vertices arc = PolygonTools.CreateArc(radians, sides, radius); arc.Rotate((MathHelper.Pi - radians) / 2); //Close the arc arc.Add(arc[0]); List <Vertices> triangles = Triangulate.ConvexPartition(arc, TriangulationAlgorithm.Earclip); return(CreateCompoundPolygon(triangles, density)); }