def makeFrustumFromCamera(camera): # Projection and ModelView matrices proj = osg.Matrixd() mv = osg.Matrixd() if camera : proj = camera.getProjectionMatrix() mv = camera.getViewMatrix() else: # Create some kind of reasonable default Projection matrix. proj.makePerspective( 30., 1., 1., 10. ) # leave mv as identity # Get near and far from the Projection matrix. near = proj(3,2) / (proj(2,2)-1.0) far = proj(3,2) / (1.0+proj(2,2)) # Get the sides of the near plane. nLeft = near * (proj(2,0)-1.0) / proj(0,0) nRight = near * (1.0+proj(2,0)) / proj(0,0) nTop = near * (1.0+proj(2,1)) / proj(1,1) nBottom = near * (proj(2,1)-1.0) / proj(1,1) # Get the sides of the far plane. fLeft = far * (proj(2,0)-1.0) / proj(0,0) fRight = far * (1.0+proj(2,0)) / proj(0,0) fTop = far * (1.0+proj(2,1)) / proj(1,1) fBottom = far * (proj(2,1)-1.0) / proj(1,1) # Our vertex array needs only 9 vertices: The origin, and the # eight corners of the near and far planes. v = osg.Vec3Array() v.resize( 9 ) (*v)[0].set( 0., 0., 0. ) (*v)[1].set( nLeft, nBottom, -near ) (*v)[2].set( nRight, nBottom, -near ) (*v)[3].set( nRight, nTop, -near ) (*v)[4].set( nLeft, nTop, -near ) (*v)[5].set( fLeft, fBottom, -far ) (*v)[6].set( fRight, fBottom, -far ) (*v)[7].set( fRight, fTop, -far ) (*v)[8].set( fLeft, fTop, -far ) geom = osg.Geometry() geom.setUseDisplayList( False ) geom.setVertexArray( v ) c = osg.Vec4Array() c.push_back( osg.Vec4( 1., 1., 1., 1. ) ) geom.setColorArray( c, osg.Array.BIND_OVERALL ) GLushort idxLines[8] = 0, 5, 0, 6, 0, 7, 0, 8
def computeViewMatrix(camera, eye, hpr): matrix = osg.Matrixd() matrix.makeTranslate( eye ) matrix.preMult( osg.Matrixd.rotate( hpr[0], 0.0, 1.0, 0.0) ) matrix.preMult( osg.Matrixd.rotate( hpr[1], 1.0, 0.0, 0.0) ) matrix.preMult( osg.Matrixd.rotate( hpr[2], 0.0, 0.0, 1.0) ) camera.setViewMatrix( osg.Matrixd.inverse(matrix) )
def createScalarBar_HUD(): geode = osgSim.ScalarBar() tp = osgSim.ScalarBar.TextProperties() tp._fontFile = "fonts/times.ttf" geode.setTextProperties(tp) stateset = geode.getOrCreateStateSet() stateset.setMode(GL_LIGHTING, osg.StateAttribute.OFF) stateset.setMode(GL_DEPTH_TEST,osg.StateAttribute.OFF) stateset.setRenderBinDetails(11, "RenderBin") modelview = osg.MatrixTransform() modelview.setReferenceFrame(osg.Transform.ABSOLUTE_RF) matrix = osg.Matrixd(osg.Matrixd.scale(1000,1000,1000) * osg.Matrixd.translate(120,10,0)) # I've played with these values a lot and it seems to work, but I have no idea why modelview.setMatrix(matrix) modelview.addChild(geode) projection = osg.Projection() projection.setMatrix(osg.Matrix.ortho2D(0,1280,0,1024)) # or whatever the OSG window res is projection.addChild(modelview) return projection #make sure you delete the return sb line
osg.Matrixd TestManipulator.getMatrix() return osg.Matrixd.rotate(_rotation)*osg.Matrixd.translate(_center) osg.Matrixd TestManipulator.getInverseMatrix() return osg.Matrixd.translate(-_center)*osg.Matrixd.rotate(_rotation.inverse()) void TestManipulator.computePosition( osg.Vec3 eye, osg.Vec3 lv, osg.Vec3 up) f = osg.Vec3(lv) f.normalize() s = osg.Vec3(f^up) s.normalize() u = osg.Vec3(s^f) u.normalize() rotation_matrix = osg.Matrixd(s[0], u[0], -f[0], 0.0, s[1], u[1], -f[1], 0.0, s[2], u[2], -f[2], 0.0, 0.0, 0.0, 0.0, 1.0) _center = eye+lv _distance = lv.length() _rotation = rotation_matrix.getRotate().inverse() bool TestManipulator.calcMovement() # return if less then two events have been added. if _ga_t0==NULL or _ga_t1==NULL : return False dx = _ga_t0.getXnormalized()-_ga_t1.getXnormalized() dy = _ga_t0.getYnormalized()-_ga_t1.getYnormalized()
def setDomeCorrection(viewer, arguments): wsi = osg.GraphicsContext.getWindowingSystemInterface() if not wsi : osg.notify(osg.NOTICE), "Error, no WindowSystemInterface available, cannot create windows." return unsigned int width, height wsi.getScreenResolution(osg.GraphicsContext.ScreenIdentifier(0), width, height) while arguments.read("--width",width) : while arguments.read("--height",height) : traits = osg.GraphicsContext.Traits() traits.x = 0 traits.y = 0 traits.width = width traits.height = height traits.windowDecoration = False traits.doubleBuffer = True traits.sharedContext = 0 gc = osg.GraphicsContext.createGraphicsContext(traits) if not gc : osg.notify(osg.NOTICE), "GraphicsWindow has not been created successfully." return tex_width = 512 tex_height = 512 camera_width = tex_width camera_height = tex_height texture = osg.TextureCubeMap() texture.setTextureSize(tex_width, tex_height) texture.setInternalFormat(GL_RGB) texture.setFilter(osg.Texture.MIN_FILTER,osg.Texture.LINEAR) texture.setFilter(osg.Texture.MAG_FILTER,osg.Texture.LINEAR) #if 0 renderTargetImplementation = osg.Camera.SEPERATE_WINDOW buffer = GL_FRONT #else: renderTargetImplementation = osg.Camera.FRAME_BUFFER_OBJECT buffer = GL_FRONT #endif # front face camera = osg.Camera() camera.setName("Front face camera") camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(0,0,camera_width, camera_height)) camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) camera.setAllowEventFocus(False) # tell the camera to use OpenGL frame buffer object where supported. camera.setRenderTargetImplementation(renderTargetImplementation) # attach the texture and use it as the color buffer. camera.attach(osg.Camera.COLOR_BUFFER, texture, 0, osg.TextureCubeMap.POSITIVE_Y) viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd()) # top face camera = osg.Camera() camera.setName("Top face camera") camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(0,0,camera_width, camera_height)) buffer = GL_BACK if (traits.doubleBuffer) else GL_FRONT camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) camera.setAllowEventFocus(False) # tell the camera to use OpenGL frame buffer object where supported. camera.setRenderTargetImplementation(renderTargetImplementation) # attach the texture and use it as the color buffer. camera.attach(osg.Camera.COLOR_BUFFER, texture, 0, osg.TextureCubeMap.POSITIVE_Z) viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd.rotate(osg.inDegrees(-90.0), 1.0,0.0,0.0)) # left face camera = osg.Camera() camera.setName("Left face camera") camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(0,0,camera_width, camera_height)) camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) camera.setAllowEventFocus(False) # tell the camera to use OpenGL frame buffer object where supported. camera.setRenderTargetImplementation(renderTargetImplementation) # attach the texture and use it as the color buffer. camera.attach(osg.Camera.COLOR_BUFFER, texture, 0, osg.TextureCubeMap.NEGATIVE_X) viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd.rotate(osg.inDegrees(-90.0), 0.0,1.0,0.0) * osg.Matrixd.rotate(osg.inDegrees(-90.0), 0.0,0.0,1.0)) # right face camera = osg.Camera() camera.setName("Right face camera") camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(0,0,camera_width, camera_height)) camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) camera.setAllowEventFocus(False) # tell the camera to use OpenGL frame buffer object where supported. camera.setRenderTargetImplementation(renderTargetImplementation) # attach the texture and use it as the color buffer. camera.attach(osg.Camera.COLOR_BUFFER, texture, 0, osg.TextureCubeMap.POSITIVE_X) viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd.rotate(osg.inDegrees(90.0), 0.0,1.0,0.0 ) * osg.Matrixd.rotate(osg.inDegrees(90.0), 0.0,0.0,1.0)) # bottom face camera = osg.Camera() camera.setGraphicsContext(gc) camera.setName("Bottom face camera") camera.setViewport(osg.Viewport(0,0,camera_width, camera_height)) camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) camera.setAllowEventFocus(False) # tell the camera to use OpenGL frame buffer object where supported. camera.setRenderTargetImplementation(renderTargetImplementation) # attach the texture and use it as the color buffer. camera.attach(osg.Camera.COLOR_BUFFER, texture, 0, osg.TextureCubeMap.NEGATIVE_Z) viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd.rotate(osg.inDegrees(90.0), 1.0,0.0,0.0) * osg.Matrixd.rotate(osg.inDegrees(180.0), 0.0,0.0,1.0)) # back face camera = osg.Camera() camera.setName("Back face camera") camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(0,0,camera_width, camera_height)) camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) camera.setAllowEventFocus(False) # tell the camera to use OpenGL frame buffer object where supported. camera.setRenderTargetImplementation(renderTargetImplementation) # attach the texture and use it as the color buffer. camera.attach(osg.Camera.COLOR_BUFFER, texture, 0, osg.TextureCubeMap.NEGATIVE_Y) viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd.rotate(osg.inDegrees(180.0), 1.0,0.0,0.0)) viewer.getCamera().setProjectionMatrixAsPerspective(90.0, 1.0, 1, 1000.0) # distortion correction set up. geode = osg.Geode() geode.addDrawable(createDomeDistortionMesh(osg.Vec3(0.0,0.0,0.0), osg.Vec3(width,0.0,0.0), osg.Vec3(0.0,height,0.0), arguments)) # we need to add the texture to the mesh, we do so by creating a # StateSet to contain the Texture StateAttribute. stateset = geode.getOrCreateStateSet() stateset.setTextureAttributeAndModes(0, texture,osg.StateAttribute.ON) stateset.setMode(GL_LIGHTING,osg.StateAttribute.OFF) camera = osg.Camera() camera.setGraphicsContext(gc) camera.setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ) camera.setClearColor( osg.Vec4(0.1,0.1,1.0,1.0) ) camera.setViewport(osg.Viewport(0, 0, width, height)) buffer = GL_BACK if (traits.doubleBuffer) else GL_FRONT camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) camera.setReferenceFrame(osg.Camera.ABSOLUTE_RF) camera.setAllowEventFocus(False) #camera.setInheritanceMask(camera.getInheritanceMask() ~osg.CullSettings.CLEAR_COLOR ~osg.CullSettings.COMPUTE_NEAR_FAR_MODE) #camera.setComputeNearFarMode(osg.CullSettings.DO_NOT_COMPUTE_NEAR_FAR) camera.setProjectionMatrixAsOrtho2D(0,width,0,height) camera.setViewMatrix(osg.Matrix.identity()) # add subgraph to render camera.addChild(geode) camera.setName("DistortionCorrectionCamera") viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd(), False) viewer.getCamera().setNearFarRatio(0.0001)
def setDomeFaces(viewer, arguments): wsi = osg.GraphicsContext.getWindowingSystemInterface() if not wsi : osg.notify(osg.NOTICE), "Error, no WindowSystemInterface available, cannot create windows." return unsigned int width, height wsi.getScreenResolution(osg.GraphicsContext.ScreenIdentifier(0), width, height) while arguments.read("--width",width) : while arguments.read("--height",height) : traits = osg.GraphicsContext.Traits() traits.x = 0 traits.y = 0 traits.width = width traits.height = height traits.windowDecoration = True traits.doubleBuffer = True traits.sharedContext = 0 gc = osg.GraphicsContext.createGraphicsContext(traits) if not gc : osg.notify(osg.NOTICE), "GraphicsWindow has not been created successfully." return center_x = width/2 center_y = height/2 camera_width = 256 camera_height = 256 # front face camera = osg.Camera() camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(center_x-camera_width/2, center_y, camera_width, camera_height)) buffer = GL_BACK if (traits.doubleBuffer) else GL_FRONT camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd()) # top face camera = osg.Camera() camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(center_x-camera_width/2, center_y+camera_height, camera_width, camera_height)) buffer = GL_BACK if (traits.doubleBuffer) else GL_FRONT camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd.rotate(osg.inDegrees(-90.0), 1.0,0.0,0.0)) # left face camera = osg.Camera() camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(center_x-camera_width*3/2, center_y, camera_width, camera_height)) buffer = GL_BACK if (traits.doubleBuffer) else GL_FRONT camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd.rotate(osg.inDegrees(-90.0), 0.0,1.0,0.0)) # right face camera = osg.Camera() camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(center_x+camera_width/2, center_y, camera_width, camera_height)) buffer = GL_BACK if (traits.doubleBuffer) else GL_FRONT camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd.rotate(osg.inDegrees(90.0), 0.0,1.0,0.0)) # bottom face camera = osg.Camera() camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(center_x-camera_width/2, center_y-camera_height, camera_width, camera_height)) buffer = GL_BACK if (traits.doubleBuffer) else GL_FRONT camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd.rotate(osg.inDegrees(90.0), 1.0,0.0,0.0)) # back face camera = osg.Camera() camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(center_x-camera_width/2, center_y-2*camera_height, camera_width, camera_height)) buffer = GL_BACK if (traits.doubleBuffer) else GL_FRONT camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd.rotate(osg.inDegrees(-180.0), 1.0,0.0,0.0)) viewer.getCamera().setProjectionMatrixAsPerspective(90.0, 1.0, 1, 1000.0) viewer.assignSceneDataToCameras() def createDomeDistortionMesh(origin, widthVector, heightVector, arguments): sphere_radius = 1.0 if arguments.read("--radius", sphere_radius) : collar_radius = 0.45 if arguments.read("--collar", collar_radius) : center = osg.Vec3d(0.0,0.0,0.0) eye = osg.Vec3d(0.0,0.0,0.0) distance = sqrt(sphere_radius*sphere_radius - collar_radius*collar_radius) if arguments.read("--distance", distance) : centerProjection = False projector = eye - osg.Vec3d(0.0,0.0, distance) osg.notify(osg.NOTICE), "Projector position = ", projector osg.notify(osg.NOTICE), "distance = ", distance # create the quad to visualize. geometry = osg.Geometry() geometry.setSupportsDisplayList(False) xAxis = osg.Vec3(widthVector) width = widthVector.length() xAxis /= width yAxis = osg.Vec3(heightVector) height = heightVector.length() yAxis /= height noSteps = 50 vertices = osg.Vec3Array() texcoords = osg.Vec3Array() colors = osg.Vec4Array() bottom = origin dx = xAxis*(width/((float)(noSteps-1))) dy = yAxis*(height/((float)(noSteps-1))) screenCenter = origin + widthVector*0.5 + heightVector*0.5 screenRadius = heightVector.length() * 0.5 int i,j if centerProjection : for(i=0i<noSteps++i) cursor = bottom+dy*(float)i for(j=0j<noSteps++j) delta = osg.Vec2(cursor.x() - screenCenter.x(), cursor.y() - screenCenter.y()) theta = atan2(-delta.y(), delta.x()) phi = osg.PI_2 * delta.length() / screenRadius if phi > osg.PI_2 : phi = osg.PI_2 phi *= 2.0 # osg.notify(osg.NOTICE), "theta = ", theta, "phi=", phi texcoord = osg.Vec3(sin(phi) * cos(theta), sin(phi) * sin(theta), cos(phi)) vertices.push_back(cursor) colors.push_back(osg.Vec4(1.0,1.0,1.0,1.0)) texcoords.push_back(texcoord) cursor += dx # osg.notify(osg.NOTICE) else:
def testGetQuatFromMatrix(scale): # Options # acceptable error range eps = 1e-6 # scale matrix # To not test with scale, use 1,1,1 # Not sure if 0's or negative values are acceptable scalemat = osg.Matrixd() scalemat.makeScale(scale) # range of rotations if True: # wide range rol1start = 0.0 rol1stop = 360.0 rol1step = 20.0 pit1start = 0.0 pit1stop = 90.0 pit1step = 20.0 yaw1start = 0.0 yaw1stop = 360.0 yaw1step = 20.0 rol2start = 0.0 rol2stop = 360.0 rol2step = 20.0 pit2start = 0.0 pit2stop = 90.0 pit2step = 20.0 yaw2start = 0.0 yaw2stop = 360.0 yaw2step = 20.0 else: # focussed range rol1start = 0.0 rol1stop = 0.0 rol1step = 0.1 pit1start = 0.0 pit1stop = 5.0 pit1step = 5.0 yaw1start = 89.0 yaw1stop = 91.0 yaw1step = 0.0 rol2start = 0.0 rol2stop = 0.0 rol2step = 0.0 pit2start = 0.0 pit2stop = 0.0 pit2step = 0.1 yaw2start = 89.0 yaw2stop = 91.0 yaw2step = 0.1 #endif print "Starting testGetQuatFromMatrix, it can take a while ..." tstart = osg.Timer.instance().tick() count = 0 for rol1 in arange(rol1start, rol1stop + 1, rol1step): # for (double pit1 = pit1start pit1 <= pit1stop pit1 += pit1step) for pit1 in arange(pit1start, pit1stop + 1, pit1step): # for (double yaw1 = yaw1start yaw1 <= yaw1stop yaw1 += yaw1step) for yaw1 in arange(yaw1start, yaw1stop + 1, yaw1step): # for (double rol2 = rol2start rol2 <= rol2stop rol2 += rol2step) for rol2 in arange(rol2start, rol2stop + 1, rol2step): # for (double pit2 = pit2start pit2 <= pit2stop pit2 += pit2step) for pit2 in arange(pit2start, pit2stop, pit2step): # for (double yaw2 = yaw2start yaw2 <= yaw2stop yaw2 += yaw2step) for yaw2 in arange(yaw2start, yaw2stop + 1, yaw2step): count += 1 # create two quats based on the roll, pitch and yaw values rot_quat1 = osg.Quat(osg.DegreesToRadians(rol1), osg.Vec3d(1, 0, 0), osg.DegreesToRadians(pit1), osg.Vec3d(0, 1, 0), osg.DegreesToRadians(yaw1), osg.Vec3d(0, 0, 1)) rot_quat2 = osg.Quat(osg.DegreesToRadians(rol2), osg.Vec3d(1, 0, 0), osg.DegreesToRadians(pit2), osg.Vec3d(0, 1, 0), osg.DegreesToRadians(yaw2), osg.Vec3d(0, 0, 1)) # create an output quat using quaternion math out_quat1 = rot_quat2 * rot_quat1 # create two matrices based on the input quats # osg.Matrixd mat1,mat2 mat1 = osg.Matrixd() mat2 = osg.Matrixd() mat1.makeRotate(rot_quat1) mat2.makeRotate(rot_quat2) # create an output quat by matrix multiplication and getRotate out_mat = mat2 * mat1 # add matrix scale for even more nastiness out_mat = out_mat * scalemat out_quat2 = out_mat.getRotate() # If the quaternion W is <0, then we should reflect # to get it into the positive W. # Unfortunately, when W is very small (close to 0), the sign # does not really make sense because of precision problems # and the reflection might not work. if out_quat1.w() < 0: out_quat1 = out_quat1 * -1.0 if out_quat2.w() < 0: out_quat2 = out_quat2 * -1.0 # if the output quat length is not one # or if the components do not match, # something is amiss componentsOK = False if (((abs(out_quat1.x() - out_quat2.x())) < eps) and ((abs(out_quat1.y() - out_quat2.y())) < eps) and ((abs(out_quat1.z() - out_quat2.z())) < eps) and ((abs(out_quat1.w() - out_quat2.w())) < eps)): componentsOK = True # We should also test for q = -q which is valid, so reflect # one quat. out_quat2 = out_quat2 * -1.0 if (((abs(out_quat1.x() - out_quat2.x())) < eps) and ((abs(out_quat1.y() - out_quat2.y())) < eps) and ((abs(out_quat1.z() - out_quat2.z())) < eps) and ((abs(out_quat1.w() - out_quat2.w())) < eps)): componentsOK = True lengthOK = False if (abs(1.0 - out_quat2.length()) < eps): lengthOK = True if (not lengthOK) or (not componentsOK): print[ "testGetQuatFromMatrix problem at: \n", " r1=", rol1, " p1=", pit1, " y1=", yaw1, " r2=", rol2, " p2=", pit2, " y2=", yaw2 ] print "quats: ", out_quat1, " length: ", out_quat1.length( ), "\n" print "mats and get: ", out_quat2, " length: ", out_quat2.length( ), "\n\n" tstop = osg.Timer.instance().tick() duration = osg.Timer.instance().delta_s(tstart, tstop) print "Time for testGetQuatFromMatrix with ", count, " iterations: ", duration
_restore = bool() DepthPeeling.CullCallback.CullCallback(unsigned int texUnit, unsigned int texWidth, unsigned int texHeight, unsigned int offsetValue) : _texUnit(texUnit), _texWidth(texWidth), _texHeight(texHeight), _offsetValue(offsetValue) void DepthPeeling.CullCallback.operator()(osg.Node* node, osg.NodeVisitor* nv) cullVisitor = static_cast<osgUtil.CullVisitor*>(nv) renderStage = cullVisitor.getCurrentRenderStage() viewport = renderStage.getViewport() m = osg.Matrixd(*cullVisitor.getProjectionMatrix()) m.postMultTranslate(osg.Vec3d(1, 1, 1)) m.postMultScale(osg.Vec3d(0.5, 0.5, 0.5)) # scale the texture coordinates to the viewport #ifdef USE_TEXTURE_RECTANGLE m.postMultScale(osg.Vec3d(viewport.width(), viewport.height(), 1)) #else: #ifndef USE_NON_POWER_OF_TWO_TEXTURE m.postMultScale(osg.Vec3d(viewport.width()/double(_texWidth), viewport.height()/double(_texHeight), 1)) #endif #endif if _texUnit not = 0 and _offsetValue : # Kind of polygon offset: note this way, we can also offset lines and points. # Whereas with the polygon offset we could only handle surface primitives.
class PosterPrinter (osg.Referenced) : typedef std.pair<unsigned int, unsigned int> TilePosition typedef std.map< TilePosition, osg.Image > TileImages PosterPrinter() #* Set to output each sub-image-tile to disk def setOutputTiles(b): _outputTiles = b def getOutputTiles(): return _outputTiles #* Set the output sub-image-tile extension, e.g. bmp def setOutputTileExtension(ext): _outputTileExt = ext def getOutputTileExtension(): return _outputTileExt #* Set the output poster name, e.g. output.bmp def setOutputPosterName(name): _outputPosterName = name def getOutputPosterName(): return _outputPosterName #* Set the size of each sub-image-tile, e.g. 640x480 def setTileSize(w, h): _tileSize.set(w, h) def getTileSize(): return _tileSize #* Set the final size of the high-res poster, e.g. 6400x4800 def setPosterSize(w, h): _posterSize.set(w, h) def getPosterSize(): return _posterSize #* Set the capturing camera def setCamera(camera): _camera = camera def getCamera(): return _camera #* Set the final poster image, should be already allocated def setFinalPoster(image): _finalPoster = image def getFinalPoster(): return _finalPoster def getPosterVisitor(): return _visitor def getPosterVisitor(): return _visitor def done(): return not _isRunning and not _isFinishing init = void( osg.Camera* camera ) init = void( osg.Matrixd view, osg.Matrixd proj ) frame = void( osg.FrameStamp* fs, osg.Node* node ) virtual ~PosterPrinter() addCullCallbacks = bool( osg.FrameStamp* fs, osg.Node* node ) removeCullCallbacks = void( osg.Node* node ) bindCameraToImage = void( osg.Camera* camera, int row, int col ) recordImages = void() _outputTiles = bool() _outputTileExt = str() _outputPosterName = str() _tileSize = osg.Vec2() _posterSize = osg.Vec2() _isRunning = bool() _isFinishing = bool() _lastBindingFrame = unsigned int() _tileRows = int() _tileColumns = int() _currentRow = int() _currentColumn = int() _intersector = PosterIntersector() _visitor = PosterVisitor() _currentViewMatrix = osg.Matrixd() _currentProjectionMatrix = osg.Matrixd() _camera = osg.Camera() _finalPoster = osg.Image() _images = TileImages()
# find coordinate system node from our parental chain i = unsigned int() for(i=0 i<nodePath.size() and csn==0 ++i) csn = dynamic_cast<osg.CoordinateSystemNode*>(nodePath[i]) if csn : ellipsoid = csn.getEllipsoidModel() if ellipsoid : inheritedMatrix = osg.Matrix() for(i+=1 i<nodePath.size()-1 ++i) transform = nodePath[i].asTransform() if transform : transform.computeLocalToWorldMatrix(inheritedMatrix, nv) matrix = osg.Matrixd(inheritedMatrix) #osg.Matrixd matrix ellipsoid.computeLocalToWorldTransformFromLatLongHeight(_latitude,_longitude,_height,matrix) matrix.preMultRotate(_rotation) mt.setMatrix(matrix) traverse(node,nv) _latitude = double() _longitude = double() _height = double() _rotation = osg.Quat() _speed = double()
class IntersectionUpdateCallback (osg.NodeCallback) : virtual void operator()(osg.Node* #node, osg.NodeVisitor* nv) if not root_ or not terrain_ or not ss_ or not intersectionGroup_ : osg.notify(osg.NOTICE), "IntersectionUpdateCallback not set up correctly." return #traverse(node,nv) frameCount_++ if frameCount_ > 200 : # first we need find the transformation matrix that takes # the terrain into the coordinate frame of the sphere segment. terrainLocalToWorld = osg.Matrixd() terrain_worldMatrices = terrain_.getWorldMatrices(root_) if terrain_worldMatrices.empty() : terrainLocalToWorld.makeIdentity() elif terrain_worldMatrices.size()==1 : terrainLocalToWorld = terrain_worldMatrices.front() else: osg.notify(osg.NOTICE), "IntersectionUpdateCallback: warning cannot interestect with multiple terrain instances, just uses first one." terrainLocalToWorld = terrain_worldMatrices.front() # sphere segment is easier as this callback is attached to the node, so the node visitor has the unique path to it already. ssWorldToLocal = osg.computeWorldToLocal(nv.getNodePath()) # now we can compute the terrain to ss transform possie = terrainLocalToWorld*ssWorldToLocal lines = ss_.computeIntersection(possie, terrain_) if not lines.empty() : if intersectionGroup_.valid() : # now we need to place the intersections which are in the SphereSegmenet's coordinate frame into # to the final position. mt = osg.MatrixTransform() mt.setMatrix(osg.computeLocalToWorld(nv.getNodePath())) intersectionGroup_.addChild(mt) # print "matrix = ", mt.getMatrix() geode = osg.Geode() mt.addChild(geode) geode.getOrCreateStateSet().setMode(GL_LIGHTING,osg.StateAttribute.OFF) for(osgSim.SphereSegment.LineList.iterator itr=lines.begin() not = lines.end() ++itr) geom = osg.Geometry() geode.addDrawable(geom) vertices = itr geom.setVertexArray(vertices) geom.addPrimitiveSet(osg.DrawArrays(GL_LINE_STRIP, 0, vertices.getNumElements())) else: osg.notify(osg.NOTICE), "No intersections found" frameCount_ = 0 root_ = osg.observer_ptr<osg.Group>() terrain_ = osg.observer_ptr<osg.Geode>() ss_ = osg.observer_ptr<osgSim.SphereSegment>() intersectionGroup_ = osg.observer_ptr<osg.Group>() frameCount_ = unsigned() class RotateUpdateCallback (osg.NodeCallback) : RotateUpdateCallback() i=0 virtual void operator()(osg.Node* node, osg.NodeVisitor* nv) ss = dynamic_cast<osgSim.SphereSegment *>(node) if ss : ss.setArea(osg.Vec3(cos(i/(2*osg.PI)),sin(i/(2*osg.PI)),0), osg.PI_2, osg.PI_2) i += 0.1 i = float() def createMovingModel(center, radius, terrainGeode, root, createMovingRadar): animationLength = 10.0 animationPath = createAnimationPath(center,radius,animationLength) model = osg.Group() glider = osgDB.readNodeFile("glider.osgt") if glider : bs = glider.getBound() size = radius/bs.radius()*0.3 positioned = osg.MatrixTransform() positioned.setDataVariance(osg.Object.STATIC) positioned.setMatrix(osg.Matrix.translate(-bs.center())* osg.Matrix.scale(size,size,size)* osg.Matrix.rotate(osg.inDegrees(-90.0),0.0,0.0,1.0)) positioned.addChild(glider) xform = osg.PositionAttitudeTransform() xform.getOrCreateStateSet().setMode(GL_NORMALIZE, osg.StateAttribute.ON) xform.setUpdateCallback(osg.AnimationPathCallback(animationPath,0.0,1.0)) xform.addChild(positioned) model.addChild(xform) if createMovingRadar : # The IntersectionUpdateCallback has to have a safe place to put all its generated geometry into, # and this group can't be in the parental chain of the callback otherwise we will end up invalidating # traversal iterators. intersectionGroup = osg.Group() root.addChild(intersectionGroup) xform = osg.PositionAttitudeTransform() xform.setUpdateCallback(osg.AnimationPathCallback(animationPath,0.0,1.0)) ss = osgSim.SphereSegment(osg.Vec3d(0.0,0.0,0.0), 700.0, # radius osg.DegreesToRadians(135.0), osg.DegreesToRadians(240.0), osg.DegreesToRadians(-60.0), osg.DegreesToRadians(-40.0), 60) iuc = IntersectionUpdateCallback() iuc.frameCount_ = 0 iuc.root_ = root iuc.terrain_ = terrainGeode iuc.ss_ = ss iuc.intersectionGroup_ = intersectionGroup ss.setUpdateCallback(iuc) ss.setAllColors(osg.Vec4(1.0,1.0,1.0,0.5)) ss.setSideColor(osg.Vec4(0.5,1.0,1.0,0.1)) xform.addChild(ss) model.addChild(xform) cessna = osgDB.readNodeFile("cessna.osgt") if cessna : bs = cessna.getBound() text = osgText.Text() size = radius/bs.radius()*0.3 text.setPosition(bs.center()) text.setText("Cessna") text.setAlignment(osgText.Text.CENTER_CENTER) text.setAxisAlignment(osgText.Text.SCREEN) text.setCharacterSize(40.0) text.setCharacterSizeMode(osgText.Text.OBJECT_COORDS) geode = osg.Geode() geode.addDrawable(text) lod = osg.LOD() lod.setRangeMode(osg.LOD.PIXEL_SIZE_ON_SCREEN) lod.setRadius(cessna.getBound().radius()) lod.addChild(geode,0.0,100.0) lod.addChild(cessna,100.0,10000.0) positioned = osg.MatrixTransform() positioned.getOrCreateStateSet().setMode(GL_NORMALIZE, osg.StateAttribute.ON) positioned.setDataVariance(osg.Object.STATIC) positioned.setMatrix(osg.Matrix.translate(-bs.center())* osg.Matrix.scale(size,size,size)* osg.Matrix.rotate(osg.inDegrees(180.0),0.0,0.0,1.0)) #positioned.addChild(cessna) positioned.addChild(lod) xform = osg.MatrixTransform() xform.setUpdateCallback(osg.AnimationPathCallback(animationPath,0.0,2.0)) xform.addChild(positioned) model.addChild(xform) return model def createOverlay(center, radius): group = osg.Group() # create a grid of lines. geom = osg.Geometry() num_rows = 10 left = center+osg.Vec3(-radius,-radius,0.0) right = center+osg.Vec3(radius,-radius,0.0) delta_row = osg.Vec3(0.0,2.0*radius/float(num_rows-1),0.0) top = center+osg.Vec3(-radius,radius,0.0) bottom = center+osg.Vec3(-radius,-radius,0.0) delta_column = osg.Vec3(2.0*radius/float(num_rows-1),0.0,0.0) vertices = osg.Vec3Array() for(unsigned int i=0 i<num_rows ++i) vertices.push_back(left) vertices.push_back(right) left += delta_row right += delta_row vertices.push_back(top) vertices.push_back(bottom) top += delta_column bottom += delta_column geom.setVertexArray(vertices) color = *(osg.Vec4ubArray(1)) color[0].set(0,0,0,255) geom.setColorArray(color, osg.Array.BIND_OVERALL) geom.addPrimitiveSet(osg.DrawArrays(GL_LINES,0,vertices.getNumElements())) geom.getOrCreateStateSet().setMode(GL_LIGHTING,osg.StateAttribute.OFF) geode = osg.Geode() geode.addDrawable(geom) group.addChild(geode) return group def computeTerrainIntersection(subgraph, x, y): bs = subgraph.getBound() zMax = bs.center().z()+bs.radius() zMin = bs.center().z()-bs.radius() intersector = osgUtil.LineSegmentIntersector(osg.Vec3(x,y,zMin),osg.Vec3(x,y,zMax)) iv = osgUtil.IntersectionVisitor(intersector) subgraph.accept(iv) if intersector.containsIntersections() : return intersector.getFirstIntersection().getWorldIntersectPoint() return osg.Vec3(x,y,0.0) ####################################### # MAIN SCENE GRAPH BUILDING FUNCTION ####################################### def build_world(root, testCase, useOverlay, technique): # create terrain terrainGeode = 0 terrainGeode = osg.Geode() stateset = osg.StateSet() image = osgDB.readImageFile("Images/lz.rgb") if image : texture = osg.Texture2D() texture.setImage(image) stateset.setTextureAttributeAndModes(0,texture,osg.StateAttribute.ON) terrainGeode.setStateSet( stateset ) numColumns = 38 numRows = 39 unsigned int r, c origin = osg.Vec3(0.0,0.0,0.0) size = osg.Vec3(1000.0,1000.0,250.0) geometry = osg.Geometry() v = *(osg.Vec3Array(numColumns*numRows)) tc = *(osg.Vec2Array(numColumns*numRows)) color = *(osg.Vec4ubArray(1)) color[0].set(255,255,255,255) rowCoordDelta = size.y()/(float)(numRows-1) columnCoordDelta = size.x()/(float)(numColumns-1) rowTexDelta = 1.0/(float)(numRows-1) columnTexDelta = 1.0/(float)(numColumns-1) # compute z range of z values of grid data so we can scale it. min_z = FLT_MAX max_z = -FLT_MAX for(r=0r<numRows++r) for(c=0c<numColumns++c) min_z = osg.minimum(min_z,vertex[r+c*numRows][2]) max_z = osg.maximum(max_z,vertex[r+c*numRows][2]) scale_z = size.z()/(max_z-min_z) pos = origin tex = osg.Vec2(0.0,0.0) vi = 0 for(r=0r<numRows++r) pos.x() = origin.x() tex.x() = 0.0 for(c=0c<numColumns++c) v[vi].set(pos.x(),pos.y(),pos.z()+(vertex[r+c*numRows][2]-min_z)*scale_z) tc[vi] = tex pos.x()+=columnCoordDelta tex.x()+=columnTexDelta ++vi pos.y() += rowCoordDelta tex.y() += rowTexDelta geometry.setVertexArray(v) geometry.setTexCoordArray(0, tc) geometry.setColorArray(color, osg.Array.BIND_OVERALL) for(r=0r<numRows-1++r) drawElements = *(osg.DrawElementsUShort(GL_QUAD_STRIP,2*numColumns)) geometry.addPrimitiveSet(drawElements) ei = 0 for(c=0c<numColumns++c) drawElements[ei++] = (r+1)*numColumns+c drawElements[ei++] = (r)*numColumns+c smoother = osgUtil.SmoothingVisitor() smoother.smooth(*geometry) terrainGeode.addDrawable(geometry) # create sphere segment ss = 0 terrainToSS = osg.Matrix() switch(testCase) case(0): ss = osgSim.SphereSegment( computeTerrainIntersection(terrainGeode,550.0,780.0), # center 510.0, # radius osg.DegreesToRadians(135.0), osg.DegreesToRadians(240.0), osg.DegreesToRadians(-10.0), osg.DegreesToRadians(30.0), 60) root.addChild(ss) break case(1): ss = osgSim.SphereSegment( computeTerrainIntersection(terrainGeode,550.0,780.0), # center 510.0, # radius osg.DegreesToRadians(45.0), osg.DegreesToRadians(240.0), osg.DegreesToRadians(-10.0), osg.DegreesToRadians(30.0), 60) root.addChild(ss) break case(2): ss = osgSim.SphereSegment( computeTerrainIntersection(terrainGeode,550.0,780.0), # center 510.0, # radius osg.DegreesToRadians(5.0), osg.DegreesToRadians(355.0), osg.DegreesToRadians(-10.0), osg.DegreesToRadians(30.0), 60) root.addChild(ss) break case(3): ss = osgSim.SphereSegment( computeTerrainIntersection(terrainGeode,550.0,780.0), # center 510.0, # radius osg.DegreesToRadians(0.0), osg.DegreesToRadians(360.0), osg.DegreesToRadians(-10.0), osg.DegreesToRadians(30.0), 60) root.addChild(ss) break case(4): ss = osgSim.SphereSegment(osg.Vec3d(0.0,0.0,0.0), 700.0, # radius osg.DegreesToRadians(135.0), osg.DegreesToRadians(240.0), osg.DegreesToRadians(-60.0), osg.DegreesToRadians(-40.0), 60) mt = osg.MatrixTransform() mt.setMatrix(osg.Matrix(-0.851781, 0.156428, -0.5, 0, -0.180627, -0.983552, -6.93889e-18, 0, -0.491776, 0.0903136, 0.866025, 0, 598.217, 481.957, 100, 1)) mt.addChild(ss) terrainToSS.invert(mt.getMatrix()) root.addChild(mt) break case(5): ss = osgSim.SphereSegment(osg.Vec3d(0.0,0.0,0.0), 700.0, # radius osg.DegreesToRadians(35.0), osg.DegreesToRadians(135.0), osg.DegreesToRadians(-60.0), osg.DegreesToRadians(-40.0), 60) mt = osg.MatrixTransform() mt.setMatrix(osg.Matrix(-0.851781, 0.156428, -0.5, 0, -0.180627, -0.983552, -6.93889e-18, 0, -0.491776, 0.0903136, 0.866025, 0, 598.217, 481.957, 100, 1)) mt.addChild(ss) terrainToSS.invert(mt.getMatrix()) root.addChild(mt) break case(6): ss = osgSim.SphereSegment(osg.Vec3d(0.0,0.0,0.0), 700.0, # radius osg.DegreesToRadians(-45.0), osg.DegreesToRadians(45.0), osg.DegreesToRadians(-60.0), osg.DegreesToRadians(-40.0), 60) mt = osg.MatrixTransform() mt.setMatrix(osg.Matrix(-0.851781, 0.156428, -0.5, 0, -0.180627, -0.983552, -6.93889e-18, 0, -0.491776, 0.0903136, 0.866025, 0, 598.217, 481.957, 100, 1)) mt.addChild(ss) terrainToSS.invert(mt.getMatrix()) root.addChild(mt) break case(7): ss = osgSim.SphereSegment( computeTerrainIntersection(terrainGeode,550.0,780.0), # center 510.0, # radius osg.DegreesToRadians(-240.0), osg.DegreesToRadians(-135.0), osg.DegreesToRadians(-10.0), osg.DegreesToRadians(30.0), 60) ss.setUpdateCallback(RotateUpdateCallback()) root.addChild(ss) break if ss.valid() : ss.setAllColors(osg.Vec4(1.0,1.0,1.0,0.5)) ss.setSideColor(osg.Vec4(0.0,1.0,1.0,0.1)) if not ss.getParents().empty() : ss.getParent(0).addChild(ss.computeIntersectionSubgraph(terrainToSS, terrainGeode)) if useOverlay : overlayNode = osgSim.OverlayNode(technique) overlayNode.getOrCreateStateSet().setTextureAttribute(1, osg.TexEnv(osg.TexEnv.DECAL)) bs = terrainGeode.getBound() overlaySubgraph = createOverlay(bs.center(), bs.radius()*0.5) overlaySubgraph.addChild(ss) overlayNode.setOverlaySubgraph(overlaySubgraph) overlayNode.setOverlayTextureSizeHint(1024) overlayNode.setOverlayBaseHeight(0.0) overlayNode.addChild(terrainGeode) root.addChild(overlayNode) else: root.addChild(terrainGeode) # create particle effects position = computeTerrainIntersection(terrainGeode,100.0,100.0) explosion = osgParticle.ExplosionEffect(position, 10.0) smoke = osgParticle.SmokeEffect(position, 10.0) fire = osgParticle.FireEffect(position, 10.0) root.addChild(explosion) root.addChild(smoke) root.addChild(fire) # create particle effects position = computeTerrainIntersection(terrainGeode,200.0,100.0) explosion = osgParticle.ExplosionEffect(position, 1.0) smoke = osgParticle.SmokeEffect(position, 1.0) fire = osgParticle.FireEffect(position, 1.0) root.addChild(explosion) root.addChild(smoke) root.addChild(fire) createMovingRadar = True # create the moving models. root.addChild(createMovingModel(osg.Vec3(500.0,500.0,500.0),100.0, terrainGeode, root, createMovingRadar)) ####################################### # main() ####################################### 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 of particle systems.") arguments.getApplicationUsage().setCommandLineUsage(arguments.getApplicationName()+" [options] image_file_left_eye image_file_right_eye") arguments.getApplicationUsage().addCommandLineOption("-h or --help","Display this information") # construct the viewer. viewer = osgViewer.Viewer(arguments) # if user request help write it out to cout. testCase = 0 while arguments.read("-t", testCase) : useOverlay = False technique = osgSim.OverlayNode.OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY while arguments.read("--object") : useOverlay = True technique = osgSim.OverlayNode.OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY while arguments.read("--ortho") or arguments.read("--orthographic") : useOverlay = True technique = osgSim.OverlayNode.VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY while arguments.read("--persp") or arguments.read("--perspective") : useOverlay = True technique = osgSim.OverlayNode.VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY # if user request help write it out to cout. if arguments.read("-h") or arguments.read("--help") : arguments.getApplicationUsage().write(std.cout) return 1 # any option left unread are converted into errors to write out later. arguments.reportRemainingOptionsAsUnrecognized() # report any errors if they have occurred when parsing the program arguments. if arguments.errors() : arguments.writeErrorMessages(std.cout) return 1 root = osg.Group() build_world(root, testCase, useOverlay, technique) # add a viewport to the viewer and attach the scene graph. viewer.setSceneData(root) return viewer.run() if __name__ == "__main__": main(sys.argv)
#include "CameraPathProperty.h" using namespace gsc void CameraPathProperty.update(osgViewer.View* view) camera = view.getCamera() fs = view.getFrameStamp() if _animationPath.valid() : cp = osg.AnimationPath.ControlPoint() _animationPath.getInterpolatedControlPoint( fs.getSimulationTime(), cp ) OSG_NOTICE, "CameraPathProperty ", fs.getFrameNumber(), " ", fs.getSimulationTime() matrix = osg.Matrixd() cp.getMatrix( matrix ) camera.setViewMatrix( osg.Matrix.inverse(matrix) ) void CameraPathProperty.loadAnimationPath() _animationPath = osg.AnimationPath() #_animationPath.setLoopMode(osg.AnimationPath.LOOP) in = osgDB.ifstream(_filename.c_str()) if not in : OSG_WARN, "CameraPathProperty: Cannot open animation path file \"", _filename, "\".\n" return _animationPath.read(in) bool CameraPathProperty.getTimeRange(double startTime, double endTime)
def singleWindowSideBySideCameras(viewer): wsi = osg.GraphicsContext.getWindowingSystemInterface() if not wsi : osg.notify(osg.NOTICE), "Error, no WindowSystemInterface available, cannot create windows." return unsigned int width, height wsi.getScreenResolution(osg.GraphicsContext.ScreenIdentifier(0), width, height) # Not fullscreen width /= 2 height /= 2 traits = osg.GraphicsContext.Traits() traits.x = 100 traits.y = 100 traits.width = width traits.height = height traits.windowDecoration = True traits.doubleBuffer = True traits.sharedContext = 0 gc = osg.GraphicsContext.createGraphicsContext(traits) if gc.valid() : osg.notify(osg.INFO), " GraphicsWindow has been created successfully." # need to ensure that the window is cleared make sure that the complete window is set the correct colour # rather than just the parts of the window that are under the camera's viewports gc.setClearColor(osg.Vec4f(0.2,0.2,0.6,1.0)) gc.setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) else: osg.notify(osg.NOTICE), " GraphicsWindow has not been created successfully." master = viewer.getCamera() # get the default settings for the camera double fovy, aspectRatio, zNear, zFar master.getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar) # reset this for the actual apsect ratio of out created window windowAspectRatio = double(width)/double(height) master.setProjectionMatrixAsPerspective(fovy, windowAspectRatio, 1.0, 10000.0) master.setName("MasterCam") camera = osg.Camera() camera.setCullMask(1) camera.setName("Left") camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(0, 0, width/2, height)) buffer = GL_BACK if (traits.doubleBuffer) else GL_FRONT camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) viewer.addSlave(camera, osg.Matrixd.scale(1.0,0.5,1.0), osg.Matrixd()) camera = osg.Camera() camera.setCullMask(2) camera.setName("Right") camera.setGraphicsContext(gc) camera.setViewport(osg.Viewport(width/2, 0, width/2, height)) buffer = GL_BACK if (traits.doubleBuffer) else GL_FRONT camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) viewer.addSlave(camera, osg.Matrixd.scale(1.0,0.5,1.0), osg.Matrixd())
optimizer.optimize(loadedModel) viewer.setSceneData( loadedModel ) if pbuffer.valid() : camera = osg.Camera() camera.setGraphicsContext(pbuffer) camera.setViewport(osg.Viewport(0,0,width,height)) buffer = GL_BACK if (pbuffer.getTraits().doubleBuffer) else GL_FRONT camera.setDrawBuffer(buffer) camera.setReadBuffer(buffer) camera.setFinalDrawCallback(WindowCaptureCallback(mode, position, readBuffer)) if pbufferOnly : viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd()) viewer.realize() else: viewer.realize() viewer.stopThreading() pbuffer.realize() viewer.addSlave(camera, osg.Matrixd(), osg.Matrixd()) viewer.startThreading() else: viewer.realize()