Bullet Softbody Rope
Soft body ropes are best compared to chains of interconnected nodes. This page deals with setup, visualization and attaching things to soft body ropes.
The following code will create a soft body rope with 8 segments (variable
res), and thus 8 + 2 = 10 nodes.
p1 is the initial position of the first
p2 is the initial position of the last node.
fixeds will be
explained later on this page.
from panda3d.bullet import BulletSoftBodyNode info = self.world.getWorldInfo() info.setAirDensity(1.2) info.setWaterDensity(0) info.setWaterOffset(0) info.setWaterNormal(Vec3(0, 0, 0)) res = 8 p1 = Point3(0, 0, 4) p2 = Point3(10, 0, 4) fixeds = 0 bodyNode = BulletSoftBodyNode.makeRope(info, p1, p2, res, fixeds) bodyNode.setTotalMass(50.0) bodyNP = worldNP.attachNewNode(bodyNode) world.attachSoftBody(bodyNode)
So far we have a physical object, the soft body rope, but aside from the debug renderer this object is not shown in our scene. We need something to visualize the rope.
There are two ways of rendering the rope. First we can make use of a NURBS curve, or we can simple render the rope using geom lines. First we have a look at how to render the rope using geom lines.
from panda3d.core import GeomNode geom = BulletHelper.makeGeomFromLinks(bodyNode) visNode = GeomNode('') visNode.addGeom(geom) visNP = bodyNP.attachNewNode(visNode) bodyNode.linkGeom(geom)
BulletHelper has a convenience method which creates a ready-to-use
Geom for us. We only need to wrap the
Geom in a
GeomNode, and insert
it into the scene graph. Since we want the visualisation of the rope to be at
the same place as the rope we insert the
GeomNode as a child of the
There is just one thing missing. The
GeomNode doesn’t know that it is the
visualization of a soft body rope. When advancing the simulation time the soft
body rope will deform, but the visualization will always stay the way it has
been created. To fix this we can tell the soft body node that this particular
Geom is it’s visualization. The soft body node will now update the
each frame. This is done in the last line, by linking the geom to the soft body
The result doesn’t look very good. It’s just a thin line. But instead of the above code we can use a NURBS curve for visualization.
from panda3d.core import RopeNode from panda3d.core import NurbsCurveEvaluator curve = NurbsCurveEvaluator() curve.reset(res + 2) bodyNode.linkCurve(curve) visNode = RopeNode('') visNode.setCurve(curve) visNode.setRenderMode(RopeNode.RMTube) visNode.setUvMode(RopeNode.UVParametric) visNode.setNumSubdiv(4) visNode.setNumSlices(8) visNode.setThickness(0.4) visNP = self.worldNP.attachNewNode(visNode) visNP.setTexture(loader.loadTexture('some_texture.jpg'))
First we create a nurbs curve (
NurbsCurveEvaluator), and then we link this
nurbs curve to the soft body rope node. The soft body node will update the nurbs
curve every frame from now on.
But we are not done yet. We still need to create something that can be seen in
the scene graph. A
RopeNode can render a
details on how to configure the
RopeNode please refer to the Panda3D API
documentation; both the
RopeNode and the
NurbsCurveEvaluator are not
part of the panda3d.bullet, but core Panda3D classes.
Attaching the rope
Now we have created a rope, and we can render it. Next we want to attach the rope to something, that is “glue” it either to some other object, usually a rigid body, or to a specific position of the world.
At the beginning of this page we promised to deal with the
later on the page. This is the place. Using the
fixeds parameter we can
attach the rope to a position in the world (global coordinates!). Depending on
the value of this parameter we can attach different nodes/vertices of the rope:
0: No node/vertex is attached.
1: Only the first node/vertex is attached.
2: Only the last node/vertex is attached.
3: Both the first and the last node/vertex are attached.
Or we want to attach the soft body rope to a rigid body. In the following code snippet the last node/vertex of a soft body rope is attached to a rigid body.
# NodePath for some BulletSoftBody "rope" softNP = ... # NodePath for some BulletRigidBody rigidNP = ... # Index of the last node of the rope idx = softNP.node().getNumNodes() - 1 # Attach the last node of the rope with the rigid body softNP.node().appendAnchor(idx, rigidNP.node())