Ejemplo n.º 1
0
 def __init__(self, canRender=0):
     self.canRender = canRender
     self.world = OdeWorld()
     self.space = OdeSimpleSpace()
     self.contactgroup = OdeJointGroup()
     self.bodyList = []
     self.geomList = []
     self.massList = []
     self.rayList = []
     self.showContacts = 0
     self.jointMarkers = []
     self.jointMarkerCount = 64
     self.meshDataList = []
     self.geomDataList = []
     self.commonObjectInfoDict = {}
     self.maxColCount = 0
     if self.canRender:
         self.odePandaRelationList = self.bodyList
         self.root = render.attachNewNode('physics root node')
     else:
         self.root = NodePath('physics root node')
     self.placerNode = self.root.attachNewNode('Placer')
     self.subPlacerNode = self.placerNode.attachNewNode('Placer Sub Node')
     self.commonObjectDict = {}
     self.commonId = 0
     self.worldAttach = self.root.attachNewNode('physics geom attach point')
     self.timingCycleLength = 10.0
     self.timingCycleOffset = 0.0
     self.timingSimTime = 0.0
     self.FPS = 60.0
     self.DTAStep = 1.0 / self.FPS
     self.DTA = 0
     self.useQuickStep = False
     self.deterministic = True
     self.numStepsInSimulateTask = 0
Ejemplo n.º 2
0
class Monde(OdeWorld):
    def __init__(self, app):
        OdeWorld.__init__(self)

        self.app = app

        self.lock = Lock()

        # Creation d'un espace
        self.espace = OdeSimpleSpace()
        # Activation de la collision automatique
        self.espace.setAutoCollideWorld(self)
        # Creation d'une jointure entre les collisions
        self.contactgroup = OdeJointGroup()
        self.espace.setAutoCollideJointGroup(self.contactgroup)

        # Creation d'une liste rassemblant les elements dynamique
        self.elements = []

    def ajouter_element(self, element):
        self.lock.acquire()
        # Ajout d'un element
        if element not in self.elements:
            self.elements.append(element)
        self.lock.release()

    def retirer_element(self, element):
        self.lock.acquire()
        # Suppression d'un element
        if element in self.elements:
            self.elements.remove(element)
        self.lock.release()

    def lancer(self):
        self.app.taskMgr.doMethodLater(1.0 / self.app.FPS, self.simulation,
                                       "SimulationPhysique")

    def arreter(self):
        self.app.taskMgr.remove("SimulationPhysique")

    def simulation(self, task):
        self.espace.autoCollide()  # Setup the contact joints
        # Step the simulation and set the new positions
        self.quickStep(1.0 / self.app.FPS)

        self.lock.acquire()

        # Met a jour chaque element dynamique lier a la physique du jeu
        for element in self.elements:
            element.maj_physique()

        self.lock.release()

        self.contactgroup.empty()  # Clear the contact joints
        return task.cont
Ejemplo n.º 3
0
    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")
Ejemplo n.º 4
0
    def __init__(self, app):
        OdeWorld.__init__(self)

        self.app = app

        self.lock = Lock()

        # Creation d'un espace
        self.espace = OdeSimpleSpace()
        # Activation de la collision automatique
        self.espace.setAutoCollideWorld(self)
        # Creation d'une jointure entre les collisions
        self.contactgroup = OdeJointGroup()
        self.espace.setAutoCollideJointGroup(self.contactgroup)

        # Creation d'une liste rassemblant les elements dynamique
        self.elements = []
Ejemplo n.º 5
0
    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")
Ejemplo n.º 6
0
    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))
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    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")
Ejemplo n.º 10
0
class MinigamePhysicsWorldBase:
    notify = DirectNotifyGlobal.directNotify.newCategory(
        'MinigamePhysicsWorldBase')

    def __init__(self, canRender=0):
        self.canRender = canRender
        self.world = OdeWorld()
        self.space = OdeSimpleSpace()
        self.contactgroup = OdeJointGroup()
        self.bodyList = []
        self.geomList = []
        self.massList = []
        self.rayList = []
        self.showContacts = 0
        self.jointMarkers = []
        self.jointMarkerCount = 64
        self.meshDataList = []
        self.geomDataList = []
        self.commonObjectInfoDict = {}
        self.maxColCount = 0
        if self.canRender:
            self.odePandaRelationList = self.bodyList
            self.root = render.attachNewNode('physics root node')
        else:
            self.root = NodePath('physics root node')
        self.placerNode = self.root.attachNewNode('Placer')
        self.subPlacerNode = self.placerNode.attachNewNode('Placer Sub Node')
        self.commonObjectDict = {}
        self.commonId = 0
        self.worldAttach = self.root.attachNewNode('physics geom attach point')
        self.timingCycleLength = 10.0
        self.timingCycleOffset = 0.0
        self.timingSimTime = 0.0
        self.FPS = 60.0
        self.DTAStep = 1.0 / self.FPS
        self.DTA = 0
        self.useQuickStep = False
        self.deterministic = True
        self.numStepsInSimulateTask = 0
        self.collisionEventName = 'ode-collision-%s' % id(self)
        self.space.setCollisionEvent(self.collisionEventName)
        self.accept(self.collisionEventName, self.__handleCollision)

    def delete(self):
        self.notify.debug('Max Collision Count was %s' % self.maxColCount)
        self.stopSim()
        self.commonObjectDict = None
        if self.canRender:
            for pair in self.odePandaRelationList:
                pair[0].removeNode()
                pair[1].destroy()

            self.odePandaRelationList = None
        else:
            for body in self.bodyList:
                body[1].destroy()

            self.bodyList = None
        for mass in self.massList:
            mass = None

        for geom in self.geomList:
            geom.destroy()
            geom = None

        for ray in self.rayList:
            ray.destroy()
            ray = None

        self.placerNode.removeNode()
        self.root.removeNode()
        for marker in self.jointMarkers:
            marker.removeNode()

        self.jointMarkers = None
        for data in self.geomDataList:
            data.destroy()

        for data in self.meshDataList:
            data.destroy()

        self.contactgroup.empty()
        self.world.destroy()
        self.space.destroy()
        self.world = None
        self.space = None
        self.ignore(self.collisionEventName)
        return

    def setupSimulation(self):
        if self.canRender:
            for count in xrange(self.jointMarkerCount):
                testMarker = render.attachNewNode('Joint Marker')
                ballmodel = loader.loadModel('phase_3/models/misc/sphere')
                ballmodel.reparentTo(testMarker)
                ballmodel.setScale(0.1)
                testMarker.setPos(0.0, 0.0, -100.0)
                self.jointMarkers.append(testMarker)

    def startSim(self):
        taskMgr.add(self.__simulationTask, 'simulation task')

    def stopSim(self):
        taskMgr.remove('simulation task')

    def __simulationTask(self, task):
        self.DTA += globalClock.getDt()
        numSteps = int(self.DTA / self.DTAStep)
        if numSteps > 10:
            self.notify.warning('phyics steps = %d' % numSteps)
        startTime = globalClock.getRealTime()
        while self.DTA >= self.DTAStep:
            if self.deterministic:
                OdeUtil.randSetSeed(0)
            self.DTA -= self.DTAStep
            self.preStep()
            self.simulate()
            self.postStep()

        if self.canRender:
            self.placeBodies()
        return task.cont

    def preStep(self):
        pass

    def postStep(self):
        if self.showContacts and self.canRender:
            for count in xrange(self.jointMarkerCount):
                pandaNodePathGeom = self.jointMarkers[count]
                if count < self.colCount:
                    pandaNodePathGeom.setPos(
                        self.space.getContactData(count * 3 + 0),
                        self.space.getContactData(count * 3 + 1),
                        self.space.getContactData(count * 3 + 2))
                else:
                    pandaNodePathGeom.setPos(0.0, 0.0, -100.0)

    def __handleCollision(self, entry):
        self.colEntries.append(entry)

    def simulate(self):
        self.colEntries = []
        self.space.autoCollide()
        eventMgr.doEvents()
        self.colCount = len(self.colEntries)
        if self.maxColCount < self.colCount:
            self.maxColCount = self.colCount
            self.notify.debug('New Max Collision Count %s' % self.maxColCount)
        if self.useQuickStep:
            self.world.quickStep(self.DTAStep)
        else:
            self.world.step(self.DTAStep)
        for bodyPair in self.bodyList:
            self.world.applyDampening(self.DTAStep, bodyPair[1])

        self.contactgroup.empty()
        self.timingSimTime = self.timingSimTime + self.DTAStep

    def placeBodies(self):
        for pair in self.odePandaRelationList:
            pandaNodePathGeom = pair[0]
            odeBody = pair[1]
            if pandaNodePathGeom:
                pandaNodePathGeom.setPos(odeBody.getPosition())
                pandaNodePathGeom.setQuat(
                    Quat(odeBody.getQuaternion()[0],
                         odeBody.getQuaternion()[1],
                         odeBody.getQuaternion()[2],
                         odeBody.getQuaternion()[3]))

    def getOrderedContacts(self, entry):
        c0 = self.space.getCollideId(entry.getGeom1())
        c1 = self.space.getCollideId(entry.getGeom2())
        if c0 > c1:
            return c1, c0
        else:
            return c0, c1
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
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
    boxNP = box.copyTo(render)
    # boxNP.setPos(randint(-10, 10), randint(-10, 10), 10 + random())
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
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)