コード例 #1
0
ファイル: ClothSim.cs プロジェクト: Scaleo96/Cloth_Physics
    private bool CheckCollision(ClothParticle p)
    {
        bool collision = false;

        foreach (ClothCollider c in colliders)
        {
            if (clothType == ClothType.spring)
            {
                if (collision)
                {
                    c.CheckCollision(p, true, this);
                }
                else
                {
                    collision = c.CheckCollision(p, true, this);
                }
            }
            else
            {
                c.CheckCollision(p, false, this);
            }
        }

        return(collision);
    }
コード例 #2
0
ファイル: ClothSim.cs プロジェクト: Scaleo96/Cloth_Physics
 public ClothSpring(ClothParticle particle1, ClothParticle particle2, float Stiffness)
 {
     this.particle1     = particle1;
     this.particle2     = particle2;
     this.length        = (particle1.pos - particle2.pos).magnitude;
     this.inverseLength = 1.0f / length;
     this.springTension = Stiffness;
 }
コード例 #3
0
ファイル: ClothSim.cs プロジェクト: Scaleo96/Cloth_Physics
    private void VerletTimeStep(ClothParticle p)
    {
        Vector3 temp = p.pos;

        p.pos          = p.pos + (p.pos - p.oldPos) * (1 - damp) + p.acceleration * Time.fixedDeltaTime;
        p.oldPos       = temp;
        p.acceleration = Vector3.zero;
    }
コード例 #4
0
ファイル: ClothSim.cs プロジェクト: Scaleo96/Cloth_Physics
    private void AddWind(ClothParticle p1, ClothParticle p2, ClothParticle p3, Vector3 windForce)
    {
        Vector3 normal = GetTriangleNormal(p1, p2, p3);
        Vector3 dir    = normal.normalized;
        Vector3 force  = normal * (Vector3.Dot(dir, windForce));

        p1.acceleration += (force * (1 / p1.mass)) * Time.fixedDeltaTime;
        p2.acceleration += (force * (1 / p2.mass)) * Time.fixedDeltaTime;
        p3.acceleration += (force * (1 / p3.mass)) * Time.fixedDeltaTime;
    }
コード例 #5
0
ファイル: ClothSim.cs プロジェクト: Scaleo96/Cloth_Physics
    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Vector3 mousePos = Input.mousePosition;

            float distance = (Camera.main.WorldToScreenPoint(particles[0, 0].pos) - mousePos).magnitude;

            ClothParticle temp = particles[0, 0];

            foreach (ClothParticle p in particles)
            {
                if ((Camera.main.WorldToScreenPoint(p.pos) - mousePos).magnitude < distance)
                {
                    distance = (Camera.main.WorldToScreenPoint(p.pos) - mousePos).magnitude;
                    temp     = p;
                }
            }

            if (temp != null)
            {
                selectedParticle = temp;
            }

            tConnections.text = selectedParticle.constraints.Count.ToString();
        }

        if (Input.GetMouseButton(1))
        {
            selectedParticle.moving = true;
            selectedParticle.pos   += Camera.main.transform.right * ((Input.mousePosition.x - oldMousePos.x) * particleMoveSpeed * (selectedParticle.pos - Camera.main.transform.position).magnitude);
            selectedParticle.pos   += Camera.main.transform.up * ((Input.mousePosition.y - oldMousePos.y) * particleMoveSpeed * (selectedParticle.pos - Camera.main.transform.position).magnitude);
        }


        if (Input.GetMouseButtonUp(1))
        {
            selectedParticle.moving = false;
            if (clothType == ClothType.spring)
            {
                selectedParticle.acceleration = Vector3.zero;
            }
        }

        if (Input.GetKeyDown(KeyCode.P))
        {
            selectedParticle.posLocked = !selectedParticle.posLocked;
            if (clothType == ClothType.spring)
            {
                selectedParticle.acceleration = Vector3.zero;
            }
        }

        oldMousePos = Input.mousePosition;
    }
コード例 #6
0
ファイル: ClothSim.cs プロジェクト: Scaleo96/Cloth_Physics
    private Vector3 GetTriangleNormal(ClothParticle p1, ClothParticle p2, ClothParticle p3)
    {
        Vector3 pos1 = p1.pos;
        Vector3 pos2 = p2.pos;
        Vector3 pos3 = p3.pos;

        Vector3 v1 = pos2 - pos1;
        Vector3 v2 = pos3 - pos1;

        return(Vector3.Cross(v1, v2));
    }
コード例 #7
0
    public override bool CheckCollision(ClothParticle p, bool elastic, ClothSim cloth)
    {
        Vector3 dir = p.pos - transform.position;

        if (p.pos.y < transform.position.y)
        {
            p.pos = new Vector3(p.pos.x, transform.position.y, p.pos.z);
            //p.acceleration = Vector3.zero;
            return(true);
        }
        return(false);
    }
コード例 #8
0
    public override bool CheckCollision(ClothParticle p, bool elastic, ClothSim cloth)
    {
        Vector3 dif = p.pos - transform.position;

        if (dif.magnitude < radius)
        {
            Vector3 dir = dif.normalized;
            dir *= (radius + 0.001f);

            p.pos          = dir + transform.position;
            p.acceleration = Vector3.zero;
            return(true);
        }
        return(false);
    }
コード例 #9
0
    public override bool CheckCollision(ClothParticle p, bool elastic, ClothSim cloth)
    {
        Vector3 dir = p.pos - transform.position;

        if (p.pos.x < transform.position.x + (boundingBox.x / 2) &&
            p.pos.x > transform.position.x - (boundingBox.x / 2) &&
            p.pos.y < transform.position.y + (boundingBox.y / 2) &&
            p.pos.y > transform.position.y - (boundingBox.y / 2) &&
            p.pos.z < transform.position.z + (boundingBox.z / 2) &&
            p.pos.z > transform.position.z - (boundingBox.z / 2))
        {
            //dir.Normalize();
            p.acceleration = Vector3.zero;
            return(true);
        }
        return(false);
    }
コード例 #10
0
 public abstract bool CheckCollision(ClothParticle p, bool elastic, ClothSim cloth);
コード例 #11
0
ファイル: ClothSim.cs プロジェクト: Scaleo96/Cloth_Physics
 public ClothConstraint(ClothParticle particle1, ClothParticle particle2)
 {
     this.particle1 = particle1;
     this.particle2 = particle2;
     this.restLegth = (particle1.pos - particle2.pos).magnitude;
 }
コード例 #12
0
ファイル: ClothSim.cs プロジェクト: Scaleo96/Cloth_Physics
    public void Reset()
    {
        constraints.Clear();
        springs.Clear();
        clothAvarage = Vector3.zero;

        gridSize = gridSizeInit;

        particles = new ClothParticle[gridSize, gridSize];

        float x = 0;

        for (int i = 0; i < particles.GetLength(0); i++)
        {
            float z = 0;
            for (int j = 0; j < particles.GetLength(1); j++)
            {
                ClothParticle p = new ClothParticle(new Vector3(x, 0, z), particleMass, particleCollider);
                particles[i, j] = p;
                z             = z + radius;
                clothAvarage += new Vector3(0, -(radius / (gridSize) / 2), radius / gridSize);
            }
            x             = x + radius;
            clothAvarage += new Vector3(radius / 2, 0, 0);
        }

        for (int i = 0; i < particles.GetLength(0); i++)
        {
            for (int j = 0; j < particles.GetLength(1); j++)
            {
                ClothParticle mainParticle = particles[i, j];
                ClothParticle subParticle;

                if (i < particles.GetLength(0) - 1)
                {
                    subParticle = particles[i + 1, j];
                    ClothSpring s1 = new ClothSpring(mainParticle, subParticle, tenstion);
                    springs.Add(s1);
                    ClothConstraint c1 = new ClothConstraint(mainParticle, subParticle);
                    constraints.Add(c1);
                    mainParticle.constraints.Add(c1);
                    subParticle.constraints.Add(c1);
                }

                if (j < particles.GetLength(1) - 1)
                {
                    subParticle = particles[i, j + 1];
                    ClothSpring s2 = new ClothSpring(mainParticle, subParticle, tenstion);
                    springs.Add(s2);
                    ClothConstraint c2 = new ClothConstraint(mainParticle, subParticle);
                    constraints.Add(c2);
                    mainParticle.constraints.Add(c2);
                    subParticle.constraints.Add(c2);
                }


                if (sheerGrid)
                {
                    if (j < particles.GetLength(0) - 1 && i < particles.GetLength(1) - 1)
                    {
                        subParticle = particles[i + 1, j + 1];
                        ClothSpring s3 = new ClothSpring(mainParticle, subParticle, tenstion);
                        springs.Add(s3);
                        ClothConstraint c3 = new ClothConstraint(mainParticle, subParticle);
                        constraints.Add(c3);
                        mainParticle.constraints.Add(c3);
                        subParticle.constraints.Add(c3);
                    }

                    if (j > 0 && i < particles.GetLength(1) - 1)
                    {
                        subParticle = particles[i + 1, j - 1];
                        ClothSpring s4 = new ClothSpring(mainParticle, subParticle, tenstion);
                        springs.Add(s4);
                        ClothConstraint c4 = new ClothConstraint(mainParticle, subParticle);
                        constraints.Add(c4);
                        mainParticle.constraints.Add(c4);
                        subParticle.constraints.Add(c4);
                    }
                }

                if (bendGrid)
                {
                    if (i < particles.GetLength(0) - 2)
                    {
                        subParticle = particles[i + 2, j];
                        ClothSpring s5 = new ClothSpring(mainParticle, subParticle, tenstion);
                        springs.Add(s5);
                        ClothConstraint c5 = new ClothConstraint(mainParticle, subParticle);
                        constraints.Add(c5);
                        mainParticle.constraints.Add(c5);
                        subParticle.constraints.Add(c5);
                    }

                    if (j < particles.GetLength(1) - 2)
                    {
                        subParticle = particles[i, j + 2];
                        ClothSpring s6 = new ClothSpring(mainParticle, subParticle, tenstion);
                        springs.Add(s6);
                        ClothConstraint c6 = new ClothConstraint(mainParticle, subParticle);
                        constraints.Add(c6);
                        mainParticle.constraints.Add(c6);
                        subParticle.constraints.Add(c6);
                    }

                    if (j < particles.GetLength(0) - 2 && i < particles.GetLength(1) - 2)
                    {
                        subParticle = particles[i + 2, j + 2];
                        ClothSpring s7 = new ClothSpring(mainParticle, subParticle, tenstion);
                        springs.Add(s7);
                        ClothConstraint c7 = new ClothConstraint(mainParticle, subParticle);
                        constraints.Add(c7);
                        mainParticle.constraints.Add(c7);
                        subParticle.constraints.Add(c7);
                    }

                    if (j > 1 && i < particles.GetLength(1) - 2)
                    {
                        subParticle = particles[i + 2, j - 2];
                        ClothSpring s8 = new ClothSpring(mainParticle, subParticle, tenstion);
                        springs.Add(s8);
                        ClothConstraint c8 = new ClothConstraint(mainParticle, subParticle);
                        constraints.Add(c8);
                        mainParticle.constraints.Add(c8);
                        subParticle.constraints.Add(c8);
                    }
                }
            }
        }


        particles[0, gridSize - 1].posLocked            = true;
        particles[0, gridSize - 1].startPos             = particles[0, gridSize - 1].pos;
        particles[gridSize - 1, gridSize - 1].posLocked = true;
        particles[gridSize - 1, gridSize - 1].startPos  = particles[gridSize - 1, gridSize - 1].pos;


        selectedParticle = particles[gridSize - 1, gridSize - 1];

        filter.mesh = GenerateMesh();

        CreateWireframe();
    }
コード例 #13
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);
        }