Panda3D Manual: Simulating the Physics World
<<prev | top | next>> |
## Simulating the physics scene Now, we've only had some theory so far, but haven't seen any simulation yet. To simulate, we will need to keep calling the `quickStep(stepSize)` function on the OdeWorld instance. stepSize is how much time should be simulated in one step. To get the most stable simulation, it is recommended that the stepSize be kept constant. The problem with using the delta time of a task to step the simulation is that the time between tasks might not be consistent. To get around this, a deltaTime accumulator is used to figure out how many steps must be taken. When a step is performed, the world is iterated a few times, you can specify how much times the world is being iterated by calling the `setQuickStepNumIterations(num)` function on the OdeWorld instance. Here's a small example showing a simple simulation showing an iron ball falling from a ridge:
    from direct.directbase import DirectStart
    from pandac.PandaModules import OdeWorld, OdeBody, OdeMass, Quat

    # Load the cube where the ball will fall from
    cube = loader.loadModel("box.egg")
    cube.reparentTo(render)
    cube.setColor(0.2, 0, 0.7)
    cube.setScale(20)

    # Load the smiley model which will act as our iron ball
    sphere = loader.loadModel("smiley.egg")
    sphere.reparentTo(render)
    sphere.setPos(10, 1, 21)
    sphere.setColor(0.7, 0.4, 0.4)

    # Setup our physics world and the body
    world = OdeWorld()
    world.setGravity(0, 0, -9.81)
    body = OdeBody(world)
    M = OdeMass()
    M.setSphere(7874, 1.0)
    body.setMass(M)
    body.setPosition(sphere.getPos(render))
    body.setQuaternion(sphere.getQuat(render))

    # Set the camera position
    base.disableMouse()
    base.camera.setPos(80, -20, 40)
    base.camera.lookAt(0, 0, 10)

    # Create an accumulator to track the time since the sim
    # has been running
    deltaTimeAccumulator = 0.0
    # This stepSize makes the simulation run at 90 frames per second
    stepSize = 1.0 / 90.0

    # The task for our simulation
    def simulationTask(task):
      global deltaTimeAccumulator
      # Set the force on the body to push it off the ridge
      body.setForce(0, min(task.time**4 * 500000 - 500000, 0), 0)
      # Add the deltaTime for the task to the accumulator
      deltaTimeAccumulator += globalClock.getDt()
      while deltaTimeAccumulator > stepSize:
        # Remove a stepSize from the accumulator until
        # the accumulated time is less than the stepsize
        deltaTimeAccumulator -= stepSize
        # Step the simulation
        world.quickStep(stepSize)
      # set the new positions
      sphere.setPosQuat(render, body.getPosition(), Quat(body.getQuaternion()))
      return task.cont

    taskMgr.doMethodLater(1.0, simulationTask, "Physics Simulation")

    run()
## Incomplete Section Note: this section is incomplete. It will be updated soon.
<<prev | top | next>> |