Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Scripting rod forces
#21
(Yesterday, 09:39 AM)Qriva0 Wrote: Yeah, I tried both methods. The problem is that I don't move rod by pressing the keyboard arrow, but I try to keep it in sync with some depth value - for instance it's 10 meters at some point, but several frames later it will be 11 and rod should reflect that by moving 1m forward. There are two problems with that.

I'm not sure what the difference would be between using the keyboard or driving motion by using a value. Do you mean the value changes in a non-smooth way, as it may suddenly jump from 10 to 11 in a single frame?

(Yesterday, 09:39 AM)Qriva0 Wrote: First one is pullback. I don't want my cable to go back on collision

I'm not sure what you mean by "pullback" or "going back on collision".

(Yesterday, 09:39 AM)Qriva0 Wrote: and that is the reason why I tried to "pin" particle - to disallow pullback from tension.

If by "pullback" you mean the rope snapping back to its rest length when one particle is moved far away from its current position in a single frame, that's the physically accurate way for the rope to react: the force applied to one particle propagates trough the rope over time and results in a pullback effect, the speed of the propagation will be faster the more iterations/substeps you use, but will never be instantaneous.

If you move one particle X meters, it wouldn't make any sense for the entire rope to suddenly *teleport* X meters away: that just doesn't happen in the real world.

(Yesterday, 09:39 AM)Qriva0 Wrote: I guess I would need to change approach to moving rod particle by invisible line, something like softbody dragon demo?

That's just using a spring force (F = -kx, where k is stiffness and x distance)  to move a particle. Still counts as modifying the particle's velocity which I think is what you were originally doing?

(Yesterday, 09:39 AM)Qriva0 Wrote: I wanted, but that causes a lot of not physical things to happen, jitters or breaking constraints. Does pinhole do that actually? I think it does not.

Pinholes just adjust the position of the particle, and then calculate the resulting change in velocity as newPosition-oldPosition/dt. All dynamic constraints in Obi work this way. Kinematic constraints (such as fixed attachments) just change the position, but keep velocity = zero.

(Yesterday, 09:39 AM)Qriva0 Wrote: In my case rod is some kind of stiff cable and when I pull it I need the whole thing to move at the same time.
You know, when you pull a plastic cable in reality it does not strech much, but the whole length moves at the same time.

Yes, I think I understand but there's bad news: This is simply not doable.

The reason is that in the real world, time is a continuous quantity, which is the same as saying the timestep/delta time is infinitely small (in Obi that would mean using infinite substeps).

If an infinitely stiff material existed, forces would propagate trough it at infinite speed, requiring infinite computational resources to simulate them. However, there's no such thing as an infinitely stiff material in reality: all materials have finite stiffness, that results in a specific speed of sound for that material - the speed at which molecules vibrate and transfer force along the material. This is the speed at which force propagates trough the material. Despite not being infinite, for very stiff materials this is an *extremely* high speed that still needs a huge amount of computational resources to be accurately simulated.

Now, Obi is an iterative solver and that means it propagates forces by repeating the process of spreading them out from one particle (roughly == molecule) to the next over many iterations. There's another family of solvers that try to directly calculate what the state of the system will be in the next timestep, called direct solvers (in Obi, chain constraints implement this). The problem with direct solvers is that their base cost is much higher than that of iterative solvers, and that they may return nonsense if they can't find a solution to the system (overconstrained system) or if there's multiple solutions (underconstrained system).

All existing physics engines face the same fundamental difficulty: for instance if you stack boxes in any rigidbody engine (you can try Unity's), the taller the stack the more wobbly/bouncy it becomes - as forces cannot propagate fast enough up the stack. You'd need a smaller fixed timestep or more velocity iterations to improve this, increasing the computational cost of the solution.

In general: the more individual "units of matter" you need to propagate force trough, and the higher the stiffness of the matter, the more computational resources you need. For Obi, this means that ropes/rods with more particles in them (longer, or higher resolution) and zero compliance (== infinite stifness) require more substeps/iterations to be accurately simulated.

(Yesterday, 09:39 AM)Qriva0 Wrote: My current solution do this problem is adding forces along the rope (according to particle orientations), not perfect, but definitely better than nothing. However I still  wonder if there is anything else I could do.

What you're trying to accomplish with this is to simulate the effect of faster force propagation, but just adding some ad-hoc extra force to all particles in the rope. It's as good as you can do without switching to much more computationally intensive methods.

Another "hack" that many games use is to just constrain particles to be within some distance of an attachment point, in an attempt to simulate instant propagation of forces - however this won't work well for non-straight ropes involving collisions. Obi Cloth features such a solution for cloth in the form of tether constraints.

kind regards,
Reply
#22
(Yesterday, 10:25 AM)josemendez Wrote: I'm not sure what the difference would be between using the keyboard or driving motion by using a value. Do you mean the value changes in a non-smooth way, as it may suddenly jump from 10 to 11 in a single frame?

Not such a big difference, but yes. My point is that it's not like I press some key and it moves rod with undefined speed/distance and it does not matter where it ends, but instead there is input that has exact values and the idea is that rod must adjust to those numbers and move to provided place and stay in sync. Obviosuly it does not matter from where this input comes, I can create variable where Time.deltaTime is added when key is pressed and result is the same, the only point is that rod should stay in sync with that value, so when I push rod for 1s, then pull for 1s it ends up in starting position.

(Yesterday, 10:25 AM)josemendez Wrote: If by "pullback" you mean the rope snapping back to its rest length when one particle is moved far away from its current position in a single frame, that's the physically accurate way for the rope to react: the force applied to one particle propagates trough the rope over time and results in a pullback effect, the speed of the propagation will be faster the more iterations/substeps you use, but will never be instantaneous.

By pullback I mean anything that causes rod to move back after I stop adding forces to it. For example bend caused by hitting an obstacle and returning to rest shape. Yes it's natural, but when I push rod via velocity, then hitting obstacle will stop rod, while my input depth still goes up. That simply descyncs rod with input, so I need to either pin particle to certain position (but that breaks physics) or use velocity method with offset (like spring) to account for difference between current and actual input depth. (by depth I mean how far rod is pushed)

(Yesterday, 10:25 AM)josemendez Wrote: That's just using a spring force (F = -kx, where k is stiffness and x distance)  to move a particle. Still counts as modifying the particle's velocity which I think is what you were originally doing?

Yes, but the difference is that previously I just added force equal to movement delta, while spring (or similar method) will pull particle towards desired position, but without breaking the simulation I guess? Because I don't teleport or force rod into colliders, but push it in physical way. At least this is how I understand this.
By the way as I mentioned before about exposing job handle, that would be actually nice if there was additonal event for each substep exposing job handle.

(Yesterday, 10:25 AM)josemendez Wrote: Yes, I think I understand but there's bad news: This is simply not doable.

The reason is that in the real world time is a continuous quantity, which is the same as saying the timestep/delta time is infinitely small (in Obi that would mean using infinite substeps).

If an infinitely stiff material existed, forces would propagate trough it at infinite speed, requiring infinite computational resources to simulate them. However, there's no such thing as an infinitely stiff material in reality: all materials have finite stiffness, that results in a specific speed of sound for that material - the speed at which molecules vibrate and transfer force along the material. This is the speed at which force propagates trough the material. Despite not being infinite, for very stiff materials this is an *extremely* high speed that still needs a huge amount of computational resources to accurately simulate.

Now, Obi is an iterative solver and that means it propagates forces by repeating the process of spreading them out from one particle (roughly == molecule) to the next over many iterations. There's another family of solvers that try to directly calculate what the state of the system will be in the next timestep, called direct solvers (in Obi, chain constraints). The problem with direct solvers is that their base cost is much higher than that of iterative solvers, and that they may return nonsense if they can't find a solution to the system (overconstrained system) or if there's multiple solutions (underconstrained system).

All existing physics engines face the same fundamental difficulty: for instance if you stack boxes in any rigidbody engine (you can try Unity's), the taller the stack the more wobbly/bouncy it becomes - as forces cannot propagate fast enough up the stack. You'd need a smaller fixed timestep or more velocity iterations to improve this, increasing the computational cost of the solution.
I am aware it is not doable to replicate real behaviour, this is why I wonder if there are some hacks to improve it, even if it's not actually very realistic.

(Yesterday, 10:25 AM)josemendez Wrote: What you're trying to accomplish with this is to simulate the effect of faster force propagation, but just adding some ad-hoc extra force to all particles in the rope. It's as good as you can do without switching to much more computationally intensive methods.

Another "hack" that many games use is to just constrain particles to be within some distance of an attachment point, in an attempt to simulate instant propagation of forces - however this won't work well for non-straight ropes involving collisions. Obi Cloth features such a solution for cloth in the form of tether constraints.
Yeah I considered something like that, but as you said it's not good for bending rods, this is why I tried to do something similar, but along particle orientations.
Sooo, I guess there is not much I can do about this, except decreasing number of particles.
Reply
#23
(Yesterday, 11:48 AM)Qriva0 Wrote: Yes it's natural, but when I push rod via velocity, then hitting obstacle will stop rod, while my input depth still goes up.

That simply descyncs rod with input, so I need to either pin particle to certain position (but that breaks physics) or use velocity method with offset (like spring) to account for difference between current and actual input depth. (by depth I mean how far rod is pushed)

I still think I don't understand your use case at all... if you just want to make the rod follow input "depth" (whatever that may mean in your game) while following physics, calculating and adding an acceleration is the proper way to do it.

(Yesterday, 11:48 AM)Qriva0 Wrote: Yes, but the difference is that previously I just added force equal to movement delta

If you literally mean force = movement delta, it doesn't make any sense: F = ma, so the resulting acceleration depends on mass. Depending on the mass of your rod, using movement delta as a force could result in an absurdly high (or low) acceleration.
What you want is to use movement delta to calculate acceleration regardless of mass - that is, a spring.

Using a damped spring will typically give better results as it avoids overshooting, and it's not much more complicated to implement: just subtract current velocity times some "damping" parameter: F = -kx-vd, or F = stiffness * (current pos - desired pos) - velocity * damping.

kind regards
Reply
#24
(Yesterday, 12:06 PM)josemendez Wrote: I still think I don't understand your use case at all... if you just want to make the rod follow input "depth" (whatever that may mean in your game) while following physics, calculating and adding an acceleration is the proper way to do it.

You are right, maybe my last example was just bad.
Consider rod controlled by some input number - starts with 0, then over time goes to 5. Every update rod velocity is upated to: inputDelta / dt.
After traveling 3 meters rod hits the wall, in result force is applied, but wall stops it from moving. In the end desired input was 5, while rod stopped at 3.
Then I pulled rod back to 0 (via input) and in result rod will end up in -2. This is the second setup I had (first one was just simple rigidbody attachment) and to fix that problem I still tried to move one particle to desired position - it worked similary to static attachment, but that obviously forces rod into unstable state.
But I noticed this approach is simply wrong and I need different solution.

(Yesterday, 12:06 PM)josemendez Wrote: If you literally mean force = movement delta, it doesn't make any sense: F = ma, so the resulting acceleration depends on mass. Depending on the mass of your rod, using movement delta as a force could result in an absurdly high (or low) acceleration.
What you want is to use movement delta to calculate acceleration regardless of mass - that is, a spring.

Using a damped spring will typically give better results as it avoids overshooting, and it's not much more complicated to implement: just subtract current velocity times some "damping" parameter: F = -kx-vd, or F = stiffness * (current pos - desired pos) - velocity * damping.
Overriding velocity ignores mass of particle, and when I used external forces I divided force by mass inversed to account that. The problem with controling velocity was that I use huge solver damping and result is affected by that.
In any case I talked about previous setup, and it was not spring, but plain (velocity+= or velocity=).
Reply
#25
(Yesterday, 01:40 PM)Qriva0 Wrote: You are right, maybe my last example was just bad.
Consider rod controlled by some input number - starts with 0, then over time goes to 5. Every update rod velocity is upated to: inputDelta / dt.

If you mean velocity = inputDelta / dt, that's wrong (as you figured out). This will just move the object a specific amount relative to its current position, while ignoring changes in velocity due to any other sources (accelerations, forces, etc). A spring will do what you're looking for which is to move it towards an absolute position, while respecting physics.

(Yesterday, 01:40 PM)Qriva0 Wrote: Overriding velocity ignores mass of particle, and when I used external forces I divided force by mass inversed to account that.

That's the same as doing velocity += value * time.

(Yesterday, 01:40 PM)Qriva0 Wrote: The problem with controling velocity was that I use huge solver damping and result is affected by that.
In any case I talked about previous setup, and it was not spring, but plain (velocity+= or velocity=).

Damping reduces velocity in the simulation every timestep, so that it tends to be zero after some time. This should be easy to overcome by just increasing the stiffness of your spring force.
Reply