Exemple #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
    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")
Exemple #3
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 = []
    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")
Exemple #5
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))
    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)
Exemple #7
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
Exemple #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
Exemple #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")
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
Exemple #11
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
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
Exemple #13
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
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 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
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()



Exemple #17
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)