Bullet Softbody Cape/Cloth?

Hi,
I have this urgent(-ish) need to make a character with a superhero-like cape, that will react dynamically to the motion of the character.

I’m wondering if I can use Bullet for this task, and since I never used it before, and the samples/manual doesn’t deal directly with this topic I’ve got some questions:

1.Can I ‘pin’ some select vertex of a SoftbodyTriMesh to a character(actor) joint that will be moved not by Bullet forces but with animations and/or setPos setHpr methods of the actor node?

  1. What’s the proper way of making a SoftbodyTriMesh from an existing model if you later want to use that model to visualize the simulation?

  2. How do you add forces to simulate global wind, blowing in one direction or an explosion blast coming from one point and going in all directions at once?

I can’t believe that this should be that difficult to do, I’ve seen thing like this in games that are now 10 years old.

Thanks in advance for any answers and code samples :wink:

I’ve managed to come up with something more or less working:

import direct.directbase.DirectStart

from direct.showbase.DirectObject import DirectObject
from panda3d.core import *
from panda3d.bullet import *

class Game(DirectObject):

  def __init__(self):
    base.setFrameRateMeter(True)

    base.cam.setPos(0, -40, 10)
    base.cam.lookAt(0, 0, 0)

    # Light
    alight = AmbientLight('ambientLight')
    alight.setColor(Vec4(0.5, 0.5, 0.5, 1))
    alightNP = render.attachNewNode(alight)

    dlight = DirectionalLight('directionalLight')
    dlight.setDirection(Vec3(5, 0, -2))
    dlight.setColor(Vec4(0.7, 0.7, 0.7, 1))
    dlightNP = render.attachNewNode(dlight)

    render.setLight(alightNP)
    render.setLight(dlightNP)
    
    self.worldNP = render.attachNewNode('World')
    #track
    track = loader.loadModel('track.egg')
    track.reparentTo(render)    

    self.world = BulletWorld()
    self.world.setGravity(Vec3(0, 0, -9.81))    
    
    # Soft body world information
    info = self.world.getWorldInfo()
    info.setAirDensity(1.2)
    info.setWaterDensity(0)
    info.setWaterOffset(0)
    info.setWaterNormal(Vec3(0, 0, 0))
    
    #load the cape model
    geom = loader.loadModel('cape2.egg') \
        .findAllMatches('**/+GeomNode').getPath(0).node() \
        .modifyGeom(0)        
    geomNode = GeomNode('')
    geomNode.addGeom(geom)      
    node = BulletSoftBodyNode.makeTriMesh(info, geom) 
    node.linkGeom(geomNode.modifyGeom(0))
    
    #material and properties setup
    node.getMaterial(0).setLinearStiffness(0.1)
    node.getCfg().setDynamicFrictionCoefficient(1)
    node.getCfg().setDampingCoefficient(0.1)
    node.getCfg().setPressureCoefficient(0.1)
    node.setTotalMass(150, True)

    softNP = self.worldNP.attachNewNode(node)
    self.world.attachSoftBody(node)
    geomNP = softNP.attachNewNode(geomNode)
    
    #pin it down    
    self.pin = self.worldNP.attachNewNode(BulletRigidBodyNode('pin')) 
    softNP.node().appendAnchor(softNP.node().getClosestNodeIndex(Vec3(11.91, -9.057, 30.947), True), self.pin.node())
    softNP.node().appendAnchor(softNP.node().getClosestNodeIndex(Vec3(11.955, 5.175, 30.992), True), self.pin.node())

    # Task
    taskMgr.add(self.update, 'updateWorld')


  def update(self, task):
    dt = globalClock.getDt()
    #move the pin
    self.pin.setX(self.pin, dt*10.0)
    #do magic!
    self.world.doPhysics(dt, 10, 0.004)
    return task.cont

game = Game()
run()

But I still got some problems:
-The original cape model has a texture, with the cloth sim it has not

-Pining the vertex by giving their position in space is a bit troublesome but if there’s no other way I can live with that. I could mark them with a color in the model editor and make some sort of parser or something.

-The properties of the softbody are voodoo magic to me. Is there somewhere a list of these properties that is readable for mere mortals? All I found is this: panda3d.org/manual/index.ph … ody_Config but terms like ‘rigid impulse split’ and ‘Dynamic friction coefficient’ are gibberish to me. I’d rather know what I need to change to make the sofbody behave more like a rubber or more like cotton fluff.

-I really have no idea how to add wind and other forces to all this. I found a ‘addForce’ method that takes a Vec3 but I don’t get the concept of how to use it.

Can’t get this to work properly :cry:

The only properties that make a difference are:
node.getMaterial(0).setLinearStiffness(0.5)
node.getCfg().setDampingCoefficient(0.5)
node.getCfg().setPoseMatchingCoefficient(0.2)

The cloth behaves as if it was weightless as soon as the character moves it lifts up and refuses to float down once the character stops (the pose matching mechanism kind of lerps it into the ‘at rest’ pose).

I’ve tried setting the gravitation, mass, air density, drag, drift, lift, dynamic friction, and pressure coefficiency, total density and volume density all stating from tiny values (0.0000001) all the way to 1.0 or some very high value (100000000000) with no visible changes at all!

I’ve parented the anchors to a exposed joint, but they don’t move with it, I have to copy the pos and hpr each frame from the parent to the child.

I’ve also parented a capsule to one of the joints called .setCollideMask(BitMask32.allOn()) on it, but it doesn’t look like it’s affecting the cloth in any way.

I’ve set up a repository with my code here:
github.com/wezu/cloth_sim

If someone could take a look at it and tell me how to get it working properly I’d be very grateful.