Exemple #1
0
        public static void Triangulate(ITriangulatable t, TriangulationAlgorithm algorithm = DEFAULT_ALGORITHM)
        {
            TriangulationContext tcx = CreateContext(algorithm);

            tcx.PrepareTriangulation(t);
            Triangulate(tcx);
        }
    private void Start()
    {
        Vector3[]  vertices = new Vector3[pointsParent.childCount];
        List <int> indices  = new List <int>();

        for (int i = 0; i < vertices.Length; i++)
        {
            vertices[i] = pointsParent.GetChild(i).position;
            indices.Add(i);
        }

        Plane plane = new Plane(Vector3.back, 0);

        ConvexHullAlgorithm.Execute(ref indices, vertices, plane.normal);

        indices.Reverse();//反转列表,逆时针变顺时针

        /*Vector3[] vertices2=new Vector3[indices.Count];
         *      for(int i=0;i<indices.Count;i++){
         *              Vector3 vertex=vertices[indices[i]];
         *              vertex.z=0;
         *              vertices2[i]=vertex;
         *      }
         *      indices=TriangulationAlgorithm.WidelyTriangleIndex(vertices2);*/

        TriangulationAlgorithm.WidelyTriangleIndex(vertices, ref indices, plane);

        for (int i = 0; i < indices.Count; i++)
        {
            int index = indices[i];
            s_points.Add(vertices[index]);
        }
    }
Exemple #3
0
		public static TriangulationContext CreateContext(TriangulationAlgorithm algorithm) {
			switch (algorithm) {
			case TriangulationAlgorithm.DTSweep:
			default:
				return new DTSweepContext();
			}
		}
Exemple #4
0
 public static TriangulationContext CreateContext(TriangulationAlgorithm algorithm)
 {
     if (algorithm != TriangulationAlgorithm.DTSweep)
     {
     }
     return new DTSweepContext();
 }
        public static Shape CreateComplexShape(Image imageBitmap, int timeout, StringBuilder spool, float hullTolerance, byte alphaTolerance, bool multiPartDetection, bool holeDetection = true, bool strict = false, TriangulationAlgorithm algorithm = TriangulationAlgorithm.Bayazit)
        {
            Shape shape = null;
            Action action = () =>
            {
                try
                {
                    shape = BuildShape(imageBitmap, spool, hullTolerance, alphaTolerance, multiPartDetection, holeDetection, strict, algorithm);
                }
                catch
                {
                    spool.AppendFormat("Error creating shape for image");
                    spool.AppendLine();
                }
            };

            var result = action.BeginInvoke(null, null);
            if (!result.AsyncWaitHandle.WaitOne(timeout))
            {
                spool.AppendFormat("Timed out attempting to create shape");
                spool.AppendLine();
            }

            return shape;
        }
Exemple #6
0
 public static void Triangulate(TriangulationAlgorithm algorithm, Triangulatable t)
 {
     //        long time = System.nanoTime();
     TriangulationContext tcx = CreateContext(algorithm);
     tcx.PrepareTriangulation(t);
     Triangulate(tcx);
     //        logger.info( "Triangulation of {} points [{}ms]", tcx.getPoints().size(), ( System.nanoTime() - time ) / 1e6 );
 }
Exemple #7
0
        public static void Triangulate(TriangulationAlgorithm algorithm, ITriangulatable t)
        {
            TriangulationContext tcx;

            tcx = CreateContext(algorithm);
            tcx.PrepareTriangulation(t);
            Triangulate(tcx);
        }
        public static void Triangulate(TriangulationAlgorithm algorithm, ITriangulatable t)
        {
            TriangulationContext tcx;

            tcx = CreateContext (algorithm);
            tcx.PrepareTriangulation (t);
            Triangulate (tcx);
        }
Exemple #9
0
 private static TriangulationContext CreateContext(TriangulationAlgorithm algorithm)
 {
     switch (algorithm)
     {
     default:
         return(new DTSweepContext());
     }
 }
Exemple #10
0
 public static TriangulationContext CreateContext(TriangulationAlgorithm algorithm)
 {
     switch (algorithm)
     {
     case TriangulationAlgorithm.DTSweep:
     default:
         return(new DTSweepContext());
     }
 }
Exemple #11
0
        public static void Triangulate(TriangulationAlgorithm algorithm, ITriangulatable t)
        {
            //System.Console.WriteLine("Triangulating " + t.FileName);
            //        long time = System.nanoTime();
            var tcx = CreateContext(algorithm);

            tcx.PrepareTriangulation(t);
            Triangulate(tcx);
            //logger.info( "Triangulation of {} points [{}ms]", tcx.getPoints().size(), ( System.nanoTime() - time ) / 1e6 );
        }
Exemple #12
0
        public static void Triangulate(TriangulationAlgorithm algorithm, Triangulatable t)
        {
            TriangulationContext tcx;

            //        long time = System.nanoTime();
            tcx = CreateContext(algorithm);
            tcx.PrepareTriangulation(t);
            Triangulate(tcx);
            //        logger.info( "Triangulation of {} points [{}ms]", tcx.getPoints().size(), ( System.nanoTime() - time ) / 1e6 );
        }
Exemple #13
0
        public static void Triangulate(TriangulationAlgorithm algorithm, Triangulatable t)
        {
            //long time = System.nanoTime();
            TriangulationContext tcx = GetFreeTcxContext(algorithm);

            tcx.Clear();
            //step 1: (3.1) initialization
            tcx.PrepareTriangulation(t);
            //step 2: (3.4) sweeping
            Triangulate(tcx);
            ReleaseCtxContext(tcx);
            //logger.info( "Triangulation of {} points [{}ms]", tcx.getPoints().size(), ( System.nanoTime() - time ) / 1e6 );
        }
Exemple #14
0
        public static void Triangulate(TriangulationAlgorithm algorithm, ITriangulatable t)
        {
            TriangulationContext tcx;

			#if !UNITY_METRO
            	System.Console.WriteLine("Triangulating " + t.FileName);
			#endif
            //        long time = System.nanoTime();
            tcx = CreateContext(algorithm);
            tcx.PrepareTriangulation(t);
            Triangulate(tcx);
            //        logger.info( "Triangulation of {} points [{}ms]", tcx.getPoints().size(), ( System.nanoTime() - time ) / 1e6 );
        }
        /// <summary>
        /// Creates a list of vertices from a texture.
        /// </summary>
        /// <param name="texture">The texture to make a body from</param>
        /// <param name="scale">The scale of the texture</param>
        /// <param name="imageSize">The size of each individual image in the hitbox</param>
        /// <param name="density">The density of the object (Will almost always be one</param>
        /// <param name="algorithm">The decomposition algorithm to use</param>
        /// <remarks> Available algorithms to use are Bayazit, Dealuny, Earclip, Flipcode, Seidel, SeidelTrapazoid</remarks>
        /// @warning In order for this to work the input must have a transparent background. I highly reccomend that you
        /// only use this with PNGs as that is what I have tested and I know they work. This will only produce a bosy as
        /// clean as the texture you give it, so avoid partically transparent areas and little edges.
        private List <Vertices>[] CreateVerticesFromTexture(Texture2D texture, float scale, Point imageSize,
                                                            float density = 1, TriangulationAlgorithm algorithm = TriangulationAlgorithm.Earclip)
        {
            int SpriteSheetSize = texture.Width * texture.Height;
            int IndividualSize  = imageSize.X * imageSize.Y;

            uint[] TextureData = new uint[SpriteSheetSize]; //Array to copy texture info into
            texture.GetData(TextureData);                   //Gets which pixels of the texture are actually filled

            List <uint[]> IndividualData = new List <uint[]>();

            for (int Processed = 0; Processed < SpriteSheetSize; Processed += IndividualSize)
            {
                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);
            }

            List <Vertices>[] TextureVertices = new List <Vertices> [IndividualData.Count];

            for (int count = 0; count < IndividualData.Count; ++count)
            {
                uint[] I = IndividualData[count];

                Vertices        vertices   = TextureConverter.DetectVertices(I, texture.Width);
                List <Vertices> VertexList = Triangulate.ConvexPartition(vertices, algorithm);

                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;

                TextureVertices[count] = VertexList;
            }

            return(TextureVertices);
        }
Exemple #16
0
        /// <summary>
        /// Vrátí objekt typu <see cref="Body"/> pro provádění dvourozměrných simulací na základě tvaru nalezeného v
        /// dané bitmapě.
        /// </summary>
        /// <param name="orthographicRender">Bitmapa pro nalezení tvaru tělesa.</param>
        /// <param name="world">Objekt typu <see cref="World"/> fyzikální knihovny představující dvourozměrný svět, do
        /// kterého má být vytvořené těleso zařazeno.</param>
        /// <param name="position">Výchozí pozice tělesa v simulovaném světě.</param>
        /// <param name="bodyType">Typ simulovaného tělesa (statické, kinematické nebo dynamické).</param>
        /// <param name="density">Hustota tělesa (počet kilogramů na metr čtvereční).</param>
        /// <param name="rotation">Výchozí rotace tělesa v simulovaném světě.</param>
        /// <param name="reduceVerticesDistance">Vzdálenost mezi vrcholy nalezeného tvaru, které mají být sloučeny
        /// (zjednodušení tvaru).</param>
        /// <param name="triangulationAlgorithm">Algoritmus pro rozdělení tvaru na množství menších konvexních
        /// polygonů.</param>
        /// <param name="graphicsToSimulationRatio">Poměr mezi grafickým zobrazením a simulovaným fyzikálním
        /// světem.</param>
        /// <returns>Dvourozměrný simulovatelný objekt.</returns>
        public static Body CreatePolygonBody(
            Texture2D orthographicRender,
            World world,
            Vector2 position             = new Vector2(),
            BodyType bodyType            = DEFAULT_BODY_TYPE,
            float density                = DEFAULT_DENSITY,
            float rotation               = DEFAULT_ROTATION,
            float reduceVerticesDistance = DEFAULT_REDUCE_VERTICES_DISTANCE,
            TriangulationAlgorithm triangulationAlgorithm = DEFAULT_TRIANGULATION_ALGORITHM,
            float graphicsToSimulationRatio = DEFAULT_GRAPHICS_TO_SIMULATION_RATIO)
        {
            List <Vertices> verticesList = CreateVerticesForBody(orthographicRender, reduceVerticesDistance,
                                                                 triangulationAlgorithm, graphicsToSimulationRatio);

            return(world.CreateCompoundPolygon(verticesList, density, position, rotation, bodyType));
        }
Exemple #17
0
 static TriangulationContext GetFreeTcxContext(TriangulationAlgorithm algorithm)
 {
     switch (algorithm)
     {
     case TriangulationAlgorithm.DTSweep:
     default:
         //return context;
         if (contextStacks.Count == 0)
         {
             return(new DTSweepContext());
         }
         else
         {
             return(contextStacks.Pop());
         }
     }
 }
Exemple #18
0
 static TriangulationContext GetFreeTcxContext(TriangulationAlgorithm algorithm)
 {
     switch (algorithm)
     {
     case TriangulationAlgorithm.DTSweep:
     default:
         //return context;
         if (contextStacks.Count == 0)
         {
             return(new DTSweepContext());
         }
         else
         {
             int last_index = contextStacks.Count - 1;
             TriangulationContext result = contextStacks[last_index];
             contextStacks.RemoveAt(last_index);
             return(result);
         }
     }
 }
Exemple #19
0
 public WoodBlock(
     World world,
     ScreenManager screenManager,
     Vector2 position,
     Camera2D camera,
     string texturePath,
     TriangulationAlgorithm triangulationAlgorithm,
     Vector2 scale,
     float strength,
     float massKoef)
     : base(
         world,
         screenManager,
         position,
         camera,
         texturePath,
         triangulationAlgorithm,
         scale,
         strength,
         massKoef)
 {
 }
Exemple #20
0
        /// <summary>
        /// Creates a polygon from a texture. This is the important function here.
        /// </summary>
        /// <param name="texture">The texture to make a body from</param>
        /// <param name="density">The density of the object (Will almost always be one</param>
        /// <param name="position">The position (in meters) of the object in the world</param>
        /// <param name="scale">The scale of the object (how much to change its size)</param>
        /// <param name="algorithm">The decomposition algorithm to use</param>
        /// <remarks> Available algorithms to use are Bayazit, Dealuny, Earclip, Flipcode, Seidel, SeidelTrapazoid</remarks>
        /// @warning In order for this to work the input must have a transparent background. I highly reccomend that you
        /// only use this with PNGs as that is what I have tested and I know they work. This will only produce a bosy as
        /// clean as the texture you give it, so avoid partically transparent areas and little edges.
        private Body CreatePolygonFromTexture(Texture2D texture, float density, Vector2 position, float scale,
                                              TriangulationAlgorithm algorithm = TriangulationAlgorithm.Bayazit)
        {
            uint[] TextureData = new uint[texture.Width * texture.Height]; //Array to copy texture info into
            texture.GetData <uint>(TextureData);                           //Gets which pixels of the texture are actually filled

            Vertices        vertices   = TextureConverter.DetectVertices(TextureData, texture.Width);
            List <Vertices> vertexList = Triangulate.ConvexPartition(vertices, algorithm);

            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
            return(BodyFactory.CreateCompoundPolygon(LevelWorld, vertexList, density, position));
        }
Exemple #21
0
    private void DrawPolygon()
    {
        mesh          = new Mesh();
        mesh.name     = "Polygon";
        mesh.vertices = points.ToArray();

        tris = TriangulationAlgorithm.WidelyTriangleIndex(new List <Vector3>(points), indexes).ToArray();

        mesh.triangles = tris;

        normals = new Vector3[mesh.vertices.Length];
        for (int i = 0; i < mesh.vertices.Length; ++i)
        {
            normals[i] = Vector3.back;
        }

        mesh.normals = normals;

        mesh.RecalculateBounds();
        mesh.RecalculateTangents();

        targetFilter.mesh = mesh;
    }
Exemple #22
0
        /// <summary>
        /// Method for creating complex bodies.
        /// </summary>
        /// <param name="world">The new object will appear in this world</param>
        /// <param name="objectTexture">The new object will get this texture</param>
        /// <param name="Scale">The new object get scaled by this factor</param>
        /// <param name="Algo">The new object get triangulated by this triangulation algorithm</param>
        /// <returns>Returns the complex body</returns>
        public Body CreateComplexBody(World world, Texture2D objectTexture, float Scale,
                                      TriangulationAlgorithm Algo = TriangulationAlgorithm.Bayazit)
        {
            Body body = null;

            uint[] data = new uint[objectTexture.Width * objectTexture.Height];
            objectTexture.GetData(data);
            Vertices textureVertices = PolygonTools.CreatePolygon(data, objectTexture.Width, false);
            Vector2  centroid        = -textureVertices.GetCentroid();

            textureVertices.Translate(ref centroid);
            tBodyOrigin     = -centroid;
            textureVertices = SimplifyTools.DouglasPeuckerSimplify(textureVertices, 4f);
            List <Vertices> list      = Triangulate.ConvexPartition(textureVertices, Algo);
            Vector2         vertScale = new Vector2(ConvertUnits.ToSimUnits(1)) * Scale;

            foreach (Vertices vertices in list)
            {
                vertices.Scale(ref vertScale);
            }

            return(body = BodyFactory.CreateCompoundPolygon(world, list, 1f));
        }
        /// <summary>
        /// Vrátí objekt typu <see cref="Body3D"/>. Tvar odpovídající dvourozměrné reprezentaci pro fyzikální simulaci
        /// je nalezen podle ortogonální projekce zadaného trojrozměrného modelu.
        /// </summary>
        /// <param name="model">Trojrozměrný model.</param>
        /// <param name="world2D">Dvourozměrný svět, do kterého má být těleso zařazeno.</param>
        /// <param name="graphicsDevice">Grafické zařízení.</param>
        /// <param name="position">Výchozí pozice objektu ve dvojrozměrném světě.</param>
        /// <param name="bodyType">Typ simulovaného tělesa (statické, kinematické nebo dynamické).</param>
        /// <param name="orthographicModelSize">Velikost modelu pro renderování. Pokud tento parametr není zadán,
        /// vypočítá se.</param>
        /// <param name="triangulationAlgorithm">Algoritmus pro rozdělení tvaru na množství menších konvexních
        /// polygonů.</param>
        /// <param name="basicEffectParams">Parametry pro třídu <see cref="BasicEffect"/>.</param>
        /// <returns>Objekt typu <see cref="Body3D"/>.</returns>
        public static Body3D CreateBody3D(
            Model model,
            World world2D,
            GraphicsDevice graphicsDevice,
            Vector2 position              = new Vector2(),
            BodyType bodyType             = BodyCreator.DEFAULT_BODY_TYPE,
            Vector2 orthographicModelSize = new Vector2(),
            TriangulationAlgorithm triangulationAlgorithm = BodyCreator.DEFAULT_TRIANGULATION_ALGORITHM,
            BasicEffectParams basicEffectParams           = null)
        {
            using (Texture2D orthoRender = BitmapRenderer.RenderOrthographic(graphicsDevice, model,
                                                                             BitmapRenderer.DEFAULT_BITMAP_SCALE, orthographicModelSize))
            {
                Body body2D = BodyCreator.CreatePolygonBody(orthoRender, world2D, position, bodyType,
                                                            1f, 0f, 1f, triangulationAlgorithm);

                Body3D body3D = new Body3D(model, body2D)
                {
                    BasicEffectParams = basicEffectParams
                };

                return(body3D);
            }
        }
        /// <summary>
        /// Creates a list of vertices from a texture.
        /// </summary>
        /// <param name="texture">The texture to make a body from</param>
        /// <param name="scale">The scale of the texture</param>
        /// <param name="algorithm">The decomposition algorithm to use</param>
        /// <remarks> Available algorithms to use are Bayazit, Dealuny, Earclip, Flipcode, Seidel, SeidelTrapazoid</remarks>
        /// @warning In order for this to work the input must have a transparent background. I highly reccomend that you
        /// only use this with PNGs as that is what I have tested and I know they work. This will only produce a bosy as
        /// clean as the texture you give it, so avoid partically transparent areas and little edges.
        private List <Vertices> CreateVerticesFromTexture(Texture2D texture, float scale,
                                                          TriangulationAlgorithm algorithm = TriangulationAlgorithm.Earclip)
        {
            int SpriteSheetSize = texture.Width * texture.Height;

            uint[] TextureData = new uint[SpriteSheetSize]; //Array to copy texture info into
            texture.GetData(TextureData);                   //Gets which pixels of the texture are actually filled

            Vertices        vertices   = TextureConverter.DetectVertices(TextureData, texture.Width);
            List <Vertices> VertexList = Triangulate.ConvexPartition(vertices, algorithm);

            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;

            return(VertexList);
        }
Exemple #25
0
        public static List <Vertices> ConvexPartition(Vertices vertices, TriangulationAlgorithm algorithm, bool discardAndFixInvalid = true, float tolerance = 0.001f)
        {
            if (vertices.Count <= 3)
            {
                return new List <Vertices> {
                           vertices
                }
            }
            ;

            List <Vertices> results = null;

            switch (algorithm)
            {
            case TriangulationAlgorithm.Earclip:
#pragma warning disable 162
                // ReSharper disable three ConditionIsAlwaysTrueOrFalse
                if (Settings.SkipSanityChecks)
                {
                    Debug.Assert(!vertices.IsCounterClockWise(), "The Ear-clip algorithm expects the polygon to be clockwise.");
                }
                else
                {
                    if (vertices.IsCounterClockWise())
                    {
                        Vertices temp = new Vertices(vertices);
                        temp.Reverse();
                        results = EarclipDecomposer.ConvexPartition(temp, tolerance);
                    }
                    else
                    {
                        results = EarclipDecomposer.ConvexPartition(vertices, tolerance);
                    }
                }
                break;

            case TriangulationAlgorithm.Bayazit:
                if (Settings.SkipSanityChecks)
                {
                    Debug.Assert(vertices.IsCounterClockWise(), "The polygon is not counter clockwise. This is needed for Bayazit to work correctly.");
                }
                else
                {
                    if (!vertices.IsCounterClockWise())
                    {
                        Vertices temp = new Vertices(vertices);
                        temp.Reverse();
                        results = BayazitDecomposer.ConvexPartition(temp);
                    }
                    else
                    {
                        results = BayazitDecomposer.ConvexPartition(vertices);
                    }
                }
                break;

            case TriangulationAlgorithm.Flipcode:
                if (Settings.SkipSanityChecks)
                {
                    Debug.Assert(vertices.IsCounterClockWise(), "The polygon is not counter clockwise. This is needed for Bayazit to work correctly.");
                }
#pragma warning restore 162
                else
                {
                    if (!vertices.IsCounterClockWise())
                    {
                        Vertices temp = new Vertices(vertices);
                        temp.Reverse();
                        results = FlipcodeDecomposer.ConvexPartition(temp);
                    }
                    else
                    {
                        results = FlipcodeDecomposer.ConvexPartition(vertices);
                    }
                }
                break;

            case TriangulationAlgorithm.Seidel:
                results = SeidelDecomposer.ConvexPartition(vertices, tolerance);
                break;

            case TriangulationAlgorithm.SeidelTrapezoids:
                results = SeidelDecomposer.ConvexPartitionTrapezoid(vertices, tolerance);
                break;

            case TriangulationAlgorithm.Delauny:
                results = CDTDecomposer.ConvexPartition(vertices);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(algorithm));
            }

            if (discardAndFixInvalid)
            {
                for (int i = results.Count - 1; i >= 0; i--)
                {
                    Vertices polygon = results[i];

                    if (!ValidatePolygon(polygon))
                    {
                        results.RemoveAt(i);
                    }
                }
            }

            return(results);
        }
Exemple #26
0
            /// <summary>
            /// Triangulate a list of polygons.
            /// </summary>
            /// <returns>The triangulation.</returns>
            /// <param name="polygons">Polygons.</param>
            /// <param name="algo">Algorithm.</param>
            public static List <Vertices> Triangulate(List <List <IntPoint> > polygons, TriangulationAlgorithm algo = TriangulationAlgorithm.Earclip)
            {
                List <Vertices> result = new List <Vertices>();

                polygons.ForEach(p => { result.AddRange(Triangulate(p)); });
                return(result);
            }
        private static Shape BuildShape(Image imageBitmap, StringBuilder spool, bool holeDetection, bool strict, TriangulationAlgorithm algorithm)
        {
            var data = LoadImageData(imageBitmap);
            var polygon = PolygonTools.CreatePolygon(data, imageBitmap.Width, holeDetection);

            var polygons = new List<Vertices> { polygon };
            return ScaleConvertAndPartition(spool, strict, imageBitmap, polygons, algorithm);
        }
        private static Shape BuildShape(Image imageBitmap, StringBuilder spool, float hullTolerance, byte alphaTolerance, bool multiPartDetection, bool holeDetection = true, bool strict = false, TriangulationAlgorithm algorithm = TriangulationAlgorithm.Bayazit)
        {
            var data = LoadImageData(imageBitmap);
            var polygons = PolygonTools.CreatePolygon(data, imageBitmap.Width, hullTolerance, alphaTolerance, multiPartDetection, holeDetection);

            return ScaleConvertAndPartition(spool, strict, imageBitmap, polygons, algorithm);
        }
Exemple #29
0
 /// <summary>
 /// Triangulate a polygon.
 /// </summary>
 /// <returns>The triangulation.</returns>
 /// <param name="polygon">Polygon.</param>
 /// <param name="algo">Algorithm.</param>
 public static List <Vertices> Triangulate(List <IntPoint> polygon, TriangulationAlgorithm algo = TriangulationAlgorithm.Earclip)
 {
     return(Physics2D.Common.Decomposition.Triangulate.ConvexPartition(PolygonToVertices(polygon, 1), algo));
 }
Exemple #30
0
        public static List <Vertices> ConvexPartition(Vertices vertices, TriangulationAlgorithm algorithm, bool discardAndFixInvalid, FP tolerance)
        {
            bool            flag = vertices.Count <= 3;
            List <Vertices> result;

            if (flag)
            {
                result = new List <Vertices>
                {
                    vertices
                };
            }
            else
            {
                List <Vertices> list;
                switch (algorithm)
                {
                case TriangulationAlgorithm.Earclip:
                {
                    bool flag2 = vertices.IsCounterClockWise();
                    if (flag2)
                    {
                        Vertices vertices2 = new Vertices(vertices);
                        vertices2.Reverse();
                        list = EarclipDecomposer.ConvexPartition(vertices2, tolerance);
                    }
                    else
                    {
                        list = EarclipDecomposer.ConvexPartition(vertices, tolerance);
                    }
                    break;
                }

                case TriangulationAlgorithm.Bayazit:
                {
                    bool flag3 = !vertices.IsCounterClockWise();
                    if (flag3)
                    {
                        Vertices vertices3 = new Vertices(vertices);
                        vertices3.Reverse();
                        list = BayazitDecomposer.ConvexPartition(vertices3);
                    }
                    else
                    {
                        list = BayazitDecomposer.ConvexPartition(vertices);
                    }
                    break;
                }

                case TriangulationAlgorithm.Flipcode:
                {
                    bool flag4 = !vertices.IsCounterClockWise();
                    if (flag4)
                    {
                        Vertices vertices4 = new Vertices(vertices);
                        vertices4.Reverse();
                        list = FlipcodeDecomposer.ConvexPartition(vertices4);
                    }
                    else
                    {
                        list = FlipcodeDecomposer.ConvexPartition(vertices);
                    }
                    break;
                }

                case TriangulationAlgorithm.Seidel:
                    list = SeidelDecomposer.ConvexPartition(vertices, tolerance);
                    break;

                case TriangulationAlgorithm.SeidelTrapezoids:
                    list = SeidelDecomposer.ConvexPartitionTrapezoid(vertices, tolerance);
                    break;

                case TriangulationAlgorithm.Delauny:
                    list = CDTDecomposer.ConvexPartition(vertices);
                    break;

                default:
                    throw new ArgumentOutOfRangeException("algorithm");
                }
                if (discardAndFixInvalid)
                {
                    for (int i = list.Count - 1; i >= 0; i--)
                    {
                        Vertices polygon = list[i];
                        bool     flag5   = !Triangulate.ValidatePolygon(polygon);
                        if (flag5)
                        {
                            list.RemoveAt(i);
                        }
                    }
                }
                result = list;
            }
            return(result);
        }
Exemple #31
0
        public Body CreatePolygonFromTexture(Texture2D tex, World world, float density, Vector2 position, float scale, TriangulationAlgorithm algorithm = TriangulationAlgorithm.Bayazit)
        {
            uint[] texData = new uint[tex.Width * tex.Height];
            tex.GetData <uint>(texData);

            Vertices        vertices   = TextureConverter.DetectVertices(texData, tex.Width);
            List <Vertices> vertexList = Triangulate.ConvexPartition(vertices, algorithm);

            Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(scale));

            foreach (Vertices vert in vertexList)
            {
                vert.Scale(ref vertScale);
            }

            Vector2 centroid = vertices.GetCentroid();

            vertices.Translate(ref centroid);
            //basketOrigin = -centroid;
            return(BodyFactory.CreateCompoundPolygon(world, vertexList, density, position, 100));
        }
        public static List <Vertices> ConvexPartition(Vertices vertices, TriangulationAlgorithm algorithm, bool discardAndFixInvalid = true, float tolerance = 0.001f)
        {
            if (vertices.Count <= 3)
            {
                return new List <Vertices> {
                           vertices
                }
            }
            ;

            List <Vertices> results;

            switch (algorithm)
            {
            case TriangulationAlgorithm.Earclip:
                if (Settings.SkipSanityChecks)
                {
                    Debug.Assert(!vertices.IsCounterClockWise(), "The Earclip algorithm expects the polygon to be clockwise.");
                }
                else
                {
                    if (vertices.IsCounterClockWise())
                    {
                        Vertices temp = new Vertices(vertices);
                        temp.Reverse();
                        results = EarclipDecomposer.ConvexPartition(temp, tolerance);
                    }
                    else
                    {
                        results = EarclipDecomposer.ConvexPartition(vertices, tolerance);
                    }
                }
                break;

            case TriangulationAlgorithm.Bayazit:
                if (Settings.SkipSanityChecks)
                {
                    Debug.Assert(vertices.IsCounterClockWise(), "The polygon is not counter clockwise. This is needed for Bayazit to work correctly.");
                }
                else
                {
                    if (!vertices.IsCounterClockWise())
                    {
                        Vertices temp = new Vertices(vertices);
                        temp.Reverse();
                        results = BayazitDecomposer.ConvexPartition(temp);
                    }
                    else
                    {
                        results = BayazitDecomposer.ConvexPartition(vertices);
                    }
                }
                break;

            case TriangulationAlgorithm.Flipcode:
                if (Settings.SkipSanityChecks)
                {
                    Debug.Assert(vertices.IsCounterClockWise(), "The polygon is not counter clockwise. This is needed for Bayazit to work correctly.");
                }
                else
                {
                    if (!vertices.IsCounterClockWise())
                    {
                        Vertices temp = new Vertices(vertices);
                        temp.Reverse();
                        results = FlipcodeDecomposer.ConvexPartition(temp);
                    }
                    else
                    {
                        results = FlipcodeDecomposer.ConvexPartition(vertices);
                    }
                }
                break;

            case TriangulationAlgorithm.Seidel:
                results = SeidelDecomposer.ConvexPartition(vertices, tolerance);
                break;

            case TriangulationAlgorithm.SeidelTrapezoids:
                results = SeidelDecomposer.ConvexPartitionTrapezoid(vertices, tolerance);
                break;

            case TriangulationAlgorithm.Delauny:
                results = CDTDecomposer.ConvexPartition(vertices);
                break;

            default:
                throw new ArgumentOutOfRangeException("algorithm");
            }

            if (discardAndFixInvalid)
            {
                for (int i = results.Count - 1; i >= 0; i--)
                {
                    Vertices polygon = results[i];

                    PolygonError errorCode = polygon.CheckPolygon();

                    if (errorCode == PolygonError.InvalidAmountOfVertices || errorCode == PolygonError.AreaTooSmall || errorCode == PolygonError.SideTooSmall || errorCode == PolygonError.NotSimple)
                    {
                        results.RemoveAt(i);
                    }
                    else if (errorCode == PolygonError.NotCounterClockWise)
                    {
                        polygon.Reverse();
                    }
                    else if (errorCode == PolygonError.NotConvex)
                    {
                        results[i] = GiftWrap.GetConvexHull(polygon);
                    }
                }
            }

            return(results);
        }
    }
Exemple #33
0
        public static List<Vertices> ConvexPartition(Vertices vertices, TriangulationAlgorithm algorithm, bool discardAndFixInvalid = true, float tolerance = 0.001f)
        {
            if (vertices.Count <= 3)
                return new List<Vertices> { vertices };

            List<Vertices> results = null;

            switch (algorithm)
            {
                case TriangulationAlgorithm.Earclip:
                    if (Settings.SkipSanityChecks)
                        Debug.Assert(!vertices.IsCounterClockWise(), "The Earclip algorithm expects the polygon to be clockwise.");
                    else
                    {
                        if (vertices.IsCounterClockWise())
                        {
                            Vertices temp = new Vertices(vertices);
                            temp.Reverse();
                            results = EarclipDecomposer.ConvexPartition(temp, tolerance);
                        }
                        else
                            results = EarclipDecomposer.ConvexPartition(vertices, tolerance);
                    }
                    break;
                case TriangulationAlgorithm.Bayazit:
                    if (Settings.SkipSanityChecks)
                        Debug.Assert(vertices.IsCounterClockWise(), "The polygon is not counter clockwise. This is needed for Bayazit to work correctly.");
                    else
                    {
                        if (!vertices.IsCounterClockWise())
                        {
                            Vertices temp = new Vertices(vertices);
                            temp.Reverse();
                            results = BayazitDecomposer.ConvexPartition(temp);
                        }
                        else
                            results = BayazitDecomposer.ConvexPartition(vertices);
                    }
                    break;
                case TriangulationAlgorithm.Flipcode:
                    if (Settings.SkipSanityChecks)
                        Debug.Assert(vertices.IsCounterClockWise(), "The polygon is not counter clockwise. This is needed for Bayazit to work correctly.");
                    else
                    {
                        if (!vertices.IsCounterClockWise())
                        {
                            Vertices temp = new Vertices(vertices);
                            temp.Reverse();
                            results = FlipcodeDecomposer.ConvexPartition(temp);
                        }
                        else
                            results = FlipcodeDecomposer.ConvexPartition(vertices);
                    }
                    break;
                case TriangulationAlgorithm.Seidel:
                    results = SeidelDecomposer.ConvexPartition(vertices, tolerance);
                    break;
                case TriangulationAlgorithm.SeidelTrapezoids:
                    results = SeidelDecomposer.ConvexPartitionTrapezoid(vertices, tolerance);
                    break;
                case TriangulationAlgorithm.Delauny:
                    results = CDTDecomposer.ConvexPartition(vertices);
                    break;
                default:
                    throw new ArgumentOutOfRangeException("algorithm");
            }

            if (discardAndFixInvalid)
            {
                for (int i = results.Count - 1; i >= 0; i--)
                {
                    Vertices polygon = results[i];

                    if (!ValidatePolygon(polygon))
                        results.RemoveAt(i);
                }
            }

            return results;
        }
        private static Shape ScaleConvertAndPartition(StringBuilder spool, bool strict, Image image, IEnumerable<Vertices> polygons, TriangulationAlgorithm algorithm)
        {
            var scale = ConvertUnits.ToSimUnits(1, 1);
            var width = ConvertUnits.ToSimUnits(image.Width);
            var height = ConvertUnits.ToSimUnits(image.Height);
            var translation = new Vector2(-width, -height)*0.5f;

            var final = new List<List<Vector2>>();

            foreach (var polygon in polygons)
            {
                polygon.Scale(scale);
                polygon.Translate(translation);

                var thisPolygon = SimplifyTools.CollinearSimplify(polygon);

                if (strict)
                {
                    var errors = thisPolygon.CheckPolygon();
                    if (errors != PolygonError.NoError)
                    {
                        spool.AppendFormat("Invalid shape ({0})", errors);
                        return null;
                    }
                }

                try
                {
                    var partition = Triangulate.ConvexPartition(thisPolygon, algorithm);
                    var vertices = partition.Select(verts => verts.Select(v => new Vector2(v.X, v.Y)).ToList());
                    final.AddRange(vertices);
                }
                catch
                {
                    spool.AppendFormat("Cannot triangulate polygon");
                    spool.AppendLine();
                }
            }

            var shape = new Shape
            {
                Vertices = final
            };
            return shape;
        }
Exemple #35
0
        public static List <Vertices> ConvexPartition(Vertices vertices, TriangulationAlgorithm algorithm, bool discardAndFixInvalid = true, float tolerance = 0.001f)
        {
            if (vertices.Count <= 3)
            {
                return new List <Vertices> {
                           vertices
                }
            }
            ;

            List <Vertices> results;

            switch (algorithm)
            {
            case TriangulationAlgorithm.Earclip:
                if (vertices.IsCounterClockWise())
                {
                    Vertices temp = new Vertices(vertices);
                    temp.Reverse();
                    results = EarclipDecomposer.ConvexPartition(temp, tolerance);
                }
                else
                {
                    results = EarclipDecomposer.ConvexPartition(vertices, tolerance);
                }
                break;

            case TriangulationAlgorithm.Bayazit:
                if (!vertices.IsCounterClockWise())
                {
                    Vertices temp = new Vertices(vertices);
                    temp.Reverse();
                    results = BayazitDecomposer.ConvexPartition(temp);
                }
                else
                {
                    results = BayazitDecomposer.ConvexPartition(vertices);
                }
                break;

            case TriangulationAlgorithm.Flipcode:
                if (!vertices.IsCounterClockWise())
                {
                    Vertices temp = new Vertices(vertices);
                    temp.Reverse();
                    results = FlipcodeDecomposer.ConvexPartition(temp);
                }
                else
                {
                    results = FlipcodeDecomposer.ConvexPartition(vertices);
                }
                break;

            case TriangulationAlgorithm.Seidel:
                results = SeidelDecomposer.ConvexPartition(vertices, tolerance);
                break;

            case TriangulationAlgorithm.SeidelTrapezoids:
                results = SeidelDecomposer.ConvexPartitionTrapezoid(vertices, tolerance);
                break;

            case TriangulationAlgorithm.Delauny:
                results = CDTDecomposer.ConvexPartition(vertices);
                break;

            default:
                throw new ArgumentOutOfRangeException("algorithm");
            }

            if (discardAndFixInvalid)
            {
                for (int i = results.Count - 1; i >= 0; i--)
                {
                    Vertices polygon = results[i];

                    if (!ValidatePolygon(polygon))
                    {
                        results.RemoveAt(i);
                    }
                }
            }

            return(results);
        }
Exemple #36
0
        /// <param name="skipSanityChecks">
        /// Set this to true to skip sanity checks in the engine. This will speed up the
        /// tools by removing the overhead of the checks, but you will need to handle checks
        /// yourself where it is needed.
        /// </param>
        public static List <Vertices> ConvexPartition(Vertices vertices, TriangulationAlgorithm algorithm, bool discardAndFixInvalid = true, float tolerance = 0.001f, bool skipSanityChecks = false)
        {
            if (vertices.Count <= 3)
            {
                return new List <Vertices> {
                           vertices
                }
            }
            ;

            List <Vertices> results;

            switch (algorithm)
            {
            case TriangulationAlgorithm.Earclip:
                if (skipSanityChecks)
                {
                    Debug.Assert(!vertices.IsCounterClockWise(), "The Earclip algorithm expects the polygon to be clockwise.");
                }
                else if (vertices.IsCounterClockWise())
                {
                    Vertices temp = new Vertices(vertices);
                    temp.Reverse();
                    vertices = temp;
                }
                results = EarclipDecomposer.ConvexPartition(vertices, tolerance);

                break;

            case TriangulationAlgorithm.Bayazit:
                if (skipSanityChecks)
                {
                    Debug.Assert(vertices.IsCounterClockWise(), "The polygon is not counter clockwise. This is needed for Bayazit to work correctly.");
                }
                else if (!vertices.IsCounterClockWise())
                {
                    Vertices temp = new Vertices(vertices);
                    temp.Reverse();
                    vertices = temp;
                }
                results = BayazitDecomposer.ConvexPartition(vertices);
                break;

            case TriangulationAlgorithm.Flipcode:
                if (skipSanityChecks)
                {
                    Debug.Assert(vertices.IsCounterClockWise(), "The polygon is not counter clockwise. This is needed for Bayazit to work correctly.");
                }
                else if (!vertices.IsCounterClockWise())
                {
                    Vertices temp = new Vertices(vertices);
                    temp.Reverse();
                    vertices = temp;
                }
                results = FlipcodeDecomposer.ConvexPartition(vertices);
                break;

            case TriangulationAlgorithm.Seidel:
                results = SeidelDecomposer.ConvexPartition(vertices, tolerance);
                break;

            case TriangulationAlgorithm.SeidelTrapezoids:
                results = SeidelDecomposer.ConvexPartitionTrapezoid(vertices, tolerance);
                break;

            case TriangulationAlgorithm.Delauny:
                results = CDTDecomposer.ConvexPartition(vertices);
                break;

            default:
                throw new ArgumentOutOfRangeException("algorithm");
            }

            if (discardAndFixInvalid)
            {
                for (int i = results.Count - 1; i >= 0; i--)
                {
                    Vertices polygon = results[i];

                    if (!ValidatePolygon(polygon))
                    {
                        results.RemoveAt(i);
                    }
                }
            }

            return(results);
        }
Exemple #37
0
        /// <summary>
        /// Vrátí list vrholů pro sestavení tvaru (složeného mnohoúhelníku) na základě ortogonální projekce
        /// trojrozměrného modelu. Provedení této metody je relativně paměťově a výpočetně náročné v závislosti na
        /// velikosti zdrojové bitmapy a zvoleném algoritmu.
        /// </summary>
        /// <param name="orthographicRender">Bitmapa pro nalezení vrcholů.</param>
        /// <param name="reduceVerticesDistance">Vzdálenost mezi vrcholy nalezeného tvaru, které mají být sloučeny
        /// (zjednodušení tvaru).</param>
        /// <param name="triangulationAlgorithm">Algoritmus pro rozdělení tvaru na množství menších konvexních
        /// polygonů.</param>
        /// <param name="graphicsToSimulationRatio">Poměr mezi grafickým zobrazením a simulovaným fyzikálním
        /// světem.</param>
        /// <returns></returns>
        public static List <Vertices> CreateVerticesForBody(
            Texture2D orthographicRender,
            float reduceVerticesDistance = DEFAULT_REDUCE_VERTICES_DISTANCE,
            TriangulationAlgorithm triangulationAlgorithm = DEFAULT_TRIANGULATION_ALGORITHM,
            float graphicsToSimulationRatio = DEFAULT_GRAPHICS_TO_SIMULATION_RATIO)
        {
            //Pole pro data bitmapové textury
            uint[] data = new uint[orthographicRender.Width * orthographicRender.Height];

            //Přenesení dat textury do pole
            orthographicRender.GetData(data);

            //Nalezení vrcholů tvořících obrys tvaru v textuře
            Vertices textureVertices = PolygonTools.CreatePolygon(data, orthographicRender.Width, false);

            //Snížení počtu nalezených vrcholů (zjednodušení)
            if (reduceVerticesDistance > 0)
            {
                textureVertices = SimplifyTools.ReduceByDistance(textureVertices, reduceVerticesDistance);
            }

            //Střed bitmapy
            Vector2 center = new Vector2(-orthographicRender.Width / 2, -orthographicRender.Height / 2);

            //Vystředění nalezených vrcholů
            textureVertices.Translate(ref center);

            List <Vertices> verticesList = new List <Vertices>();

            if (!textureVertices.IsConvex())
            {
                try
                {
                    //Konkávní polygon je nutné rozdělit na množství menších konvexních polygonů s využitím
                    //preferovaného algoritmu
                    verticesList = Triangulate.ConvexPartition(textureVertices, triangulationAlgorithm);
                }
                catch (Exception ex)
                {
                    if (ex.Message == "Intersecting Constraints")
                    {
                        throw new ArgumentException(
                                  "Tvar se nepodařilo rozdělit na konvexní polygony, zkuste změnit parametr udávající " +
                                  "vzdálenost vrcholů pro sloučení nebo použijte jiný algoritmus pro rozdělení.",
                                  "reduceVerticesDistance, triangulationAlgorithm", ex);
                    }
                }
            }
            else
            {
                verticesList.Add(textureVertices);
            }

            //Změna velikost polygonu podle poměru ke grafickému zobrazení
            Vector2 vertScale = new Vector2(graphicsToSimulationRatio);

            foreach (Vertices vertices in verticesList)
            {
                vertices.Scale(new Vector2(1f, -1f));
                vertices.Scale(vertScale);
            }

            return(verticesList);
        }
Exemple #38
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;
        }