Set position on BulletRigidBodyNode missing ?

I noticed something I dont understand when you create a new Bullet body.

	shape = BulletBoxShape(Vec3(0.4,0.5,0.5))
	box = BulletRigidBodyNode('Box')
	box.setMass(1.0)
	box.addShape(shape)
	np = render.attachNewNode(box)
	np.setPos(x, 0, 2)
	world.attachRigidBody(box)
	model = loader.loadModel('models/box.egg')
	model.flattenLight()

It seems that you have to create a node through the “render” object, through this statement “np = render.attachNewNode(box)”

Then you can set position by using the np.setPos().

Any explanation to why you can’t set it directly ?

This is the difference between a PandaNode, the lower-level scenegraph node object, and a NodePath, the high-level interface over PandaNodes and other scenegraph operations. BulletRigidBodyNode inherits from PandaNode. PandaNode doesn’t have a setPos method, only a setTranform method which is less intuitive. PandaNode.setTransform takes a TransformState object, which has several static constructors corresponding to the types of transforms you might want to set. The equivalent of NodePath.setPos(x,y,z) looks something like this:

box.setTransform(TransformState.makePos(VBase3(x,y,z))

But if you want it to be visible it still must be attached under render somehow, so you might as well use a the NodePath (since render is a NodePath). As in your example, you should generally only set an initial position before it is attached to the BulletWorld unless you’ve made it a “kinematic” body. During simulation, moving dynamic bodies other than by applying forces can result in crazy forces being applied to things they collide with or are attached to.

Thank you.

“But if you want it to be visible it still must be attached under render somehow”
I’m not sure I understand this.

What is wrong with this approach ?

pos = bulletBox.getPos()
myNodeContainingABox.setPos(pos)

Perhaps “must” was too strong. You can do that, but you’d have to do it every frame. In the general case the visible model should simply be a child of the body node. Let the scenegraph do the “bookkeeping” and save your per-frame tasks for more high-level stuff.

I still can’t see what physics object have to do with the view. To me, they are business objects and do not have a visual representation on their own, other than what one decides to give them. Why force that on the user ?

Also, what if your game is running on a server ? Do you have to start a “view” just to make your physics model ?

Let me try to be more precise. Nodes in the scenegraph are not required to be visible or have visible children. But if you want to have a visible representation of a physics object, it should be under the body node, and the body node should be under render (‘render’ is the default root node of the visible scenegraph, but really the rendering engine will traverse from wherever the tree above the active camera starts).

For a server or whatever, you simply don’t load the visual resources (or sounds, etc.). You don’t even have to open a graphics window. But a server will still have a scenegraph with nodes, because those contain the positions, rotations, bounding volumes, hierarchies, etc which are still needed. You shouldn’t need to copy those values around in lots of “pos = node.getPos()” kind of code to mirror related objects together; that is what the scenegraph is for.

Thanks for the lengthy response. I’m sure it will make perfect sense the more I work with Panda. Thanks.