Don't mind the mess!
We're currently in the process of migrating the Panda3D Manual to a new service. This is a temporary layout in the meantime.
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 segment (variable
res), and thus 8 + 2 = 10 nodes.
p1 is the initial position of the first node, and
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 curse, 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
Geom each frame. This is done in the last line, by linking the geom to the soft body node.
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
NurbsCurveEvaluator. For 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
fixeds parameter 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())