I have a 3D tube, and there are two rope inside the tube. For example,
The two red color indicates the rope. Then, I pull rope b
, and the tube would be bend.
Intuitively, I think the tube would bend into a arc. I want to know how to simulate this situation?
I have tried to use multiple cylinder to simulate this situation, and the pull
actoin is simulated as a force on the top of tube. My simulation code is:
import direct.directbase.DirectStart
from panda3d.core import Vec3, TransformState, Point3, BitMask32, LPoint3, LVector3, Material
from panda3d.bullet import BulletWorld, BulletDebugNode, BulletCylinderShape
from panda3d.bullet import BulletPlaneShape, BulletSphericalConstraint, BulletConeTwistConstraint
from panda3d.bullet import BulletRigidBodyNode, BulletTriangleMesh, BulletTriangleMeshShape
from panda3d.bullet import BulletBoxShape
from direct.showbase.InputStateGlobal import inputState
import numpy as np
base.cam.setPos(0, -10, 0)
base.cam.lookAt(0, 0, 0)
debugNode = BulletDebugNode('Debug')
debugNode.showWireframe(True)
debugNode.showConstraints(True)
debugNode.showBoundingBoxes(True)
debugNode.showNormals(False)
debugNP = render.attachNewNode(debugNode)
debugNP.show()
# World
world = BulletWorld()
world.setGravity(Vec3(0, 0, 0))
world.setDebugNode(debugNP.node())
# Plane
shape = BulletPlaneShape(Vec3(0, 0, 1), 0)
node = BulletRigidBodyNode('Ground')
node.addShape(shape)
nodePath = render.attachNewNode(node)
nodePath.setPos(0, 0, 0)
world.attachRigidBody(node)
inputState.watchWithModifiers('x_add', 'd')
inputState.watchWithModifiers('x_minu', 'a')
num_segment = 30 # 5段圆柱
segment_length = 1
segment_radius = 1
shape = BulletCylinderShape(radius=segment_radius, height=segment_length)
previous_node = None
node_paths = []
for i in range(num_segment):
node = BulletRigidBodyNode(f'segment_{i}')
node.addShape(shape)
node.setMass(1.0)
if i == 0:
# node.set_static(True)
node_path = render.attachNewNode(node)
node_path.setPos(0, 0, segment_length/2)
constraint = BulletSphericalConstraint(node, Point3(0, 0, -segment_length / 2))
world.attach_constraint(constraint)
else:
# # 将前一个节点连接到当前节点
constraint = BulletConeTwistConstraint(previous_node, node, TransformState.make_pos(Vec3(0, 0, segment_length/2)),
TransformState.make_pos(Vec3(0, 0, -segment_length/2)))
constraint.setLimit(5, 5, 0, 100, relaxation=10)
# constraint.set_damping(100)
world.attach_constraint(constraint)
node_path = render.attachNewNode(node)
node_path.setPos(previous_node_path.get_pos() + Vec3(0, 0, segment_length))
previous_node = node
previous_node_path = node_path
world.attachRigidBody(node)
node_paths.append(node_path)
def process_input():
force = LVector3(0, 0, 0)
if inputState.isSet('x_minu'): force.x = -1.0
if inputState.isSet('x_add'): force.x = 1.0
force*=30
last = node_paths[-1]
last.node().set_active(True)
last.node().apply_central_force(force)
def update(task):
dt = globalClock.getDt()
process_input()
world.doPhysics(dt)
return task.cont
taskMgr.add(update, 'update')
base.run()
This code has three problems:
-
The tube would be bend when I press
a
, but theBulletConeTwistConstraint
would try to reset it. And I don’t know how to fix it. -
The tube would no bend into a arc. For example:
-
The
BulletConeTwistConstraint
would make this tube acting behave like the wind: theBulletConeTwistConstraint
would alternately make the tube bend to right and left. I hope it bend and keep the status.
Is there any solution can simulate the tube and the inside rope? Any suggestion is appreciated~~~