#C++ source file - Open Producer - Copyright (C) 2002 Don Burns #Distributed under the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE (LGPL) #as published by the Free Software Foundation. # A simple example demonstrating the use of the Producer.OsgCameraGroup from PyOSG import * class KBMCB(Producer.KeyboardMouseCallback): def __init__(self): Producer.KeyboardMouseCallback.__init__(self) self._mx = 0.0 self._my = 0.0 self._mbutton = 0 # Trick to allow passing py reference of _toggleResetTrackball, # since it is modified in _checkToggle self._toggleResetTrackball = [False] self._quit = False def mouseMotion(self, mx, my ): self._mx = mx self._my = my def buttonPress(self, mx, my, button): self._mx = mx self._my = my self._mbutton |= (1<<(button-1)) def buttonRelease(self, mx, my, button ): self._mx = mx self._my = my self._mbutton &= ~(1<<(button-1)) def keyPress(self, key ): if key == ord(' '): self._toggleResetTrackball[0] = True def specialKeyPress(self, key ): if key == Producer.KeyChar_Escape : self._quit = True def mx(self): return self._mx def my(self): return self._my def mbutton(self): return self._mbutton def resetTrackball(self): return self._checkToggle(self._toggleResetTrackball) def quit(self): return self._quit def _checkToggle(self,toggle): if toggle[0]: toggle[0] = False return True return False def main(): # Set up the osgProducer Camera Group # Output configuration changes by simply changing # the config file here cameraGroup = osgProducer.OsgCameraGroup( "singleWindow.cfg") # Load the database root = osgDB.readNodeFile( "cow.osg" ) # Tell the camera group about the scene # OsgCameraGroup manages all cameras and their associated # scene handlers and will pass this root data to each. cameraGroup.setSceneData(root) # Set up the Producer Trackball. Trackball is just one # example of a camera manipulator bs = root.getBound() tb = Producer.Trackball() tb.setDistance( bs.radius() * 3.4) tb.setReference() # Set up a KeyboardMouse handler. # This will run in a background thread after the call to # startThread(). # kbm = Producer.KeyboardMouse() # Note the use of InputArea here as defined in singleWindow.cfg # If InputArea is not defined, then use the 0th window as the sole # input area inputArea = cameraGroup.getCameraConfig().getInputArea() if inputArea != None: kbm = Producer.KeyboardMouse(inputArea) else: kbm = Producer.KeyboardMouse(cameraGroup.getCamera(0).getRenderSurface()) # Set up a keyboardmouse callback, which is our own implementation # of a Producer.KeyboardMouseCallback. See kbmcb.h kbmcb = KBMCB() kbm.setCallback(kbmcb ) kbm.startThread() # Use thread per camera when using more than one Camera #cameraGroup.realize( Producer.CameraGroup.ThreadPerCamera ) cameraGroup.realize( Producer.CameraGroup.SingleThreaded ) # The keyboard mouse callback will indicate when its time # to quit (press ) while not kbmcb.quit(): cameraGroup.sync() # When running multi-threaded (ThreadPerCamera or ThreadPerRenderSurface) # Altering of the scene graph or any other data must occur only between # cameraGroup.sync() and cameraGroup.frame(). Data is NOT protected # between frame() and sync(). # The KeyboardMouseCallback will tell us when to reset the # trackball (press ). if kbmcb.resetTrackball(): tb.reset() # The trackball manipulator takes normalized values for # x and y(ranging from -1 to 1), and a button state with # a bit set for each button pressed tb.input( kbmcb.mx(), kbmcb.my(), kbmcb.mbutton() ) # The Trackball manipulator outputs a matrix. Pass this # to the Producer;:Camera cameraGroup.setViewByMatrix(tb.getMatrix()) # Call the frame. In multi-threaded mode, this returns immediately # Data must not be altered until after sync(), or unless the application # mutibuffers it. cameraGroup.frame() if __name__ == "__main__": main()