private void UpdateRopeSimulation()
    {
        Vector3 gravityVec = new Vector3(0f, -9.81f, 0f);

        float t = Time.fixedDeltaTime;


        //Move the first section to what the rope is hanging from
        RopeSection firstRopeSection = allRopeSections[0];

        firstRopeSection.pos = whatTheRopeIsConnectedTo.position;

        allRopeSections[0] = firstRopeSection;


        //Move the other rope sections with Verlet integration
        for (int i = 1; i < allRopeSections.Count; i++)
        {
            RopeSection currentRopeSection = allRopeSections[i];

            //Calculate velocity this update
            Vector3 vel = currentRopeSection.pos - currentRopeSection.oldPos;

            //Update the old position with the current position
            currentRopeSection.oldPos = currentRopeSection.pos;

            //Find the new position
            currentRopeSection.pos += vel;

            //Add gravity
            currentRopeSection.pos += gravityVec * t;

            //Add it back to the array
            allRopeSections[i] = currentRopeSection;
        }


        //Make sure the rope sections have the correct lengths
        for (int i = 0; i < 20; i++)
        {
            ImplementMaximumStretch();
        }
    }
Exemple #2
0
    protected Rope CreateRopeWithSectionType(RopeSection sectionPrefab)
    {
        // Create Rope Container
        Rope ropeContainer = Instantiate(ropePrefab, transform.position, Quaternion.identity) as Rope;

        ropeContainer.name = "Rope " + index;

        // Create First section and remove its joint
        RopeSection lastSection = Instantiate(sectionPrefab, new Vector3(ropeEnds.x, transform.position.y, 0), Quaternion.identity) as RopeSection;

        // Connect to Rope Container
        ropeContainer.AddSection(lastSection);

        // Count variables and section length
        float offset        = 0f;
        float sectionLength = lastSection.transform.localScale.x - 0.05f;

        // Calculate number of sections based on draw length
        float distance = ropeEnds.y - ropeEnds.x;
        int   num      = Mathf.CeilToInt(distance / sectionLength);

        while (num > 0)
        {
            // Count
            num--;
            offset += sectionLength;

            // Add new Section
            RopeSection newSection = Instantiate(sectionPrefab, new Vector3(ropeEnds.x + offset, transform.position.y, 0), Quaternion.identity) as RopeSection;
            newSection.ConnectTo(lastSection);

            // Add to Rope Container
            ropeContainer.AddSection(newSection);

            // Reset for next iteration
            lastSection = newSection;
        }

        return(ropeContainer);
    }
    private void UpdateRopeSimulation(List <RopeSection> allRopeSections, float timeStep)
    {
        //Move the last position, which is the top position, to what the rope is attached to
        RopeSection lastRopeSection = allRopeSections[allRopeSections.Count - 1];

        lastRopeSection.pos = whatTheRopeIsConnectedTo.position;

        allRopeSections[allRopeSections.Count - 1] = lastRopeSection;


        //
        //Calculate the next pos and vel with Forward Euler
        //
        //Calculate acceleration in each rope section which is what is needed to get the next pos and vel
        List <Vector3> accelerations = CalculateAccelerations(allRopeSections);

        List <RopeSection> nextPosVelForwardEuler = new List <RopeSection>();

        //Loop through all line segments (except the last because it's always connected to something)
        for (int i = 0; i < allRopeSections.Count - 1; i++)
        {
            RopeSection thisRopeSection = RopeSection.zero;

            //Forward Euler
            //vel = vel + acc * t
            thisRopeSection.vel = allRopeSections[i].vel + accelerations[i] * timeStep;

            //pos = pos + vel * t
            thisRopeSection.pos = allRopeSections[i].pos + allRopeSections[i].vel * timeStep;

            //Save the new data in a temporarily list
            nextPosVelForwardEuler.Add(thisRopeSection);
        }

        //Add the last which is always the same because it's attached to something
        nextPosVelForwardEuler.Add(allRopeSections[allRopeSections.Count - 1]);


        //
        //Calculate the next pos with Heun's method (Improved Euler)
        //
        //Calculate acceleration in each rope section which is what is needed to get the next pos and vel
        List <Vector3> accelerationFromEuler = CalculateAccelerations(nextPosVelForwardEuler);

        List <RopeSection> nextPosVelHeunsMethod = new List <RopeSection>();

        //Loop through all line segments (except the last because it's always connected to something)
        for (int i = 0; i < allRopeSections.Count - 1; i++)
        {
            RopeSection thisRopeSection = RopeSection.zero;

            //Heuns method
            //vel = vel + (acc + accFromForwardEuler) * 0.5 * t
            thisRopeSection.vel = allRopeSections[i].vel + (accelerations[i] + accelerationFromEuler[i]) * 0.5f * timeStep;

            //pos = pos + (vel + velFromForwardEuler) * 0.5f * t
            thisRopeSection.pos = allRopeSections[i].pos + (allRopeSections[i].vel + nextPosVelForwardEuler[i].vel) * 0.5f * timeStep;

            //Save the new data in a temporarily list
            nextPosVelHeunsMethod.Add(thisRopeSection);
        }

        //Add the last which is always the same because it's attached to something
        nextPosVelHeunsMethod.Add(allRopeSections[allRopeSections.Count - 1]);



        //From the temp list to the main list
        for (int i = 0; i < allRopeSections.Count; i++)
        {
            allRopeSections[i] = nextPosVelHeunsMethod[i];

            //allRopeSections[i] = nextPosVelForwardEuler[i];
        }


        //Implement maximum stretch to avoid numerical instabilities
        //May need to run the algorithm several times
        int maximumStretchIterations = 2;

        for (int i = 0; i < maximumStretchIterations; i++)
        {
            ImplementMaximumStretch(allRopeSections);
        }
    }
Exemple #4
0
 public void InsertSection(RopeSection rs, int index)
 {
     sections.Insert(index, rs);
     rs.transform.SetParent(transform);
 }
Exemple #5
0
 public void AddSection(RopeSection rs)
 {
     sections.Add(rs);
     rs.transform.SetParent(transform);
 }