Having trouble referencing bullet rigid bodies

In my code I set gravity, spawn a few models and a few rigid body boxes. Then, when the player picks up an object, I reparent the object to the player/actor’s hand.

This works great for models, but with rigid bodies, gravity causes the actor to instantly drop objects. So I tried setting the mass of objects to zero:

if len(self.hasRight) > 5:  # this determines if the held object is a rigid body
    for i in self.handRight.getChildren():
        i.setPos(-0.2, 0.1, 0)
        i.setMass(0)

Just setting the position each frame isn’t enough because gravity still accelerates it’s speed, so setting it down becomes throwing it down at 100 mph. However, running the code above returns the error: ‘panda3d.core.NodePath’ object has no attribute ‘setMass’

Any help would be greatly appeciated :slight_smile:

Indeed, NodePaths don’t have a “setMass” method. In the case of a Bullet body, the body in question is a node (i.e. a descendant of PandaNode), not a NodePath.

Thus, in order to access the rigid body in question, you would presumably want to find the relevant NodePath and access its node. (Or store a reference directly to the node, of course.)

For example:

Given the following initialisation:

rigidBody = BulletRigidBodyNode("collider")
# <further initialisation here--setting mass, etc.>
self.physicsObject = render.attachNewNode(rigidBody)

We might then later do this:

body = self.physicsObject.node()
body.setMass(0)

By the way, it might be worth considering instead making your object “kinematic”. Alas, it looks like our manual doesn’t explain the concept overmuch, but, if I recall correctly, a “kinematic” object is simply one that can take part in collisions, but which is not affected by forces. Thus a kinematic object should, if I have it aright, be unaffected by gravity. (And not be pushed around by any other collisions, which might be useful when the player is holding it.)

You can toggle whether an object is kinematic or not by calling “setKinematic” on the BulletBodyNode in question, I believe.

Because the setMass function is for a BulletRigidBodyNode object, not for NodePath. You might have re parented the BulletRigidBodyNode to a NodePath. That doesn’t mean the NodePath will get it’s children’s methods. Call:

i.node().setMass(num) # Where num is your mass

thanks :smiley: got it working, and setKinematic was just what I was looking for

1 Like