Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Setting velocity to 0
#1
Hello

I am trying to set the velocity of cloth particles to 0 so that there is no more movement with the following code:

Code:
ObiNativeVector4List velocities = actor.solver.velocities;
ObiNativeVector4List angularVelocities = actor.solver.angularVelocities;
ObiNativeVector4List forces = actor.solver.externalForces;
ObiNativeVector4List torques = actor.solver.externalTorques;
           
    for (int i = 0; i < actor.solverIndices.count; i++)
    {
        int solverIndex = actor.solverIndices[i];
        velocities[solverIndex] = Vector3.zero;
        angularVelocities[solverIndex] = Vector3.zero;
        forces[solverIndex] = Vector3.zero;
        torques[solverIndex] = Vector3.zero;
    }
actor.UpdateParticleProperties();

I execute this code once a certain action occurs in the game.
It works when damping is set to 0.5 but when I reduce the damping I see particles start to move again.
Can you point me in the right direction and verify if I am using the right code to do the job?

Thanks
Aroosh
Reply
#2
(06-12-2025, 09:37 PM)Aroosh Wrote: Hello

I am trying to set the velocity of cloth particles to 0 so that there is no more movement with the following code:

Hi Aroosh,

Setting the velocity of an object to zero won't keep it from moving: it will just get rid of momentum, but if there's any forces/accelerations acting upon the object (such as gravity, for example), the object will immediately continue moving. This is true both in the real world as well as any physics engine.

If you want an object to stop moving, you want the make sure no force/acceleration can affect them. This is done by giving it infinite mass, which in Obi is done by setting the particle's inverse mass to zero as explained in the manual. Setting external forces/torques to zero does absolutely nothing since these are external to the simulation - forces you want to add to the simulation, but things like gravity will still affect the particles.

Also note that cloth particles don't use any rotational information (only softbody and rod particles do) so torques and angular velocities aren't playing any role here either.

Code:
           
    for (int i = 0; i < actor.solverIndices.count; i++)
    {
       int solverIndex = actor.solverIndices[i];
        actor.solver.velocities[solverIndex] = Vector3.zero;
        actor.solver.invMasses[solverIndex] = 0;
    }

(06-12-2025, 09:37 PM)Aroosh Wrote: It works when damping is set to 0.5 but when I reduce the damping I see particles start to move again.

This is because a high damping factor will keep the particle's kinetic energy below the solver's sleep threshold, putting the particle to sleep.

kind regards,
Reply
#3
Hello Jose,

I appreciate the prompt response to my query. 
I understand that setting the inverse mass to 0 would ensure that particles are not being affected by forces/accelerations acting upon the object, hence freezing the particles. 
That would also mean that the next time there are forces/accelerations applied to the object, the particles will stay frozen until I explicitly set the inverse mass to a non 0 value.

That being said, a better way to frame my question would be is there any way I can access the data structure holding the forces/accelerations so I can explicitly set them to 0?
Note: I ensure that gravity and ambient wind are both set to 0 when running the sim.

I see. That makes sense why increasing damping will stop the particles from moving. Thanks for clarifying that!

Thanks
Aroosh
Reply
#4
(08-12-2025, 12:12 AM)Aroosh Wrote: Hello Jose,

I appreciate the prompt response to my query. 
I understand that setting the inverse mass to 0 would ensure that particles are not being affected by forces/accelerations acting upon the object, hence freezing the particles. 
That would also mean that the next time there are forces/accelerations applied to the object, the particles will stay frozen until I explicitly set the inverse mass to a non 0 value.

Correct. The usual way to do this is to store the inverse mass of the particle in a helper variable, and set the inverse mass to zero. Then once you want the particle to resume movement, set it back to the value stored in the helper variable.

(08-12-2025, 12:12 AM)Aroosh Wrote: That being said, a better way to frame my question would be is there any way I can access the data structure holding the forces/accelerations so I can explicitly set them to 0?

You could find *all* constraints affecting the particle(s) and disable them. This is considerably more complex (and costly) than dealing with the particle's inverse mass, though, as it involves iterating trough every constraint in every batch of every type of constraint and find those that reference a specific particle. Let me know if you need help with this.

Kind regards,
Reply
#5
(08-12-2025, 09:24 AM)josemendez Wrote: Correct. The usual way to do this is to store the inverse mass of the particle in a helper variable, and set the inverse mass to zero. Then once you want the particle to resume movement, set it back to the value stored in the helper variable.


You could find *all* constraints affecting the particle(s) and disable them. This is considerably more complex (and costly) than dealing with the particle's inverse mass, though, as it involves iterating trough every constraint in every batch of every type of constraint and find those that reference a specific particle. Let me know if you need help with this.

Kind regards,

Hello

First of all I want to apologize for the late reply.

I would indeed love some help in writing a function which would find *all* constraints affecting particle(s) and disable them. I would outline the capabilities I would like out of the function below.

I would like a function that I can call at an arbitrary frame which would preserve the current positions but will clear the velocities given there are no collisions happening so that the particle(s) do not move until and unless external stimulus is applied to them again which could be collision/gravity/wind etc.

Please let me know what I can do to be of service for this.

Thanks and Happy Holidays!
Aroosh
Reply
#6
(20-12-2025, 01:06 AM)Aroosh Wrote: 你好!

首先,很抱歉回复晚了。

我非常需要你的帮助,编写一个函数来查找并禁用所有影响粒子的约束。以下是我对该函数功能的简要说明。我希望这个函数

可以在任意帧调用,它能够保留粒子的当前位置,但清除速度值(假设没有发生碰撞),这样粒子就不会移动,直到再次受到外部刺激(例如碰撞、重力、风等)。

请告诉我我能做些什么来帮助你完成这项工作。

谢谢!祝你节日快乐!
Aroosh
You probably can just set Sleep threshold to a large value and set it to 0 when you need
Reply
#7
(20-12-2025, 01:06 AM)Aroosh Wrote: I would like a function that I can call at an arbitrary frame which would preserve the current positions but will clear the velocities given there are no collisions happening so that the particle(s) do not move until and unless external stimulus is applied to them again which could be collision/gravity/wind etc.

I’m not sure I understand, what you describe is accomplished using what I assume is yout original code:

solver.velocities[index] = Vector4.zero;

Note that external stimulus is usually applied every frame (gravity for instance), so the particle would immediately start moving again after calling this function unless it’s in a vacuum, zero gravity environment.

In case you’re already removed all external stimulus (zero gravity, zero wind, zero inertial forces, etc) then this code should do what you’re after.
Reply
#8
I am confused too, but I think problem comes from the fact you misunderstood how forces inside simulation work.

Constraints can generate velocities. For example if you set velocity to 0 of two particles, those particles are connected with distance constraint and it's not met (rest distance is 1, but current distance is 0.5), then velocity will be generated from moving particles to meet that constraint. This is why drag stops your particles, because it cuts velocity every frame, not just once.
To get your desired behaviour you would need to disable constraints and all forces (what actually might be not what you want) or make them super heavy, but both cases has been already mentioned and explained.

I guess it might be not possible to directly get what you want, and make it work in every possible case in efficient way.
Reply