예제 #1
0
 public CableJoint(CableBody body1, CableBody body2, Vector3 offset1, Vector3 offset2, float restLength)
 {
     Body1           = body1;
     Body2           = body2;
     this.offset1    = offset1;
     this.offset2    = offset2;
     this.restLength = restLength;
 }
예제 #2
0
 public CableJoint(CableBody body1, CableBody body2, Vector3 offset1, Vector3 offset2, float restLength)
 {
     this.body1      = body1;
     this.body2      = body2;
     this.rb1        = body1.GetRigidbody();
     this.rb2        = body2.GetRigidbody();
     this.offset1    = offset1;
     this.offset2    = offset2;
     this.restLength = restLength;
 }
예제 #3
0
        private void SplitMerge()
        {
            if (!dynamicSplitMerge)
            {
                return;
            }

            // merge links with negative stored cable:
            for (int i = 1; i < links.Count - 1; ++i)
            {
                CableJoint prevJoint = joints[i - 1];
                CableJoint nextJoint = joints[i];

                if (links[i].type == Link.LinkType.Rolling && links[i].body != null && prevJoint != null && nextJoint != null)
                {
                    if (links[i].storedCable < 0)
                    {
                        prevJoint.restLength += nextJoint.restLength;
                        prevJoint.Body2       = nextJoint.Body2;

                        // Update joint attachment points:
                        Vector3 t1, t2;
                        FindCommonTangents(links[i - 1], links[i + 1], out t1, out t2);
                        prevJoint.offset1 = prevJoint.Body1.transform.InverseTransformPoint(t1);
                        prevJoint.offset2 = prevJoint.Body2.transform.InverseTransformPoint(t2);
                        prevJoint.Initialize();

                        links.RemoveAt(i);
                        joints.RemoveAt(i);
                    }
                }
            }

            // split joints that intersect a body:
            for (int i = 0; i < joints.Count; ++i)
            {
                CableJoint currentJoint = joints[i];

                if (currentJoint != null)
                {
                    RaycastHit hit;

                    if (Physics.Raycast(new Ray(currentJoint.WorldSpaceAttachment1, currentJoint.WorldSpaceAttachment2 - currentJoint.WorldSpaceAttachment1), out hit, currentJoint.length))
                    {
                        CableBody body = hit.collider.GetComponent <CableBody>();

                        // Only split if the body is a disc or a convex shape, and the raycast hit is sane.
                        if ((body is CableDisc || body is CableShape) && hit.distance > 0.1f && hit.distance + 0.1f < currentJoint.length)
                        {
                            float initialRestLength = currentJoint.restLength;

                            // Create new joint and link:
                            CableJoint newJoint = new CableJoint(body, currentJoint.Body2, Vector3.zero, Vector3.zero, currentJoint.restLength);
                            currentJoint.Body2 = body;

                            Link newLink = new Link();
                            newLink.type = Link.LinkType.Rolling;
                            newLink.body = body;

                            // Calculate orientation.
                            Vector3 v     = body.transform.position - currentJoint.WorldSpaceAttachment1;
                            Vector3 cross = Vector3.Cross(body.GetCablePlaneNormal(), v);
                            newLink.orientation = Vector3.Dot(cross, hit.point - currentJoint.WorldSpaceAttachment1) < 0;

                            // Update joint attachment points:
                            Vector3 t1, t2;
                            FindCommonTangents(links[i], newLink, out t1, out t2);
                            currentJoint.offset1 = currentJoint.Body1.transform.InverseTransformPoint(t1);
                            currentJoint.offset2 = currentJoint.Body2.transform.InverseTransformPoint(t2);

                            FindCommonTangents(newLink, links[i + 1], out t1, out t2);
                            newJoint.offset1 = newJoint.Body1.transform.InverseTransformPoint(t1);
                            newJoint.offset2 = newJoint.Body2.transform.InverseTransformPoint(t2);

                            currentJoint.Initialize();
                            newJoint.Initialize();

                            // Adjust rest lengths so that tensions are equal:
                            float tension = initialRestLength / (currentJoint.length + newJoint.length);
                            currentJoint.restLength = currentJoint.length * tension;
                            newJoint.restLength     = newJoint.length * tension;

                            // Insert new joint/link:
                            joints.Insert(i + 1, newJoint);
                            links.Insert(i + 1, newLink);
                        }
                    }
                }
            }
        }