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