Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Copy ropes in play mode
#6
Here's a basic script that ensures both ropes have the same amount of particles and elements, then copies particle positions/velocities from one rope to the other:

Code:
using UnityEngine;
using Obi;

public class CopyRope : MonoBehaviour
{
    public ObiRope src;
    public ObiRope dst;

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.C))
            Copy();
    }

    void Copy()
    {
        // store inital amount of elements in destination rope:
        int initialElementCount = dst.elements.Count;

        // if the destination has more particles than the source, remove excess particles/elements.
        while (dst.activeParticleCount > src.activeParticleCount)
        {
            dst.elements.RemoveAt(dst.elements.Count - 1);
            dst.DeactivateParticle(dst.activeParticleCount - 1);
        }

        // if the destination has less particles than the source, add more particles/elements.
        while (dst.activeParticleCount < src.activeParticleCount)
        {
            // create a new element joining the last two particles, of length equal
            // to the average distance between particles:
            dst.elements.Add(new ObiStructuralElement
            {
                particle1 = dst.elements[dst.elements.Count - 1].particle2,
                particle2 = dst.solverIndices[dst.activeParticleCount],
                restLength = dst.interParticleDistance
            });

            // copy data from the last active particle to the first inactive one, then activate it.
            dst.CopyParticle(dst.activeParticleCount-1, dst.activeParticleCount);
            dst.ActivateParticle(dst.activeParticleCount);
        }

        // now that both ropes have same amount of particles/elements,
        // just copy positions/velocities:
        int srcParticle, dstParticle;
        for (int i = 0; i < src.elements.Count; ++i)
        {
            srcParticle = src.elements[i].particle1;
            dstParticle = dst.elements[i].particle1;
            dst.solver.positions[dstParticle] = src.solver.positions[srcParticle];
            dst.solver.velocities[dstParticle] = src.solver.velocities[srcParticle];
        }

        // don't forget to copy last particle too:
        srcParticle = src.elements[src.elements.Count - 1].particle2;
        dstParticle = dst.elements[dst.elements.Count - 1].particle2;
        dst.solver.positions[dstParticle] = src.solver.positions[srcParticle];
        dst.solver.velocities[dstParticle] = src.solver.velocities[srcParticle];

        // if the amount of elements has changed, rebuild constraints:
        if (initialElementCount != dst.elements.Count)
            dst.RebuildConstraintsFromElements();
    }
}

You could also use a cursor and replace the first two while loops with calls to ChangeLength(), however since cursors work in terms of length and we are interested in directly counting particles, it's simpler to handle elements and particles by hand.

Also note this script assumes blueprint resolution is the same for both ropes (so that the gap between particles and the size of the particles is the same for both), and that they have non-zero pool sizes (so that there's inactive particles available to be used).

let me know if you need further help!
Reply


Messages In This Thread
Copy ropes in play mode - by Alexander34 - 08-01-2024, 03:53 PM
RE: Copy ropes in play mode - by josemendez - 16-01-2024, 08:41 AM
RE: Copy ropes in play mode - by Alexander34 - 16-01-2024, 02:47 PM
RE: Copy ropes in play mode - by josemendez - 16-01-2024, 07:42 PM
RE: Copy ropes in play mode - by Alexander34 - 16-01-2024, 08:08 PM
RE: Copy ropes in play mode - by josemendez - 17-01-2024, 11:08 AM