Public feed #603182

collision.py

public python v1 · immutable
Raw Edit
·published 2007-07-04 16:10 UTC
rendered paste body
# This code is in the Public Domain# -----------------------------------------------------------------------------# This source file is part of Python-Ogre# For the latest info, see http://python-ogre.org/## It is likely based on original code from OGRE and/or PyOgre# For the latest info, see http://www.ogre3d.org/## You may use this sample code for anything you like, it is not covered by the# LGPL.# -----------------------------------------------------------------------------import ogre.renderer.OGRE as ogreimport ogre.physics.ODE as odeimport SampleFramework as sfimport sys# Initialize Physicsworld = ode.dWorld()world.setGravity( 0,-9.81,0 )world.setERP(0.8)world.setCFM(1E-5)space = ode.CreateSimpleSpace()contactgroup = ode.dJointGroup()ball = {}floor = {}## As this demo does it's own key input we need to cope with the change to OISif ogre.OgreVersionString[:2]=="12":    KC_N = ogre.KC_N    KC_M = ogre.KC_M    KC_H = ogre.KC_H    KC_J = ogre.KC_J    KC_SPACE = ogre.KC_SPACEelse:    import ogre.io.OIS as OIS    KC_N = OIS.KC_N    KC_M = OIS.KC_M    KC_H = OIS.KC_H    KC_J = OIS.KC_J    KC_SPACE = OIS.KC_SPACEclass SkyBoxApplication(sf.Application):    def _createScene(self):        sceneManager = self.sceneManager        sceneManager.ambientLight = ogre.ColourValue(0.1, 0.1, 0.1)        sceneManager.setSkyBox(True, "Examples/SpaceSkyBox")                # Create the ball        body = ode.dBody( world.id() )        body.setPosition( 0, 100, 0 )        mass = ode.dMass()        density = 100        radius = 5        mass.setSphere( density, radius )        body.setMass( mass )                geom = ode.dCreateSphere( space.id(), radius )        ode.dGeomSetBody( geom, body.id() )        # Default sphere is 100 units, will compensate with node scale to make it 10 units        entity = sceneManager.createEntity( "myBall", ogre.SceneManager.PT_SPHERE )        entity.getMesh().buildTangentVectors( ogre.VertexElementSemantic.VES_TANGENT )        entity.setMaterialName( "Examples/BumpMapping/MultiLightSpecular" )                   node = sceneManager.getRootSceneNode().createChildSceneNode( "ball_node" )        node.setPosition( body.getPosition() )        node.setScale( 0.1, 0.1, 0.1 )        node.attachObject( entity )                ball["body"] = body        ball["entity"] = entity        ball["node"] = node                        # Create the floor        body = ode.dBody( world.id() )        body.setPosition( 0, -100, 0 )        body.setGravityMode( False )        mass = ode.dMass()        density = 100        box = { 'x':200, 'y':10, 'z':200 }        mass.setBox( density, box['x'], box['y'], box['z'] )        body.setMass( mass )                geom = ode.dCreateBox( space.id(), box['x'], box['y'], box['z'] )        ode.dGeomSetBody( geom, body.id() )                entity = sceneManager.createEntity( "myFloor", ogre.SceneManager.PT_CUBE )        entity.setMaterialName( "Ground" )           entity.setCastShadows( False )                node = sceneManager.getRootSceneNode().createChildSceneNode( "floor_node" )        node.setPosition( body.getPosition() )        node.setScale( 2, 0.1, 2 )        node.attachObject( entity )                floor["body"] = body        floor["entity"] = entity        floor["node"] = node                        # Need a light         light = sceneManager.createLight('MainLight')        light.setType(ogre.Light.LT_SPOTLIGHT)        light.setDirection(ogre.Vector3.NEGATIVE_UNIT_Y)        light.setCastShadows(True)        light.setAttenuation(8000,1,0.0005,0)        light.setSpotlightRange(ogre.Degree(d=80),ogre.Degree(d=90))        light.setDiffuseColour( 1, 0.8, 0.8 )        light.setSpecularColour( 0.5, 0, 0 )        light.setPosition (20, 180, 50)        sceneManager.setShadowTechnique( ogre.SHADOWTYPE_STENCIL_ADDITIVE )            def _createFrameListener(self):        self.frameListener = SkyBoxListener(self.renderWindow, self.camera, self.sceneManager)        self.root.addFrameListener(self.frameListener)class SkyBoxListener(sf.FrameListener):    def __init__(self, renderWindow, camera, sceneManager):        sf.FrameListener.__init__(self, renderWindow, camera)        self.sceneManager = sceneManager        self.delta_step = 0.0        def near_callback(self, args, geom1, geom2):        """Callback function for the collide() method.            This function checks if the given geoms do collide and        creates contact joints if they do.        """        # Check if the objects do collide        contacts = ode.dCollide( geom1, geom2 )            # Create contact joints        world,contactgroup = args        for c in contacts:            c.setBounce(0.2)            c.setMu(5000)            j = ode.dContactJoint(self.world, self.contactgroup, c)            j.attach(geom1.getBody(), geom2.getBody())                    def updatePhysics(self, frameEvent ):        self.delta_step += frameEvent.timeSinceLastFrame        while( self.delta_step > 0.03 ):            world.step( 0.03 )            self.delta_step -= 0.03            space.collide( ( world, contactgroup ), self.near_callback, "" )                ball["node"].setPosition( ball["body"].getPosition() )        ball["node"].setOrientation( ball["body"].getQuaternion() )        floor["node"].setPosition( floor["body"].getPosition() )        floor["node"].setOrientation( floor["body"].getQuaternion() )        def frameStarted(self, frameEvent):                    if self._isToggleKeyDown(KC_SPACE, 0.1):            pos = self.camera.getPosition()            ball["body"].setPosition( pos.x, pos.y, pos.z )            dir = self.camera.getOrientation() * ogre.Vector3.NEGATIVE_UNIT_Z * 200.0            ball["body"].setLinearVel( dir.x, dir.y, dir.z )                self.updatePhysics( frameEvent )                return sf.FrameListener.frameStarted(self, frameEvent)if __name__ == '__main__':            try:        application = SkyBoxApplication()        application.go()    except ogre.OgreException, e:        print e