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)); }
/// <summary> /// Turns a list of triangles into a list of convex polygons. Very simple /// method - start with a seed triangle, keep adding triangles to it until /// you can't add any more without making the polygon non-convex. /// /// Returns an integer telling how many polygons were created. Will fill /// polys array up to polysLength entries, which may be smaller or larger /// than the return value. /// /// Takes O(N///P) where P is the number of resultant polygons, N is triangle /// count. /// /// The final polygon list will not necessarily be minimal, though in /// practice it works fairly well. /// </summary> /// <param name="triangulated">The triangulated.</param> ///<param name="maxPolys"></param> ///<returns></returns> public static List <Vertices> PolygonizeTriangles(List <Triangle> triangulated, int maxPolys, float tolerance) { List <Vertices> polys = new List <Vertices>(50); int polyIndex = 0; if (triangulated.Count <= 0) { //return empty polygon list return(polys); } bool[] covered = new bool[triangulated.Count]; for (int i = 0; i < triangulated.Count; ++i) { covered[i] = false; //Check here for degenerate triangles if (((triangulated[i].X[0] == triangulated[i].X[1]) && (triangulated[i].Y[0] == triangulated[i].Y[1])) || ((triangulated[i].X[1] == triangulated[i].X[2]) && (triangulated[i].Y[1] == triangulated[i].Y[2])) || ((triangulated[i].X[0] == triangulated[i].X[2]) && (triangulated[i].Y[0] == triangulated[i].Y[2]))) { covered[i] = true; } } bool notDone = true; while (notDone) { int currTri = -1; for (int i = 0; i < triangulated.Count; ++i) { if (covered[i]) { continue; } currTri = i; break; } if (currTri == -1) { notDone = false; } else { Vertices poly = new Vertices(3); for (int i = 0; i < 3; i++) { poly.Add(new Vector2(triangulated[currTri].X[i], triangulated[currTri].Y[i])); } covered[currTri] = true; int index = 0; for (int i = 0; i < 2 * triangulated.Count; ++i, ++index) { while (index >= triangulated.Count) { index -= triangulated.Count; } if (covered[index]) { continue; } Vertices newP = AddTriangle(triangulated[index], poly); if (newP == null) { continue; // is this right } if (newP.Count > Settings.MaxPolygonVertices) { continue; } if (newP.IsConvex()) { //Or should it be IsUsable? Maybe re-write IsConvex to apply the angle threshold from Box2d poly = new Vertices(newP); covered[index] = true; } } //We have a maximum of polygons that we need to keep under. if (polyIndex < maxPolys) { SimplifyTools.MergeParallelEdges(poly, tolerance); //If identical points are present, a triangle gets //borked by the MergeParallelEdges function, hence //the vertex number check if (poly.Count >= 3) { polys.Add(new Vertices(poly)); } //else // printf("Skipping corrupt poly\n"); } if (poly.Count >= 3) { polyIndex++; //Must be outside (polyIndex < polysLength) test } } } return(polys); }