Escribe para buscar…

Bullet

Esta página todavía no se ha traducido — se muestra en su idioma original:English

Introduction

Panda3D offers two main ways to handle physics:

  1. Its Built-in Physics Engine (very basic, uses ActorNode) and
  2. The Bullet Physics Engine (more powerful, industry-standard).

For a beginner, Bullet, it’s much more robust for games and generally easier to scale as your project grows.

We will walk you through setting up a “Hello World” of physics: a falling box hitting a floor.

Hello World

To use Bullet physics, we need to have a BulletWorld.

The world is Panda3D’s term for a “space” or “scene”. The world holds physical objects like rigid bodies, soft bodies, or character controllers. It controls global parameters, such as gravity, and it advances the simulation state.

python
from direct.showbase.ShowBase import ShowBase
from panda3d.bullet import BulletWorld
from panda3d.core import Vec3


class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))


app = MyApp()
app.run()

The above code creates a new world, and it sets the worlds gravity to a downward vector with length 9.81. While Bullet is in theory independent of any particular units, it is recommended to stick with SI units (kilogram, meter, second). In SI units 9.81 m/s² is the gravity on Earth’s surface.

Next, we need to advance the simulation state. This is best done by a task which gets called each frame. We find out about the elapsed time (dt), and pass this value to the do_physics() method.

python
class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.world = BulletWorld()
        self.world.setGravity(Vec3(0, 0, -9.81))

        self.taskMgr.add(self.update, 'update')

    def update(self, task):
        dt = globalClock.getDt()
        self.world.doPhysics(dt)
        return task.cont

The doPhysics method allows finer control on the way the simulation state is advanced. Internally, Bullet splits a timestep into several substeps. We can pass a maximum number of substeps and the size of each substep, like shown in the following code.

python
world.doPhysics(dt, 10, 1.0/180.0)

Here we have a maximum of 10 substeps, each with 1/180 seconds. Choosing smaller substeps will make the simulation more realistic, but performance will decrease too. Smaller substeps also reduce jitter.

Static bodies

So far we just have an empty world. We next need to add some objects. The most simple objects are static bodies. Static object doesn’t change their position or orientation with time. Typical static objects are the ground or terrain, and houses or other non-moveable obstacles. Here we create a simple plane which will serve as a ground.

python
class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        # ...

        # Floor
        floor = BulletRigidBodyNode('Ground')
        floor.addShape(BulletPlaneShape(Vec3(0, 0, 1), 1))
        floor_np = self.render.attachNewNode(floor)
        floor_np.setPos(0, 0, -2)
        self.world.attachRigidBody(floor)

Estás leyendo una vista previa.

Inicia sesión para leer el artículo completo. Cualquier cuenta abre 4 artículos gratuitos al mes; el alumnado y el profesorado leen las páginas de su curso sin límite.

Iniciar sesión