Here is my code, it’s kind of messy:
# -*- coding: utf-8 -*-
from direct.directbase import DirectStart
from pandac.PandaModules import OdeWorld, OdeSimpleSpace, OdeJointGroup
from pandac.PandaModules import OdeBody, OdeMass, OdeSphereGeom, OdePlaneGeom, OdeBoxGeom
from pandac.PandaModules import BitMask32, CardMaker, Vec4, Quat
from random import randint, random
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
import sys, os, math
# Setup our physics world
world = OdeWorld()
world.setGravity(0, 0, -9.81)
# The surface table is needed for autoCollide
world.initSurfaceTable(1)
#odeWorld.setSurfaceEntry(surfaceID1, surfaceID2, mu, bounce, bounce_vel, soft_erp, soft_cfm, slip, dampen)
world.setSurfaceEntry(0, 0, 15, 0.5, 9.1, 0.9, 0.00001, 0.0, 0.002)
# Create a space and add a contactgroup to it to add the contact joints
space = OdeSimpleSpace()
space.setAutoCollideWorld(world)
contactgroup = OdeJointGroup()
space.setAutoCollideJointGroup(contactgroup)
# Load the sphere
sphere = loader.loadModel("ping_ball")
#sphere.setTextureOff()
# Add a random amount of spherees
spherees = []
for i in range(randint(15, 30)):
# Setup the geometry
sphereNP = sphere.copyTo(render)
sphereNP.setPos(randint(-10, 10), randint(-10, 10), 10 + random())
sphereNP.setHpr(randint(-45, 45), randint(-45, 45), randint(-45, 45))
# Create the body and set the mass
sphereBody = OdeBody(world)
M = OdeMass()
M.setSphere(8, 1)
sphereBody.setMass(M)
sphereBody.setPosition(sphereNP.getPos(render))
sphereBody.setQuaternion(sphereNP.getQuat(render))
# Create a sphereGeom
sphereGeom = OdeSphereGeom(space, 1)
sphereGeom.setCollideBits(BitMask32(0x00000002))
sphereGeom.setCategoryBits(BitMask32(0x00000001))
#this will automatically reposition the geometry (collision solid) with regard to the position
#of the position of the related body in the OdeWorld.
sphereGeom.setBody(sphereBody)
spherees.append((sphereNP, sphereBody))
# Add a plane to collide with
cm = CardMaker("ground")
cm.setFrame(-20, 20, -20, 20)
cm.setColor(0.1, 0.5, 0, 1)
ground = render.attachNewNode(cm.generate())
ground.setPos(0, 0, -1)
ground.lookAt(0, 0, -2)
groundBody = OdeBody(world)
groundBody.setPosition(ground.getPos())
groundBody.setQuaternion(ground.getQuat())
groundGeom = OdeBoxGeom(space, 20, 20, 1)
groundGeom.setCollideBits(BitMask32(0x00000001))
groundGeom.setCategoryBits(BitMask32(0x00000002))
groundGeom.setBody(groundBody)
# Set the camera position
base.disableMouse()
base.camera.setPos(40, 40, 20)
base.camera.lookAt(0, 0, 0)
#move the floor
class World(DirectObject):
def __init__(self):
self.keyMap = {"forward":0}
self.accept("escape", sys.exit)
self.accept("arrow_up", self.setKey, ["forward",1])
self.accept("arrow_up-up", self.setKey, ["forward",0])
taskMgr.add(self.move,"moveTask")
# Game state variables
self.prevtime = 0
def setKey(self, key, value):
self.keyMap[key] = value
def move(self, task):
elapsed = task.time - self.prevtime
if (self.keyMap["forward"]!=0):
ground.setX(ground, -elapsed*50)
print "move"
# Store the task time and continue.
self.prevtime = task.time
return Task.cont
w = World()
# The task for our simulation
def simulationTask(task):
space.autoCollide() # Setup the contact joints
# Step the simulation and set the new positions
world.quickStep(globalClock.getDt())
for np, body in spherees:
np.setPosQuat(render, body.getPosition(), Quat(body.getQuaternion()))
contactgroup.empty() # Clear the contact joints
return task.cont
taskMgr.doMethodLater(0.5, simulationTask, "Physics Simulation")
run()
I don’t quite understand what “step resolution” is, Is the
world.quickStep(globalClock.getDt())
If so, I change it to
world.quickStep(globalClock.getDt() - 0.015)
but it didn’t work.
I am trying the “joint” way.