def ode_cols(self): world = OdeWorld() world.setGravity(0, 0, -9) world.initSurfaceTable(1) world.setSurfaceEntry(0, 0, 150, 0.0, 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) space.autoCollide() #try ODE for collisions t_trimesh = OdeTriMeshData(self.terrain.getRoot(), True) t_geom = OdeTriMeshGeom(space, t_trimesh)
from panda3d.ode import OdeWorld, OdeSimpleSpace, OdeJointGroup from panda3d.ode import OdeBody, OdeMass, OdeBoxGeom, OdePlaneGeom from panda3d.core import BitMask32, CardMaker, Vec4, Quat from random import randint, random from direct.directbase import DirectStart from direct.directtools.DirectGeometry import LineNodePath from panda3d.core import * from panda3d.ode import * # Setup our physics world world = OdeWorld() world.setGravity(0, 0, -9.81) # The surface table is needed for autoCollide world.initSurfaceTable(1) world.setSurfaceEntry(0, 0, 150, 0.0, 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 box box = loader.loadModel("box") box.setScale(4, 4, 1) # Make sure its center is at 0, 0, 0 like OdeBoxGeom box.setPos(1, 1, 1) box.flattenLight() # Apply transform box.setTextureOff()
class PhysicsSimulator(ShowBase): def __init__(self): ShowBase.__init__(self) self.smiley = loader.loadModel("smiley") self.smiley.set_scale(1) self.cam.set_pos(0, -50, 25) self.setup_ODE() self.add_ground() self.add_static_box(1, 1, 1) self.s1 = self.add_smiley(0, 0, 50) self.s2 = self.add_smiley(0, 0, 40) self.accept("escape", sys.exit) self.accept('a', self.velocity) taskMgr.add(self.update_ODE, "update_ODE") self.accept('on_collision', self.on_collision) def velocity(self): self.s2.set_linear_vel(0, 0, 10) def setup_ODE(self): # Setup our physics world self.world = OdeWorld() self.world.setGravity(0, 0, -9.81) self.world.initSurfaceTable(1) self.world.setSurfaceEntry(0, 0, 200, 0.7, 0.2, 0.9, 0.00001, 0.0, 0.002) self.space = OdeSimpleSpace() self.space.setAutoCollideWorld(self.world) self.contacts = OdeJointGroup() self.space.setAutoCollideJointGroup(self.contacts) self.space.setCollisionEvent("on_collision") def on_collision(self, entry): geom1 = entry.getGeom1() geom2 = entry.getGeom2() body1 = entry.getBody1() body2 = entry.getBody2() def add_ground(self): cm = CardMaker("ground") cm.setFrame(-1, 1, -1, 1) ground = render.attachNewNode(cm.generate()) ground.setColor(0.5, 0.7, 0.8) ground.lookAt(0, 0, -1) groundGeom = OdePlaneGeom(self.space, Vec4(0, 0, 1, 0)) def add_smiley(self, x, y, z): sm = render.attachNewNode("smiley-instance") sm.setPos(x, y, z) self.smiley.instanceTo(sm) body = OdeBody(self.world) mass = OdeMass() mass.setSphereTotal(10, 1) body.setMass(mass) body.setPosition(sm.getPos()) geom = OdeSphereGeom(self.space, 1) geom.setBody(body) sm.setPythonTag("body", body) return body def add_static_box(self, x, y, z): self.box = OdeBoxGeom(self.space, Vec3(x, y, z)) self.box.set_position(0, 0, 25) def draw_box(self, box): line_collection = LineNodePath(parent=render, thickness=1.0, colorVec=Vec4(1, 0, 0, 1)) pos = box.get_position() lengths = box.get_lengths() x = pos[0] y = pos[1] z = pos[2] half_width = lengths[0] / 2 half_length = lengths[1] / 2 half_height = lengths[2] / 2 lines = [ # Bottom Face ((x - half_width, y - half_length, z - half_height), (x + half_width, y - half_length, z - half_height)), ((x + half_width, y - half_length, z - half_height), (x + half_width, y + half_length, z - half_height)), ((x + half_width, y + half_length, z - half_height), (x - half_width, y + half_length, z - half_height)), ((x - half_width, y + half_length, z - half_height), (x - half_width, y - half_length, z - half_height)), # Top Face ((x - half_width, y - half_length, z + half_height), (x + half_width, y - half_length, z + half_height)), ((x + half_width, y - half_length, z + half_height), (x + half_width, y + half_length, z + half_height)), ((x + half_width, y + half_length, z + half_height), (x - half_width, y + half_length, z + half_height)), ((x - half_width, y + half_length, z + half_height), (x - half_width, y - half_length, z + half_height)), # Vertical Lines ((x - half_width, y - half_length, z - half_height), (x - half_width, y - half_length, z + half_height)), ((x + half_width, y - half_length, z - half_height), (x + half_width, y - half_length, z + half_height)), ((x + half_width, y + half_length, z - half_height), (x + half_width, y + half_length, z + half_height)), ((x - half_width, y + half_length, z - half_height), (x - half_width, y + half_length, z + half_height)), ] line_collection.drawLines(lines) line_collection.create() def update_ODE(self, task): self.space.autoCollide() self.world.quickStep(globalClock.getDt()) self.draw_box(self.box) for smiley in render.findAllMatches("smiley-instance"): body = smiley.getPythonTag("body") smiley.setPosQuat(body.getPosition(), Quat(body.getQuaternion())) self.contacts.empty() return task.cont
class BaseApp(ShowBase): odeBoxes = [] def createOdeEnv(self, model): geomNodeCollection = model.findAllMatches('**/+GeomNode') for nodePath in geomNodeCollection: geomNode = nodePath.node() #print "\n\nGeomNode: ", geomNode.getName() for i in range(geomNode.getNumGeoms()): geom = geomNode.getGeom(i) #state = geomNode.getGeomState(i) T = geomNode.getTransform() #print " - ", T pos = T.getPos() if T.hasComponents(): Q = T.getQuat() S = T.getScale() vdata = geom.getVertexData() vertex = GeomVertexReader(vdata, 'vertex') #mins and maxes for MBB minX = 1e10 maxX = -1e10 minY = 1e10 maxY = -1e10 minZ = 1e10 maxZ = -1e10 while not vertex.isAtEnd(): v = vertex.getData3f() minX = min(minX,v[0]) minY = min(minY,v[1]) minZ = min(minZ,v[2]) maxX = max(maxX,v[0]) maxY = max(maxY,v[1]) maxZ = max(maxZ,v[2]) #print "v = %s" % (repr(v)) #print "X:(%f->%f) Y(%f->%f) Z(%f->%f)" % (minX, maxX, minY, maxY, minZ, maxZ) minX *= S[0] maxX *= S[0] minY *= S[1] maxY *= S[1] minZ *= S[2] maxZ *= S[2] #print "X:(%f->%f) Y(%f->%f) Z(%f->%f)" % (minX, maxX, minY, maxY, minZ, maxZ) box = OdeBoxGeom(self.space, maxX-minX, maxY-minY, maxZ-minZ) box.setPosition(pos) box.setQuaternion(Q) self.odeBoxes.append(box) else: print "Error Transform does not have components - skipping" def load_environment(self, modelfile): self.room = loader.loadModel(modelfile) self.room.reparentTo(render) self.room.setPos(0,0,0) self.createOdeEnv(self.room) def __init__(self): ShowBase.__init__(self) ambLight = AmbientLight("ambient") ambLight.setColor(Vec4(0.1,0.11,0.12,1.0)) ambNode = render.attachNewNode(ambLight) render.setLight(ambNode) dirLight = DirectionalLight("directional") dirLight.setColor(Vec4(0.7,0.7,0.68,1.0)) dirNode = render.attachNewNode(dirLight) dirNode.setHpr(60,-40,90) render.setLight(dirNode) sptLight = Spotlight("spot") sptLens = PerspectiveLens() sptLight.setLens(sptLens) sptLight.setColor(Vec4(0.6,0.6,0.6,1.0)) sptLight.setShadowCaster(True) sptNode = render.attachNewNode(sptLight) sptNode.setPos(0,0,20) sptNode.lookAt(0,0,0) render.setLight(sptNode) render.setShaderAuto() base.camLens.setFov(70) base.camLens.setNear(0.1) base.camLens.setFar(50) self.cam.setPos(-1,-4,4) self.cam.lookAt(0,-1,1) def create_ode_world(self): self.world = OdeWorld() self.world.setGravity(0,0,-9.81) self.world.initSurfaceTable(1) #self.world.setSurfaceEntry(0,0,0.5,0.35,0.1,0.9,0.00001,0.4,0.002) self.world.setSurfaceEntry(0,0,0.8,0.7,0.1,0.9,0.00001,0.4,0.002) self.space = OdeSimpleSpace() self.space.setAutoCollideWorld(self.world) self.contacts = OdeJointGroup() self.space.setAutoCollideJointGroup(self.contacts) self.groundGeom = OdePlaneGeom(self.space, Vec4(0,0,1,0)) def updateODE(self, n_millis): for n in range(0,n_millis): self.space.autoCollide() self.world.quickStep(0.001) self.contacts.empty() return True
from direct.directbase import DirectStart from panda3d.ode import OdeWorld, OdeSimpleSpace, OdeJointGroup from panda3d.ode import OdeBody, OdeMass, OdeBoxGeom, OdePlaneGeom, OdeTriMeshGeom, OdeTriMeshData from panda3d.core import BitMask32, CardMaker, Vec4, Quat from random import randint, random # Setup our physics world world = OdeWorld() world.setGravity(0, 0, -9.81) # The surface table is needed for autoCollide world.initSurfaceTable(1) world.setSurfaceEntry(0, 0, 150, 0.0, 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 box box = loader.loadModel("box") # Make sure its center is at 0, 0, 0 like OdeBoxGeom box.setPos(-.5, -.5, -.5) box.flattenLight() # Apply transform box.setTextureOff() # Add a random amount of boxes boxes = [] for i in range(randint(5, 10)): # Setup the geometry
class World(object): def __init__(self, game): super(World, self).__init__() self.game = game self.things = [] #initialize the rendering self.renderer = self.game.render self.initFog() #FIXME do better lighting alight = AmbientLight('alight') alight.setColor(VBase4(0.2, 0.2, 0.2, 1)) alnp = self.renderer.attachNewNode(alight) self.renderer.setLight(alnp) #initialize a hud self.hud = HUD() self.add(self.hud) #physics self.world = OdeWorld() self.world.setGravity(0, -20, 0) #FIXME (0,-9.81) would be realistic physics self.world.initSurfaceTable(1) self.world.setSurfaceEntry(0, 0, 0.6, 0.0, 9.1, 0.9, 0.00001, 1.0, 0.02) #FIXME I have no idea what this means self.space = OdeSimpleSpace() self.space.setAutoCollideWorld(self.world) self.contactGroup = OdeJointGroup() self.space.setAutoCollideJointGroup(self.contactGroup) #constrain to 2d self.plane = OdePlane2dJoint(self.world) self.timeAccumulator = 0 self.dt = 1.0 / 60.0 #give it a player self.player = Player(self, Point3(0,10,0)) self.add(self.player) self.game.taskMgr.add(self.player.move, "movePlayer") def initFog(self): f = Fog("World Fog") f.setColor(0.5,0.5,0.5) f.setLinearOnsetPoint(0,0,0) f.setLinearOpaquePoint(0,0,-Thing.REVERTS_VISIBLE * 3)#THING_REVERT_DISTANCE) self.renderer.attachNewNode(f) self.renderer.setFog(f) def add(self, obj): obj.model.reparentTo(self.renderer) if isinstance(obj, Physical): self.things += [obj] self.plane.attach(obj.body, None) def step(self, task): self.timeAccumulator += globalClock.getDt() while(self.timeAccumulator > self.dt): self.timeAccumulator -= self.dt self.space.autoCollide() self.world.quickStep(self.dt) self.contactGroup.empty() for x in self.things: x.constrainQuat() x.model.setPosQuat(self.renderer, x.body.getPosition(), Quat(x.body.getQuaternion())) return task.cont
class Physics(): def __init__(self): #init the world self.world = OdeWorld() self.world.setGravity(0, 0, -9.81) #init the friction self.world.initSurfaceTable(1) surfaceId1 = 0 surfaceId2 = 0 mu = 500 bounce = 0. # 2 bounce_vel = 0.1 soft_erp = 0.9 soft_cfm = 0.00001 slip = 0.0 dampen = 0.002 self.world.setSurfaceEntry( surfaceId1, surfaceId2, mu, bounce, bounce_vel, soft_erp, soft_cfm, slip, dampen) #init the collision space self.space = OdeSimpleSpace() self.space.setAutoCollideWorld(self.world) self.contactgroup = OdeJointGroup() self.space.setAutoCollideJointGroup(self.contactgroup) self.servogroup = OdeJointGroup() #cm = CardMaker("ground") #cm.setFrame(-20, 20, -20, 20) #ground = render.attachNewNode(cm.generate()) #ground.setPos(0, 0, 0); ground.lookAt(0, 0, -1) # Ground definition self.groundGeom = OdePlaneGeom(self.space, Vec4(0, 0, 1, 0)) self.groundGeom.setCollideBits(BitMask32(0x00000001)) self.groundGeom.setCategoryBits(BitMask32(0x00000002)) self.deltaTimeAccumulator = 0.0 self.stepSize = 0.01 # The task for our simulation def simulationTask(self, creatures, dt=0): # Add the deltaTime for the task to the accumulator self.stepSize = dt for c in creatures: c.update_angles(dt) c.draw() #model.setPosQuat(render, body.getPosition(), Quat(body.getQuaternion())) if dt == 0: self.deltaTimeAccumulator += globalClock.getDt() else: self.deltaTimeAccumulator = dt #while self.deltaTimeAccumulator > self.stepSize: # Remove a stepSize from the accumulator until # the accumulated time is less than the stepsize # self.deltaTimeAccumulator -= self.stepSize # Step the simulation self.space.autoCollide() # Setup the contact joints self.world.quickStep(self.stepSize) # set the new positions self.contactgroup.empty() # Clear the contact joints def run_physics(self, t, creatures): """ run physics for t steps """ for i in range(t): self.simulationTask(creatures, 0.01)