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(); } }
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); } }
public void InsertSection(RopeSection rs, int index) { sections.Insert(index, rs); rs.transform.SetParent(transform); }
public void AddSection(RopeSection rs) { sections.Add(rs); rs.transform.SetParent(transform); }