Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Resize rope when apply force to attached mass
#1
Hello! I am using ObiRope to simulate fishing rod with reel. 

What i have: 
1. Cursor to resize my rope when the player reel in.
2. Hook. Just rigidbody attached dynamically with ObiParticleAttachment at the end of the rope. Static attachment at the fishing rod top point.

I apply force to fishing hook when player cast or fish move with hook. After that my rope will be stretched and i want to prevent this by giving extra lengthHow can i get the speed of first 1-2 rope particle point and also tension force? How can I compare the current rope tension with the tension at rest? I need these values to calculate resize speed and make more realistic fishing rod behaviour. Or maybe there is other solution for my case?

Thanks for your advices!
Reply
#2
(04-07-2024, 10:39 AM)Jaxel Wrote: How can i get the speed of first 1-2 rope particle point and also tension force? 

Hi!

You can get any per-particle value (velocity, position, size, etc) using the particles API. To get the index of the first particle on the rope, you should use the rope's elements array.

(04-07-2024, 10:39 AM)Jaxel Wrote: How can I compare the current rope tension with the tension at rest?

By definition, the tension at rest or any object is zero. Maybe you're interested in strain instead, which is the % of deformation caused by tension? You can calculate it like this:

Code:
float strain = rope.CalculateLength() / rope.restLength;

It will be 1 when the rope is at rest, >1 if stretched, <1 if compressed.

kind regards
Reply
#3
(08-07-2024, 12:02 PM)josemendez Wrote: Hi!

You can get any per-particle value (velocity, position, size, etc) using the particles API. To get the index of the first particle on the rope, you should use the rope's elements array.


By definition, the tension at rest or any object is zero. Maybe you're interested in strain instead, which is the % of deformation caused by tension? You can calculate it like this:

Code:
float strain = rope.CalculateLength() / rope.restLength;

It will be 1 when the rope is at rest, >1 if stretched, <1 if compressed.

kind regards
Thank you very much! This should help.
Reply
#4
I made a script for my game that connects multiple targets to a defined spline as an attachment. The rope is able to feed through the attachment with a desired friction.

Here's the code where the magic happens, maybe that can help you. The lambda for the distance constraint can be interpreted as the force stretching the rope element if you divide by time squared. Instead of manipulating _positionInElement and _elementIndex, I guess you want to update the cursor script instead.
Code:
float sqrTime = stepTime * stepTime;
float forwardForce = -SolverLambda(startElement, solverConstraints) / sqrTime;
float backwardForce = -SolverLambda(endElement, solverConstraints) / sqrTime;

float totalForce = forwardForce - backwardForce;

if (totalForce > ForwardFriction) ApplyForceToMovement(totalForce - ForwardFriction, sqrTime);
else if (totalForce < -BackwardFriction) ApplyForceToMovement(totalForce + BackwardFriction, sqrTime);

Code:
private float SolverLambda(int elementIndex, ObiConstraints<ObiDistanceConstraintsBatch> solverConstraints)
{
    int batchCount = solverConstraints.GetBatchCount();
    int index = elementIndex / batchCount;
    int batchIndex = elementIndex % batchCount;
   
    int offset = _rope.solverBatchOffsets[(int)Oni.ConstraintType.Distance][batchIndex];

    return solverConstraints.batches[batchIndex].lambdas[offset + index];
}


Code:
private void ApplyForceToMovement(float force, float sqrTime)
{
    float movement = (force) * sqrTime;
    movement = Mathf.Lerp(movement, 0, _movemementDamping);
    int startElement = Mathf.Clamp(_elementIndex - 1, 0, _rope.elements.Count - 1);
    float movementInElement = movement / _rope.elements[startElement].restLength;
   
    _positionInElement += movementInElement;
    if (_positionInElement < 0)
    {
        _positionInElement += 1f;
        _positionInElement *= _rope.elements[startElement].restLength;
        _elementIndex--;
        _positionInElement /= _rope.elements[startElement].restLength;
    } else if (_positionInElement > 1f)
    {
        _positionInElement -= 1f;
        _positionInElement *= _rope.elements[startElement].restLength;
        _elementIndex++;
        _positionInElement /= _rope.elements[startElement].restLength;
    }

    _position = _elementIndex + _positionInElement;
}
Reply