IntermediateTutorial4Source

From PyWiki

Jump to: navigation, search
import ogre.renderer.OGRE as ogre
import ogre.io.OIS as OIS
import ogre.gui.CEGUI as cegui
import SampleFramework
import ctypes
 
from CEGUI_framework import *
 
##===============================================================================##
##   Selection Rectangle Class
##===============================================================================##
class SelectionRectangle (ogre.ManualObject):
    def __init__(self,name):
        ogre.ManualObject.__init__(self,name)
        ## set selection rectangle to render in 2D and it sits on top of all other objects on screen
        ## ( render when Ogre's Overlays render)
 
        self.setRenderQueueGroup(ogre.RenderQueueGroupID.RENDER_QUEUE_OVERLAY)
        #self.setRenderQueueGroup(ogre.RENDER_QUEUE_OVERLAY)
 
        self.setUseIdentityProjection(True)
        self.setUseIdentityView(True)
        self.setQueryFlags(0)
 
 
    def setCorners(self, vecFirst, vecSecond):
        self._setCorners(vecFirst.x, vecFirst.y, vecSecond.x, vecSecond.y)
 
 
    ##
    ## Sets the corners of the SelectionRectangle.  Every parameter should be in the
    ## range [0, 1] representing a percentage of the screen the SelectionRectangle
    ## should take up.
    ##
    def _setCorners(self, left, top, right, bottom):
 
        ## CEGUI mouse cursor defines the top of the screen at 0, the bottom at 1. 
        ## Convert these to numbers in the range [-1, 1], in our new coordinate system, 
        ## the top of the screen is +1, the bottom is -1
 
        left = left * 2 - 1
        right = right * 2 - 1
        top = 1 - top * 2
        bottom = 1 - bottom * 2
 
 
        ## create our rectangle, we will define 5 points (the first and the last point 
        ## are the same to connect the entire rectangle)
 
        self.clear()
        self.begin("", ogre.RenderOperation.OT_LINE_STRIP)
        self.position(left, top, -1)
        self.position(right, top, -1)
        self.position(right, bottom, -1)
        self.position(left, bottom, -1)
        self.position(left, top, -1)
        self.end()
 
        # set the bounding box of the object to be infinite, so that the camera will 
        # always be inside of it
 
        box = ogre.AxisAlignedBox()
        box.setInfinite()
        self.setBoundingBox(box)
 
 
##===============================================================================##
##   Subclassed Scene Query Listener
##===============================================================================##
class PlaneQueryListener(ogre.SceneQueryListener):
    """ the listener that gets called for each pair of intersecting objects """   
    def __init__ ( self):
        ogre.SceneQueryListener.__init__ ( self )
        self.selectObjects = []
 
    ##----------------------------------------------------------------##
    def queryResult (  self, firstMovable):
        firstMovable.getParentSceneNode().showBoundingBox(True)
        self.selectObjects.append(firstMovable)
        print type(firstMovable)
        #print firstMovable.name, dir(firstMovable)
        return True
 
    ##----------------------------------------------------------------##
    def deselectObjects(self):
        for movableObject in self.selectObjects:
            movableObject.getParentSceneNode().showBoundingBox(False)
 
 
##===============================================================================##
##   CEGUI Application
##===============================================================================##
class GEUIApplication ( SampleFramework.Application ):
 
    def __init__(self):
        SampleFramework.Application.__init__(self)
        self.GUIRenderer=0
        self.GUIsystem =0
        self.EditorGuiSheet=0
 
 
    def __del__(self):
 
        del self.camera
        del self.sceneManager
        del self.frameListener
        try:
            if self.EditorGuiSheet:
                CEGUI.WindowManager.getSingleton().destroyWindow(self.EditorGuiSheet) 
        except:
            pass
        del self.GUIsystem
        del self.GUIRenderer
        del self.root
        del self.renderWindow        
 
    ##----------------------------------------------------------------##
    def _chooseSceneManager(self):
        #self.sceneManager = self.root.createSceneManager("TerrainSceneManager")
        self.sceneManager = self.root.createSceneManager(ogre.ST_EXTERIOR_CLOSE)  
 
    ## Just override the mandatory create scene method
    ##----------------------------------------------------------------##
    def _createScene(self):
        sceneManager = self.sceneManager
        sceneManager.ambientLight = ogre.ColourValue(0.5, 0.5, 0.5)
 
        sceneManager.setWorldGeometry('terrain.cfg')
 
 
        ## Create a light
        l = self.sceneManager.createLight("MainLight") 
        l.setPosition(20,80,50) 
 
        ## setup GUI system
        self.GUIRenderer = CEGUI.OgreCEGUIRenderer(self.renderWindow, 
            ogre.RENDER_QUEUE_OVERLAY, False, 3000, self.sceneManager) 
 
        self.GUIsystem = CEGUI.System(self.GUIRenderer) 
 
        logger = CEGUI.Logger.getSingleton()
        logger.setLoggingLevel( CEGUI.Informative ) 
 
        ## load scheme and set up defaults
        CEGUI.SchemeManager.getSingleton().loadScheme("TaharezLookSkin.scheme") 
        CEGUI.MouseCursor.getSingleton().setImage("TaharezLook", "MouseArrow")
 
        self.camera.setPosition(-60, 100, -60)
        self.camera.lookAt(60, 0, 60)
 
        self.sceneManager.setAmbientLight(ogre.ColourValue.White)
        for i in range(10):
            for j in range(10):
                name = 
                ent = self.sceneManager.createEntity("Robot" + str(i + j * 10), "robot.mesh")
                node = self.sceneManager.getRootSceneNode().createChildSceneNode(ogre.Vector3(i * 15, 0, j * 15))
                node.attachObject(ent)
                node.setScale(0.1, 0.1, 0.1)
 
 
 
    ##----------------------------------------------------------------##
    def _createFrameListener(self):
        self.frameListener = CEGUIFrameListener( self.renderWindow,
                                                 self.camera,
                                                 self.sceneManager,
                                                 self.GUIRenderer)
        self.root.addFrameListener(self.frameListener)
        self.frameListener.showDebugOverlay(True)
 
 
##===============================================================================##
##   CEGUI FrameListener
##===============================================================================##
class CEGUIFrameListener(SampleFramework.FrameListener, OIS.KeyListener, OIS.MouseListener):
 
    def __init__(self, renderWindow, camera, sceneManager, CEGUIRenderer):
 
        SampleFramework.FrameListener.__init__(self, renderWindow, camera, True, True, True)
 
        OIS.KeyListener.__init__(self)
        OIS.MouseListener.__init__(self)
        self.Mouse.setEventCallback(self)
        self.Keyboard.setEventCallback(self)
 
 
        self.ShutdownRequested = False
        self.GUIRenderer = CEGUIRenderer
        self.keepRendering = True   # whether to continue rendering or not
        self.numScreenShots = 0     # screen shot count
 
        self.mSelected = []  ## list selected movable objects
        self.keepRendering = True   # whether to continue rendering or not
 
        self.sceneManager = sceneManager
        self.camera = camera
 
        self.mStart = ogre.Vector2()
        self.mStop = ogre.Vector2()
 
        #self.mVolQuery = None  ## PlaneBoundedVolumeListSceneQuery
        self.mRect = None      ## SelectionRectangle 
        self.mSelecting = False
 
 
        self.mRect = SelectionRectangle("Selection SelectionRectangle")
        self.sceneManager.getRootSceneNode().createChildSceneNode().attachObject(self.mRect)
        self.mVolQuery = sceneManager.createPlaneBoundedVolumeQuery(ogre.PlaneBoundedVolumeList())
 
        # and a listener to receive the results
        self.querylistener = PlaneQueryListener()
 
    def __del__(self):
 
        self.sceneManager.destroyQuery(self.mVolQuery)
        del self.mRect
        del self.mVolQuery
 
    ## Tell the frame listener to exit at the end of the next frame
    ##----------------------------------------------------------------##
    def requestShutdown( self ):
        self.ShutdownRequested = True
 
    ##----------------------------------------------------------------##
    def frameEnded(self, evt):
        if self.ShutdownRequested:
            return False
        else:
            return SampleFramework.FrameListener.frameEnded(self, evt)
 
    ##----------------------------------------------------------------##
    def keyPressed( self, arg ):
        if arg.key == OIS.KC_ESCAPE:
            self.ShutdownRequested = True
        CEGUI.System.getSingleton().injectKeyDown( arg.key )
        CEGUI.System.getSingleton().injectChar( arg.text )
        return True
 
    ##----------------------------------------------------------------##
    def keyReleased( self, arg ):
        CEGUI.System.getSingleton().injectKeyUp( arg.key )
        return True
 
    ##----------------------------------------------------------------##
    def frameStarted(self, evt):
        return SampleFramework.FrameListener.frameStarted(self,evt)
 
    ##----------------------------------------------------------------##
    def performSelection(self, vec2first, vec2second):
        left =  vec2first.x
        right = vec2second.x
        top = vec2first.y
        bottom = vec2second.y
 
        if left > right:
            left, right = right, left
 
        if top > bottom:
            top, bottom = bottom, top
 
        if (right - left) * (bottom - top) < 0.0001:
            return
 
        ## Rays
        topLeft     = self.camera.getCameraToViewportRay(left, top)
        topRight    = self.camera.getCameraToViewportRay(right, top)
        bottomLeft  = self.camera.getCameraToViewportRay(left, bottom)
        bottomRight = self.camera.getCameraToViewportRay(right, bottom);
 
 
        vol = ogre.PlaneBoundedVolume()
        planeList = vol.planes
        p = ogre.Plane(  topLeft.getPoint(3),
                         topRight.getPoint(3),
                         bottomRight.getPoint(3))
        p2 = ogre.Plane( topLeft.getOrigin(),
                         topLeft.getPoint(100),
                         topRight.getPoint(100))
        p3 = ogre.Plane( topLeft.getOrigin(),
                         bottomRight.getPoint(100),
                         bottomLeft.getPoint(100))
        p4 = ogre.Plane( topLeft.getOrigin(),
                         topRight.getPoint(100),
                         bottomRight.getPoint(100))
 
        vol.planes.append(p)  ## front plane
        vol.planes.append(p2) ## left plane
        vol.planes.append(p3) ## bottom plane
        vol.planes.append(p4) ## top plane
 
 
        ## These planes have now defined an "open box" which extends to infinity in front of the
        ## camera. You can think of the rectangle we drew with the mouse as being the termination
        ## point of the box just in front of the camera. 
        ## Now that we have created the planes, we need to execute the query:
 
        volList = ogre.PlaneBoundedVolumeList()
        volList.append(vol)
 
        self.mVolQuery.setVolumes(volList)
 
        if 1==1:
            self.mVolQuery.execute( self.querylistener )
        else:
 
            print "=================="
            print "THIS CRASHES"
            print "=================="
 
            for queryResult in self.mVolQuery.execute():
                if queryResult.movableObject is not None:
                    self.selectObject(queryResult.movableObject)
 
 
    ##----------------------------------------------------------------##
    def selectObject(self, movableObject):
        movableObject.getParentSceneNode().showBoundingBox(True)
        self.mSelected.append(movableObject)
 
    ##----------------------------------------------------------------##
    def mousePressed(  self, arg, id ):
 
        if convertOISMouseButtonToCegui(id) == OIS.MB_Left:
            self.querylistener.deselectObjects()
            mouse = CEGUI.MouseCursor.getSingletonPtr()
            print mouse.getPosition().d_x
            self.mStart.x = mouse.getPosition().d_x / float(arg.get_state().width  )
            self.mStart.y = mouse.getPosition().d_y / float(arg.get_state().height )
            self.mStop = ogre.Vector2(self.mStart.x, self.mStart.y)
            self.mSelecting = True
            self.mRect.clear()
            self.mRect.setVisible(True)
        CEGUI.System.getSingleton().injectMouseButtonDown(convertOISMouseButtonToCegui(id))
        return True
 
    ##----------------------------------------------------------------##
    def mouseReleased( self, arg, id ):
        if convertOISMouseButtonToCegui(id) == OIS.MB_Left:
            self.performSelection(self.mStart, self.mStop)
            self.mSelecting = False
            self.mRect.setVisible(False)
        CEGUI.System.getSingleton().injectMouseButtonUp(convertOISMouseButtonToCegui(id))
        return True
 
    ##----------------------------------------------------------------##
    def mouseMoved( self, arg ):
        if self.mSelecting:
            mouse = CEGUI.MouseCursor.getSingletonPtr()
            self.mStop.x = mouse.getPosition().d_x / float(arg.get_state().width)
            self.mStop.y = mouse.getPosition().d_y / float(arg.get_state().height)
            #print self.mStart, self.mStop
            self.mRect.setCorners(self.mStart, self.mStop)
        CEGUI.System.getSingleton().injectMouseMove( arg.get_state().X.rel, arg.get_state().Y.rel )
        return True
 
 
 
 
if __name__ == '__main__':
    try:
        ta = GEUIApplication()
        ta.go()
    except ogre.OgreException, e:
        print e
Personal tools