# Obi Official Forum

Full Version: Get rope speed, velocity and angle
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
What is the best way to get the rope swing  speed, velocity? Also get an angle of two particle?
(01-10-2021, 06:32 AM)lacasrac Wrote: [ -> ]What is the best way to get the rope swing  speed, velocity?

Deformable objects in general (this includes ropes) do not have a single speed or velocity. Where would you measure it? Different parts of the object can move at different speeds in different directions.

For deformable objects, you have two options: calculate some kind of average of all velocities in the object, or measure the velocity of a single point in the object.

Obi allows you to read/write any per-particle property: positions, velocities, mass, etc. So for the first option, the velocity of the object's center of mass (mass-weighted average of all particle positions) is often a good choice. For the second, just pick a particle of your choice and read its velocity back.

The manual contains sample snippets to calculate the center of mass, and to read the velocity of each individual particle:
http://obi.virtualmethodstudio.com/manua...icles.html

Quote:Also get an angle of two particle?

Two points in space do not define an angle, unless you mean their rotation with respect the XZ plane or some other fixed reference orientation. You need at least 3 points to have angles in there. Then, it is a matter of just getting the vectors between them and using Vector3.Angle()

You can get the particle positions using the particles API, see the same link above:
http://obi.virtualmethodstudio.com/manua...icles.html
(01-10-2021, 06:32 AM)lacasrac Wrote: [ -> ]What is the best way to get the rope swing  speed, velocity? Also get an angle of two particle?

private Vector3 GetVelocity()
{
int index = 0;
int actorIndex = 0; //solver.actors[index].solverIndices.Count() / 2;
var solverIndex = solver.actors[index].solverIndices[actorIndex];
Vector3 velocity = solver.velocities[solverIndex];
Debug.Log("velocity v3 " + name + " " + velocity + " " + solverIndex);
return velocity;
}

What is the probleme with this code? I added the rope from code, and I want to get the velocity of the rope's half height's particle. How can I do that?
I only get 0 always.

(04-10-2021, 01:12 PM)lacasrac Wrote: [ -> ]private Vector3 GetVelocity()
{
int index = 0;
int actorIndex = 0; //solver.actors[index].solverIndices.Count() / 2;
var solverIndex = solver.actors[index].solverIndices[actorIndex];
Vector3 velocity = solver.velocities[solverIndex];
Debug.Log("velocity v3 " + name + " " + velocity + " " + solverIndex);
return velocity;
}

What is the probleme with this code? I added the rope from code, and I want to get the velocity of the rope's half height's particle. How can I do that?
I only get 0 always.

private
Vector3 GetVelocity()
{
var index = _rope.activeParticleCount - 1;
var solverIndex = _rope.solverIndices[index];
return solver.velocities[solverIndex];
}

this is working, but I don't know this is good or not? Hi!

You're accessing the particle in the middle of the rope's particle pool. This is not the particle physically in the middle of the rope. You made the assumption that particles are guaranteed to appear in the arrays in the same order they appear in the rope, but that's not the case.

Also, usually the particle pool is much larger than the amount of active particles (by default, 100 + amount of particles in the rope). Particles in the pool might be active (in use by the rope) or inactive (not yet used). As you resize the rope using a cursor, or tear it, more particles will become active. Think of it just like a regular particle system: particles might be "alive" or "dead" and transition between these two states, but the total amount of particles allocated is always the same.

You want to get the element at the center of the rope, pick the particle at either end of the element, and use that. Also, no need to access the actor by index. Usually you already have a reference to the rope component around. Putting it all together:

Code:
```int index = rope.GetElementAt(0.5f).particle1; Vector3 vel = rope.solver.velocities[index];```

Edit: If your rope has say, 12 particles and your blueprint's pooledParticles property is the default (100), rope.solverIndices length is 112. So your original code is reading the position of particle 56 (which is inactive, so it has zero velocity).

Your second attempt is better, as you're using the amount of active particles in the rope (in my example, 12), and accessing the last one. However if you resize the rope or cut it, particles will be reordered so your code will cease working. The proper way to reason about the rope's topology is using elements, since particles can appear in any order.
Thanks again!