#!/bin/env python # Copyright (C) 2002-2003 Gideon May (gideon@computer.org) # # Permission to copy, use, sell and distribute this software is granted # provided this copyright notice appears in all copies. # Permission to modify the code and to distribute modified code is granted # provided this copyright notice appears in all copies, and a notice # that the code was modified is included with the copyright notice. # # This software is provided "as is" without express or implied warranty, # and with no claim as to its suitability for any purpose. # -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield # # This application is open source and may be redistributed and/or modified # freely and without restriction, both in commericial and non commericial applications, # as long as this copyright notice is maintained. # # This application is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # import sys from PyOSG import Producer from PyOSG import osg from PyOSG import osgDB from PyOSG import osgUtil from PyOSG import osgGA from PyOSG import osgProducer def write_usage(name): print "usage:" print " ",name," [options] infile1 [infile2 ...]" print print "options:" print " -l libraryName - load plugin of name libraryName" print " i.e. -l osgdb_pfb" print " Useful for loading reader/writers which can load" print " other file formats in addition to its extension." print " -e extensionName - load reader/wrter plugin for file extension" print " i.e. -e pfb" print " Useful short hand for specifying full library name as" print " done with -l above, as it automatically expands to" print " the full library name appropriate for each platform." print print " -stereo - switch on stereo rendering, using the default of," print " ANAGLYPHIC or the value set in the OSG_STEREO_MODE " print " environmental variable. See doc/stereo.html for " print " further details on setting up accurate stereo " print " for your system. " print " -stereo ANAGLYPHIC - switch on anaglyphic(red/cyan) stereo rendering." print " -stereo QUAD_BUFFER - switch on quad buffered stereo rendering." print print " -stencil - use a visual with stencil buffer enabled, this " print " also allows the depth complexity statistics mode" print " to be used (press 'p' three times to cycle to it)." print def decorate_with_clip_node(subgraph): rootnode = osg.Group() # create wireframe view of the model so the user can see # what parts are being culled away. stateset = osg.StateSet() polymode = osg.PolygonMode() polymode.setMode(osg.PolygonMode.FRONT_AND_BACK,osg.PolygonMode.LINE) stateset.setAttributeAndModes(polymode,osg.StateAttribute.OVERRIDE|osg.StateAttribute.ON) wireframe_subgraph = osg.Group() wireframe_subgraph.setStateSet(stateset) wireframe_subgraph.addChild(subgraph) rootnode.addChild(wireframe_subgraph) """ # simple approach to adding a clipnode above a subrgaph. # create clipped part. clipped_subgraph = osg.ClipNode() bs = subgraph.getBound() bs.radius( bs.radius() * 0.4) bb = osg.BoundingBox() bb.expandBy(bs) clipped_subgraph.createClipBox(bb) clipped_subgraph.addChild(subgraph) rootnode.addChild(clipped_subgraph) """ # more complex approach to managing ClipNode, allowing # ClipNode node to be transformed independantly from the subgraph # that it is clipping. transform= osg.MatrixTransform() nc = osgUtil.newTransformCallback(subgraph.getBound().center(),osg.Vec3(0.0,0.0,1.0),osg.inDegrees(45.0)) transform.setUpdateCallback(nc) clipnode = osg.ClipNode() bs = subgraph.getBound() bs.radius(bs.radius() * 0.4) bb = osg.BoundingBox() bb.expandBy(bs) clipnode.createClipBox(bb) clipnode.setCullingActive(0) transform.addChild(clipnode) rootnode.addChild(transform) # create clipped part. clipped_subgraph = osg.Group() clipped_subgraph.setStateSet(clipnode.getStateSet()) clipped_subgraph.addChild(subgraph) rootnode.addChild(clipped_subgraph) return rootnode def main(argv): # use an ArgumentParser object to manage the program arguments. arguments = osg.ArgumentParser(argv) # set up the usage document, in case we need to print out how to use this program. arguments.getApplicationUsage().setDescription(arguments.getApplicationName()+" is the example which demonstrates use multi-pass and osg.ClipNode to clip parts of the scene away..") arguments.getApplicationUsage().setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...") arguments.getApplicationUsage().addCommandLineOption("-h or --help","Display this information") # initialize the viewer. viewer = osgProducer.Viewer(arguments) # set up the value with sensible default event handlers. viewer.setUpViewer(osgProducer.Viewer.STANDARD_SETTINGS) # get details on keyboard and mouse bindings used by the viewer. viewer.getUsage(arguments.getApplicationUsage()) # if user request help write it out to cout. if arguments.read("-h") or arguments.read("--help"): arguments.getApplicationUsage().write() return 1 # any option left unread are converted into errors to write out later. arguments.reportRemainingOptionsAsUnrecognized() # report any errors if they have occured when parsing the program aguments. if arguments.errors(): arguments.writeErrorMessages() return 1 if arguments.argc()<=1: arguments.getApplicationUsage().write(osg.ApplicationUsage.COMMAND_LINE_OPTION) return 1 # load the nodes from the commandline arguments. loadedModel = osgDB.readNodeFiles(arguments) if not loadedModel: write_usage(osg.notify(osg.NOTICE),argv[0]) return 1 # decorate the scenegraph with a clip node. rootnode = decorate_with_clip_node(loadedModel) # run optimization over the scene graph optimzer = osgUtil.Optimizer() optimzer.optimize(rootnode) # set the scene to render viewer.setSceneData(rootnode) # create the windows and run the threads. viewer.realize() while not viewer.done(): # wait for all cull and draw threads to complete. viewer.sync() # update the scene by traversing it with the the update visitor which will # call all node update callbacks and animations. viewer.update() # fire off the cull and draw traversals of the scene. viewer.frame() # wait for all cull and draw threads to complete before exit. viewer.sync() return 0 if __name__ == "__main__": main(sys.argv)