protected internal override IList <Fixture> CreateShape(Body body, Transform shapeTransform, List <Vector2> rigidBodyLocalPoints)
        {
            var epsilon = 0.0001f;

            //clear data
            processedVertices = null;
            processedIndices  = null;
            processedTrianglesToSourceIndex = null;

            //get source geometry
            if (!GetSourceData(out var sourceVertices, out var sourceIndices))
            {
                return(null);
            }

            //check valid data
            if (CheckValidData)
            {
                if (!MathAlgorithms.CheckValidVertexIndexBuffer(sourceVertices.Length, sourceIndices, false))
                {
                    Log.Info("Component_CollisionShape2D_Mesh: CreateShape: Invalid source data.");
                    return(null);
                }
            }

            //process geometry
            if (MergeEqualVerticesRemoveInvalidTriangles)
            {
                MathAlgorithms.MergeEqualVerticesRemoveInvalidTriangles(sourceVertices, sourceIndices, epsilon, epsilon, out processedVertices, out processedIndices, out processedTrianglesToSourceIndex);
            }
            else
            {
                processedVertices = sourceVertices;
                processedIndices  = sourceIndices;
            }

            if (ShapeType.Value == ShapeTypeEnum.Auto && ParentRigidBody.MotionType.Value == Component_RigidBody2D.MotionTypeEnum.Dynamic && MathAlgorithms.IsMeshConvex(processedVertices, processedIndices, epsilon) || ShapeType.Value == ShapeTypeEnum.Convex)
            {
                //convex

                var    points = new List <Vector2>(processedVertices.Length);
                Bounds bounds = Bounds.Cleared;
                foreach (var p in processedVertices)
                {
                    var p2 = shapeTransform * new Vector3(p.ToVector2(), 0);
                    points.Add(p2.ToVector2());
                    bounds.Add(p2);
                    //points.Add( ( shapeTransform * new Vector3( p.ToVector2(), 0 ) ).ToVector2() );
                }

                var fixtures = new List <Fixture>();
                {
                    var currentList = new Vertices(points.Count);

                    for (int vertex = 0; vertex < points.Count; vertex++)
                    {
                        currentList.Add(Physics2DUtility.Convert(points[vertex]));

                        if (currentList.Count == Settings.MaxPolygonVertices)
                        {
                            fixtures.Add(body.CreatePolygon(currentList, 0));

                            currentList = new Vertices();
                            currentList.Add(Physics2DUtility.Convert(points[0]));
                            currentList.Add(Physics2DUtility.Convert(points[vertex]));
                        }
                    }

                    if (currentList.Count >= 3)
                    {
                        fixtures.Add(body.CreatePolygon(currentList, 0));
                    }
                }

                //rigidBodyLocalPoints
                {
                    var r = bounds.ToRectangle();
                    rigidBodyLocalPoints.Add(r.LeftTop);
                    rigidBodyLocalPoints.Add(r.RightTop);
                    rigidBodyLocalPoints.Add(r.RightBottom);
                    rigidBodyLocalPoints.Add(r.LeftBottom);
                }

                if (fixtures.Count != 0)
                {
                    return(fixtures.ToArray());
                }

                //var points = new List<Vector2>();
                //foreach( var p in processedVertices )
                //	points.Add( ( shapeTransform * new Vector3( p.ToVector2(), 0 ) ).ToVector2() );

                //var vertices = new Vertices( points.Count );
                //foreach( var p in points )
                //	vertices.Add( Physics2DUtility.Convert( p ) );

                //if( vertices.Count > 1 )
                //	return new Fixture[] { body.CreatePolygon( vertices, 0 ) };
            }
            else
            {
                //chain shapes

                var       fixtures = new List <Fixture>();
                Rectangle bounds   = Rectangle.Cleared;


                //!!!!

                ESet <(Vector2, Vector2)> wasAdded = new ESet <(Vector2, Vector2)>();

                void Add(Vector2 p1, Vector2 p2)
                {
                    if (p1 != p2 && !wasAdded.Contains((p1, p2)) && !wasAdded.Contains((p2, p1)))
                    {
                        wasAdded.Add((p1, p2));

                        fixtures.Add(body.CreateEdge(Physics2DUtility.Convert(p1), Physics2DUtility.Convert(p2)));

                        bounds.Add(p1);
                        bounds.Add(p2);
                    }
                }

                for (int nTriangle = 0; nTriangle < processedIndices.Length / 3; nTriangle++)
                {
                    var v0 = shapeTransform * processedVertices[processedIndices[nTriangle * 3 + 0]];
                    var v1 = shapeTransform * processedVertices[processedIndices[nTriangle * 3 + 1]];
                    var v2 = shapeTransform * processedVertices[processedIndices[nTriangle * 3 + 2]];

                    Add(v0.ToVector2(), v1.ToVector2());
                    Add(v1.ToVector2(), v2.ToVector2());
                    Add(v2.ToVector2(), v0.ToVector2());
                }



                //rectangle

                //for( int nTriangle = 0; nTriangle < processedIndices.Length / 3; nTriangle++ )
                //{
                //	//!!!!slowly shapeTransform *
                //	var v0 = shapeTransform * processedVertices[ processedIndices[ nTriangle * 3 + 0 ] ];
                //	var v1 = shapeTransform * processedVertices[ processedIndices[ nTriangle * 3 + 1 ] ];
                //	var v2 = shapeTransform * processedVertices[ processedIndices[ nTriangle * 3 + 2 ] ];
                //	bounds.Add( v0 );
                //	bounds.Add( v1 );
                //	bounds.Add( v2 );
                //}

                //var vertices = new Vertices();
                //var r = bounds.ToRectangle();
                //vertices.Add( Physics2DUtility.Convert( r.LeftTop ) );
                //vertices.Add( Physics2DUtility.Convert( r.RightTop ) );
                //vertices.Add( Physics2DUtility.Convert( r.RightBottom ) );
                //vertices.Add( Physics2DUtility.Convert( r.LeftBottom ) );



                //local points for space bounds calculation
                rigidBodyLocalPoints.Add(bounds.LeftTop);
                rigidBodyLocalPoints.Add(bounds.RightTop);
                rigidBodyLocalPoints.Add(bounds.RightBottom);
                rigidBodyLocalPoints.Add(bounds.LeftBottom);

                return(fixtures.ToArray());

                //return new Fixture[] { body.CreateLoopShape( vertices ) };
            }

            return(null);
        }