Hi,
I have cloak applied to character as softbody. It fits tight to the character if character z position is 0
(by default). This is fine. But my character also has capsule collider (rigidbody) and character itself needs to be shifted down, i.e. self.korlan.setZ(-1)
to be fully covered by capsule. A-a-a-nd then my cloak, of course, leaves higher than character. I set cloak z position to -1
and here softbody behavior becomes broken: when I rotate character the cloak rotates too, but it gets shifted to left or right or just rotates in the opposite direction.
I don’t know how to solve this trouble with Bullet. Can someone help me?
Here is my sample code:
# cloth stuff
self.world = BulletWorld()
self.world.setGravity(Vec3(0, 0, -9.81))
self.debugNP = render.attachNewNode(BulletDebugNode('Debug'))
# self.debugNP.show()
# self.debugNP.node().showWireframe(True)
# self.debugNP.node().showConstraints(True)
# self.debugNP.node().showBoundingBoxes(False)
# self.debugNP.node().showNormals(True)
self.world.setDebugNode(self.debugNP.node())
# Plane
shape = BulletPlaneShape(Vec3(0, 0, 1), 0)
node = BulletRigidBodyNode('Ground')
node.addShape(shape)
np = render.attachNewNode(node)
np.setPos(0, 0, 0)
self.world.attachRigidBody(node)
self.world.setGroupCollisionFlag(0, 0, False)
# Player
self.korlan = Actor("{0}/Assets/Actors/NPC/NPC_Ernar/Korlan.egg.bam".format(self.game_dir),
{"idle": '{0}/Assets/Animations/Korlan-Standing_idle_female.egg'.format(self.game_dir),
"walk": "{0}/Assets/Animations/Korlan-Walking.egg".format(self.game_dir),
"left_t": "{0}/Assets/Animations/exp/Korlan-left_turn.egg".format(self.game_dir),
"right_t": "{0}/Assets/Animations/exp/Korlan-right_turn.egg".format(self.game_dir),
"slash": "{0}/Assets/Animations/Korlan-great_sword_slash.egg".format(self.game_dir),
"draw_bow": "{0}/Assets/Animations/archering/Korlan-archer_standing_draw_arrow.egg".format(
self.game_dir),
}
)
self.korlan.reparent_to(render)
self.korlanRigidNP = None
# Player
bullet_char_contr_node = BulletCharacterControllerNode(shape,
0.4,
col_name)
self.korlanRigidNP = self.render.attach_new_node(bullet_char_contr_node)
self.world.attach(bullet_char_contr_node)
self.korlanRigidNP.set_collide_mask(BitMask32.bit(0))
self.korlan.reparent_to(self.korlanRigidNP)
self.korlan.setZ(-1)
# Soft body world information
info = self.world.getWorldInfo()
info.setAirDensity(0.2)
info.setWaterDensity(0)
info.setWaterOffset(0)
info.setWaterNormal(Vec3(0, 0, 0))
# load the cloak model
model = loader.loadModel('{0}/Assets/Actors/Korlan/Korlan_cloak.bam'.format(self.game_dir))
geom = model.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.5)
node.getCfg().setDampingCoefficient(0.01)
node.getCfg().setPoseMatchingCoefficient(0.2)
node.setPose(False, False)
node.setTotalMass(1)
softNP = render.attachNewNode(node)
self.world.attachSoftBody(node)
geomNP = softNP.attachNewNode(geomNode)
geomNP.setTwoSided(True)
# pin it down
self.hip_bone = self.korlan.exposeJoint(None, 'modelRoot', 'Korlan:Spine2')
self.pin = self.hip_bone.attachNewNode(BulletRigidBodyNode('pin'))
# the model should know what verts to pin
for vertex in json.loads(model.getTag('pins')):
softNP.node().appendAnchor(softNP.node().getClosestNodeIndex(Vec3(*vertex), True), self.pin.node())
# Task
taskMgr.add(self.update, 'updateWorld')
def update(self, task):
dt = globalClock.getDt()
# self.pin is a child of self.hip_bone but without these lines it won't work
self.pin.setPos(render, self.hip_bone.getPos(render))
self.pin.setHpr(render, self.hip_bone.getHpr(render))
self.world.doPhysics(dt, 10, 0.004)
return task.cont
Here how it does look:
with self.korlan.setZ(-1) (after reparenting to rigidbody node)
with self.korlan.setZ(0) (after reparenting to rigidbody node)