I have a soft body patch set up. I need to set it’s position more than once every frame, although I can make this once a frame. I have 2 anchors set and a wind velocity set.
Doing setPos on the NodePath outright doesn’t work. The soft body flies across the screen and the program crashes.
I’ve also tried making the anchors by appending 2 rigid bodies and moving those instead. The rigid bodies are kinematic and I’ve tried with them being static and dynamic. If I do that then the patch moves but the simulation moves the anchors slightly as part of it’s work, and so the patch vibrates a lot as it flickers between my position and the position set by bullet. I’ve tried adding constraints to these as well.
The same thing happens if I try to move the geometry node (whether or not it’s a child of the soft body node).
I’ve also tried putting the soft body in a container NodePath and setting that position but that results in the same thing as setting the position directly. Putting rigid body anchors in a NodePath is the same as setting their positions directly as well.
How can I move this soft body?
If it would help if I made a test case then just ask. Thanks for any help you can give
I checked in a fix, which hopefully fixes handling of soft body transforms in a better way. I tried to be smart again, though I am not 100 percent sure I have considered every possible case.
The reason why this is a bit tricky is that I try to map Panda3D node pos to the approximate center of the soft body bounding box. And Bullet knows only about the initial transform of a soft body.
If it turns out that we run into more problems with trying to be smart I will fall back to binding the Panda3D node pos to the Bullet initial transform.
The flag on the left is using default bullet anchors, where a specific node on the soft body patch is set to static (ie mass is 0) by bullet in lines 572-575 of bullet/src/BulletSoftBody/btSoftBodyHelpers.cpp for bullet 2.82. The flag is moved by setting the position of the flag directly.
The flag on the right is using rigid bodies attached as anchors. It is being moved by moving the rigid bodies of the anchors themselves. It shows when I mean by the vibrating and is what I’m using currently.
As you move the flags up and down with the arrow keys the flag on the left gets more and more distorted.
All of the commented out code more closely resembles when I’m actually using in my game but is commented to make the test case simpler.
I thinkthe right side works as expected. The linked rigid bodies get moved, and pull the soft body along. It is expected that the soft body gets streched (temporary) when it is pulled around.
The left side however is not ok. The deformation of the soft body should not happen. I looked at our own sources and the Bullet sources, but so far I don’t see what exactly is going wrong. This problem will be tricky to track down.
I found the problem which causes the distortion after translating a soft body with links.
When the PandaNode’s transform changes we call into Bullet using the btSoftBody->translate function. This funtion in turn calls btSoftBody::updateConstants which calls btSoftBody::resetLinkRestLengths. This method resets the rest length of all links based on their CURRENT state.
This means if a soft body link is currently not in it’s initial state but e.g. a bit stretched because the soft body hangs down from a point (you case) then after calling translate the link will be “longer”. Each following call will make it longer and longer. Exactly what we observe in your sample.
No plan yet what to do about this problem, but I keep this problem on my todo list for the next days.
Seems like this is going to be a deadend. “teleporting” soft bodies seems to be something not supported by Bullet itself. My advice would be to do such jumps only when absolutely necessary, and then destroy the soft body and recreate it at a different position.
That’s no problem. I think it makes more sense to move soft bodies by their anchors anyway. I can’t think of any cases where moving the soft body directly would result in something more realistic than moving it’s anchors.
I the only other option I can think of is making setPos move the anchored nodes directly (when using the default bullet anchors) but I don’t know how nicely this would integrate into Panda.
I just wanted to point out one thing which is - in my eyes - important when dealing with physics, no matter what engine used (internal, ODE, Bullet, PhysX). The two approaches are very very different:
The first one (pulling the soft body using bodies) is a natural thing for a physics simulation. It is similar to pushing a rigid body using forces. It is something which happens in the real world too. No physics laws are violated.
The second on (just setting a new transform for a soft/rigid body) is not. It is a teleportation, and would never happen in the real world (at least at macroscopic scale - we are not talking about quantum physics for games!). Physics laws would get violated. For a physics simulation such a teleportation means a lot of work to do. All the internal state of an object needs to be updated, or better re-created from scratch (jus thing about the contact information, or pre-calculated information about movement). Overwriting information like position/orientation/speed/… during an simulation is something which should be used only in rare cases. For example a “teleport” magic spell, or recovering a player/vehicle from a stuck position. For such rare cases the destruction and re-creation of the physics object is often a reasonable workaround if not the preferred way.