Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Getting/Setting Particle Positions on Runtime
#1
Greetings,

I'm looking to create a system that will allow me to tangle some ropes in runtime and then be able to recreate that tangling. My logic is to get the position of the particles, store them and then use them to re-position the particles of that rope later on.

My approach ivolves actor.GetParticlePosition(solverIndex), which, as stated in the post mentioned bellow, returns the renderable positions. I'm able to see results tho, but the ropes, altohugh they tangle the way they supposed to, they move to some other position and then return to their repsective handles, untying themselfs (I have the start and end partcile attached to an object so I can move the rope from one end, while the other remains stationary)

I found this post http://obi.virtualmethodstudio.com/forum...ad-50.html which pretty much wanted to do the same thing (although I'm not involving any networking in the proccess), the problem is tho that I can't seem to get particles' position data from Oni like this
 
Code:
Oni.GetParticlePositions(ObiRope.Solver.OniSolver, particlePositions, ObiRope.UsedParticles, ObiRope.particleIndices[0]);

since the GetParticlePositions is not present in the Oni class. I'm using v5.3 of Obi rope.

I'm I searching on the wrong path, or am I missing something essential here due to inexperince.

Thanks in advance,
Jackson.
Reply
#2
Hi there,

The manual explains how to get/set any particle property, including position:
http://obi.virtualmethodstudio.com/tutor...icles.html

The post you linked is quite outdated, and refers to Obi 2 or 3. You can now directly read/write from/to the solver data arrays (solver.positions, solver.velocities, solver.invMasses, etc), there's no GetParticleX() functions.

cheers,
Reply
#3
Hey there, thanks for the reply.

I've read the article (should have mentioned it I suppose xD), and I can indeed tangle the ropes, but the ropes move from their attachments and return to them a frame later.

Here's the code for storing the positions (I store them in a scriptable object)
Code:
void StoreRopeParticles(GameObject rope)
    {

        List<Vector3> particlePos = new List<Vector3>();
        ObiActor actor = rope.GetComponent<ObiActor>();
        int solverIndex;

        for (int i = 0; i < actor.particleCount; i++)
        {
            solverIndex = actor.solverIndices[i];
            particlePos.Add(actor.GetParticlePosition(solverIndex));
        }

        RopeParticlePosition newRope = new RopeParticlePosition(rope, particlePos);

        ropePositionsSO.StoreData(newRope);
    }

And here is the code that applies the stored position
Code:
void InitializeParticles(RopePositionsSO particlesPosition)
{
   foreach (RopeParticlePosition positions in particlesPosition.ropePositions)
   {
    if(positions.ropeID == RopeID)
        {
            ObiActor actor = GetComponent<ObiActor>();
        int solverIndex;

        for (int i = 0; i < actor.solverIndices.Length; i++)
        {
            solverIndex = actor.solverIndices[i];
            actor.solver.positions[solverIndex] = positions.particlePositions[i];
            }
        }
        }
}

.png   Ropes Tangle.PNG (Size: 55.28 KB / Downloads: 30)
Ropes Tangle

.png   Ropes return.PNG (Size: 27.73 KB / Downloads: 30)
Ropes Return to attachments
Reply
#4
Hi!


All particle properties are expressed in solver space. The documentation for actor.GetParticlePosition() reads:

Quote:Given a solver particle index, returns the position of that particle in world space.

So it's basically a convenience function for when you need world space positions for direct rendering or something similar.

If you retrieve the particle positions in world space, but later apply them as if they were expressed in the solver's local space, problems like the one you're experiencing may happen Sonrisa.

Either retrieve the position by reading it from solver.positions directly (without any conversion to world space), or -if you want to use GetParticlePosition()- convert them back to solver space when applying the stored positions back.
Reply
#5
Well that's embarrassing xD

Was looking on the end of the proccess while the problem was in the start. Just replaced actor.GetParticlePosition(solverIndex) with actor.solver.positions[solverIndex].

Thank you very much!
Reply
#6
(23-09-2020, 09:39 AM)Jackson Wrote: Well that's embarrassing xD

Was looking on the end of the proccess while the problem was in the start. Just replaced actor.GetParticlePosition(solverIndex) with actor.solver.positions[solverIndex].

Thank you very much!

No worries! dealing with vector spaces is always a headache. Glad you got it working! Sonrisa
Reply