Bullet and forces applied to objects

I have some issues in understanding the use of the bullet package. My problem is that I cannot understand how to apply a specific force to an object.

For clarity, we could refer to the following piece of code appearing in the Panda3d Manual pages.

import direct.directbase.DirectStart
from panda3d.core import Vec3
from panda3d.bullet import BulletWorld
from panda3d.bullet import BulletPlaneShape
from panda3d.bullet import BulletRigidBodyNode
from panda3d.bullet import BulletBoxShape
 
base.cam.setPos(0, -10, 0)
base.cam.lookAt(0, 0, 0)
 
# World
world = BulletWorld()
world.setGravity(Vec3(0, 0, -9.81))
 
# 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)
 
# Box
shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5))
node = BulletRigidBodyNode('Box')
node.setMass(1.0)
node.addShape(shape)
np = render.attachNewNode(node)
np.setPos(0, 0, 2)
world.attachRigidBody(node)
model = loader.loadModel('models/box.egg')
model.flattenLight()
model.reparentTo(np)
 
# Update
def update(task):
  dt = globalClock.getDt()
  world.doPhysics(dt)
  return task.cont
 
taskMgr.add(update, 'update')
run()

Now the question is: suppose I want to apply a specific force to the box, maybe a force that depends on its position and time.

  1. I should place the calculations of the force in the update() function, correct? Hence modify the function to be able to access the specific node I want the force applied to, since I will have to change the force magnitude during execution. Right? Or is there maybe a method that provides a callback function?

  2. How do I apply the force? I saw that there is a “applyForce()” method for the BulletRigidBodyNode class. However, this function requires 2 arguments: a vector for the force components, and a position, and both parameter must be specified. I do not understand what does this position refer to, since what I want to do is to apply a force to the node, not in a specific position.

  3. Suppose the above issue is solved, the “doPhysics()” call should update the position of the node, right?
    That is, if I use getPos() on the node pointer to the node, I will get the new position, right?

Thanks in advance

Ode

Mmm, ok I realized that there is also “applyCentralForce()” that seems actually to be what I want. So if I understand correctly, one can specify:

  • a force to apply to the centre of mass -> applyCentralForce()
  • a torque -> applyCentralTorque
  • a force to apply at some point that might be decomposed into a torque + force applied to center of mass -> applyForce()

Is that right?

And what exactly is intended for “Impulse”? In Physics the impulse is the integral of a force during a time interval, but here I don’t understand how it is used. How can I apply an impulse? Over which period of time is it supposed to have been applied?

I tried to have a look to the User Manual of the bullet library, but there is no information on this.

Ode

Well, for impulse we have applyCentralImpulse and applyImpulse for linear impulse, and applyTorqueImpulse for angular impulse.

Here is the API doc:
panda3d.org/reference/devel/ … idBodyNode

Yes, I saw the API doc, but it does not explain anything regarding what the function does. Nor does the bullet User’s Manual. My current understanding is that an impulse means a force applied during the time of 1 frame, that leads to an instantaneous change in velocity (that is v_new = v_old + impulse / mass). In other words the impulse is intended to last one frame. Is that correct?

The impuls is applied at the next simulation tick, and instantaneous (i.e. not over a specific duration). It is not re-applied at the next ticks.

tick = one subframe or substep. Each Panda3D frame is divided into several fixed size substeps, plus one interpolation step which fills the gap from the last substep to the end of the Panda3D frame.

Ok, great! Thanks a lot for the clarification!