Exemple #1
0
        public static EdgeConstraint AddEdgeConstraint(Point a, Point b, float distance, EdgeConstraintType type)
        {
            EdgeConstraint edgeConstraint = new EdgeConstraint(a, b, distance, type);

            Instance.edgeConstraints.Add(edgeConstraint);
            return(edgeConstraint);
        }
Exemple #2
0
        private void FixedUpdate()
        {
            float   dt2 = Time.deltaTime * Time.deltaTime;
            Vector3 gravity = Vector3.down * 9.82f;
            Vector3 temp, edge, direction, vector, start, end, penetrationVector, projectedVector;

            for (int pointIndex = 0; pointIndex < points.Count; pointIndex++)
            {
                Point point = points[pointIndex];
                //point.acceleration = gravity + point.force;
                point.acceleration = gravity;
                VectorAdd(ref point.acceleration, ref point.force);

                temp = point.position;
                //point.position += point.position - point.oldPosition + point.acceleration * dt2;

                VectorAdd(ref point.position, ref point.position);
                VectorSub(ref point.position, ref point.oldPosition);
                VectorMul(ref point.acceleration, dt2);
                VectorAdd(ref point.position, ref point.acceleration);

                point.oldPosition = temp;
                point.force       = Vector3.zero;
            }

            for (int i = 0; i < iterations; i++)
            {
                // Edge Constraints
                for (int edgeIndex = 0; edgeIndex < edgeConstraints.Count; edgeIndex++)
                {
                    EdgeConstraint edgeConstraint = edgeConstraints[edgeIndex];
                    //edge = edgeConstraint.b.position - edgeConstraint.a.position;
                    edge = edgeConstraint.b.position;
                    VectorSub(ref edge, ref edgeConstraint.a.position);

                    float distance = edge.magnitude;

                    if (edgeConstraint.type == EdgeConstraintType.ExactDistance ||
                        edgeConstraint.type == EdgeConstraintType.MaximumDistance && distance > edgeConstraint.length ||
                        edgeConstraint.type == EdgeConstraintType.MinimumDistance && distance < edgeConstraint.length)
                    {
                        //direction = edge / distance;
                        direction = edge;
                        VectorDiv(ref direction, distance);

                        float diff = distance - edgeConstraint.length;
                        if (i == 0)
                        {
                            edgeConstraint.tension = diff;
                        }
                        else
                        {
                            edgeConstraint.tension = 0.5f * edgeConstraint.tension + 0.5f * diff;
                        }
                        //edgeConstraint.a.position += direction * diff * 0.5f;
                        //edgeConstraint.b.position -= direction * diff * 0.5f;
                        VectorMul(ref direction, diff * 0.5f);
                        VectorAdd(ref edgeConstraint.a.position, ref direction);
                        VectorSub(ref edgeConstraint.b.position, ref direction);
                    }
                }

                // Collisions
                for (int pointIndex = 0; pointIndex < points.Count; pointIndex++)
                {
                    Point point         = points[pointIndex];
                    float radius        = 0.05f;
                    float frictionCoeff = 0.98f;
                    //vector = point.position - point.oldPosition;
                    vector = point.position;
                    VectorSub(ref vector, ref point.oldPosition);

                    float distance = vector.magnitude;

                    //direction = vector / distance;
                    direction = vector;
                    VectorDiv(ref direction, distance);

                    float maxDistance = distance + radius;
                    //start = point.oldPosition - direction * radius;
                    //end = point.position + direction * radius;

                    VectorMul(ref direction, radius);

                    start = point.oldPosition;
                    VectorSub(ref start, ref direction);

                    end = point.position;
                    VectorAdd(ref end, ref direction);

                    if (Physics.SphereCast(start, radius, end - start, out RaycastHit hitInfo, maxDistance, layerMaskWorld))
                    {
                        penetrationVector = point.position - hitInfo.point;
                        projectedVector   = Vector3.ProjectOnPlane(penetrationVector, hitInfo.normal);

                        point.position = hitInfo.point + hitInfo.normal * radius + projectedVector * frictionCoeff;
                        //Debug.DrawLine(start, end, Color.green);
                    }