Example #1
0
        public static Cloth CreateQuad(ClothQuadDefinition def)
        {
            var resX = def.ResX;
            var resY = def.ResY;

            var pts = new ClothParticle[resX * resY];

            for (var y = 0; y < resY; y++)
            {
                var fy = y / (float)(resY - 1);
                var p0 = Vector3.Lerp(def.V00, def.V01, fy);
                var p1 = Vector3.Lerp(def.V10, def.V11, fy);
                for (var x = 0; x < resX; x++)
                {
                    var fx = x / (float)(resX - 1);
                    var p  = new ClothParticle {
                        Position = Vector3.Lerp(p0, p1, fx), Velocity = Vector3.Zero, Tension = Vector3.Zero, Uv = new Vector2(fx, fy)
                    };
                    pts[y * resX + x] = p;
                }
            }

            #region Pin Particles

            foreach (var pin in def.Pins)
            {
                pts[pin.Y * resX + pin.X].Pinned = true;
            }

            #endregion

            #region Calculate Particle Masses from Area

            var totalArea = 0f;
            for (var y = 0; y < resY; y++)
            {
                for (var x = 0; x < resX; x++)
                {
                    var idx = y * resX + x;
                    var pos = pts[idx].Position;

                    var normal = Vector3.One;
                    var area   = 0f;
                    if (x < resX - 1 && y < resY - 1)
                    {
                        area += (normal = Vector3.Cross(pts[idx + 1].Position - pos, pts[idx + resX].Position - pos)).Length() / 2;
                    }
                    if (x < resX - 1 && y > 0)
                    {
                        area += (normal = Vector3.Cross(pts[idx + 1].Position - pos, pts[idx - resX].Position - pos)).Length() / 2;
                    }
                    if (x > 0 && y < resY - 1)
                    {
                        area += (normal = Vector3.Cross(pts[idx - 1].Position - pos, pts[idx + resX].Position - pos)).Length() / 2;
                    }
                    if (x > 0 && y > 0)
                    {
                        area += (normal = Vector3.Cross(pts[idx - 1].Position - pos, pts[idx - resX].Position - pos)).Length() / 2;
                    }

                    normal.Normalize();
                    pts[idx].Normal      = normal;
                    pts[idx].Area        = area;
                    pts[idx].InverseMass = def.Mass * area;
                    totalArea           += area;
                }
            }

            for (var i = 0; i < pts.Length; i++)
            {
                pts[i].InverseMass = 1 / (pts[i].InverseMass / totalArea);
            }

            #endregion

            var springs = new List <ClothSpring>(resX * (resY - 1) + (resX - 1) * resY + (resX - 1) * (resY - 1) + (resX - 2) * (resY - 1) +
                                                 (resX - 1) * (resY - 2));

            #region Create Springs

            // + X
            for (var y = 0; y < resY; y++)
            {
                for (var x = 0; x < resX - 1; x++)
                {
                    var idx = y * resX + x;
                    springs.Add(new ClothSpring
                    {
                        P0        = idx,
                        P1        = idx + 1,
                        Stiffness = def.TensionStrength
                    });
                }
            }

            // + Y
            for (var y = 0; y < resY - 1; y++)
            {
                for (var x = 0; x < resX; x++)
                {
                    var idx = y * resX + x;
                    springs.Add(new ClothSpring
                    {
                        P0        = idx,
                        P1        = idx + resX,
                        Stiffness = def.TensionStrength
                    });
                }
            }

            // + X, +Y
            if (def.ShearStrength > 0)
            {
                for (var y = 0; y < resY - 1; y++)
                {
                    for (var x = 0; x < resX - 1; x++)
                    {
                        var idx = y * resX + x;
                        springs.Add(new ClothSpring
                        {
                            P0        = idx,
                            P1        = idx + resX + 1,
                            Stiffness = def.ShearStrength
                        });
                    }
                }
            }

            if (def.StructuralStrength > 0)
            {
                // + 2X, +Y
                for (var y = 0; y < resY - 1; y++)
                {
                    for (var x = 0; x < resX - 2; x++)
                    {
                        var idx = y * resX + x;
                        springs.Add(new ClothSpring
                        {
                            P0        = idx,
                            P1        = idx + resX + 2,
                            Stiffness = def.StructuralStrength
                        });
                    }
                }

                // +X, +2Y
                for (var y = 0; y < resY - 2; y++)
                {
                    for (var x = 0; x < resX - 1; x++)
                    {
                        var idx = y * resX + x;
                        springs.Add(new ClothSpring
                        {
                            P0        = idx,
                            P1        = idx + resX * 2 + 1,
                            Stiffness = def.StructuralStrength
                        });
                    }
                }
            }

            #endregion

            #region Fill Spring Lengths

            for (var i = 0; i < springs.Count; i++)
            {
                var s   = springs[i];
                var len = Vector3.Distance(pts[s.P0].Position, pts[s.P1].Position);
                s.Length    = len;
                s.InvLength = 1 / len;
                springs[i]  = s;
            }

            #endregion

            var quadStream = new int[4 * (resX - 1) * (resY - 1)];

            #region Create Quad Stream

            var quadOffset = 0;
            for (var y = 0; y < resY - 1; y++)
            {
                for (var x = 0; x < resX - 1; x++)
                {
                    var idx = y * resX + x;
                    quadStream[quadOffset++] = idx;
                    quadStream[quadOffset++] = idx + 1;
                    quadStream[quadOffset++] = idx + 1 + resX;
                    quadStream[quadOffset++] = idx + resX;
                }
            }

            #endregion

            var cloth = new Cloth(pts, springs.ToArray(), quadStream)
            {
                Damping = def.Damping
            };
            return(cloth);
        }
 public ClothSection(MyObjectBuilder_ClothSquaresComponentDefinition.ClothSquare sq)
 {
     Def      = new ClothQuadDefinition(sq);
     Bindings = sq.Pins.Where(x => !string.IsNullOrWhiteSpace(x.Bone)).Select(x => new Binding(x)).ToArray();
 }