private void MaxStretch(List <ropeSec> setRopeSections) { float maxStretch = 1.0f + stretchRange; float minStretch = 1.0f - stretchRange; for (int i = setRopeSections.Count - 1; i > 0; i--) { ropeSec topSection = setRopeSections [i]; ropeSec bottomSection = setRopeSections [i - 1]; float dist = (topSection.pos - bottomSection.pos).magnitude; float stretch = dist / sectionLength; if (stretch > maxStretch) { float compressLength = dist - (sectionLength * maxStretch); Vector3 compressDir = (topSection.pos - bottomSection.pos).normalized; compressDir *= compressLength; MoveSection(compressDir, i - 1); } else if (stretch < minStretch) { float stretchLength = (sectionLength * minStretch) - dist; Vector3 stretchDir = (topSection.pos - bottomSection.pos).normalized; stretchDir *= stretchLength; MoveSection(stretchDir, i - 1); } } }
private void MoveSection(Vector3 finalChange, int listPos) { ropeSec bottomSection = myRopeSections [listPos]; Vector3 pos = bottomSection.pos; pos += finalChange; bottomSection.pos = pos; myRopeSections [listPos] = bottomSection; }
private void UpdateRopeSimulation(List <ropeSec> setRopeSections, float timeStep) { // Setting the last rope section to the end position (since it doesnt move) ropeSec lastRopeSec = setRopeSections[setRopeSections.Count - 1]; lastRopeSec.pos = ropeConnectStart.position; setRopeSections [setRopeSections.Count - 1] = lastRopeSec; List <Vector3> accelerations = CalculateAccelerations(setRopeSections); List <ropeSec> nextPosVelForwardEuler = new List <ropeSec> (); // Should use count -1 or not? for (int i = 0; i < setRopeSections.Count - 1; i++) { ropeSec thisRopeSec = ropeSec.zero; // Velocity thisRopeSec.vel = setRopeSections[i].vel + (accelerations[i] * timeStep); thisRopeSec.pos = setRopeSections [i].pos + (setRopeSections [i].vel * timeStep); nextPosVelForwardEuler.Add(thisRopeSec); } // add last for pos vec List <Vector3> accelFromEul = CalculateAccelerations(nextPosVelForwardEuler); List <ropeSec> nextPosVelHeunsMethod = new List <ropeSec> (); for (int i = 0; i < setRopeSections.Count - 1; i++) { ropeSec thisRopeSection = ropeSec.zero; thisRopeSection.vel = setRopeSections [i].vel + ((accelerations [i] + accelFromEul [i]) * .5f * timeStep); thisRopeSection.pos = setRopeSections [i].pos + ((setRopeSections [i].vel + nextPosVelForwardEuler [i].vel) * .5f * timeStep); nextPosVelHeunsMethod.Add(thisRopeSection); } // Add last if not already added for (int i = 0; i < setRopeSections.Count - 1; i++) { setRopeSections [i] = nextPosVelHeunsMethod [i]; //setRopeSEctions[i] = nextPosVelForwardEuler[i]; } int maximumStretchIterations = 2; for (int i = 0; i < maximumStretchIterations; i++) { MaxStretch(setRopeSections); } }