Obi Official Forum
Copy position from one rope to another - Printable Version

+- Obi Official Forum (https://obi.virtualmethodstudio.com/forum)
+-- Forum: Obi Users Category (https://obi.virtualmethodstudio.com/forum/forum-1.html)
+--- Forum: Obi Rope (https://obi.virtualmethodstudio.com/forum/forum-4.html)
+--- Thread: Copy position from one rope to another (/thread-3275.html)

Pages: 1 2


Copy position from one rope to another - lufydad - 13-01-2022

Hello,

I have two ropes 0 and 1. The rope 0 is physically managed by the obi solver, and I would like the rope 1 to be only a copy of the rendering of the first one.

To do this, I tried to get all the positions of the rope 0 and I applied them to the rope 1 (see code below).

Code:
public void LateUpdate()
{     
     for (int i = 0; i < _obiRope0.solverIndices.Length; i++)
     {
          var indexParticles = _obiRope0.solverIndices.SolverIndices[i];
                   
                   
          if (_obiRope0.IsParticleActive(indexParticles) == false)
              continue;

          _obiSolver0.positions[indexParticles] = _obiSolver1.positions[indexParticles];
    }
}


However, there are two problems with this solution:
- In the rendering there is a regular teleportation of the rope 1 to its "physical position".
- In terms of performance, physical calculations are still done for the rope 1.


How should the obi solver for the rope 1 be set up to solve the two points above ? Or is there another way to achieve this goal ?

Thanks,


RE: Copy position from one rope to another - josemendez - 13-01-2022

Hi!

(13-01-2022, 10:33 AM)lufydad Wrote: - In the rendering there is a regular teleportation of the rope 1 to its "physical position".

Not sure what you mean by this, but keep in mind particle positions are expressed in solver space. So even if the position is the same, this position is expressed relative to the solver position.

Also, you probably want to copy renderablePositions instead of positions. The renderablePositions are the actual positions being rendered, and are generated from positions and previous positions using interpolation.

(13-01-2022, 10:33 AM)lufydad Wrote: - In terms of performance, physical calculations are still done for the rope 1.

Simply disable the first solver. That will stop physics from being updated.


RE: Copy position from one rope to another - lufydad - 13-01-2022

(13-01-2022, 10:55 AM)josemendez Wrote: Hi!


Not sure what you mean by this, but keep in mind particle positions are expressed in solver space. So even if the position is the same, this position is expressed relative to the solver position.

Also, you probably want to copy renderablePositions instead of positions. The renderablePositions are the actual positions being rendered, and are generated from positions and previous positions using interpolation.


Simply disable the first solver. That will stop physics from being updated.

Sorry, I can't reproduce the bug where the rope 1 teleports to its physical position, so it must be a bad modification on my part ^^.

I tried using renderablePositions instead of positions, but the rope 1 seems de-synchronize with rope 0 (see https://imgur.com/a/7GklcBR).
When I disable the solver parent of rope 1, it stop completely the motion of rope 1, even if we hard set the position of particle with the code below (see https://imgur.com/SZu31aA).


RE: Copy position from one rope to another - lufydad - 14-01-2022

To rephrase my question :

How can I disable physics calculation on a given obi solver while keeping the obi solver updating the positions of the rope when we set them from script ?

Code:
_obiSolver0.positions[i] = pos



RE: Copy position from one rope to another - josemendez - 14-01-2022

(14-01-2022, 09:52 AM)lufydad Wrote: To rephrase my question :

How can I disable physics calculation on a given obi solver while keeping the obi solver updating the positions of the rope when we set them from script ?

Code:
_obiSolver0.positions[i] = pos

Hi!

What you need in this case is for the renderers to keep updating the rope mesh as if the solver was being updated, but without updating the solver. This means taking control of the update cycle.

You can inherit from ObiUpdater to write your own updater component for this, or slightly modify one of the existing ones to add a "simulate" boolean flag. While this flag is inactive, call updater.Interpolate() but don't call BeginStep(), Substep() or EndStep(). This will trigger rendering updates as if the simulation was running.

Note that you can also deactivate simulation on a per-particle basis, by setting the particle inverse mass to 0 (see http://obi.virtualmethodstudio.com/manual/6.3/scriptingparticles.html):

Quote:Inverse mass for each particle. An inverse mass of 0 means the particle's mass is infinite, so its position will be unaffected by dynamics (allowing you to override it manually).

If you do this for all particles in a solver, most housekeeping stuff (updating internal spatial structures, updating constraints) will still be performed, so the performance gains are negligible compared to not updating the entire solver.


RE: Copy position from one rope to another - lufydad - 14-01-2022

(14-01-2022, 10:10 AM)josemendez Wrote: Hi!

What you need in this case is for the renderers to keep updating the rope mesh as if the solver was being updated, but without updating the solver. This means taking control of the update cycle.

You can inherit from ObiUpdater to write your own updater component for this, or slightly modify one of the existing ones to add a "simulate" boolean flag. While this flag is inactive, call updater.Interpolate() but don't call BeginStep(), Substep() or EndStep(). This will trigger rendering updates as if the simulation was running.

Note that you can also deactivate simulation on a per-particle basis, by setting the particle inverse mass to 0 (see http://obi.virtualmethodstudio.com/manual/6.3/scriptingparticles.html):


If you do this for all particles in a solver, most housekeeping stuff (updating internal spatial structures, updating constraints) will still be performed, so the performance gains are negligible compared to not updating the entire solver.

Thanks a lot it seems to work Gran sonrisa

I return on my problem of "teleportation" which reappeared (cf. the right rope on https://imgur.com/a/AZ3G4f8), do you have an idea where it may come from ?


RE: Copy position from one rope to another - josemendez - 14-01-2022

(14-01-2022, 02:17 PM)lufydad Wrote: Thanks a lot it seems to work Gran sonrisa

I return on my problem of "teleportation" which reappeared (cf. the right rope on https://imgur.com/a/AZ3G4f8), do you have an idea where it may come from ?

Not really, never have seen similar behavior. Looks close to what happens when the solver's sleep threshold is too high (particles move in a stop-motion fashion) but not quite the same.

Is the code you originally posted the same you're currently using to copy data from one solver to the other?


RE: Copy position from one rope to another - lufydad - 14-01-2022

(14-01-2022, 02:28 PM)josemendez Wrote: Not really, never have seen similar behavior. Looks close to what happens when the solver's sleep threshold is too high (particles move in a stop-motion fashion) but not quite the same.

Is the code you originally posted the same you're currently using to copy data from one solver to the other?

For the sleep threshold I use what you suggest in this post, therefore I don't think it's related. And yes I use the same code that the one in first question.


RE: Copy position from one rope to another - josemendez - 14-01-2022

(14-01-2022, 02:40 PM)lufydad Wrote: For the sleep threshold I use what you suggest in this post, therefore I don't think it's related. And yes I use the same code that the one in first question.

Which kind of ObiUpdater are you using? Fixed, LateFixed or Late? I see you're copying particle positions in LateUpdate(), but if you're also updating the simulation in LateUpdate() that's a problem because the order in which Unity calls these for different objects is undefined. It may cause you to copy positions before/after the simulation depending on the frame, giving rise to jitter.

This is just a shot in the dark though, I'd expect you to be using ObiFixedUpdater which is the default one. If this is not the culprit I'd need to take a look at the scene for further investigation. You can send it to support(at)virtualmethodstudio.com ad I'll take a closer look.


RE: Copy position from one rope to another - lufydad - 17-01-2022

(14-01-2022, 05:56 PM)josemendez Wrote: Which kind of ObiUpdater are you using? Fixed, LateFixed or Late? I see you're copying particle positions in LateUpdate(), but if you're also updating the simulation in LateUpdate() that's a problem because the order in which Unity calls these for different objects is undefined. It may cause you to copy positions before/after the simulation depending on the frame, giving rise to jitter.

This is just a shot in the dark though, I'd expect you to be using ObiFixedUpdater which is the default one. If this is not the culprit I'd need to take a look at the scene for further investigation. You can send it to support(at)virtualmethodstudio.com ad I'll take a closer look.

I'm indeed, using the ObiFixedUpdater.
I can't reproduce the bug in a separate project, so I'll keep looking on my side.

Thanks a lot anyway!