bullet physics, static node to kinematic node

in my code i gave a rigid body mass, so it falls while physics is being calculated. then soon after this (i mapped it to a keypress) i set it to static so it floats but is still solid. then after this i set it to static(false) and it still is static. any ideas on how to get this to become kinematic again?

node.setMass(1.0)

… do stuff while object is falling …

node.setStatic(True)

… do stuff while object is still…

node.setStatic(False)
node.setKinematic(True)
node.setActive(True)

all 3 are what i tried together in order to break its static nature. but with no luck

There are three types of objects: “static”, “dynamic” and “kinematic”. Kinematic objects are not affected by any physical force - only by direct user input. This is why they are used e. g. for character controllers.

Making the object kinematic is probably the issue with your code.

thanks for the reply, some in the chat said you might chime in. i couldn’t find a way to setDynamic(True) but that is what I assumed it should be. Was this left out for python functions?

panda3d.org/reference/1.8.0/ … 4b91ba442e

What’s the best way to accomplish what I want, all I’ve come up with and others have offered as a solution is to remove the bullet node and recreate it.

To get from “dynamic” to “static”:

self.np.node().setStatic(True)

And to get from “static” to “dynamic”:

self.np.node().setStatic(False)

That’s it. No other calls to make the object kinematic.

i tried that originally, i think i fixed my problem though.

i had world.doPhysics(globalClock.getDt()) running constantly in a task. if i paused the task and switched the static to dynamic and then unpaused the task it now works. thanks for the nudge, i didn’t even think the task could be getting in the way.

A task is not a thread, and does not run constantly.
I can switch between static and dynamic without pausing/unpausing any tasks.

You might have a problem somewhere else in your code. Can you provide a sample which shows your pause/unpause phenomenon?

Thanks for all your input, it’s much appreciated :slight_smile:

i pulled it all out into a new file and it works like you said. sigh
now to find my issue in my main python file :-\ haha

out of curiosity, why does checkcollisionwith always return true for me? am i using it wrong?
example on:
panda3d.org/manual/index.php/Bullet_Queries
if node1.checkCollisionWith(node2):
print “Body 1 and 2 collide”

also on same page, for contact test example there is:
result = world.contactTest(node1, node2)
which isn’t possible for 2 arguments, it seems. I figured out how to use it properly but I am just curious really.

here’s some example code where it shows that it is always colliding:

import direct.directbase.DirectStart
from panda3d.core import Vec3
from panda3d.bullet import BulletWorld
from panda3d.bullet import BulletPlaneShape
from panda3d.bullet import BulletSphereShape
from panda3d.bullet import BulletRigidBodyNode
from panda3d.bullet import BulletBoxShape
from panda3d.bullet import BulletDebugNode
from panda3d.core import Point3

base.cam.setPos(-15, -55, 15)


debugNode = BulletDebugNode('Debug')
debugNode.showWireframe(True)
debugNode.showConstraints(True)
debugNode.showBoundingBoxes(False)
debugNode.showNormals(False)
debugNP = render.attachNewNode(debugNode)
debugNP.show()

# World
world = BulletWorld()
world.setGravity(Vec3(0, 0, -9.81))
world.setDebugNode(debugNP.node())

# Plane
shape = BulletPlaneShape(Vec3(0, 0, 1), 1)
node = BulletRigidBodyNode('Ground')
node.addShape(shape)
np = render.attachNewNode(node)
np.setPos(0, 0, -2)
world.attachRigidBody(node)



#big box
#model = loader.loadModel('models/box.egg')
#model.setPos(0,0,0)
 #model.flattenLight()
shape2 = BulletBoxShape(Vec3(.5,.5,.5))
node2 = BulletRigidBodyNode('box')
node2.addShape(shape2)
node2.setMass(1.0)
np2 = render.attachNewNode(node2)
world.attachRigidBody(node2)
#model.copyTo(np2)
np2.setScale(3,1,1)
np2.setPos(0, 0, 55)


def stuff():

	if np2.node().isStatic():
		np2.node().setStatic(False)
	else: np2.node().setStatic(True)

pause = False
def pause():
	global pause
	if pause: pause=False
	else: pause = True
		
		
def update(task):
	dt = globalClock.getDt()

	if not pause:
		world.doPhysics(dt)

	base.cam.lookAt(np2.getPos())
	
	
	
	if node.checkCollisionWith(node2): #always true?
		print "colliding at " + str(np2.getPos())
		
		
	result = world.contactTest(node)
	for contact in result.getContacts():
		print contact.getNode0()
		print contact.getNode1()
	return task.cont
	
	
base.accept('b',stuff)
base.accept('m',pause)
taskMgr.add(update, 'update')
run()

Well, because it should return true. I should admit that (1)the explanation on the manual page has been outright wrong, and (2) I probably should not have exposed this method anyway since it leads to confusion.

checkCollisionWith is used internally by Bullet to skip collision testing if two objects are linked by a joint/constraint. It has nothing to do with actual collisions of objects. The method you probably want is world.contactTestPair (see below).

The method to check for contacts between two bodies is “contactTestPair”. It has been wrong on the manual page. Page is fixed now.

thanks so much for your help on this. i am enjoying bullet physics and find it logical to use, so the effort to integrate it with panda is worth it in my opinion :slight_smile:

I’m having the same (or similar) problem.

When using the code given, after the node2 is at rest for a few seconds, its debug wireframe turns green. After that, it cannot be made white again. This does not appear to be correlated with its “static” or “dynamic” state.

I do notice that the ground plane is green, as well.

How do we make the object movable again?

Of course, ten minutes after I post this, I’m able to finally download the samples and it’s right there in the first one.