# ODE Physics Setup

I hate to ask and I have looked through the tutorial on setting up ODE physics. I need some clarification because when I tried to integrate the code with my code I got several errors and such.

My Goal:
Add gravity to the actorPanda so the panda falls…that’s it. I just need some help navigating through that ODE physics tutorial because they generate a box and procedurally texture it. I wish they would have just loaded a model instead of generating random cubes

Thanks in advance and if someone could point me to a tutorial that maybe has this in there that would be great. (by tutorial I mean an example that uses ODE in the code)

here is my code ( I apologize in advance its really messy and I haven’t had time to clean it up. )

``````from math import pi, sin, cos
import math, sys
from pandac.PandaModules import Vec3, Vec4

from direct.showbase.ShowBase import ShowBase
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import Sequence
from panda3d.core  import Point3
from pandac.PandaModules import OdeWorld, OdeSimpleSpace, OdeJointGroup
from pandac.PandaModules import OdeBody, OdeMass, OdeBoxGeom, OdePlaneGeom
from pandac.PandaModules import CardMaker, Quat
class Panda(ShowBase):
def __init__(self):
ShowBase.__init__(self)
#setup gravity and physics world using ODE
#gravity is standard earth gravity rounded two decimal places -9.81 units/second
#               self.world = OdeWorld()
#               self.world.setGravity(0,0,-9.81)
#               self.space = OdeSimpleSpace()
#               self.space.setAutoCollideWorld(self.world)
#               self.contactGroup = OdeJointGroup()
#               self.space.setAutoCollideJointGroup(self.contactGroup)

self.environ.reparentTo(self.render)
self.environ.setScale(0.25,0.25,0.25)
self.environ.setPos(-8, 42, 0)

self.pandaActor = Actor("models/panda-model", {"walk": "models/panda-walk4"})
self.pandaActor.setScale(0.005,0.005,0.005)
self.pandaActor.reparentTo(self.render)

#ode stuff for the pandaActor
#               self.pandaActor.flattenLight()
#               self.pandaActorMass = OdeBody(self.world)
#               self.pandaActorMass.setMass(50,1,1,1)
#ode physics setup simulation

#------------------
#Movement of character sections

self.accept('w', self.walking_forward)
self.accept('w-up', self.stop_walking_forward)
self.accept('s', self.walking_backward)
self.accept('s-up', self.stop_walking_backward)
self.accept('a', self.turn, [ -1 ])
self.accept('a-up', self.stopTurn)
self.accept('d', self.turn, [ 1 ])
self.accept('d-up', self.stopTurn)
self.acceptOnce('escape', sys.exit)

#------------------
#        self.space.autoCollide()
#        self.world.quickStep(globalClock.getDt())
#        self.pandaActor.setPosQuat(render, self.pandaActor.getPosition(), Quat(self.pandaActor.getQuaterion()))
#        self.contactGroup.empty()
def turn(self, direction):
self.pandaActor.setH(self.pandaActor.getH()-direction)
def stopTurn(self):

def walking_forward(self):
self.pandaActor.loop("walk")
distance = 0.025
angle = self.pandaActor.getH()*math.pi/-180
correction = math.pi/2
dx = distance * math.cos( correction + angle )
dy = distance * -math.sin( correction + angle )
self.pandaActor.setPos( Vec3( self.pandaActor.getX( ) + dx, self.pandaActor.getY( ) + dy, 0 ) )
def walking_backward(self):
self.pandaActor.loop("walk")
distance = 0.025
angle = self.pandaActor.getH()*math.pi/-180
correction = math.pi/2
dx = distance * math.cos( correction + angle )
dy = distance * -math.sin( correction + angle )
self.pandaActor.setPos( Vec3( self.pandaActor.getX() - dx, self.pandaActor.getY() - dy, 0))
def stop_walking_forward(self):
self.pandaActor.stop()
def stop_walking_backward(self):
self.pandaActor.stop()
#    def stop_walking(self):
#        self.pandaActor.stop()

app = Panda()
app.run()``````

I tried to fix the code you posted, but I can only do so much. I changed just enough so it doesn’t crash and you can see some effect. It also doesn’t really work.

But making a character controller in ODE is a complex task I haven’t tackled yet. You need to apply movement to the OdeBody, not the NodePath. The NodePath should be purely a “slave” to the simulation task. It’s hard because physics bodies are meant to be pushed around by forces, not explicitly moved from point to point. And dragging along the ground against friction causes it to jump around a lot as you will see.

``````from math import pi, sin, cos
import math, sys
from pandac.PandaModules import Vec3, Vec4

from direct.showbase.ShowBase import ShowBase
from direct.actor.Actor import Actor
from panda3d.core  import Point3
from pandac.PandaModules import OdeWorld, OdeSimpleSpace, OdeJointGroup
from pandac.PandaModules import OdeBody, OdeMass, OdeBoxGeom, OdePlaneGeom
from pandac.PandaModules import CardMaker, Quat

class Panda(ShowBase):
def __init__(self):
ShowBase.__init__(self)
#setup gravity and physics world using ODE
#gravity is standard earth gravity rounded two decimal places -9.81 units/second
self.world = OdeWorld()
self.world.setGravity(0,0,-9.81)
# you need these next two lines or it will CRASH
self.world.initSurfaceTable(1)
self.world.setSurfaceEntry(0, 0, 150, 0.0, 9.1, 0.9, 0.00001, 0.0, 0.002)
self.space = OdeSimpleSpace()
self.space.setAutoCollideWorld(self.world)
self.contactGroup = OdeJointGroup()
self.space.setAutoCollideJointGroup(self.contactGroup)

self.environ.reparentTo(self.render)
self.environ.setScale(0.25,0.25,0.25)

# you need something to collide with as the ground or you will just fall through
self.groundGeom = OdePlaneGeom(self.space, Vec4(0, 0, 1, 0))

self.pandaActor = Actor("models/panda-model", {"walk": "models/panda-walk4"})
self.pandaActor.setScale(0.005,0.005,0.005)
self.pandaActor.reparentTo(self.render)

# ODE STUFF
pandaMass = OdeMass()      # <-- no need to store on self, the OdeBody will hold it
pandaMass.setBox(50,1,1,1) # <-- this should match the shape of your OdeGeom
self.pandaBody = OdeBody(self.world)
self.pandaBody.setMass(pandaMass) # <-- THIS is what you pass to setMass
pandaGeom = OdeBoxGeom(self.space, 1, 1, 1) # <-- doesn't really fit the panda, but whatever
pandaGeom.setBody(self.pandaBody) # <-- again the OdeBody will hold the ref

#ode physics setup simulation

#Movement of character sections

self.accept('w', self.walking_forward)
self.accept('w-up', self.stop_walking_forward)
self.accept('s', self.walking_backward)
self.accept('s-up', self.stop_walking_backward)
self.accept('a', self.turn, [ -1 ])
self.accept('a-up', self.stopTurn)
self.accept('d', self.turn, [ 1 ])
self.accept('d-up', self.stopTurn)
self.acceptOnce('escape', sys.exit)

self.space.autoCollide()
self.world.quickStep(globalClock.getDt())
self.pandaActor.setPosQuat(render, self.pandaBody.getPosition(), Quat(self.pandaBody.getQuaternion()))
self.contactGroup.empty()
def turn(self, direction):
self.pandaActor.setH(self.pandaActor.getH()-direction)
def stopTurn(self):

def walking_forward(self):
self.pandaActor.loop("walk")
distance = 0.025
angle = self.pandaActor.getH()*math.pi/-180
correction = math.pi/2
dx = distance * math.cos( correction + angle )
dy = distance * -math.sin( correction + angle )
self.pandaBody.setPosition( Vec3( self.pandaActor.getX( ) + dx, self.pandaActor.getY( ) + dy, 0 ) )
def walking_backward(self):
self.pandaActor.loop("walk")
distance = 0.025
angle = self.pandaActor.getH()*math.pi/-180
correction = math.pi/2
dx = distance * math.cos( correction + angle )
dy = distance * -math.sin( correction + angle )
self.pandaBody.setPosition( Vec3( self.pandaActor.getX() - dx, self.pandaActor.getY() - dy, 0))
def stop_walking_forward(self):
self.pandaActor.stop()