///内侧轴线(未完成) ---- 2017-09-07
        ///
        public static void MedialAxis(this TriangleNet.Mesh triMesh)
        {
            var bounds  = triMesh.bounds;
            var voronoi = new StandardVoronoi(triMesh, bounds);

            //List<TriangleNet.Topology.DCEL.HalfEdge> edges = new List<TriangleNet.Topology.DCEL.HalfEdge>();

            Dictionary <dVertex, int> vertLookup = new Dictionary <dVertex, int>();

            foreach (var vert in voronoi.Vertices.Where(v => !v.IsOn(bounds)))
            {
                if (!vert.leaving.origin.IsOn(bounds))
                {
                    if (!vertLookup.Keys.Contains(vert))
                    {
                        vertLookup.Add(vert, 0);
                    }
                    vertLookup [vert]++;
                }
            }

            foreach (var vert in vertLookup)
            {
                Debug.Log(vert.Key + ", " + vert.Value);
            }

            //Dictionary<halfEdge, int> edgeLookup = new Dictionary<halfEdge, int>();
            int count = 0;

            foreach (var edge in voronoi.HalfEdges.Where(e => !e.origin.IsOn(bounds)))
            {
                Debug.Log(" : " + count++ + edge + " <=> " + edge.twin);
            }
        }
        public static List <List <Vertex> > VonoroiFaces(this TriangleNet.Mesh triMesh)
        {
            var voronoi = new StandardVoronoi(triMesh);

            List <List <Vertex> > result = new List <List <Vertex> >();

            foreach (var face in voronoi.Faces)
            {
                result.Add(face.GetAllVertices( ).Select(p => new Vertex(p.x, p.y, p.id)).ToList( ));
            }

            var rect = triMesh.Bounds;

            result.Add(new List <Vertex> (rect.Path( )));

            return(result);
        }
    private VoronoiBase GenerateVoronoi(ref Polygon polygon, int relaxationCount = 0)
    {
        if (polygon.Count < 3)
        {
            return(null);
        }

        StandardVoronoi voronoi = null;

        for (int i = 0; i < relaxationCount + 1; i++)
        {
            TriangleNet.Mesh mesh = (TriangleNet.Mesh)polygon.Triangulate();
            data.bounds = mesh.Bounds;
            voronoi     = new StandardVoronoi(mesh, rectangle);
            if (relaxationCount != 0)
            {
                polygon = voronoi.Lloyd_Relaxation(rectangle);
            }
        }
        return(voronoi);
    }
        Dictionary <Point, Rigidbody> UpdateRigidbodys(SkinnedMeshRenderer skineedRenderer, TriangleNet.Mesh triMesh, bool isForward)
        {
            var vertexLookup = new Dictionary <Point, Rigidbody> ( );

            var skinnedRoot = skineedRenderer.transform;
            ///-------------------------------------------------------------------------
            ///

            int boneIndex0 = 0;
            var bindposes  = new List <Matrix4x4>();
            var bones      = new List <Transform>();

            var fBoneWeights = new List <BoneWeight>();


            var voronoi = new StandardVoronoi(triMesh);

            var triAreas = triMesh.Triangles.Sum(t => t.Area());

            Debug.Log("Tri Areas : " + triAreas);

            foreach (var face in voronoi.Faces)
            {
                var origins = face.GetAllVertices();

                if (origins.Count( ) > 0)
                {
                    var center = face.generator;

                    var obj = GameObject.CreatePrimitive(UnityEngine.PrimitiveType.Sphere);//new GameObject();
                    obj.name = "V_" + center.Label + "_" + center.ID;
                    obj.transform.localScale = Vector3.one * 0.005F;
                    var renderer = obj.GetComponent <MeshRenderer> ( );
                    if (renderer)
                    {
                        renderer.enabled = false;
                    }

                    var worldPosition = skinnedRoot.transform.TransformPoint(new Vector3(( float )center.x, ( float )center.y, 0));
                    obj.transform.position = worldPosition;
                    obj.transform.parent   = skinnedRoot;// Root.transform;
                    bones.Add(obj.transform);
                    bindposes.Add(obj.transform.worldToLocalMatrix * skinnedRoot.localToWorldMatrix);

                    var weight = new BoneWeight();

                    weight.boneIndex0 = boneIndex0;
                    weight.weight0    = 1.0F;
                    fBoneWeights.Add(weight);

                    var rigidbody = obj.AddComponent <Rigidbody>();
                    rigidbody.useGravity    = false;
                    rigidbody.interpolation = RigidbodyInterpolation.Interpolate;
                    rigidbody.mass          = origins.Area( ) * KGSM;
                    rigidbody.drag          = 4;
                    rigidbody.angularDrag   = 2;

                    // if ( center.Label == 0 )
                    rigidbody.constraints ^= RigidbodyConstraints.FreezeRotation;

                    vertexLookup.Add(center, rigidbody);

                    boneIndex0++;
                }
            }

            foreach (var edge in triMesh.Edges)
            {
                var  v0       = triMesh.Vertices.ElementAt(edge.P0);
                var  v1       = triMesh.Vertices.ElementAt(edge.P1);
                bool isBounds = v0.Label != 0 && v1.Label != 0;
                var  pt_0     = new Vector2((float)v0.x, (float)v0.y);
                var  pt_1     = new Vector2((float)v1.x, (float)v1.y);
                var  distance = Vector2.Distance(pt_0, pt_1);

                var rigid_0 = vertexLookup[v0];
                var rigid_1 = vertexLookup[v1];

                var spring = rigid_0.gameObject.AddComponent <SpringJoint>();
                spring.connectedBody = rigid_1;
                spring.minDistance   = distance * .96F;
                spring.maxDistance   = distance * 1.00F;
                spring.spring        = isBounds ? 4F : 8F;
                spring.damper        = 0F;
                spring.autoConfigureConnectedAnchor = false;
                spring.enableCollision     = false;
                spring.connectedAnchor     = spring.anchor = Vector3.zero;
                spring.axis                = Vector3.back;
                spring.tolerance           = 0.01F;
                spring.enablePreprocessing = false;
            }

            var vertices = triMesh.Vertices.Select(v => new Vector3((float)v.x, (float)v.y, 0)).ToArray();

            var triangles = isForward ?
                            triMesh.Triangles.SelectMany(t => t.vertices.Reverse().Select(v => v.id)).ToArray() :
                            triMesh.Triangles.SelectMany(t => t.vertices.Select(v => v.id)).ToArray();//.Reverse()

            var normals = triMesh.Vertices.Select(v => isForward ? Vector3.back : Vector3.forward);

            var bounds = triMesh.bounds;
            var l      = bounds.Left;
            var b      = bounds.Bottom;
            var w      = bounds.Width;
            var h      = bounds.Height;

            float dir = isForward ? 1F : -1F;
            var   uvs = triMesh.Vertices.Select(v => new Vector2(dir * (float)((v.x)), (float)((v.y))) * 0.2F).ToArray();

            var uniMesh = new Mesh();

            uniMesh.vertices  = vertices;
            uniMesh.triangles = triangles;
            uniMesh.uv        = uvs;
            uniMesh.normals   = normals.ToArray( );

            uniMesh.boneWeights = fBoneWeights.ToArray( );
            uniMesh.bindposes   = bindposes.ToArray( );

            skineedRenderer.sharedMesh = uniMesh;
            skineedRenderer.bones      = bones.ToArray( );
            skineedRenderer.rootBone   = skinnedRoot;

            return(vertexLookup);
        }
    void GenMap()
    {
        /*
         *  <settings>
         */
        int starsAm = 10000;

        // What percentage of space is taken up by stars.
        int starDensity = 20;

        // Minimal corridor length relative to maximal star size.
        float minCorridorLengthCoeff = 3.0f;

        // What percentage of space is taken up by corridors.
        int corridorDensity = 60;

        float maxz = 3.0f;

        /*
         *  </settings>
         */

        float max_star_size = Mathf.Max(pos_star_sizes);

        Debug.Log("Max star size: " + max_star_size);
        float min_corridor_length         = max_star_size * minCorridorLengthCoeff;
        float min_corridor_length_squared = Mathf.Pow(min_corridor_length, 2);

        int starsx = Mathf.RoundToInt(Mathf.Sqrt(starsAm));
        int starsy = starsx;

        float width  = (starsx * max_star_size) + ((starsx - 1) * min_corridor_length);
        float height = (starsy * max_star_size) + ((starsy - 1) * min_corridor_length);

        background.transform.localScale = new Vector3(width * 0.11f, 1.0f, height * 0.11f);
        background.GetComponent <MeshRenderer>().material.SetTextureScale("_MainTex", new Vector2(width / 70.0f, height / 70.0f));

        Debug.Log("Dimensions: " + width + ", " + height);

        float minx = width * -0.5f;
        float miny = height * -0.5f;

        float maxx = width * 0.5f;
        float maxy = height * 0.5f;

        float max_offset_x = (width / starsx) - ((min_corridor_length - max_star_size) * 0.5f);
        float max_offset_y = (height / starsy) - ((min_corridor_length - max_star_size) * 0.5f);

        Debug.Log("Offsets: " + max_offset_x + ", " + max_offset_y);

        Rectangle bounds = new Rectangle(minx, miny, width, height);

        TriangleNet.Mesh mesh = (TriangleNet.Mesh)GenericMesher.StructuredMesh(bounds, starsx - 1, starsy - 1);

        List <TriangleNet.Geometry.Vertex> stars = new List <TriangleNet.Geometry.Vertex>();

        List <TriangleNet.Geometry.Vertex> shuffled_verts = new List <TriangleNet.Geometry.Vertex>(mesh.Vertices);

        shuffled_verts.Shuffle();

        int stars_amount = 0;

        foreach (TriangleNet.Geometry.Vertex v in shuffled_verts)
        {
            if (stars_amount > 3 && Random.Range(0, 101) > starDensity)
            {
                continue;
            }
            stars.Add(v);
            stars_amount++;
        }
        GenericMesher gm = new GenericMesher(new SweepLine());

        mesh = (TriangleNet.Mesh)gm.Triangulate(stars);

        StandardVoronoi sv = new StandardVoronoi(mesh);

        Polygon final = new Polygon(sv.Vertices.Count);

        Dictionary <int, TriangleNet.Geometry.Vertex> good_stars = new Dictionary <int, TriangleNet.Geometry.Vertex>();
        Dictionary <int, int> bad2goodstar  = new Dictionary <int, int>();
        List <int>            outBoundStars = new List <int>();

        foreach (TriangleNet.Topology.DCEL.Vertex v in sv.Vertices)
        {
            if (v.x < minx || v.x > maxx || v.y < miny || v.y > maxy)
            {
                outBoundStars.Add(v.id);
                continue;
            }

            bool invalid = false;
            foreach (TriangleNet.Geometry.Vertex other in good_stars.Values)
            {
                Vector2 v1 = new Vector2((float)v.x, (float)v.y);
                Vector2 v2 = new Vector2((float)other.x, (float)other.y);

                if ((v2 - v1).sqrMagnitude < min_corridor_length_squared)
                {
                    invalid = true;

                    bad2goodstar[v.id] = other.id;
                }
            }

            if (invalid)
            {
                continue;
            }

            TriangleNet.Geometry.Vertex new_v = new TriangleNet.Geometry.Vertex(v.x, v.y);
            new_v.id         = v.id;
            good_stars[v.id] = new_v;
            final.Add(new_v);
        }

        List <Segment> good_segments = new List <Segment>();

        foreach (Edge e in sv.Edges)
        {
            if (outBoundStars.Contains(e.P0) || outBoundStars.Contains(e.P1))
            {
                continue;
            }

            int P0_id;
            int P1_id;

            if (bad2goodstar.ContainsKey(e.P0))
            {
                P0_id = bad2goodstar[e.P0];
            }
            else
            {
                P0_id = e.P0;
            }

            if (bad2goodstar.ContainsKey(e.P1))
            {
                P1_id = bad2goodstar[e.P1];
            }
            else
            {
                P1_id = e.P1;
            }

            if (P0_id == P1_id)
            {
                continue;
            }

            good_segments.Add(new Segment(good_stars[P0_id], good_stars[P1_id]));
        }

        Dictionary <int, List <int> > connected_stars = new Dictionary <int, List <int> >();

        foreach (Segment s in good_segments)
        {
            if (!connected_stars.ContainsKey(s.P0))
            {
                connected_stars[s.P0] = new List <int>();
            }
            connected_stars[s.P0].Add(s.P1);

            if (!connected_stars.ContainsKey(s.P1))
            {
                connected_stars[s.P1] = new List <int>();
            }
            connected_stars[s.P1].Add(s.P0);
        }

        Debug.Log("Currently edges: " + good_segments.Count);

        List <Segment> temp_segments = new List <Segment>(good_segments);

        temp_segments.Shuffle();

        foreach (Segment s in temp_segments)
        {
            if (Random.Range(0, 101) > corridorDensity && RemovalConnectionsCheck(connected_stars, s.P0, s.P1))
            {
                connected_stars[s.P0].Remove(s.P1);
                connected_stars[s.P1].Remove(s.P0);
                good_segments.Remove(s);
            }
        }

        foreach (Segment s in good_segments)
        {
            final.Add(s);
        }

        Debug.Log("Stars after everything: " + final.Points.Count);
        Debug.Log("Corridors after everything: " + good_segments.Count);
        CreateMap(final, maxz, 0.0f);
    }
示例#6
0
    // Use this for initialization
    void Start( )
    {
        var p = new Polygon();

        p.Add(CosSegements(-Size, -Size, Size, -Size, partsNum, 1));
        p.Add(CosSegements(Size, -Size, Size, Size, partsNum, 2));
        p.Add(CosSegements(Size, Size, -Size, Size, partsNum, 3));
        p.Add(CosSegements(-Size, Size, -Size, -Size, partsNum, 4));

        //var polygon = FileProcessor.Read("Assets/Plugins/Data/box_with_a_hole.poly");

        var options = new ConstraintOptions()
        {
            ConformingDelaunay = true
        };
        var quality = new QualityOptions()
        {
            MinimumAngle = 25F, MaximumArea = 0.1F
        };

        var triMesh = (TriangleNet.Mesh)p.Triangulate(options, quality);

        var smoothing = new SimpleSmoother();

        smoothing.Smooth(triMesh);

        triMesh.Refine(quality);

        triMesh.Renumber( );

        int boneIndex0 = 0;
        var bindposes  = new List <Matrix4x4>();
        var bones      = new List <Transform>();

        var fBoneWeights = new List <BoneWeight>();

        var vertexLookup = new Dictionary <Point, Rigidbody>();

        Root = new GameObject( );
        Root.transform.parent        = transform;
        Root.transform.localRotation = Quaternion.identity;

        var voronoi = new StandardVoronoi(triMesh);

        var triAreas = triMesh.Triangles.Sum(t => t.Area());

        Debug.Log("Tri Areas : " + triAreas);

        Debug.Log("Vor Count : " + voronoi.Faces.Count);
        float SumArea = 0F;

        foreach (var face in voronoi.Faces)
        {
            var origins = face.GetAllVertices();
            //var origins = face.EnumerateEdges().Select(e => (Point) e.Origin);

            if (origins.Count() > 0)
            {
                SumArea += origins.Area( );
                var obj = GameObject.CreatePrimitive(PrimitiveType.Sphere);//new GameObject();
                obj.transform.localScale = Vector3.one * 0.005F;
                var renderer = obj.GetComponent <MeshRenderer> ( );
                if (renderer)
                {
                    renderer.enabled = false;
                }

                //obj.GetComponent<SphereCollider> ( ).enabled = false;

                var center        = face.generator;// origins.MassCenter();
                var worldPosition = transform.TransformPoint(new Vector3(( float )center.x, ( float )center.y, 0));
                obj.transform.position = worldPosition;
                obj.transform.parent   = Root.transform;
                bones.Add(obj.transform);
                bindposes.Add(obj.transform.worldToLocalMatrix * transform.localToWorldMatrix);

                var weight = new BoneWeight();

                weight.boneIndex0 = boneIndex0;
                weight.weight0    = 1.0F;
                fBoneWeights.Add(weight);


                var rigidbody = obj.AddComponent <Rigidbody>();
                rigidbody.useGravity    = false;
                rigidbody.interpolation = RigidbodyInterpolation.Interpolate;
                rigidbody.mass          = origins.Area( ) * KGSM;
                rigidbody.drag          = 4;
                rigidbody.angularDrag   = 2;


                rigidbody.constraints ^= RigidbodyConstraints.FreezeRotation;

                //if ( center.y > 1.9 )                    rigidbody.isKinematic = true;
                if (center.y == Size)
                {
                    rigid_Up.Add(rigidbody);
                }
                else if (center.y == -Size)
                {
                    rigid_Down.Add(rigidbody);
                }
                else if (center.x == Size)
                {
                    rigid_Right.Add(rigidbody);
                }
                else if (center.x == -Size)
                {
                    rigid_Left.Add(rigidbody);
                }
                else
                {
                    others.Add(rigidbody);
                }

                All.Add(rigidbody);

                vertexLookup.Add(center, rigidbody);

                boneIndex0++;
            }

            //SkinnedMeshRenderer.BakeMesh
        }

        foreach (var edge in triMesh.Edges)
        {
            var v0       = triMesh.Vertices.ElementAt(edge.P0);
            var v1       = triMesh.Vertices.ElementAt(edge.P1);
            var pt_0     = new Vector2((float)v0.x, (float)v0.y);
            var pt_1     = new Vector2((float)v1.x, (float)v1.y);
            var distance = Vector2.Distance(pt_0, pt_1);

            var rigid_0 = vertexLookup[v0];
            var rigid_1 = vertexLookup[v1];

            var spring = rigid_0.gameObject.AddComponent <SpringJoint>();
            spring.connectedBody = rigid_1;
            spring.minDistance   = distance * .96F;
            spring.maxDistance   = distance * 1.00F;
            spring.spring        = 8F;
            spring.damper        = 0F;
            spring.autoConfigureConnectedAnchor = false;
            spring.enableCollision     = false;
            spring.connectedAnchor     = spring.anchor = Vector3.zero;
            spring.axis                = Vector3.back;
            spring.tolerance           = 0.01F;
            spring.enablePreprocessing = false;
        }

        var vertices = triMesh.Vertices.Select(v => new Vector3((float)v.x, (float)v.y, 0)).ToArray();

        var triangles = triMesh.Triangles.SelectMany(t => t.vertices.Select(v => v.id)).ToArray();//.Reverse()

        var normals = triMesh.Vertices.Select(v => transform.forward);

        var bounds = triMesh.bounds;
        var l      = bounds.Left;
        var b      = bounds.Bottom;
        var w      = bounds.Width;
        var h      = bounds.Height;
        var uvs    = triMesh.Vertices.Select(v => new Vector2(-(float)((v.x - l) / w), (float)((v.y - b) / h))).ToArray();

        Debug.Log(string.Format("Vertices : {0}, Edge : {1}, Segments : {2}, Triangles : {3}, Holes : {4}",
                                triMesh.Vertices.Count, triMesh.Edges.Count( ), triMesh.Segments.Count, triMesh.Triangles.Count, triMesh.Holes.Count));

        var skinnedRenderer = GetComponent <SkinnedMeshRenderer>();

        //var meshFilter = GetComponent<MeshFilter>();
        //if ( !meshFilter )
        //{
        //    meshFilter = gameObject.AddComponent<MeshFilter> ( );
        //}
        var uniMesh = new Mesh();

        uniMesh.vertices  = vertices;
        uniMesh.triangles = triangles;
        uniMesh.uv        = uvs;
        uniMesh.normals   = normals.ToArray( );

        uniMesh.boneWeights = fBoneWeights.ToArray( );
        uniMesh.bindposes   = bindposes.ToArray( );

        skinnedRenderer.sharedMesh = uniMesh;
        skinnedRenderer.bones      = bones.ToArray( );
        skinnedRenderer.rootBone   = Root.transform;

        //GetComponent<MeshCollider> ( ).sharedMesh = uniMesh;
    }
        private void ResetBuffers(TriangleNet.Mesh triMesh)
        {
            var bounds = triMesh.Bounds;
            var x      = (float)(bounds.Left + bounds.Right) * 0.5F;
            var y      = (float)(bounds.Top + bounds.Bottom) * 0.5F;

            Center = new Vector3(x, y, 0);
            //Mass : Vertex
            massesCount = triMesh.Vertices.Count;

            List <Mass> masses = new List <Mass>();//new Mass [massesCount];

            var voronoi = new StandardVoronoi(triMesh);

            foreach (var vertex in triMesh.Vertices)
            //for(int i =0; i < vertCount; i++ )
            {
                var mass = new Mass();
                mass.id    = vertex.id;    //0, 1, 2, ... index
                mass.label = vertex.label; //1, 1, ..., 2, 2, ..., 3, 3, ..., 4, 4, ..., 0, 0, 0 ...
                mass.nor   = Vector3.back; //new Vector3 ( ( float ) vertex.x, ( float ) vertex.y, 0 );
                //var z = vertex.label == 0 ? -0.1F : 0.0F;
                mass.pos   = new Vector3(( float )vertex.X, ( float )vertex.Y, 0);
                mass.vel   = Vector3.zero;
                mass.force = Vector3.zero;

                var face    = voronoi.Faces [vertex.id];
                var origins = face.GetAllVertices();
                mass.mass = (origins.Count > 0 ? origins.Area( ) : 0) * KGSM;

                //masses [ vertex.id ] = mass;
                masses.Add(mass);
            }

            //如果 顶点数量 不能被十整除 则 增加 不足 部分;
            if (massesCount % 10 > 0)
            {
                massesCount += 10 - (massesCount % 10);
                for (int k = triMesh.vertices.Count; k < massesCount; k++)
                {
                    masses.Add(new Mass( )
                    {
                        id = -1
                    });
                }
            }

            massBuffer = new ComputeBuffer(massesCount, sizeof(float) * 13 + sizeof(int) * 2);

            massBuffer.SetData(masses.ToArray( ));

            //Spring : Edge + Shear spring


            //Spring[] springs = new Spring[edgeCount];
            List <Spring> springs = new List <Spring>();

            //int  i = 0;
            foreach (var edge in triMesh.Edges)
            {
                var spring = new Spring();
                spring.m0 = edge.P0;
                spring.m1 = edge.P1;

                var v0 = triMesh.Vertices.ElementAt(edge.P0);
                var v1 = triMesh.Vertices.ElementAt(edge.P1);
                //bool isBounds = v0.Label != 0 && v1.Label != 0;
                var pt_0 = new Vector2((float)v0.x, (float)v0.y);
                var pt_1 = new Vector2((float)v1.x, (float)v1.y);
                spring.length = Vector2.Distance(pt_0, pt_1);
                //bool isEdge  = v0.label != 0 && v1.label != 0;
                //spring.stiffness =10.0F;

                //springs [ i ] = spring;
                springs.Add(spring);

                //i++;
            }

            foreach (var triangle in triMesh.Triangles)
            {
                for (int j = 0; j < 3; j++)
                {
                    var currID   = triangle.GetVertexID(j);
                    var nextID   = triangle.GetVertexID((j + 1) % 3);
                    var preID    = triangle.GetVertexID((j + 2) % 3);
                    var neighbor = triangle.GetNeighbor(j);

                    if (neighbor != null)
                    {
                        var ids = new int[3] {
                            neighbor.GetVertexID(0), neighbor.GetVertexID(1), neighbor.GetVertexID(2)
                        };
                        var oppID = ids.FirstOrDefault(id => id != nextID && id != preID);

                        bool isContants = springs.Any(s => (s.m0 == currID && s.m1 == oppID) || (s.m1 == currID && s.m0 == oppID));

                        if (!isContants)
                        {
                            var spring = new Spring();
                            spring.m0 = currID;
                            spring.m1 = oppID;

                            var v0 = triMesh.Vertices.ElementAt(currID);
                            var v1 = triMesh.Vertices.ElementAt(oppID);
                            //bool isBounds = v0.Label != 0 && v1.Label != 0;
                            var pt_0 = new Vector2((float)v0.x, (float)v0.y);
                            var pt_1 = new Vector2((float)v1.x, (float)v1.y);
                            spring.length = Vector2.Distance(pt_0, pt_1);
                            //bool isEdge  = v0.label != 0 && v1.label != 0;
                            //spring.stiffness = 10.0F;
                            springs.Add(spring);
                        }
                    }
                }
            }

            springsCount = springs.Count;
            if (springsCount % 10 > 0)
            {
                springsCount += 10 - (springsCount % 10);
                for (int l = springs.Count; l < springsCount; l++)
                {
                    springs.Add(new Spring( )
                    {
                        m0 = 0, m1 = 0, length = 0
                    });                                                           //, stiffness = 0 } );
                }
            }


            springBuffer = new ComputeBuffer(springsCount, sizeof(float) * 1 + sizeof(int) * 2);
            springBuffer.SetData(springs.ToArray( ));

            clothingShader.SetBuffer(initForcesKernel, ClothingShaderProperties.MassBufferName, massBuffer);
            clothingShader.SetBuffer(updateForcesKernel, ClothingShaderProperties.MassBufferName, massBuffer);
            clothingShader.SetBuffer(updateForcesKernel, ClothingShaderProperties.SpringBufferName, springBuffer);
            clothingShader.SetBuffer(updatePosKernel, ClothingShaderProperties.MassBufferName, massBuffer);


            clothingShader.SetFloat(ClothingShaderProperties.DampingName, Damping);
            clothingShader.SetFloat(ClothingShaderProperties.SpringStiffnessName, SpringStiffness);
            clothingShader.SetVector(ClothingShaderProperties.CenterName, Center);
        }