Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Part of rope Tense
#1
With regard to this post http://obi.virtualmethodstudio.com/forum...d-490.html , I would like to know if it is possible to test if a specific part of the rope is tense , for example the part between 2 control points
Reply
#2
(17-03-2021, 03:55 PM)tpaslou Wrote: With regard to this post http://obi.virtualmethodstudio.com/forum...d-490.html , I would like to know if it is possible to test if a specific part of the rope is tense , for example the part between 2 control points

Hi there,

It's possible, but you will have to implement it yourself.

The idea is exactly the same as checking tension for the entire rope: you calculate the current length and the rest length between two points in the rope, and their quotient tells you the strain.

To calculate the current length between two points, you can take ObiRopeBase's CalculateLength() method as reference:

Code:
public float CalculateLength()
        {
            float length = 0;

            if (isLoaded)
            {
                // Iterate trough all distance constraints in order:
                int elementCount = elements.Count;
                for (int i = 0; i < elementCount; ++i)
                    length += Vector4.Distance(solver.positions[elements[i].particle1],
                                               solver.positions[elements[i].particle2]);
            }
            return length;
}

Only instead of iterating trough all elements from 0 to elementCount (the entire rope), you iterate between any two elements you like.

Same for the rest length, the base implementation does:

Code:
public void RecalculateRestLength()
{
            restLength_ = 0;

            // Iterate trough all distance elements and accumulate their rest lengths.
            int elementCount = elements.Count;
            for (int i = 0; i < elementCount; ++i)
                restLength_ += elements[i].restLength;
}

Again, you just change the iteration range.

When you have both lengths, just divide them to get the strain.
Reply
#3
I have made some modifications and the part appears to be mostly tense even when it's not. So I checked the indexes for which I am calculating the strain. 

What does the elements array consist of ? My rope has 15 control points , but the rope.elements.count  is 86.
Reply
#4
(18-03-2021, 12:47 PM)tpaslou Wrote: I have made some modifications and the part appears to be mostly tense even when it's not. So I checked the indexes for which I am calculating the strain. 

What does the elements array consist of ? My rope has 15 control points , but the rope.elements.count  is 86.

Control points do not exist at runtime. They are not part of the rope, they are part of the path used in-editor to define the rope's initial shape.

Ropes are made of particles (since Obi is a particle based engine) and structural elements. You can think of elements as the "edges" in between particles. Each edge joins two particles.

So for instance: if you rope has 86 elements, the element at 10% of the rope's length is element 0.1 * 86 = 9.
Reply
#5
This is what I thought too. But still the rope even when not tense , returns value >1. Am I missing something ?

Code:
public class RopeTensity : MonoBehaviour
{
    [Header("Obi Rope Fields")]
    [SerializeField]
    private ObiSolver solver;
    [SerializeField]
    private ObiRope rope;

    [Header("Points to check")][Tooltip("Use these values like a percentage")]
    [SerializeField]
    private int startPointIndex;
    [SerializeField]
    private int endPointIndex;
    public float strain;


    private void Update()
    {
        if (IsPartStreched())
            Debug.Log("PART STRECHED!");
       
    }

    public bool IsPartStreched()
    {

        strain = CalculateLength() / CalculateRestLength();
       
        Debug.Log(rope.elements.Count);
       
        if (strain > 1)
            return true;
        else
            return false;

    }

    private float CalculateLength()
    {
        float length = 0;

        if (rope!=null)
        {
            // Iterate trough all distance constraints in order:
            for (int i = startPointIndex; i < endPointIndex ; ++i)
                length += Vector4.Distance(solver.positions[rope.elements[i].particle1],
                                           solver.positions[rope.elements[i].particle2]);
        }
        return length;
    }

    private float  CalculateRestLength()
    {
        float restLength_ = 0;

        // Iterate trough all distance elements and accumulate their rest lengths.
        for (int i = startPointIndex; i < endPointIndex; ++i)
            restLength_ += rope.elements[i].restLength;

        return restLength_;
    }
}
Reply
#6
If your simulation doesn't perfectly converge (and I doubt it does, unless you're using hundreds of substeps/iterations), the result will always be larger than 1 under even the slightest external force/acceleration. A simple rope hanging under the force of gravity will have strain > 1.

What you probably want is to compare the strain to a threshold (eg 1.1, 1.2, etc). If the strain is over this threshold, then you consider the rope as "stretched".
Reply
#7
(18-03-2021, 02:34 PM)josemendez Wrote: If your simulation doesn't perfectly converge (and I doubt it does, unless you're using hundreds of substeps/iterations), the result will always be larger than 1 under even the slightest external force/acceleration. A simple rope hanging under the force of gravity will have strain > 1.

What you probably want is to compare the strain to a threshold (eg 1.1, 1.2, etc). If the strain is over this threshold, then you consider the rope as "stretched".

I have found out that due to the rotation of the rope the strain was calculated for the oposite site. 

Indeed , the threshold has to be around 1.03-1.05 for stretched parts. 

I want to thank you for the great support that you have provided in every single post  !  Sonrisa
Reply
#8
You're welcome! glad you got it working Sonrisa
Reply