public BreakableObj1( World world, ScreenManager screenManager, Vector2 position, Camera2D camera, string texturePath, TriangulationAlgorithm triangulationAlgorithm, Vector2 scale, float strength, float massKoef) { _world = world; _screenManager = screenManager; _camera = camera; _texturePath = texturePath; _textureScale = scale; _triangulationAlgorithm = triangulationAlgorithm; #region "Триангуляция текстуры в полигоны" Texture2D alphabet = _screenManager.Content.Load <Texture2D>(_texturePath); 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 } List <Vertices> triangulated = new List <Vertices>(); for (int i = 0; i < list.Count; i++) { polygon = list[i]; centroid = -polygon.GetCentroid(); polygon.Translate(ref centroid); polygon = SimplifyTools.CollinearSimplify(polygon); polygon = SimplifyTools.ReduceByDistance(polygon, 4); triangulated = Triangulate.ConvexPartition(polygon, triangulationAlgorithm); Vector2 vertScale = _textureScale /*new Vector2(0.01f, 0.01f)*//*(new Vector2(13.916667f, 23.25f) / new Vector2(alphabet.Width, alphabet.Height)) * scale*//*0.5f*/; foreach (Vertices vertices in triangulated) { vertices.Scale(ref vertScale); } } _breakableBody = new SegmentableBody(_world, triangulated, 1); _breakableBody.MainBody.Position = position; //_breakableBody.MainBody.Mass = 5f; _breakableBody.MainBody.SetFriction(_breakableBody.MainBody.Mass * 50f); _breakableBody.Strength = /*50*/ strength * massKoef; #endregion #region "Массивы для индексного рассчета вершин под графен" //2.1)лист вершин для каждого полигона List <Vertices> temp = _breakableBody.Parts .Select(a => ((PolygonShape)(a.Shape)).Vertices) .ToList(); //2.2)коллекция для подсчета суммарного количества вершин IEnumerable <VertexPositionTexture> temp2 = new VertexPositionTexture[0]; //2.3)буфер вершин под каждый полигон vertexBuffers = new List <VertexBuffer>(); //2.4)координаты центров полигонов для сортировки вершин этих полигонов относительно их центров centroids = new List <Vector2>(); //2.5)сортированый массив вершин и их цветов полигонов для отрисовки TESTListOfVertices = new List <VertexPositionTexture[]>(); //Поиск размера исходного объекта float mainBodyWidth = 0f; float mainBodyHeight = 0f; //Поиск смещения объекта в отрицательную часть координатной плоскости float leftOffsetFromZero = temp.First().First().X; //для всего объекта, а не отдельных полигонов float downOffsetFromZero = temp.First().First().Y; float rightOffsetFromZero = temp.First().First().X; //для всего объекта, а не отдельных полигонов float upOffsetFromZero = temp.First().First().Y; for (int i = 0; i < temp.Count; i++) { for (int j = 0; j < temp[i].Count; j++) { if (temp[i][j].X <= leftOffsetFromZero) { leftOffsetFromZero = temp[i][j].X; } if (temp[i][j].Y <= downOffsetFromZero) { downOffsetFromZero = temp[i][j].Y; } if (temp[i][j].X >= rightOffsetFromZero) { rightOffsetFromZero = temp[i][j].X; } if (temp[i][j].Y >= upOffsetFromZero) { upOffsetFromZero = temp[i][j].Y; } } } mainBodyWidth = Math.Abs(leftOffsetFromZero - rightOffsetFromZero); mainBodyHeight = Math.Abs(downOffsetFromZero - upOffsetFromZero); leftOffsetFromZero = Math.Abs(leftOffsetFromZero); downOffsetFromZero = Math.Abs(downOffsetFromZero); //rightOffsetFromZero = Math.Abs(rightOffsetFromZero); //upOffsetFromZero = Math.Abs(upOffsetFromZero); for (int i = 0; i < temp.Count; i++) { var tempUnsorted = temp[i] .Select(a => new VertexPositionTexture( new Vector3(a.X, a.Y, 0f), /*Color.Crimson*/ new Vector2(a.X, a.Y))) .ToArray(); temp2 = temp2.Concat(tempUnsorted); var centr = temp[i].GetCentroid(); centroids.Add(centr); var temp3 = VertexClockwiseSort(tempUnsorted, centr); //for (int j = 0; j < temp3.Length; j++) //{ // temp3[j].Position.Z = -10f;///////////////////////////////////////////// //} for (int j = 0; j < temp3.Length; j++) { temp3[j].TextureCoordinate.X = ((temp3[j].TextureCoordinate.X + leftOffsetFromZero) / ((mainBodyWidth /*width*/))); temp3[j].TextureCoordinate.Y = 1f - ((temp3[j].TextureCoordinate.Y + downOffsetFromZero) / ((mainBodyHeight /*height*/))); } TESTListOfVertices.Add(temp3); } triangleVertices = temp2.ToArray(); //(2.2) int verticesCount = 0; foreach (var e in TESTListOfVertices) { verticesCount += e.Length; } //(2.3) foreach (var e in TESTListOfVertices) { var vb = new VertexBuffer( _screenManager.GraphicsDevice, typeof(VertexPositionTexture), e.Length, BufferUsage.None); vb.SetData(e); vertexBuffers.Add(vb); } #endregion effect = new BasicEffect(_screenManager.GraphicsDevice); texture = _screenManager.Content.Load <Texture2D>(/*"wood2"*//*"wood-plank2"*/ texturePath); effect.TextureEnabled = true; effect.Texture = texture; //буферы индексов для полигонов с разным числом вершин indexBuffer3 = new IndexBuffer(_screenManager.GraphicsDevice, typeof(short), 36, BufferUsage.WriteOnly); indexBuffer3.SetData <short>(TriangleCubeIndices.triangleCubeIndices3_1); indexBuffer4 = new IndexBuffer(_screenManager.GraphicsDevice, typeof(short), 36, BufferUsage.WriteOnly); indexBuffer4.SetData <short>(TriangleCubeIndices.triangleCubeIndices4_1); indexBuffer5 = new IndexBuffer(_screenManager.GraphicsDevice, typeof(short), 36, BufferUsage.WriteOnly); indexBuffer5.SetData <short>(TriangleCubeIndices.triangleCubeIndices5_1); indexBuffer6 = new IndexBuffer(_screenManager.GraphicsDevice, typeof(short), 36, BufferUsage.WriteOnly); indexBuffer6.SetData <short>(TriangleCubeIndices.triangleCubeIndices6_1); indexBuffer7 = new IndexBuffer(_screenManager.GraphicsDevice, typeof(short), 36, BufferUsage.WriteOnly); indexBuffer7.SetData <short>(TriangleCubeIndices.triangleCubeIndices7_1); indexBuffer8 = new IndexBuffer(_screenManager.GraphicsDevice, typeof(short), 36, BufferUsage.WriteOnly); indexBuffer8.SetData <short>(TriangleCubeIndices.triangleCubeIndices8_1); //точка для отрисовки центрода(ТЕСТ) TESTCentroid = new Sprite(_screenManager.Assets.CircleTexture(0.1f, MaterialType.Squares, Color.Black, 1f, 24f)); //IsCanDraw = true; }