#!/usr/bin/env python import sys import os import math from PyOSG import Producer from PyOSG import osg from PyOSG import osgGA from PyOSG import osgUtil from PyOSG import osgProducer from PyOSG import osgDB class KeyboardEventHandler(osgGA.GUIEventHandler): def __init__(self, stateset): osgGA.GUIEventHandler.__init__(self) self._stateset = stateset self._point=osg.Point() self._point.setDistanceAttenuation(osg.Vec3(0.0,0.0, 0.05)) self._stateset.setAttribute(self._point) self._self = self def handle(self, ea, aa): eType = ea.getEventType() if eType == osgGA.GUIEventAdapter.KEYDOWN: if ea.getKey()==ord('+') or ea.getKey()==osgGA.GUIEventAdapter.KEY_KP_Add: self.changePointSize(1.0) return True elif ea.getKey()==ord('-') or ea.getKey()==osgGA.GUIEventAdapter.KEY_KP_Subtract: self.changePointSize(-1.0) return True elif ea.getKey()==ord('<'): self.changePointAttenuation(1.1) return True elif ea.getKey()==ord('>'): self.changePointAttenuation(1.0 / 1.1) return True return False def accept(self, v): v.visit(self) def getPointSize(self): return self._point.getSize() def setPointSize(self, psize): if psize>0.0: self._point.setSize(psize) print "Point size ", psize def changePointSize(self, delta): self.setPointSize(self.getPointSize()+delta) def changePointAttenuation(self, scale): self._point.setDistanceAttenuation(self._point.getDistanceAttenuation() * scale) 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().setApplicationName(arguments.getApplicationName()) arguments.getApplicationUsage().setDescription(arguments.getApplicationName()+" example provides an interactive viewer for visualising point clouds..") arguments.getApplicationUsage().setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...") arguments.getApplicationUsage().addCommandLineOption("-h or --help","Display this information") arguments.getApplicationUsage().addCommandLineOption("--sprites","Point sprites.") # construct 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()) shader = False while (arguments.read("--shader")): shader = True # if user request help write it out to cout. if arguments.read("-h") or arguments.read("--help"): arguments.getApplicationUsage().write(os.stdout) return 1 usePointSprites = False while (arguments.read("--sprites")): usePointSprites = True # 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(sys.stdout) return 1 if arguments.argc()<=1: arguments.getApplicationUsage().write(sys.stdout,osg.ApplicationUsage.COMMAND_LINE_OPTION) return 1 timer = osg.Timer() start_tick = timer.tick() # read the scene from the list of file specified commandline args. loadedModel = osgDB.readNodeFiles(arguments) # if no model has been successfully loaded report failure. if not loadedModel: print arguments.getApplicationName(), ": No data loaded" return 1 end_tick = timer.tick() print "Time to load = ", timer.delta_s(start_tick,end_tick) # optimize the scene graph, remove rendundent nodes and state etc. optimizer = osgUtil.Optimizer() optimizer.optimize(loadedModel) # set the scene to re viewer.setSceneData(loadedModel) if usePointSprites: stateset = loadedModel.getOrCreateStateSet() # Setup cool blending fn = osg.BlendFunc() stateset.setAttributeAndModes(fn, osg.StateAttribute.ON) # Setup the point sprites sprite = osg.PointSprite() stateset.setTextureAttributeAndModes(0, sprite, osg.StateAttribute.ON) # The texture for the sprites tex = osg.Texture2D() tex.setImage(osgDB.readImageFile("Images/particle.rgb")) stateset.setTextureAttributeAndModes(0, tex, osg.StateAttribute.ON) # register the handler for modifying the point viewer.getEventHandlerList().push_front(KeyboardEventHandler(viewer.getGlobalStateSet())) if shader: stateset = loadedModel.getOrCreateStateSet() # /////////////////////////////////////////////////////////////////// # vertex shader using just Vec4 coefficients vertexShaderSource =\ "void main(void) \n" +\ "{ \n" +\ "\n" +\ " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" +\ "}\n" program = osg.Program() stateset.setAttribute(program) vertex_shader = osg.Shader(osg.Shader.VERTEX, vertexShaderSource) program.addShader(vertex_shader) if 0: # ////////////////////////////////////////////////////////////////// # // fragment shader # // fragmentShaderSource = \ "void main(void) \n" +\ "{ \n" +\ " gl_FragColor = gl_Color; \n" +\ "}\n" fragment_shader = osg.Shader(osg.Shader.FRAGMENT, fragmentShaderSource) program.addShader(fragment_shader) # 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 # 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)