예제 #1
0
        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;
        }